Hello everyone,
I'm facing a weird issue about Flash programming on a
STM32g0b1
microcontroller on
IAR Workbench for ARM
.
Context
I'm working on a bootloader project. I am able to lock, unlock, erase and program flash at the beginning of my program. Following a state machine, this is working well.
Issue
When it comes to save a new bunch of data for the second time (I always program by block of 256 bytes so 32 double-words which is required by the library), it triggers a HardFault exception
Remark 1
If I go step by step in debug mode, I can program double-word by double-word without any exception. But if I run the program without going step by step (going over the function or without triggering any breakpoint), I automatically trigger the exception. And when the exception is triggered, no double-word has been written to flash so it is cancelled from the beginning
Remark 2
What is weird is that I'm able to fully erase flash (without touching the program of course) and to program few datas at different location without any issue. It only comes to it when reaching this special part of my program. And as I said, in any case, I'm writing 256 bytes (divided in 32 double-words)
Remark 3
I checked FLASH_SR and FLASH_CR register, it seems to not detect any issue. Also, interrupts are correctly disable before performing a program. I also increase Heap/stack size and nothing changed.
I'm starting to run out of idea. Can you help me to find a solution please?
Thanks in advance and have a good day !
Adrien
Hi
@Florian LR
:)
The first step of my program is to erase all the memory that is going to be written so I just do it once but a complete erase (again, except main program).
Concerning the FSTPG bit :
-
Between HAL_FLASH_Unlock() and HAL_FLASH_Program() calls, FSTPG = 0
-
Then I can't step into HAL_FLASH_Program() methods, ti directly goes to HardFault exception
If I open disassembly mode, I can step into HAL_FLASH_Program() through assembly code :
-
When reaching FLASH_Program_DoubleWord(), FSTPG = 0
Do I need to use Fast Programming instead of DoubleWord programming?
@DunaDridri
,
In the Reference Manual
RM0444
chapter 3.3.8 ->
fast programming
you can find the sequence needed to perform the block programming you're describing. It includes the FSTPG bit set before the programming :
You can either reproduce the sequence on your own, or use the function
FLASH_Program_Fast()
that will set the FSTPG bit, program the 32 double-words, and wait until the BSY1 bit is cleared (you still need to perform the other elements of the sequence described in the Reference Manual in order to do a proper programming).
I hope this will help you,
Best Regards,
Florian LR
By calling the exact same function (Flash_Program) but with dummy datas, I am able to go through the process without hardfault
BUT
the Flash driver is not able to program. This time I was able to extract information that were invisible before, in the SR register :
-
FASTERR = 1
-
MISERR = 1
-
PGAERR = 1
I still don't know why I can step into this function without hardfault and the next line I can't but at least I get more information.
In the file attached, the blue part is what I have added to extract information. The next line is where the HardFault is triggered.
Do you have any interrupt that could prevent some words to be written ?
The MISSERR flag is raised when the previous data write is finished and the next data is not written in fast mode.
So the second word may be written not fast enough, raising the MISSERR, and when it does try to write it, it
causes PGAERR since it's not aligned. We can test it by disabling irq before the write, and re enabling it just after the function (using __disable_irq() __enable_irq() ).
I don't know if that will solve it, but it may at least help us to eliminate that option.
Regards,
Florian LR
Hi
@Florian LR
Using __disable_irq() has the same behavior than LGM_Disable_Interrupts() and I tried both. The error is still triggered.
Ok I kinda fix the issue for now but in a weird way :
-
I had to remove the return value of the function of my API
-
I had to force your library to use standard mode and not fast programming
-
I had to put parameters data into a local buffer before passing it to my Flash API
I'll continue my tests and keeps you updated, not sure what is involved here for now