Problem with running Zephyr from external flash on STM32xx


Jan Pohanka
 

Hello,
I'm trying to run zephyr using external QSPI flash on custom board with stm32h750vb cpu. I thought that it should be as easy as just changing FLASH_BASE_ADDRESS to correct value (0x90000000 for stm32x) but unfortunately that is not the case.
I have very simple bootloader sitting in internal flash that just sets up the QSPI peripheral to memory mapped mode, correct stack pointer and jumps to starting address of zephyr in external flash. There is just hello world application with shell and logging enabled. Zephyr unfortunately ends in arch_system_halt very soon - immediately when k_sleep is called from main function. I was not able yet to find the source of the problem. When the same application is linked to internal flash, everything works fine.
Can someone give me any hint, please?
 
best regards
Jan


Erwan Gouriou
 

Hi Jan,

If you're able to go till the main function, I guess this means QSPI configuration is working correctly.
If issue happens following k_sleep call, I'd check potential syscall check issue, but on that side
a kernel expert might be more helpful than myself.

One point though, are you using same usart peripheral on console and shell ?
If not, this could be strangely similar to https://github.com/zephyrproject-rtos/zephyr/issues/20068
which has been seen on internal flash as well.

Cheers
Erwan

On Fri, 22 Nov 2019 at 15:14, Jan Pohanka <xhpohanka@...> wrote:
Hello,
I'm trying to run zephyr using external QSPI flash on custom board with stm32h750vb cpu. I thought that it should be as easy as just changing FLASH_BASE_ADDRESS to correct value (0x90000000 for stm32x) but unfortunately that is not the case.
I have very simple bootloader sitting in internal flash that just sets up the QSPI peripheral to memory mapped mode, correct stack pointer and jumps to starting address of zephyr in external flash. There is just hello world application with shell and logging enabled. Zephyr unfortunately ends in arch_system_halt very soon - immediately when k_sleep is called from main function. I was not able yet to find the source of the problem. When the same application is linked to internal flash, everything works fine.
Can someone give me any hint, please?
 
best regards
Jan


Jan Pohanka
 

On Fri, Nov 22, 2019 at 07:35 AM, Erwan Gouriou wrote:
One point though, are you using same usart peripheral on console and shell ?
If not, this could be strangely similar to https://github.com/zephyrproject-rtos/zephyr/issues/20068
which has been seen on internal flash as well.
Thanks you for suggestion, but this probably is not related. I use the same UART and moreover all works normally when running from internal flash. In fact only change is in linking for internal flash FLASH is located in 0x08000000 for external 0x90000000. The memory mapped QSPI is working fine. I reach the main function

void main(void)
{
while (1) {
printk("Hello World! %s\n", CONFIG_BOARD);
k_sleep(K_MSEC(500));
}
}

but second call to k_sleep ends in fault. The arch_system_halt is called from main thread.... Surprisingly no fault message is prined out even if it is enabled.

br
Jan


laczenJMS
 

Hi Jan,

There are many things that can go wrong here. I would start by checking that what is in the qspi flash is equal to what you want. How do you write the program to the flash ?

Kind regards,

Jehudi


Jan Pohanka
 

I'm quite sure that content of the flash is correct. I use openocd (pending commit with stmqspi support) for flash programming and verify is ok. Moreover simple code with blinking led or even Zephyr with just a loop without sleep in main works. It looks like there is some kernel issue, but I do not find the source of the problem yet...


Jan Pohanka
 

I have found interesting thing. _oops event that I'm facing when running from external flash is caused by stack sentinel checking so in fact I'm getting a stack corruption - shell thread is overwriting stack of main_thread.
This situation never happens when running from internal flash.

Strange... Where is the context switching done? I need to check, what is setting SP to wrong value.

BR
Jan


Jan Pohanka
 

Finally... problem solved.
I found that stack pointer was getting wrong vaule after context switch. Then I noticed that link register during pendsv interrupt indicates floating point exception. After enabling CONFIG_FP_SHARING option everything works fine.
I'm still a bit confused why this was not an issue while running from internal flash. My bootloader does not explicitly use any float operations...

best regards
Jan