cancel
Showing results for 
Search instead for 
Did you mean: 

task doesn't start when run in ram

lbapplem
Associate II

hello:

    I use NUCLEO-H7A3ZI-Q to test a bootloader feature:the bootloader runs in 0x08000000 at flash, when it starts, it copies the application stored in 0x08005000 to 0x24000000 in RAM, then jump to 0x24000000, I turn on a led in main function to signal the success, so far it works well, but if I put the turn on code in a task, the led won't be turned on, which means the task fails to run, also if I use HAL_Delay in main, it will be stuck in HAL_Delay, can anyone help me out? Thanks.

Bill

1 ACCEPTED SOLUTION

Accepted Solutions
SofLit
ST Employee

Hello @lbapplem ,

Based on the statement below it's mostly related to the vector table that was not inline with your new mapping as it's a code execution from RAM:


@lbapplem wrote:

if I use HAL_Delay in main, it will be stuck in HAL_Delay, 


HAL_Delay is using system tick interrupt and the vector table start address is wongly set.

Look for example at system_stm32h7xx.c file, the vector table start address register (VTOR) has different values according to the location:

 

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = D1_AXISRAM_BASE  | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal FLASH */
#endif  

 

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

3 REPLIES 3

Not sure with the level of detail provided.

Make sure SCB->VTOR points to a vector table you've placed at 0x24000000 and those vectors point to the right routines and the right addresses.

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

Hello @lbapplem ,

Based on the statement below it's mostly related to the vector table that was not inline with your new mapping as it's a code execution from RAM:


@lbapplem wrote:

if I use HAL_Delay in main, it will be stuck in HAL_Delay, 


HAL_Delay is using system tick interrupt and the vector table start address is wongly set.

Look for example at system_stm32h7xx.c file, the vector table start address register (VTOR) has different values according to the location:

 

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = D1_AXISRAM_BASE  | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal FLASH */
#endif  

 

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

hi, SofLit:

    I've tried according to your suggestion by adding SCB->VTOR = 0x24000000 in main function of application, then if I use STM32CubeIDE 1.16.0 to run in debug mode, all LEDs will turn on which indicate the task run normally, but if I use bootloader to copy the application from flash to ram, still the same result, and the code in bootloader is below, can you help to check if anything I missed here? 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