cancel
Showing results for 
Search instead for 
Did you mean: 

Executing code at AXI SRAM in STM32H750 (custom bootloader)

AFedu.1
Associate II

Hello everyone!

I am developing a custom bootloader for STM32H750XBH and run into problem:

  • some applications successfully start and run in AXI SRAM (0x2400 0000);
  • some applications starting but breaks somewhere.

Note: both kind of applications very similar, they have the same peripheral initialization code and parameters, they are built with exact the same linker script (see STM32H750XBHx_FLASH.txt); and they differs only in high-level side (application logic, user messages).

My bootloader can act in two ways:

  • copying an application from external flash (using QSPI interface) to AXI SRAM and then jumping into it (like in the ExtMem_Boot example);
  • or getting an application through x-modem, using USART1, and putting it into AXI SRAM.

In both ways I checked the CRC32 of firmware and it is correct.

I use FreeRTOS for both the bootloader and the application, if it matters.

What could be wrong? Why some apps work fine, some doesn't?

Thanks, Artem.

1 ACCEPTED SOLUTION

Accepted Solutions
AFedu.1
Associate II

UPDATE:

1 problem is resolved - all applications successfully start and run in AXI SRAM.

The reason of breaking was I didn't update the vector table, that is used by NVIC to handle interrupts.

So,

SCB->VTOR = 0x24000000;

must be in the start of an application.

And now I'm figuring out, why the jump to app doesn't work with all apps.

View solution in original post

3 REPLIES 3
AFedu.1
Associate II

UPDATE:

1 problem is resolved - all applications successfully start and run in AXI SRAM.

The reason of breaking was I didn't update the vector table, that is used by NVIC to handle interrupts.

So,

SCB->VTOR = 0x24000000;

must be in the start of an application.

And now I'm figuring out, why the jump to app doesn't work with all apps.

AFedu.1
Associate II

I have not found exact location where my code corrupts everything. But I figured out why jump has worked not with all apps.

The reason is: Cortex-M has two stack registers: MSP (main stack pointer) and PSP (process stack pointer). Cortex-M also has common SP (stack pointer), which in fact points to PSP or MSP. To get to know which one is active, you should read the Control register (see PM0253 Programming manual or Cortex docs).

After reset SP points to MSP.

When I had add a code to make SP point to MSP, everything started to work as I want.

The code before the jump is:

uint32_t app_start_addr = 0x24000000; // for example
 
__asm volatile
(
/* To make SP point to MSP we should write 0 in bit [1] of Control register. */
    " mov r0, #0                           \n" /* Write 0 to R0 register. */
    " msr control, r0                      \n" /* Copy value from R0 to Control register. */
    " isb                                  \n" /* Instruction sync barrier to make sure SP points to MSP. */
    " cpsie i                              \n" /* Enable interrupt handling, when they occure. */
    " cpsie f                              \n" /* Enable interrupt handling, when they occure. */
    " msr psp, r0                          \n" /* Reset PSP register. */
    " msr basepri, r0                      \n" /* Reset Basepri register. */
    " mov lr, #0xFFFFFFFF                  \n" /* Reset LR register. */
    " dsb                                  \n" /* Data sync barrier just in case. */
    " isb                                  \n" /* Instruction sync barrier just in case. */
    " mov r0, %0                           \n" /* Move app_start_addr (actually the start of the new vector table). */
    " ldr r0, [r0, #4]                     \n" /* Read the second word (the address of the first instruction in an app). */
    " bx  r0                               \n" /* Branch to the app. */
    :: "r" (app_start_addr) : "memory"
);

NOTE1: FreeRTOS use the PSP for tasks. Exceptions use the MSP.

NOTE2: For some reasons my apps are like the loader, I mean it also has SystemInit() call at the very beginning, next LoopCopyDataInit, LoopFillZerobss, then jump to main(), then HAL_Init() and SystemClock_Config() and so on, and then FreeRTOS again. Yes, both the loader and apps use FreeRTOS.

Hopefully, It will help somebody.

DLouk.1
Associate II

I had similar problem attempting to run loadable programs in RAM/TCM RAM with CubeMX32/Eclipse development tools and ST-LINK debugger probe. With all the magic hidden in HAL and startup code generated by the tool, it is a pity that the initialization of VTOR is not included there (as the user may naively expect), and no hint is given in the documentation. The linker creates a new vector table, and gives the symbol for it, but the startup code simply ignores it without advertisement. It was difficult to find because the first test programs run without interrupts, and thus calls into garbage code in flash occasionally happens under debugging.

SCB->VTOR = 0x24000000; placed immediately after main() or better in startup code will solve the problem!