2024-06-11 02:25 AM - edited 2024-06-11 02:53 AM
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
2024-06-11 06:31 AM
Hi @DunaDridri and welcome to the STCommunity,
Are you performing a page erase (of the page that will be written) each time before the writes ?
Is the FSTPG bit in FLASH control register (FLASH_CR) correctly set during the programming ?
Regards,
Florian
2024-06-11 06:47 AM
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 :
If I open disassembly mode, I can step into HAL_FLASH_Program() through assembly code :
Do I need to use Fast Programming instead of DoubleWord programming?
2024-06-11 07:05 AM
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
2024-06-11 07:20 AM
I used HAL_FLASH_Program() with TypeProgram = FLASH_TYPEPROGRAM_FAST, which is performing the process you mentionned, and the exception is still happening.
I correctly erased all pages, FSTPG is set but still...
And initial write is still working
2024-06-11 07:46 AM
Alright, this function performs the sequence, did you try to erase only the needed page just before you try to write in the page? (as mentioned in the RM).
Regards,
Florian LR
2024-06-12 12:27 AM
Yep, I tried both things :
HardFault is still triggered
2024-06-13 01:45 AM
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 :
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.
2024-06-13 01:58 AM - edited 2024-06-13 02:00 AM
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
2024-06-13 02:18 AM
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'll continue my tests and keeps you updated, not sure what is involved here for now