I am working on a bootloader and an application on the F28M36 M3 core. These are two entirely separate programs, each with their own CCS projects.
The bootloader is programmed into flash sector N and M (0x200000) and does not use an RTOS. Eventually, it will check program validity and allow updates from some external sources to application flash (after copying itself to RAM). It is not intended to ever be changed (though, in theory, it could, just at the risk of corrupting itself).
The application is programmed into the remaining sectors (starts at 0x210000, but main program space is 0x218000). The application uses TI-RTOS, and is currently basically a blinky example with modified linker layouts to avoid the bootloader and provide a known address to jump to.
When the bootloader concludes that the application should start (i.e. no update or completed update), it jumps to the application start, and begins execution.
The project setups look like this:
main_bootloader.c
static void jumpStackPointer(uint32_t address)
{
__asm(" mov sp, r0\n" // sp is now *address
" bx r0\n" ); // jump to *address
}
void jumpToApplication(void)
{
/*
* Disable interrupts
* Doesn't work with or without this line.
* With this line means PRIMASK will be 1 after start app
* Without means PRIMASK will be 0
*/
IntMasterDisable();
/* Adding this gives a hard fault */
//HWREG(NVIC_VTABLE) = 0x210000; // redirect the vector table
jumpStackPointer(0x210000 + 1);
}
bootloader.cmd
MEMORY
{
/* Flash Block 0, Sector N */
RESETISR (RX) : origin = 0x00200030, length = 0x0008
INTVECS (RX) : origin = 0x00201000, length = 0x0258
/* Flash copied to RAM (e.g. Flash API functions)
* for now, all BL functions go here, but that's not required
*/
FLASHLOAD (RX) : origin = 0x00201258, length = 0xEDA8
/* Flash Block 0, Sector L to Flash Block 0, Sector A, minus Z2 CSM */
/* Application flash, not used by bootloader */
APP_FLASH (RX) : origin = 0x00210000, length = 0xEFE00
...
}
application.cfg
var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
m3Hwi.resetVectorAddress = 0x218000;
application.cmd
MEMORY
{
BOOTROM (RX) : origin = 0x0, length = 0x10000
/* Bootloader Reset ISR */
BL_RESETISR (RX) : origin = 0x00200030, length = 0x0008
/* Application starts at Flash Block 0, Sector L */
/* Reset ISR is mapped to bootloader-known address */
FLASH_BOOT (RX) : origin = 0x00210000, length = 0x0008
/* not currently used */
INTVECS (RX) : origin = 0x00211000, length = 0x0258
/* For storing code in Flash to copy to RAM at runtime
* Remainder of Flash Block 0, Sector L */
FLASHLOAD (RX) : origin = 0x00211258, length = 0x6DA8
/* Flash Block 0, Sector K to Flash Block 0, Sector A - minus Z2 CSM*/
FLASH (RX) : origin = 0x00218000, length = 0xE7E00
/* RAM areas */
C03SRAM (RWX) : origin = 0x20000000, length = 0x8000
S07SHRAM (RWX) : origin = 0x20008000, length = 0x10000
C415SRAM (RWX) : origin = 0x20018000, length = 0x18000
CTOMMSGRAM (R) : origin = 0x2007F000, length = 0x800
MTOCMSGRAM (RW) : origin = 0x2007F800, length = 0x800
}
SECTIONS
{
/* Allocate program areas: */
.text : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.binit : > FLASH
.init_array : > FLASH
/* Initialized sections go in Flash */
.const : > FLASH
/* Allocate uninitalized data sections: */
.data : > C03SRAM | C415SRAM
.bss : > C03SRAM | C415SRAM
.dma : > S07SHRAM | C415SRAM
.sysmem : > C03SRAM | C415SRAM
.stack : > C03SRAM | C415SRAM
.cio : > C03SRAM | C415SRAM
.neardata : > C03SRAM | C415SRAM
.rodata : > C03SRAM | C415SRAM
.args : > C03SRAM | C415SRAM
}
__STACK_TOP = __stack + 256;
Both programs compile and run in isolation. Some bits of the map files indicate things look normal - the application doesn't have anything in BL flash and the BL has nothing in application flash, and each has a _c_int00 entry point:
bootloader.map
ENTRY POINT SYMBOL: "_c_int00" address: 0020975d
MEMORY CONFIGURATION
name origin length used unused attr fill
---------------------- -------- --------- -------- -------- ---- --------
RESETISR 00200030 00000008 00000006 00000002 R X
INTVECS 00201000 00000258 00000200 00000058 R X
FLASHLOAD 00201258 0000eda8 00008b54 00006254 R X
APP_FLASH 00210000 000efe00 00000000 000efe00 R
...
application.map
ENTRY POINT SYMBOL: "_c_int00" address: 0021ff55
MEMORY CONFIGURATION
name origin length used unused attr fill
---------------------- -------- --------- -------- -------- ---- --------
BOOTROM 00000000 00010000 00000000 00010000 R X
BL_RESETISR 00200030 00000008 00000000 00000008 R X
FLASH_BOOT 00210000 00000008 00000004 00000004 R X
INTVECS 00211000 00000258 00000000 00000258 R X
FLASHLOAD 00211258 00006da8 00000000 00006da8 R X
FLASH 00218000 000e7e00 0000c3ac 000dba54 R X
C03SRAM 20000000 00008000 000020fb 00005f05 RW
S07SHRAM 20008000 00010000 00000000 00010000 RW X
C415SRAM 20018000 00018000 00000000 00018000 RW X
CTOMMSGRAM 2007f000 00000800 00000000 00000800 R
MTOCMSGRAM 2007f800 00000800 00000000 00000800 RW
GLOBAL SYMBOLS: SORTED BY Symbol Address
address name
------- ----
00000000 __ASM__
...
00000300 __STACK_SIZE
00210001 _ti_catalog_arm_cortexm3_concertoInit_Boot_entry
00218000 ti_sysbios_family_arm_m3_Hwi_resetVectors
0021803d SysCtlSRAMSizeGet
...
When I call the bootloader jump into the application, it does work - the program goes off into the higher flash memory, first to 0x210000, when it vectors to _c_int00:
00210000: F00FBFA8 b.w #0x21ff54
The reset vectors "ti_sysbios_family_arm_m3_Hwi_resetVectors" at 0x218000 (start of main application flash area) also look plausible:
00218000: 1DFC adds r4, r7, #7 00218002: 2000 movs r0, #0 00218004: FF550021 vhadd.u16 d16, d5, d17 00218008: 12C5 asrs r5, r0, #0xb 0021800a: 0022 movs r2, r4 0021800c: 12C5 asrs r5, r0, #0xb 0021800e: 0022 movs r2, r4 00218010: 12C5 asrs r5, r0, #0xb 00218012: 0022 movs r2, r4
After that, the the LEDs light up (they initialise to on) and the program starts, but gets stuck in the idle task: ti_sysbios_knl_Idle_loop__E and ti_sysbios_knl_Idle_run__E. I lose all debugging symbols after the jump, but the application map file tells me what the addresses are.
I have tried not turning the interrupts off before jumping (which seems dangerous). This had the effect of not setting PRIMASK to 1 when the application runs, but otherwise did nothing.
I have also tried setting the XDC bootFromFlash config to false, but that didn't change anything either:
var Boot = xdc.useModule('ti.catalog.arm.cortexm3.concertoInit.Boot');
Boot.bootFromFlash = false;
Is there a further step I should take when jumping into a TI-RTOS application from a bootloader on an F28M36 M3 processor?