Skip to main content
Associate II
September 14, 2024
Solved

task doesn't start when run in ram

  • September 14, 2024
  • 3 replies
  • 1013 views

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

This topic has been closed for replies.
Best answer by mƎALLEm

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 

 

 

3 replies

Tesla DeLorean
Guru
September 14, 2024

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
September 15, 2024

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 "Best answer" on the reply which solved your issue or answered your question.
lbapplemAuthor
Associate II
September 18, 2024

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