Skip to main content
Explorer
September 14, 2024
Solved

task doesn't start when run in ram

  • September 14, 2024
  • 2 replies
  • 961 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 

     

     

    2 replies

    Graduate II
    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.

    mƎALLEmAnswer
    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 

     

     

    lbapplemAuthor
    Explorer
    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