cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_Flash_Program triggers HardFault exception

DunaDridri
Associate II

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

 

 

9 REPLIES 9
Florian LR
ST Employee

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

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 : 

2024-06-11 16_01_31-STM32G0x1 advanced Arm®-based 32-bit MCUs - Reference manual.png

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

 

@Florian LR 

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

@DunaDridri

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

@Florian LR 

Yep, I tried both things : 

  • Full erase then write
  • Erase before each write

 

HardFault is still triggered

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.

Florian LR
ST Employee

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