Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

system_rtc_mem_write not working in latest code #619

Closed
torntrousers opened this issue Jul 27, 2015 · 16 comments
Closed

system_rtc_mem_write not working in latest code #619

torntrousers opened this issue Jul 27, 2015 · 16 comments
Assignees
Milestone

Comments

@torntrousers
Copy link
Contributor

Has something change in how to use system_rtc_mem_write?

The following sketch works with the old 1.6.1 release and the serial prints show the rtc byte incrementing, but with the latest code it doesn't work and always outputs "first time".

extern "C" {
  #include "user_interface.h"
}

byte rtcStore[2];

void setup() {
  Serial.begin(115200);
  Serial.println();

  system_rtc_mem_read(64, rtcStore, 2);

  if (rtcStore[0] != 123) {
     Serial.println("first time");
     rtcStore[0] = 123;
     rtcStore[1] = 0;
  } else {
     rtcStore[1] += 1;
     Serial.print("rtc = ");
     Serial.println(rtcStore[1]);
  }

  system_rtc_mem_write(64, rtcStore, 2);

  Serial.println("deep sleep 3 seconds...");

  //ESP.deepSleep(5000000, WAKE_RF_DISABLED);
  system_deep_sleep_set_option(4); // 4 = low power, radio off mode
  system_deep_sleep(2000000); 
  delay(1000);
}

void loop() {
   // shouldn't get here
}
@igrr
Copy link
Member

igrr commented Jul 27, 2015

Yes, i think while adding a workaround for "RTC MEM CHECK FAIL", i made it wipe user data as well:

@torntrousers
Copy link
Contributor Author

Just as an FYI - this is still not working in the latest trunk code

@torntrousers
Copy link
Contributor Author

I guess for a work around i can change to use EEPROM. What are the pros and cons of EEPROM compared to the RTC memory? EEPROM seems quite a lot slower for one thing.

@torntrousers
Copy link
Contributor Author

Playing around with this some more just now and i find that the example code at the top of this issue works ok if the RTC memory address is changed from 64 to be 65. Thats odd isn't it? The ESP8266 SDK Guide is pretty clear that 64 is the start of the user area.

@aperepel
Copy link

aperepel commented Feb 9, 2016

Still an issue in a current release. But... using to the next segment (not 64) works...

@Duality4Y
Copy link
Contributor

sure enough starting at 65 works, i had spend hours and hours trying to figure out why it doesn't work!

@redge76
Copy link

redge76 commented Mar 5, 2016

Hi,

The is also an issue at address 124. (124th byte of the user memory. If you run the following code, you will see that the "address" 0,1,2,3 (expected as reported by torntrousers ) and 124,125,126,127 are cleared.
This was tested on a nodemcu v2 and a wemos D1 mini.
If you remove the deepsleep(), the memory is not cleared.

#include <Arduino.h>
extern "C" {
#include "user_interface.h"
}

#define BUFFER_SIZE 500
void setup() {
  Serial.begin(115200);
}

void loop() {
    // put your main code here, to run repeatedly:
  Serial.println("");

  char foo[BUFFER_SIZE];
  Serial.println("Size of foo = " + String(sizeof(foo)));
  system_rtc_mem_read(64, foo, sizeof(foo));
  for (int i = 0; i < sizeof(foo); i++) {
    Serial.println(String(i) + "  read = " + String((int)foo[i]));
  }

  Serial.println("*************************************");

  char bar[BUFFER_SIZE];
  for (int i = 0; i < sizeof(bar); i++) {
    bar[i] = 255;
  }
  Serial.println("Size of bar = "  + String(sizeof(bar)));
  system_rtc_mem_write(64, bar, sizeof(bar));


  delay(1000);
  Serial.println("END" );

  ESP.deepSleep(10000000, WAKE_RF_DEFAULT);
  delay(10000);
}

@martinayotte
Copy link
Contributor

I'm confirming that too ! So, the word 64 and word 95 are prohibited area ! 😧
I've verified the rest of userspace, all other are Ok !
(Is that mean that Espressif is running-out of their own SystemSpace and start using our space ? 😢 )

@Duality4Y
Copy link
Contributor

no i don't think espressif is anywhere near running out of their systemspace, and besides that rtcmem is in a totally different memory :) that isn't shared by anything else. (correct me if i am wrong:)

@martinayotte
Copy link
Contributor

If it is not my own sketch, it is either Arduino framework, which I doubt, or Espressif SDK itself, which reserved the first 64 words but in fact it is already known that the 65th word is used by them.

@murilopontes
Copy link

Hi guys, I'm debug this bug!

That is debug sketch with hexdump the complete RTC mem (all 512 user bytes)
rtcmem.ino.txt

Memory map in Arduino Serial Console look like this
esp-rtc-mem

The code to get RTC memory working throught reboot

typedef struct {
byte junk01[32]; //may be constant
byte usable01[192];
byte junk02[48]; //may be constant
byte usable02[96];
byte junk03[16]; //may be constant
byte usable02[128];
} rtc_usable_area_t ;

void setup(){
rtc_usable_area_t RTC_persistent_data;
system_rtc_mem_read(0, &RTC_persistent_data, 512);
RTC_persistent_data.usable01[0]='o';
RTC_persistent_data.usable01[1]='k'';
system_rtc_mem_write(0, &RTC_persistent_data, 512);
}

@martinayotte
Copy link
Contributor

You code is starting wirting/reading at word 0, which is not the UserSpace, it is SystemSpace reserved by Espressif. Simply start reading at word 64, and continue until the end of 512 bytes.
But Yes, there is 2 words that Espressif seems to have stolen from us 😢 , the word 64 itself and the word 95, as you discovered yourself too, but the rest of the 512 (the last 256 that you didn't scanned) seems to be Ok !

@igrr
Copy link
Member

igrr commented Mar 27, 2016

Doh! I forgot that my bootloader clears the command passed through RTC memory even if there was no valid command there:
https://github.com/esp8266/Arduino/blob/master/bootloaders/eboot/eboot.c#L125
https://github.com/esp8266/Arduino/blob/master/bootloaders/eboot/eboot_command.c#L60-L64
Which overwrites those 2 words.
Sorry about that, will fix.

@murilopontes
Copy link

Hi @igrr,

Looking at
https://github.com/esp8266/Arduino/blob/master/bootloaders/eboot/eboot_command.h#L25-L30
the eboot are using the first 32 words of 32bits = 128bytes of RTC mem, so left 96 words of 32bits = 384 bytes of RTC mem for user data.

#define RTC_MEM ((volatile uint32_t*)0x60001200)
RTC_MEM[0] up to RTC_MEM[31] -> used by eboot
RTC_MEM[32] up to RTC_MEM[127] -> user data (@igrr, is safe use this range?)

@murilopontes
Copy link

murilopontes commented May 31, 2016

@igrr, inspired by eboot CRC, I can do the same to user_data.

https://gist.github.com/murix/b7ec396c8876f44cdcc757b08de5b180

<script src="https://gist.github.com/murix/b7ec396c8876f44cdcc757b08de5b180.js"></script>

RTC User data store into offset range 32 up to 127 seems do not corrupt CRC through deep-sleep cycles. So, I think RTC mem is safe if offset is correct.

torntrousers added a commit to torntrousers/Arduino that referenced this issue Aug 16, 2018
@9crk
Copy link

9crk commented Feb 12, 2019

finally I found this page....this bug sucks. wastes my hours!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants