cancel
Showing results for 
Search instead for 
Did you mean: 

Jump to Freertos application

Qusai
Associate II

Hi all,

I have developed a bootloader for STM32F412, the bootloader works perfectly, however, when I change the user app to be FreeRTOS based, it ceases to work.

I added a blink led in the Hard Fault in both the bootloader and app, but both were not triggered.

Any idea what is going on?

void jump_to_application(void) {
    void (*app_reset_handler)(void);
    uint32_t msp_value = *(volatile uint32_t*)(APP_START_ADDRESS + APP_HEADER_SIZE);
    uint32_t reset_handler_address = *(volatile uint32_t*)(APP_START_ADDRESS + APP_HEADER_SIZE + 4);

    __disable_irq();

    HAL_RCC_DeInit();
    HAL_DeInit();

    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;


    for (uint32_t i = 0; i < 8; i++)
    {
        NVIC->ICER[i] = 0xFFFFFFFF;
        NVIC->ICPR[i] = 0xFFFFFFFF;
    }

    __enable_irq();

    __set_MSP(msp_value);
    __set_PSP(msp_value);
    __set_CONTROL(0);
    app_reset_handler = (void*)reset_handler_address;
    app_reset_handler();
} 



Thanks in advance.

Regards, 

1 ACCEPTED SOLUTION

Accepted Solutions
Qusai
Associate II

After investigating the binaries of both the bare-metal and FreeRTOS applications, I discovered the following: although both apps use the same linker script and startup code, FreeRTOS enforces a stricter alignment on memory sections. This caused the .text section to shift by three words, leaving a gap of three words filled with 0x00 after the .isr_vector section, which ultimately led to the PRECISERR fault.

Adding the linker option --gap-fill=0xFF in the post-build steps resolved the issue. By default, .bin and .hex files do not include gap-filling, whereas flashing the memory via the debugger automatically fills these gaps. This explains why the application worked when flashed through the debugger but not when loaded by my bootloader.

Additionally, in the bare-metal build, the .text section starts immediately after the .isr_vector section, whereas in the FreeRTOS build, a 16-byte alignment is enforced instead of the 4-byte alignment used in bare metal.

I haven’t yet identified exactly where does this alignment requirement come from, but the issue is now resolved, and the bootloader is running smoothly.

For context, I am using FreeRTOS CMSIS V2, and the files are generated using STM32CubeMX.

View solution in original post

15 REPLIES 15
TDK
Super User

Nothing wrong with the code posted. If app doesn't work, I wouldn't suspect an issue with the bootloader.

General rules:

  • Don't jump to application from within an interrupt.
If you feel a post has answered your question, please click "Accept as Solution".
KnarfB
Super User

FreeRTOS uses unprivileged access level for tasks. Are you sure the the MCU always has privileged acces level when your bootloader is executed?

hth

KnarfB

Qusai
Associate II

I am not jumping from an interrupt, after flashing is done, the bootloader should jump to the app immediately.

 

I am unware of this, enlighten me please. Does it have to do anything with __set_CONTROL(0); ??

Yes, and more like setting MSP, manipulating NVIC, ... All details are in the Cortex-M4 Technical Reference Manual.

This only matters if you enter the bootloader from a FreeRTOS thread for example. After reset, everything should work as expected. 

The bootloader is the main app in my case, and it will check whether the firmware is valid to jump to it, or stay in the bootloader, so I guess, this is irrelevant to my case, right?

 

Right.

Don't you have to set the Vector table offset register (VTOR) to a different value?

You may compare your code to How to Jump to the STM32 Bootloader and Return to the Application. 

hth

KnarfB

Pavel A.
Super User

Note that FreeRTOS needs VTOR to point to app interrupt vectors, and the 1st word of the vectors be the MSP for interrupts. Does your bootloader sets the MSP for the app to something else?

 

I have already done this on app side. Still not working.

In the provided code, 

WRITE_REG(SCB->VTOR, 0x08020200 & SCB_VTOR_TBLOFF_Msk);

 
My understanding is that setting the VTOR in the bootloader will have no effect, since, the app should take care of it. The base address is relevant when setting the MSP value, am I right?