EEPROM Woes on BluePill

Post here first, or if you can't find a relevant section!
Post Reply
PGSmick
Posts: 3
Joined: Tue Jun 15, 2021 9:19 pm

EEPROM Woes on BluePill

Post by PGSmick »

First of all, thanks for being here. This is my first post and I apologize if you find it too long.

What am I missing or Did something recently change with the EEPROM.h library? I have a program that I initially developed on an Arduino Nano, but have successfully adapted the code for use on a number of BluePill clones. The code is used to store a handful of integer values in emulated EEPROM, so that the same data is available the next time the device powers on. It has worked fine (on the Bluepills) for several years, but this past week I made some changes to the code (unrelated to EEPROM), and now the EEPROM storage isn't working as I expect.

I have tested out the following EEPROM code which does much the same sort of thing I need working for my main program code:

Code: Select all

#include <EEPROM.h>

int Address0=0;    
int Address2=2;    
int Address4=4;         
int Address6=6;
int Address8=8;
int Address10=10; 
int Address12=12;          

int TestData=0;
int ClearData=0;
int DisplayData;


void setup() {
  
  // put your setup code here, to run once:
Serial.begin(9600);
delay(5000);

ClearEEPROM();
DisplayEEPROM();
WriteEEPROMTest1();
DisplayEEPROM();
WriteEEPROMTest2();
DisplayEEPROM();

}

void loop() {
  // put your main code here, to run repeatedly:


}

void ClearEEPROM()
{
  //Clear EEPROM addresses
  Serial.println("-----------------------------------------");
  Serial.println("Clearing EEPROM..."); 

  EEPROM.put(Address0,ClearData);
  EEPROM.put(Address2,ClearData);
  EEPROM.put(Address4,ClearData);
  EEPROM.put(Address6,ClearData);
  EEPROM.put(Address8,ClearData);
  EEPROM.put(Address10,ClearData);
  EEPROM.put(Address12,ClearData);

  
}
void WriteEEPROMTest1()
{
  Serial.println("-----------------------------------------");
  Serial.println("Writing single digit test values... ");
  TestData=1;
  EEPROM.put(Address0,TestData);
  TestData=2;
  EEPROM.put(Address2,TestData);
  TestData=3;
  EEPROM.put(Address4,TestData);
  TestData=4;
  EEPROM.put(Address6,TestData);
  TestData=5;
  EEPROM.put(Address8,TestData);
  TestData=6;
  EEPROM.put(Address10,TestData);
  TestData=7;
  EEPROM.put(Address12,TestData);
 
}
void WriteEEPROMTest2()
{
  Serial.println("-----------------------------------------");
  Serial.println("Writing 3-digit test values: ");
  TestData=101;
  EEPROM.put(Address0,TestData);
  TestData=202;
  EEPROM.put(Address2,TestData);
  TestData=303;
  EEPROM.put(Address4,TestData);
  TestData=404;
  EEPROM.put(Address6,TestData);
  TestData=505;
  EEPROM.put(Address8,TestData);
  TestData=606;
  EEPROM.put(Address10,TestData);
  TestData=707;
  EEPROM.put(Address12,TestData);
}


void DisplayEEPROM()
{
  Serial.println("-----------------------------------------");
  Serial.println("Stored EEPROM Data: ");
   
  EEPROM.get(Address0,DisplayData);
  Serial.print("First: ");Serial.println(DisplayData);
  EEPROM.get(Address2,DisplayData);
  Serial.print("Second: ");Serial.println(DisplayData);
  EEPROM.get(Address4,DisplayData);
  Serial.print("Third: ");Serial.println(DisplayData);
  EEPROM.get(Address6,DisplayData);
  Serial.print("Fourth: ");Serial.println(DisplayData);
  EEPROM.get(Address8,DisplayData);
  Serial.print("Fifth: ");Serial.println(DisplayData);
  EEPROM.get(Address10,DisplayData);
  Serial.print("Sixth: ");Serial.println(DisplayData);
  EEPROM.get(Address12,DisplayData);
  Serial.print("Seventh: ");Serial.println(DisplayData);
  
}


When I run the code on a Nano, I get these expected results:

-----------------------------------------
Clearing EEPROM...
-----------------------------------------
Stored EEPROM Data:
First: 0
Second: 0
Third: 0
Fourth: 0
Fifth: 0
Sixth: 0
Seventh: 0
-----------------------------------------
Writing single digit test values...
-----------------------------------------
Stored EEPROM Data:
First: 1
Second: 2
Third: 3
Fourth: 4
Fifth: 5
Sixth: 6
Seventh: 7
-----------------------------------------
Writing 3-digit test values:
-----------------------------------------
Stored EEPROM Data:
First: 101
Second: 202
Third: 303
Fourth: 404
Fifth: 505
Sixth: 606
Seventh: 707

But on any Bluepill board, I get this instead:

