cancel
Showing results for 
Search instead for 
Did you mean: 

EEPROM emulator corrupts STM32G431KBU6 program

WSpar.1
Associate III

Hi all,

We deployed a lot of devices that have a STM32G431KBU6 controller.
It basically has a foot switch to turn on/off a 12v DC motor and a rotary switch to control the speed.

We use EEPROM emulator to save the speed setting.
If speed setting is different from the stored value and there is no new speed change detected within a minute we store the new value. (to safe unnecessary writes)

Clients mostly only set the speed setting once when they first use the product.

So EEPROM emulated write is almost never done only EEPROM emulated read on start up of the device

Somehow support receives a lot of complains about non responding devices. Only reprogram the device helps. But this is a temporarily fix.

Sometimes clients tell us they had a power outage before these issues appear.

We can not reproduce the issue, maybe because our mains power is very clean?

Can power glitches (12v power jack) cause flash program corruption?
  

 

 

 

 

 

31 REPLIES 31

You mean you are not using EEPROM emulation at all?
And have workable defaults on every reboot?

In my case I always need custom set values on reboot

WSpar.1
Associate III

In my code, I found the following EEPROM config

/* Configuration of eeprom emulation in flash, can be custom */
#define START_PAGE_ADDRESS      0x0801B000U /*!< Start address of the 1st page in flash, for EEPROM emulation */
#define CYCLES_NUMBER           1U   /*!< Number of 10Kcycles requested, minimum 1 for 10Kcycles (default),
                                        for instance 10 to reach 100Kcycles. This factor will increase
                                        pages number */
#define GUARD_PAGES_NUMBER      2U   /*!< Number of guard pages avoiding frequent transfers (must be multiple of 2): 0,2,4.. */

/* Configuration of crc calculation for eeprom emulation in flash */
#define CRC_POLYNOMIAL_LENGTH   LL_CRC_POLYLENGTH_16B /* CRC polynomial lenght 16 bits */
#define CRC_POLYNOMIAL_VALUE    0x8005U /* Polynomial to use for CRC calculation */
Bob S
Principal

> You mean you are not using EEPROM emulation at all?

Putting words in @Tesla DeLorean mouth - he probably doesn't use ST's EEPROM emulation, but rather his own custom version.  That is what I do.

**IF** you can guarantee that you have stable power and operating conditions when the motor config data is written to FLASH (the ubiquitous "updating, do not remove power" kind of situation, and code that won't reboot on FLASH errors), you don't need the ST EEPROM code and its side effects.(writing to FLASH on every startup). Pick a page of FLASH and write the data (with checksums/CRCs/etc. for validation).

I know you want custom values, but if that FAILS you want a default position that's not locked in a loop of death..

I load custom values from Flash sectors/pages, but I have defaults for the initial and failing cases. On parts with EEPROM, I use those that same fashion. The data structure has a CRC so I know it's intact, and if I journal across multiple pages I can find the most recent intact values too.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
WSpar.1
Associate III

Ok found something interesting today.
STMCubeProgrammer doesn't erase all sectors when programming



18:16:52 : Address : 0x08000000
18:16:52 : Erasing memory corresponding to segment 0:
18:16:52 : Erasing internal memory sectors [0 52]
18:16:53 : Download in Progress:

I seperated my EEPROM pages a bit further away to 0x0801C000 (btw what will be a good way to determine end address of my program?) 
After programming, all EEPROM writes are still there.
So EE_Init() doesn't clear anything?
It is expected behavior that every write is on a new line?

Since I got these chips via brokers, I don't trust the content of these chips.
The programmer only erases the sectors that are going to be programmed for my program? 

End of the program, or end of the image? The linker packs statics at the back of the code/text section.

You should be able to find or place a symbol via the Linker Script, or create a suitably aligned or placed MEMORY area that's distinct from the area the linker can put code/data in.

End of Image is typically _sidata + (_edata - _sdata)

In Keil there are some $$LIMIT$$ or $$SIZE$$ type symbols

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Maybe good is go back to start and learn how emulation driver is writed or corect in what you need.

1. Unlock and Lock is part of EE func your code never need setup it.

2. If header file start page you set, then too is required modify linker available memory, otherwise you kill your code in flash

3. EE_Init erase only not prepared or full ocupied emulated partitions (pages)

And erasing in flash aplication process is configurable, you can set full or only necesary place...

Well 7 out of 12 devices got corrupted somehow after a power outage.
I still have to receive one device so I can diff the content.
But all devices are repairable with a reprogram.

My PCB ground is connected to the metal housing.

Maybe use brown-out detector to block Flash_unlock() from executing when power is unstable?

Bob S
Principal

If they were corrupted after a power outage, is it possible that power flickered (or glitched) on and off as power went out or came back on?  If so, the corruption could be from the EE_Init write to FLASH that I mentioned before, i.e. power glitches on just long enough for your code to get to the write operation in EE_Init then power drops and corrupts that write.

If you are able to read out the "corrupted" FLASH contents, it will be interesting to see if the corruption was in code space or your EEPROM data space (could corrupted config data make it look like your program was corrupted?).

Yes this approach has priority.

Can program space also get corrupted with power glitches while Flash is locked?
Is there a possibility to only unlock the EEPROM pages and keep program pages locked?

I'm running a stress test that is writing eeprom values for more then 24 hours without any issues. So power glitches or ESD discharge seem more likely.

Firmware improvements I can think of now are:
* Don't use Flash_unlock() high in my main()
* Unlock/Lock direct before and after the write.
* Detect setting changes and only write and unlock Flash after 1 minute of no new incoming changes and detect stable voltages. (BOR detection?)

* Use EE_Init(EE_FORCED_ERASE); instead of EE_Init(EE_CONDITIONAL_ERASE);
* Proper handle any errors that can occur. (how can I simulate these?)

 

My client wants a self repairing mechanism to avoid so many support tickets.
But since it is a single bank flash I think it is really hard to have the program multiple times in flash and build some form of in-app-programmer that CRC checks the program and repair it.
Probably this is getting very complex with Interrupt vectors etc.

Maybe I can convert the USB-mini port to an OTG one and program from a flash drive.
Does such a functionality exist or even fit in the bootloader space?