Content originally posted in LPCWare by kris_sin on Wed Feb 19 14:31:19 MST 2014
Maybe I will start. I made a very simple blinky led - like example in LPCXpresso 6.1.4. I modified linker script to something like this:
MEMORY
{
/* Define each memory region */
Flash (rx) : ORIGIN = 0x14000000, LENGTH = 256K /* 256K bytes */
Ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K /* 128K bytes */
Shadow_Ram (rwx) : ORIGIN = 0x00000000, LENGTH = 128K /* 128K bytes */
}
EXTERN (ResetISR)
ENTRY(ResetISR)
GROUP(libcr_c.a libcr_eabihelpers.a)
SECTIONS
{
.text : {
. = ALIGN(0x400);
_text_ram = (. - ORIGIN(Shadow_Ram)) + ORIGIN(Ram);
*(.isr_vector)
*(.text*)
. = ALIGN(4);
*(.rodata*)
. = ALIGN(4);
*(.after_vectors*)
} >Shadow_Ram
. = ALIGN(4);
_etext = .;
_etext_ram = (. - ORIGIN(Shadow_Ram)) + ORIGIN(Ram);
_etext_rom = (. - ORIGIN(Shadow_Ram)) + ORIGIN(Flash);
. = ORIGIN(Ram);
.data : {
_data = .;
*(.data*) /* Read-write initialized data */
. = ALIGN(4);
_edata = .;
} >Ram AT >Shadow_Ram
_data_loadaddr = LOADADDR(.data);
_data_rom = LOADADDR (.data) + ORIGIN(Flash);
_edata_rom = _data_rom + SIZEOF (.data);
.bss : {
_bss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >Ram
PROVIDE(_pvHeapStart = .);
PROVIDE(_vStackTop = ORIGIN(Ram) + ( ORIGIN(Shadow_Ram) + LENGTH(Shadow_Ram) - 32 ) );
}
So the program should be downloaded to shadow memory located in 0x00000000. Then I modified cr_startup_lpc43xx.c file so while in ResetISR() I will copy the code from SPIFI Flash to internal SRAM. Startup code below:
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
#define CREG_BASE 0x40043000
#define MMIO32(addr) (*(volatile unsigned long *)(addr))
#define CREG_M4MEMMAP MMIO32(CREG_BASE + 0x100)
extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
extern unsigned long _text_ram; /* Correspond to start of Code in RAM */
extern unsigned long _etext_ram; /* Correspond to end of Code in RAM */
extern unsigned long _etext_rom; /* Correspond to end of Code in ROM */
extern unsigned long _etext;
extern void main(void);
extern void _vStackTop(void);
extern void SystemInit(void);
void pre_main(void);
void ResetISR(void);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void MemManage_Handler(void);
WEAK void BusFault_Handler(void);
WEAK void UsageFault_Handler(void);
WEAK void SVC_Handler(void);
WEAK void DebugMon_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
WEAK void IntDefaultHandler(void);
void DAC_IRQHandler(void) ALIAS(IntDefaultHandler);
void M0CORE_IRQHandler(void) ALIAS(IntDefaultHandler);
void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);
void FLASH_EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler);
void ETH_IRQHandler(void) ALIAS(IntDefaultHandler);
void SDIO_IRQHandler(void) ALIAS(IntDefaultHandler);
void LCD_IRQHandler(void) ALIAS(IntDefaultHandler);
void USB0_IRQHandler(void) ALIAS(IntDefaultHandler);
void USB1_IRQHandler(void) ALIAS(IntDefaultHandler);
void SCT_IRQHandler(void) ALIAS(IntDefaultHandler);
void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);
void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);
void ADC0_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);
void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);
void ADC1_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2S0_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2S1_IRQHandler(void) ALIAS(IntDefaultHandler);
void SPIFI_IRQHandler(void) ALIAS(IntDefaultHandler);
void SGPIO_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO0_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO1_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO2_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO3_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO4_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO5_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO6_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO7_IRQHandler(void) ALIAS(IntDefaultHandler);
void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
void EVRT_IRQHandler(void) ALIAS(IntDefaultHandler);
void CAN1_IRQHandler(void) ALIAS(IntDefaultHandler);
void VADC_IRQHandler(void) ALIAS(IntDefaultHandler);
void ATIMER_IRQHandler(void) ALIAS(IntDefaultHandler);
void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);
void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
void M0SUB_IRQHandler(void) ALIAS(IntDefaultHandler);
void CAN0_IRQHandler(void) ALIAS(IntDefaultHandler);
void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);
//*****************************************************************************
//
// The vector table.
// This relies on the linker script to place at correct location in memory.
//
//*****************************************************************************
extern void (* const g_pfnVectors[])(void);
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
// Core Level - CM4
&_vStackTop, // The initial stack pointer
ResetISR, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
PendSV_Handler, // The PendSV handler
SysTick_Handler, // The SysTick handler
// Chip Level - LPC43 (M4)
DAC_IRQHandler, // 16
M0CORE_IRQHandler, // 17
DMA_IRQHandler, // 18
0, // 19
FLASH_EEPROM_IRQHandler, // 20
ETH_IRQHandler, // 21
SDIO_IRQHandler, // 22
LCD_IRQHandler, // 23
USB0_IRQHandler, // 24
USB1_IRQHandler, // 25
SCT_IRQHandler, // 26
RIT_IRQHandler, // 27
TIMER0_IRQHandler, // 28
TIMER1_IRQHandler, // 29
TIMER2_IRQHandler, // 30
TIMER3_IRQHandler, // 31
MCPWM_IRQHandler, // 32
ADC0_IRQHandler, // 33
I2C0_IRQHandler, // 34
I2C1_IRQHandler, // 35
SPI_IRQHandler, // 36
ADC1_IRQHandler, // 37
SSP0_IRQHandler, // 38
SSP1_IRQHandler, // 39
UART0_IRQHandler, // 40
UART1_IRQHandler, // 41
UART2_IRQHandler, // 42
UART3_IRQHandler, // 43
I2S0_IRQHandler, // 44
I2S1_IRQHandler, // 45
SPIFI_IRQHandler, // 46
SGPIO_IRQHandler, // 47
GPIO0_IRQHandler, // 48
GPIO1_IRQHandler, // 49
GPIO2_IRQHandler, // 50
GPIO3_IRQHandler, // 51
GPIO4_IRQHandler, // 52
GPIO5_IRQHandler, // 53
GPIO6_IRQHandler, // 54
GPIO7_IRQHandler, // 55
GINT0_IRQHandler, // 56
GINT1_IRQHandler, // 57
EVRT_IRQHandler, // 58
CAN1_IRQHandler, // 59
0, // 60
VADC_IRQHandler, // 61
ATIMER_IRQHandler, // 62
RTC_IRQHandler, // 63
0, // 64
WDT_IRQHandler, // 65
M0SUB_IRQHandler, // 66
CAN0_IRQHandler, // 67
QEI_IRQHandler, // 68
};
void ResetISR(void)
{
unsigned long *src, *dest;
unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
for (src = &_data_loadaddr, dest = &_data;
dest < &_edata;
src++, dest++) {
*dest = *src;
}
while (dest < &_ebss) {
*dest++ = 0;
}
pre_main();
*pSCB_VTOR = (unsigned int) g_pfnVectors;
main();
//
// main() shouldn't return, but if it does, we'll just enter an infinite loop
//
while(1)
{
}
}
/**
*
*/
void pre_main(void)
{
volatile unsigned *src, *dest;
/* Copy the code from ROM to Real RAM (if enabled) */
if ((&_etext_ram-&_text_ram) > 0)
{
src = &_etext_rom-(&_etext_ram-&_text_ram);
/* Change Shadow memory to ROM (for Debug Purpose in case Boot
* has not set correctly the M4MEMMAP because of debug)
*/
CREG_M4MEMMAP = (unsigned long)src;
for (dest = &_text_ram; dest < &_etext_ram; ) {
*dest++ = *src++;
}
/* Change Shadow memory to Real RAM */
CREG_M4MEMMAP = (unsigned long)&_text_ram;
/* Continue Execution in RAM */
}
}
//*****************************************************************************
// Default exception handlers. Override the ones here by defining your own
// handler routines in your application code.
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void NMI_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void HardFault_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void MemManage_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void BusFault_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void UsageFault_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void SVC_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void DebugMon_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void PendSV_Handler(void) {
while (1) {
}
}
__attribute__ ((section(".after_vectors")))
void SysTick_Handler(void) {
while (1) {
}
}
//*****************************************************************************
//
// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.
//
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void IntDefaultHandler(void) {
while (1) {
}
}
As You see after copying ROM to RAM I change memory mapping pointer to internal SRAM.
My current problem is that I cannot write to address 0x00000000 using LPCXpresso's flash loader for SPIFI. Every time I try to debug or just download using GUI, it throws an error that it cannot write to 0x0 address. From the way I thought I should be able to write the image at this place but the software needs to take care of memory mapping register to proper address. I use NXG LPCXplorer 4330 and LPC-Link as debugger.
When I replace "Shadow_Ram" into "Ram", the program will be executed in internal SRAM without any problems but mu intention is to have the code in SPIFI Flash and after reset copy the code in SRAM and execute it from there.
Can anyone from LPCXpresso support can help me with that. Is it even possible with that toolset execute this kind of application?