-----------------------------------------
Clearing EEPROM...
-----------------------------------------
Stored EEPROM Data:
First: 0
Second: 0
Third: 0
Fourth: 0
Fifth: 0
Sixth: 0
Seventh: 0
-----------------------------------------
Writing single digit test values...
-----------------------------------------
Stored EEPROM Data:
First: 131073
Second: 196610
Third: 262147
Fourth: 327684
Fifth: 393221
Sixth: 458758
Seventh: 7
-----------------------------------------
Writing 3-digit test values:
-----------------------------------------
Stored EEPROM Data:
First: 13238373
Second: 19857610
Third: 26476847
Fourth: 33096084
Fifth: 39715321
Sixth: 46334558
Seventh: 707

And the data being reported back are the same values regardless of when I run the code or on which Bluepill board. (I.e. whatever values those are they are not random.) It's also odd that the last values that get written (here the 7 and 707) are as expected. For example, if I shorten the code to store only 4 values, then I get 3 garbage numbers and the last value again is correct (would be a 4 and 404 with this code). Why just the last value?

A side question: Is the emulated EEPROM on these STM32 boards subject to the same 100,000 cycle limitation that applies to real EEPROM as in an Arduino? All my testing is being done on new Bluepill boards whose memory has never been stressed in any regard.

Am I doing something wrong here? I notice that the EEPROM.h library was recently updated, but I don't know in what regard, and I have no idea how to troubleshoot a library.

Any suggestions before I move to some really stupid workaround? Anything more I can tell you?

Thanks in advance,
Peter
by GonzoG » Tue Sep 06, 2022 7:45 pm
You're overwriting data in EEPROM. And it couldn't work before.
size of int is 32b not 16b like on ATMega 8b MCUs.
You need to put them every 4 bytes or use 16b variables.

As to life cycle - no, it's not. Virtual EEPROM is put in flash memory and it's life is about 1k erase cycles. But virtual EEPROM works in a different way than hardware EEPROM and rewriting data under certain address doesn't actually rewrite it, but writes it free space on flash page, until this page is full. If flash page becomes full, all actual data are rewritten to second flash page, and the first page is erased. And this is one erase cycle.
Go to full post
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 26
Location: Prudnik, Poland

Re: EEPROM Woes on BluePill

Post by GonzoG »

You're overwriting data in EEPROM. And it couldn't work before.
size of int is 32b not 16b like on ATMega 8b MCUs.
You need to put them every 4 bytes or use 16b variables.

As to life cycle - no, it's not. Virtual EEPROM is put in flash memory and it's life is about 1k erase cycles. But virtual EEPROM works in a different way than hardware EEPROM and rewriting data under certain address doesn't actually rewrite it, but writes it free space on flash page, until this page is full. If flash page becomes full, all actual data are rewritten to second flash page, and the first page is erased. And this is one erase cycle.
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: EEPROM Woes on BluePill

Post by ag123 »

are you using the 'official' STM core?
that core is bundled with its own 'eeprom' lib
https://github.com/stm32duino/Arduino_C ... ies/EEPROM

for 'blue pills' there are quite a lot of 'gotchas' and pit falls
recently quite some (blue) pills appear with stm32f103 c6 32k flash 10k sram
https://www.aliexpress.com/item/4000120259350.html
https://www.aliexpress.com/item/1005001621626894.html

this is different from what 'used to be' stm32f103 c8 64k flash 20k sram
and back earlier it used to be stm32f103 cb 128k flash 20k sram (this is the grand 'old' maple mini)
for c6 boards, which has much less flash and ram, you would run out of flash and sram sooner than you can do anything much on it.

----
then for 'blue pills' there are 'clones' and 'fakes'
https://hackaday.com/2020/10/22/stm32-c ... -the-ugly/

this one matters the most as for different chips, the flash implementation may be different from a real stm32 but they are nevertheless sold as 'blue pills' and labelled as 'stm32f103c8' - i.e. they may not be after all.
there have been cases of a c6 being sold as a c8 as well, so check those things, for c6 those flash memory may not even exist at those locations that is there on c8 and cb

these days there is even a 'blue pills diagnostic project' !
https://hackaday.com/2021/06/23/test-yo ... 103c8-mcu/
https://mecrisp-stellaris-folkdoc.sourc ... -v1.6.html
Last edited by ag123 on Tue Sep 06, 2022 8:46 pm, edited 1 time in total.
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: EEPROM Woes on BluePill

Post by ag123 »

There is another problem that is *much, much harder* to figure out, if you have a rather big sketch or a sketch that does quite a few things, you can run out of SRAM and the stack overwrite your global variables. - stack overflow.
There are no errors, no warnings, nothing. If it is more apparent, your app simply crash, if it isn't, data just gets corrupted.
PGSmick
Posts: 3
Joined: Tue Jun 15, 2021 9:19 pm

Re: EEPROM Woes on BluePill

Post by PGSmick »

