cancel
Showing results for 
Search instead for 
Did you mean: 

Question on Flash-to-Flash IAP on STM32F303CC

Thatcher
Visitor

Hello everyone,

I'm working on an In-Application Programming (IAP) solution for an STM32F303CC. I've divided the flash memory into two application areas (let's call them App1 and App2), and I want to rewrite the program in App2 from code running in App1.

I have already implemented this, and it seems to be working correctly. However, I have some doubts and would appreciate it if anyone with knowledge on this topic could provide some clarification.

Here is my implementation detail:

  • The code that erases the App2 area is located in the App1 area.

  • It executes the standard HAL sequence: HAL_FLASH_Unlock(), HAL_FLASHEx_Erase(), and HAL_FLASH_Lock().

  • Global interrupts are not disabled during this process.

  • Several interrupts are active, but I have confirmed that all of their ISRs are also located within the App1 memory area.

My understanding was that the CPU should stall if an interrupt occurs during a flash erase operation, as it would try to fetch the ISR from a busy flash. However, this stall does not seem to be happening in my tests. A colleague suggested that it might be working without conflict because the program area and the target area are in clearly separated sectors.

My questions are:

  1. Is this control method (erasing one flash sector while executing from another on a single-bank device) valid and safe according to the official specifications?

  2. If it is valid, could you please provide evidence from a reference manual or application note that confirms this behavior?

  3. If this method is problematic, would creating a critical section by disabling interrupts (__disable_irq() / __enable_irq()) be a sufficient and correct solution?

Any insights or guidance you could offer would be greatly appreciated. Thank you for your time and consideration.

3 REPLIES 3
Ozone
Principal II

> My questions are:

  1. Is this control method (erasing one flash sector while executing from another on a single-bank device) valid and safe according to the official specifications?

Yes.
You can check the reference manual yourself, section 4, "Embedded Flash memory".

However, it states the core stalls on every fetch (read) attempted while IAP is ongoing. Quote :
An on going Flash memory operation will not block the CPU as long as the CPU does not access the Flash memory.
On the contrary, during a program/erase operation to the Flash memory, any attempt to read the Flash memory will stall the bus. The read operation will proceed correctly once the program/erase operation has completed. This means that code or data fetches cannot be made while a program/erase operation is ongoing.

You might not notice it, though.
For MCUs with single-bank Flash, you would need to move code to RAM that must be running during Flash erase/program. If your IAP code, including the host side, can handle the somewhat unpredictable delays during the process there is no need to do that, though.

Hi Ozone,

Thank you very much for your answer. It was very helpful, and I really appreciate you pointing me to the specific section in the reference manual.

I understand that the ideal solution is to execute the code from RAM. However, based on your explanation, I have a new understanding of my current implementation, where I run the code from Flash without disabling interrupts.

My interpretation is this: The hardware stall is effectively creating a temporary, automatic "interrupt disable" period. When an interrupt occurs during the erase, the CPU stalls because it cannot fetch the ISR from the busy flash. It only services the interrupt after the erase operation has completed.

This behavior seems to have a similar effect to manually wrapping the operation in a __disable_irq() / __enable_irq() block.

Is this understanding correct?

Thank you again for your help.

I have not investigated in detail, but AFAIK it is not related to interupts at all.
And note, a "fetch" is not directly tied to an instruction.
The Flash interface in most STM32 devices is 128 bit wide (AFAIK), and one fetch to refill the core pipeline reads four 32-bit words at once. This, together with a caching mechanism named "ART" serves to reduce the Flash speed bottleneck.
IRQ vector fetches from a VTOR in Flash are certainly affected as well.

But any code execution is in a kind of suspended animation as long as it tries to read from a Flash bank being affected by erase/program.

The "bank" configuration is not always advertised by manufacturers, and I haven't found any such statement in the F3xx reference manual. A Flash bank is the amount of sectors connected to a single (internal) power supply. Flash needs voltages >+9V for programming, which are generated on-die. When these step-up converters are fired up, no code can by executed from any attached sector.

Only multipe-bank designs would allow you to execute code from one bank while programming the other.
My company has used some Fujitsu MCUs with such a feature (proprietary + ARM CM3/4), but as usually, this comes at increased costs.