cancel
Showing results for 
Search instead for 
Did you mean: 

bootloader start application in ram, can't run task

lbapplem
Associate II

hello:

    I use NUCLEO-H7A3ZI-Q to implement a bootloader feature:the bootloader runs in 0x08000000 at flash, it'll copy the application stored in 0x08005000 to 0x24000000 in RAM, then jump to 0x24000000, if one LED turns on, indicates jumping to application successfully, and it does, but another two LEDs fail to turn on in a task, I doubt the interrupt fails and the task can't be scheduled, but I've set the SCB->VTOR = 0x24000000 both in bootloader and application, here're some codes in bootloader, plus about application, I use the default ram.ld file generated by the IDE, if I run the application by using the IDE in debug mode, it works well, three LEDs all turn, I don't understand if the bootloader and IDE do the same thing(move application to ram) why the behaviors are different?can you help me to figure out what can be the cause? Thanks.

void JumpToApplication(uint32_t jump_address)
{
void (*app_reset_handler)(void);

uint32_t main_stack_pointer_value = *(volatile uint32_t *)jump_address;
uint32_t reset_handler = *(volatile uint32_t *)(jump_address + 4);

app_reset_handler = (void*) reset_handler;
/**
* Step: Disable all interrupts
*/
__disable_irq();
HAL_RCC_DeInit();
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
SCB->VTOR = jump_address;
/**
* Step: Enable all interrupts
*/
__enable_irq();

__set_MSP(main_stack_pointer_value);

app_reset_handler();

}

void Copy2RamJump(void)
{
uint32_t app_addr = APP_START_ADDR;
uint32_t ram_exec_addr = RAM_EXECUTION_ADDRESS;
uint8_t* size_ptr = (uint8_t*)app_addr;
//the first 4 bytes is the size of executive image exclude 4 bytes CRC and the size itself
uint32_t size = (size_ptr[0] | (uint32_t)size_ptr[1] << 8 | (uint32_t)size_ptr[2] << 16 | (uint32_t)size_ptr[3] << 24) / 4 + 1;
uint32_t *flash_ptr = (uint32_t *)(app_addr + 4);//skip first 4 bytes which is size
uint32_t *ram_ptr = (uint32_t *)ram_exec_addr;
for (uint32_t i = 0; i < size; i++)
{
ram_ptr[i] = flash_ptr[i];
}
// Jump to RAM execution address
JumpToApplication(ram_exec_addr);
}

Bill

1 REPLY 1

Like the fourth question on this.

a) instrument this so you can observe what's happening and confirm addresses and values at each step.

b) use the debugger, step into the control transfer

c) have a working hard fault handler so you can unpack that

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..