GonzoG wrote: Tue Sep 06, 2022 7:45 pm You're overwriting data in EEPROM. And it couldn't work before.
size of int is 32b not 16b like on ATMega 8b MCUs.
You need to put them every 4 bytes or use 16b variables.

As to life cycle - no, it's not. Virtual EEPROM is put in flash memory and it's life is about 1k erase cycles. But virtual EEPROM works in a different way than hardware EEPROM and rewriting data under certain address doesn't actually rewrite it, but writes it free space on flash page, until this page is full. If flash page becomes full, all actual data are rewritten to second flash page, and the first page is erased. And this is one erase cycle.
I'll be darned. You're right! I was redeveloping from an earlier version of the code for Nano which was set up for 16b integers. And I missed that I should have been working from the version I had last done for the STM32 where the addresses were properly spaced. And I had independently forgotten that integers for STM32 needed 32b. :oops: You got me out of the rut I was in for two whole days! Thanks again.

And also thanks for the info on EEPROM flash pages work.
Peter
PGSmick
Posts: 3
Joined: Tue Jun 15, 2021 9:19 pm

Re: EEPROM Woes on BluePill

Post by PGSmick »

ag123 wrote: Tue Sep 06, 2022 8:10 pm are you using the 'official' STM core?
that core is bundled with its own 'eeprom' lib
https://github.com/stm32duino/Arduino_C ... ies/EEPROM

for 'blue pills' there are quite a lot of 'gotchas' and pit falls
recently quite some (blue) pills appear with stm32f103 c6 32k flash 10k sram
...


then for 'blue pills' there are 'clones' and 'fakes'
https://hackaday.com/2020/10/22/stm32-c ... -the-ugly/
...

I know about the existence of fakes and that I am exposing myself to them whenever I buy these low-cost clones. I try to be careful and examine each one as they arrive before I put them into inventory. But I know that sooner or later I'll fall victim to one scam or other.

I am leery also about changing versions of software (whether it's core, component or library) once I have desired code working on a given piece of hardware. I just don't know enough about it (yet) to be sure that I don't shoot myself in the foot by applying a new version without being sure I can go back if the new one messes me up. For example, I think the core I am using is official, but it's 1.9.0. I know this is out of date, but since things are working....

When I use #include <EEPROM.h> how does the Arduino IDE know to use the version of EEPROM.h bundled with the STM32 core rather than the one I see in the Arduino libraries folder? Or are they one and the same having been installed when I installed the STM32core software? And if I wanted to examine (no, not edit yet) that bundled library, where would I find it? So much to learn!

Thanks,
Peter
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: EEPROM Woes on BluePill

Post by ag123 »

I do not know which library Arduino uses literally, In most cases, I copied source codes into the sketch folder to build with the library codes.
And at times when there is trouble, I'd go into the 'library' source codes place Serial.print() statements etc just to see that it is 'working as expected'.
It is debugging kind of, just that that can normally be done without using GDB and tracing codes etc.
Quite commonly as well, I'd use original library codes say from the Github repositories. Hence, for that, I'd copy those codes and place it in the sketch folder for the build.
massonal
Posts: 12
Joined: Mon Aug 08, 2022 9:12 am

Re: EEPROM Woes on BluePill

Post by massonal »

PGSmick wrote: Tue Sep 06, 2022 9:10 pm When I use #include <EEPROM.h> how does the Arduino IDE know to use the version of EEPROM.h bundled with the STM32 core rather than the one I see in the Arduino libraries folder? Or are they one and the same having been installed when I installed the STM32core software? And if I wanted to examine (no, not edit yet) that bundled library, where would I find it? So much to learn!
Definitely not the same libraries, I don't know of any copies being made in this regard.

The process of library resolution is actually quite convoluted, here is the doc: https://arduino.github.io/arduino-cli/0 ... resolution
Basically, Arduino extracts the header name, and tries to fuzzy-match it to libraries it knows about, in a variety of locations (core, ~/Arduino/libraries, ...), on a variety of criteria, to "elect" the one to use.

If you use arduino-cli to build your sketch, you can see that in the recap at the end :

------------------
arduino-cli compile -b STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_L433RC_P .

Sketch uses 13300 bytes (5%) of program storage space. Maximum is 262144 bytes.
Global variables use 948 bytes (1%) of dynamic memory, leaving 64588 bytes for local variables. Maximum is 65536 bytes.

Used library Version Path
EEPROM 2.0.1 ~/.arduino15/packages/STMicroelectronics/hardware/stm32/2.3.0/libraries/EEPROM
SrcWrapper 1.0.1 ~/.arduino15/packages/STMicroelectronics/hardware/stm32/2.3.0/libraries/SrcWrapper

Used platform Version Path
STMicroelectronics:stm32 2.3.0 ~/.arduino15/packages/STMicroelectronics/hardware/stm32/2.3.0
------------------

Orrrrr... you can look into building with CMake ;) ; in this case, it's up to you to point to libraries, so you necessarily know where they are!
viewtopic.php?p=10389#p10389
Post Reply

Return to “General discussion”