cancel
Showing results for 
Search instead for 
Did you mean: 

EEPROM emulation on STM32H7

heveskar
Senior

This issue was already mentioned here except now it is on different line. I think it is still there.

In EEPROM emulation in the \STM32Cube\Repository\STM32Cube_FW_H7_V1.9.0\Projects\STM32H743I-EVAL\Applications\EEPROM\EEPROM_Emulation\Src\eeprom.c file on line 394 in function EE_ReadVariable(), there is

Address = Address - 32;

but there should be

Address = Address - 64;

Bug is that data can be interpreted as address and we end up reading incorrect data. The same issue is in examples for Nucleo-H743ZI and Nucleo-H7A3ZI (for the last one it should be 32 instead of 16).

Karel

1 ACCEPTED SOLUTION

Accepted Solutions
Pavel A.
Evangelist III

You can open an issue on github against this example.

https://github.com/STMicroelectronics/STM32CubeH7/blob/5975bffae9358bc2b2890a35a203d940a395efef/Projects/STM32H743I-EVAL/Applications/EEPROM/EEPROM_Emulation/Src/eeprom.c#L394

IMHO the "EEPROM emulation" example is less usable on 'H7 as is, because the minimal write unit is 32 bytes (TL;DR) so storing 2-byte values this way is wasteful.

View solution in original post

5 REPLIES 5
Pavel A.
Evangelist III

You can open an issue on github against this example.

https://github.com/STMicroelectronics/STM32CubeH7/blob/5975bffae9358bc2b2890a35a203d940a395efef/Projects/STM32H743I-EVAL/Applications/EEPROM/EEPROM_Emulation/Src/eeprom.c#L394

IMHO the "EEPROM emulation" example is less usable on 'H7 as is, because the minimal write unit is 32 bytes (TL;DR) so storing 2-byte values this way is wasteful.

Thank you, I will do that.

I know about the wastefulness, but we are writing only few tens of bytes for configuration and we must reserve whole sector for this either way, so we are using this as is.

I could use the X-CUBE-EEPROM expansion that can be downloaded (I think that it is written a little bit better), but it is not ported to H7 and this just seemed easier to use without the porting.

Karel

TMA1of3
Associate III

Hi guys,

I’m also using the STM32H743 and have a requirement to store a few bytes of data in non-volatile memory. I’ve noticed your posts, and see you had/have a similar requirement.

Can you help me understand what’s going on here, please ?

I believe I’m looking at the same sample code that you’ve referred to; ie, “Projects\STM32H743I-EVAL\Applications\EEPROM\EEPROM_Emulation\�?

There’s an initialisation routine, EE_Init(), but after that do I simply use EE_WriteVariable() and EE_ReadVariable() whenever I need to write to or read from ‘eeprom’ ?

The sample code has defined:

uint16_t VirtAddVarTab[NB_OF_VAR] = {0x5555, 0x6666, 0x7777};

Are these just three random addresses chosen solely for the purposes of demonstration ? Can I choose any 16-bit address values (except for 0xFFFF which I see is noted as being prohibited although I don’t know why) ? And how many such addresses can I have in total ? I think this micro’s Flash memory is based on 256 bits, so is it basically 256/16 = 16 that can be done with this sample code (16 different variables I could define each of which could then be stored in non-volatile memory and read after power-up or whenever needed) ?

Apart from 0xFFFF does it not matter what the address values are ? The three values chosen in the sample seem very random ?

My main concern is whether adding this to the existing code could break something particularly in relation to the other Flash operations ? It uses Flash sectors 6 and 7, so how to ensure this isn’t needed by anything else ? And why is it using two sectors ? I see the sample code uses HAL_FLASH_Unlock() – does ‘unlocking’ Flash create any sort of potential risk, and should there be an accompanying HAL_FLASH_Lock() after the ‘eeprom’ activity has ended ? I’m assuming Flash is ‘unlocked’ to begin with ?

Normal eeprom allows about 100k write cycles, but how many are allowed/safe here with this H7 technique ? Is it basically just the Nend parameter given in the datasheet in Table 54 “Flash memory endurance and data retention�? which is given as 10k ?

I will try to answer some of your questions.

1) Yes, it is enough to call EE_WriteVariable() and EE_ReadVariable() after EE_Init()

2) Yes, the virtual addresses are random for the example.

3) 0xFFFF is the only prohibited adress as this data means that there is nothing stored at this location.

4) I think you have the capacity calculation completely wrong. What matters except of write size (which is 256 bits) is also page size (or sector size), which here is 128 Kbytes. This is why EEPROM emulation is so ineffective on H7. Each variable takes 512 bits = 64 B (256 b for address and 256 b for data). In total this would be 128 KB / 64 b = 2048 variables. You have to subtract page header from this which is I think 256 bits. So you can store around 2000 variables I think.

5) HAL_FLASH_Unlock() must be called so that FLASH_CR register can be read and flash operations can be done. You should find information about this in the datasheet... Calling HAL_FLASH_Lock() is not necessary.

6) At least two sectors must be used to ensure proper EEPROM emulation operation. I won't explain this here, you can study for example AN4894 for basics of the emulation operation. This example is not the same as described in the document but it is very similar. Well, you could use more sectors but as one sector is 128 KBytes, you probably won't do that. Again, this is why this techique is ineffective here.

7) Calculation of the number of write cycles can be found in the AN4894 document. The more sectors you use, the endurance is better. Again, this is more relevant for e.g. the STM32G4 family, where sector/pages are 2 KB.

😎 How to ensure last two sectors are not used by any other code: you must reserve that area in the linker. I believe ST's examples ignore it but with a bit of googling you can find out how to do that.

Bottom note, please study relevant documents and datasheets before asking a question, you will find things a lot more clear.

I have one more note to add about this EEPROM emulation example. Beware that when there occurs an ECC error in the Flash (and it happened to us), there is no code to take care of this, so the program will from that point stay in HardFault forever and go there everytime the offending address is read. When used in production code, this should be handled. My suggestion is to go look into X-CUBE-EEPROM (implementation for other families than H7) and take inspiration from how it is implemented there. Right now we just scan the whole area (read all the addresses) and if hard fault occurs, delete whole sector where the bad address is located.