I wrote a very simplistic bootloader, that (for now) doesn't do anything but jumps to the application.
bootloader code:
Code: Select all
#define PROG_START 0x0800C000
static void prepareInterruptsForJump() {
// interrupt control
SCB->ICSR &= ~SCB_ICSR_PENDSVSET_Msk;
// set interrupt vectors
for(int i = 0; i < 8; i++)
NVIC->ICER[i] = NVIC->IABR[i];
__set_CONTROL(0);
}
void JumpToProg(uint32_t addr) {
typedef void (*pFunction)(void);
chSysDisable();
uint32_t jumpAddress = *((uint32_t *)(addr + 4));
pFunction jump = (pFunction)jumpAddress;
prepareInterruptsForJump();
SCB->VTOR = addr;
// set stack pointer
__set_MSP(*(uint32_t *)addr);
// call
jump();
// all is lost if we ever get here
chSysHalt("jump() FAIL");
}
int main(void) {
halInit();
chSysInit();
JumpToProg(PROG_START);
My application code executes fine when .ld file is set to 0x08000000, but when I change it to 0x0800C000 and flash the bootloader I can't get the application code to run. The bootloader executes OK.
Linker of the application code:
Code: Select all
MEMORY
{
flash0 (rx) : org = 0x0800C000, len = 464k
flash1 (rx) : org = 0x00000000, len = 0
flash2 (rx) : org = 0x00000000, len = 0
flash3 (rx) : org = 0x00000000, len = 0
flash4 (rx) : org = 0x00000000, len = 0
flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0
ram0 (wx) : org = 0x20000000, len = 128k /* SRAM1 + SRAM2 */
ram1 (wx) : org = 0x20000000, len = 112k /* SRAM1 */
ram2 (wx) : org = 0x2001C000, len = 16k /* SRAM2 */
ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x10000000, len = 64k /* CCM SRAM */
ram5 (wx) : org = 0x40024000, len = 4k /* BCKP SRAM */
ram6 (wx) : org = 0x00000000, len = 0
ram7 (wx) : org = 0x00000000, len = 0
}
When I flash the .bin of the application code to 0x08000000 the code executes fine, but that's without the bootloader of course. I'm currently not sure if the Jump() inside the bootloader code is not working correctly or of the application code is not executing.