Jump to FreeRTOS application

Is it now same as the projects I shared above or does it still have more features which can be removed to just test the bootloader?

You do not need to touch VTOR in the app. Only bootloader needs to program it before jumping to the application.

Is it possible to turn off the USB peripheral to eliminate this possibility?

Making the bootloader as simple as possible can help us narrow down the problem.

I have the STM32F429I-DISC1 discovery board. If you can create a project for that board, I can give that a try.

Hi friend, I encountered this bug. The reason is that when jumping to the app, the program will jump to the Reset_Handler of the app. In the Reset_Handler function, the VTOR register is reset to address 0x0800 0000 (Default). Solution: Reset VTOR at the beginning of main()

Does your Reset Handler reset VTOR explicitly? I think you should remove that if so.

UPDATE:

This is my latest jump method:

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();



    for( uint32_t i = 0; i < 8; i++ )

    {

        NVIC->ICER[ i ] = 0xFFFFFFFF;

    }



	HAL_RNG_DeInit(&hrng);

	USBD_Stop(&hUsbDeviceFS);

	USBD_DeInit(&hUsbDeviceFS);

	HAL_PCD_DeInit(&hpcd_USB_OTG_FS);

	HAL_NVIC_DisableIRQ(OTG_FS_IRQn);

    __HAL_RCC_USB_OTG_FS_CLK_DISABLE();

    __HAL_RCC_USB_OTG_FS_FORCE_RESET();

    __HAL_RCC_USB_OTG_FS_RELEASE_RESET();



    HAL_RCC_DeInit();

    HAL_DeInit();





    for( uint32_t i = 0; i < 8; i++ )

    {

        NVIC->ICPR[ i ] = 0xFFFFFFFF;

    }



	SysTick->CTRL = 0;

	SysTick->LOAD = 0;

	SysTick->VAL  = 0;

	SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk ;

	SCB->VTOR = ( uint32_t ) (APP_START_ADDRESS + APP_HEADER_SIZE);



    __set_MSP(msp_value);

//    __set_PSP(msp_value);

    __set_CONTROL(0);

    app_reset_handler = (void*)reset_handler_address;

    app_reset_handler();

}

Now, I am getting hard fault “precise data access violation“ address 0x8100000.

I tried jumping to the app from the system init to avoid any deinitialization issues, however, I am always getting “Invalid state“ error.

The App now is aligned at 0x8040000 address, I tried with and without the header. No progress.

The VTOR is right. And here is a chunk of the linker script of the app

/* Entry Point */

ENTRY(Reset_Handler)



/* Highest address of the user mode stack */

_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */



_Min_Heap_Size = 0x200; /* required amount of heap */

_Min_Stack_Size = 0x400; /* required amount of stack */



/* Memories definition */

MEMORY

{

  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 256K

  FLASH    (rx)    : ORIGIN = 0x8040000,   LENGTH = 128K

}

And this is the Linker of the bootloader:

/* Entry Point */

ENTRY(Reset_Handler)



/* Highest address of the user mode stack */

_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */



_Min_Heap_Size = 0x200; /* required amount of heap */

_Min_Stack_Size = 0x400; /* required amount of stack */



/* Memories definition */

MEMORY

{

  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K

  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 128K

}

Any leads?

What code is trying to access this address? Looking at your linker scripts, this does not look like a valid address.

Step through the jump_to_application and ensure that the MSP and reset handler address of app are correct.

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 FreeRTOS enforces this alignment, but the issue is now resolved, and the bootloader is running smoothly.

I do not think we enforce any such alignment. Please share whatever you find.

Thank you for sharing your solution!

To be more precise, this issue may have been introduced by STM32CubeIDE when generating the FreeRTOS files. For context, I am using CMSIS v2.