cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 running code from RAM and erasing flash simultaneously

DBurr
Senior

Hi, I've got an application which is running on an STM32F746ZGT. During in the field firmware upgrades, it has to erase part of the device's internal flash memory and then write to the flash. The problem I'm trying to overcome is to enable the device to continue executing code during the erase operation, which takes around 5 to 6 seconds. To do this, I'm moving some of the code chunks that I want to keep running during the erase operation into RAM. There's an interrupt and also the ISR vector that I'm moving into RAM. I'm following this example: https://community.st.com/t5/stm32-mcus/how-to-place-and-execute-stm32-code-in-sram-memory-with/ta-p/49528 It involves adding a ".RamFunc" section to the linker script. The issue is that so far I haven't been able to get code to continue executing during the flash erase process. I'm wondering if erasing flash will block the CPU from executing code, even if it's executed from RAM. Any advice would be greatly appreciated.

Thanks,
Doug

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

If the cpu attempts a flash read operation while the erase process in in progress, the cpu will block until the erase is complete.

If you have code entirely in RAM, it will continue to run. However, be aware that any constants that code refers to that it needs to read from FLASH will cause it to block. Probably what is happening here. Also be aware of speculative reads that may be occurring, or cached accesses, or interrupt routines still in flash.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

9 REPLIES 9
TDK
Guru

If the cpu attempts a flash read operation while the erase process in in progress, the cpu will block until the erase is complete.

If you have code entirely in RAM, it will continue to run. However, be aware that any constants that code refers to that it needs to read from FLASH will cause it to block. Probably what is happening here. Also be aware of speculative reads that may be occurring, or cached accesses, or interrupt routines still in flash.

If you feel a post has answered your question, please click "Accept as Solution".

That sounds like a pretty good explanation, I'll have to move more parts into RAM. Ideally I could move all code and constants into RAM, but my code is just a little larger than the available RAM.

Would you recommend turning off instruction and data caching too?

Thanks,

Doug

If I change the .rodata section from ">FLASH" to ">RAM AT> FLASH" my code does not run. What I'm doing seems pretty straight forward, not sure why it won't run? Any ideas?

Can you share your code? A few possibilities:

  • You're accessing something in flash, unintentionally. Functions typically access data. Is that data all in RAM?
  • Another interrupt you're not aware of is accessing something in flash.

DCACHE and ICACHE shouldn't be affecting things, outside of speculative access, but I'd turn them off during debugging to eliminate that possibility.

Are any interrupts active during this process? If so, which ones? Is the vector table in RAM? Are the interrupt functions? Convince yourself and us that is the case by showing screenshots of the relevant registers. For example, set a breakpoint in an interrupt or a function you think is in RAM and examine the PC value. Look at SCB->VTOR and the values within to ensure they point to RAM.

If you feel a post has answered your question, please click "Accept as Solution".

If I change the .rodata section from ">FLASH" to ">RAM AT> FLASH" my code does not run.

Because .rodata is not in the area that is copied from flash to ram by the standard startup code.

While erasing the flash, try to disable any access to it (speculative or not) at MPU.

 

Thanks for the tip, I can see in the startup code, only the .data section is copied to RAM, so will either have to move the .rodata section into .data or create another copy loop for .rodata.

If I set up the MPU to protect against access to flash before I erase the flash, won't that block me from erasing it? And what will protecting against access to flash do to help with this issue?

I've changed the .isr_vector section from ">FLASH" to ">RAM AT> FLASH" in the linker script and the code still works but hearing from @Pavel A. about the .rodata not getting copied into RAM by the startup code makes me question whether the vector table is actually in RAM.

Pavel A.
Evangelist III

If I set up the MPU to protect against access to flash before I erase the flash, won't that block me from erasing it?

It should not, as the command to start the erase is written to the flash control registers, not to the flash data area.

> And what will protecting against access to flash do to help with this issue?

Blocking access to flash data area in MPU should prevent any interference from the CPU, including the notorious speculative reads.

 

Thanks for the suggestions. I've been stepping through the code, and I'm realizing that there's a huge chain of functions that also need to be moved to RAM in order for this to work as I want it to. That's where I'll focus now.