cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H730: Enabling caching on OCTOSPI RAM crashes the program

sirpietruch
Associate II

Dear Community,

I've got STM32H730 with ext Flash on OCTOSPI2 and ext RAM (s70kl1283) on OCTOSPI1.

I call  SCB_EnableICache(); and  SCB_EnableDCache(); early in main, then I configure the MPU.

I've got no problems executing code from ext Flash/OCTOSPI2 when MPU is configured as follows:

MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = OCTOSPI2_BASE;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);

It has a big, measurable impact on the execution speed compared to non-cached OCTOSPI2 MPU configuration.

I can also execute code from ext RAM on OCTOSPI1 if I set MPU parameters as above, but disable buffering, caching and sharing. I tried enabling caching, enabling all options, playing with TEX LEVEL (basically trying to use various setting combinations from MPU docu in relevant Programmers Manual). I either crash on any RAM access or crash on RAM execution, depending on tested MPU settings (I didn't note precisely which setting set causes which outcome). And the CPU gets seemingly stuck in HAL TICK isr, doesn't even signal any MPU or whatever fault.

I tried invalidating cache after setting the MPU, configuring the MPU both when in bootloader or external image (when in external image, the MPU config fcn actually executes from within ITCM and problems start on 1st ext ram access).

I haven't noticed anything relevant in Errata sheet.

I'm quite lost in what direction should I investigate. 

 

Can those problems result from a different place- namely wrongly configuring OCTISPI1 parameters for the RAM chip? I'm pretty sure thy're OK but maybe I'm overlooking something here (I also tried setting the Refresh to 0). I'm operating the RAM chip at its defaults.

hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 1;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_APMEMORY;
hospi1.Init.DeviceSize = 24;
hospi1.Init.ChipSelectHighTime = 2;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.WrapSize = HAL_OSPI_WRAP_32_BYTES;
hospi1.Init.ClockPrescaler = 4;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
hospi1.Init.ChipSelectBoundary = 10;
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;
hospi1.Init.MaxTran = 0;
hospi1.Init.Refresh = 200;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
sOspiManagerCfg.ClkPort = 1;
sOspiManagerCfg.DQSPort = 1;
sOspiManagerCfg.NCSPort = 1;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

 

I'd be grateful for any tips what could I check more or what I may be doing wrong.

 

PS- now that I think of it, the "stuck in HAL tick isr" without fault may be because I got to the point where bootloader jumps to ext ram, but waits indefinitely to fetch instructions for some reason. VTOR is not remapped yet so still points to bootloader ISRs so HAL tick gets fired periodically. Which would be weird because I do call HAL_SuspendTick before jumping, but well... As I said I'm a bit lost here.

1 ACCEPTED SOLUTION

Accepted Solutions
KDJEM.1
ST Employee

Hello @sirpietruch and welcome to the community :),

I think this issue is due to wrong sequence "I call  SCB_EnableICache(); and  SCB_EnableDCache(); early in main, then I configure the MPU." 

The correct sequence is to configure MPU firstly, then enable cache.

It is recommend to configure MPU before enabling the caches. This is because the MPU settings can be affect the behavior of the caches. 

I think Level 1 cache on STM32F7 Series and STM32H7 Series application note can help to use cache.

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

7 REPLIES 7

It crashed or it faulted?

Output details from fault. 

Watch use of DCache Invalidate, can cause failure, use By Address variant to limit damaging behavior 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sirpietruch
Associate II

Thank you for response, I used the By Address on entire OCTOSPI1 address space but that didn't change the behavior.

And I'm afraid I don't have any fault output because there's no fault. Under debugger, it kind of looks to me as if the CPU was stuck waiting indefinitely for the bus transfer to complete, I'm not getting any mem/hard fault- Segger Ozone doesn't detect any, and I also don't see any in SCB registers.

 
Wondering if there needs to be any alignment between memory wrap size and some cache requirements, because for external RAM on OCTOSPI1 (so the problematic memory) I have
hospi1.Init.WrapSize = HAL_OSPI_WRAP_32_BYTES;
 
and for external Flash on OCTOSPI2 I have
hospi2.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
 
KDJEM.1
ST Employee

Hello @sirpietruch and welcome to the community :),

I think this issue is due to wrong sequence "I call  SCB_EnableICache(); and  SCB_EnableDCache(); early in main, then I configure the MPU." 

The correct sequence is to configure MPU firstly, then enable cache.

It is recommend to configure MPU before enabling the caches. This is because the MPU settings can be affect the behavior of the caches. 

I think Level 1 cache on STM32F7 Series and STM32H7 Series application note can help to use cache.

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thank you very much!

I will try this approach next time I have the chance to (which is next Monday) and will report back.

If there's any more tips on what could I check as well, please write.

Hi!

Thank you for your tip! The order was indeed important. There was still a problem, however and my hunch was also correct.

Apart from correct initialization order, to make the code execute from cached ext ram I also needed to disable wrap on octospi1, so set

hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;

I don't know why wrap configuration makes cached ext ram execution unstable, but it works when disabled. I would be happy to hear any thoughts on this.

KDJEM.1
ST Employee

Hi @sirpietruch ,

Thank you for coming back to the Community and sharing the update.

What do you mean by "ext ram execution unstable" ?

Do you have a corrupted data? Can you please share a screenshot describing the issue?

Please take a look at wrap errata in the errata sheet may help you.

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi!

Unfortunately I don't have any data to share, it's just when I apply the correct ordering of initialization but still have the wrap set to 32B I can spin in some text function located in external RAM for a while and then the debugger connection gets lost- therefore I can't read any possible fault details.

It may be possible that the point 2.7.2 from Errata sheet applies (I had REFRESH set at 200), and definitely not 2.7.3, as I'm not using those registers at all.

The problem disappears if I don't use the wrap function, just use linear bursts. It would be possible to do some investigation on the 2.7.2 from errata sheet but I'm afraid I don't have the time for it at the moment and just not using wrap is satisfactory.

Thank you for your help!