Replies: 14 comments 44 replies
-
Hi, see: #963 From LoRaWan 1.1.0 the counter value should be saved, or you must wait until the counter value will be reached again. As sample you can save every 30 minutes the session what will save number of write cycles (if you think it is critical for your application). Michael |
Beta Was this translation helpful? Give feedback.
-
Now I could be totally wrong about the below, and please correct me if this is the case. However: The way I look at the code, there is indeed all sorts of cleverness happening in Then however, on the ESP32, this emulated EEPROM is actually just a binary blob that lives in a key called 'eeprom' in NVS non-volatile key-value storage. So when Unless I am seeing this wrong (which is wholly possible) the clever FCntUp wear-levelling mechanism is clever on top of an abstraction, has never worked as intended on ESP32 and any devices relying on it are potentially dying faster than planned. The impact could be not-so-bad if the nvs flash region is big enough to hold lots of copies of the entire EEPROM before it needs erasing, but that still means that on ESP32 the If I am wrong I am terribly sorry for wasting whoever looks at this next's time. If I am right, this should probably become an issue. And I still think the ephemeral data should live in the RTC RAM.
|
Beta Was this translation helpful? Give feedback.
-
@ropg I would like to point out that all this is specific to ESP32, which isn't the only platform that emulates EEPROM/persistent storage by using flash (at least RP2040 does that too), and is just one of the platforms supported (albeit a popular one) . If there is some other memory in the ESP32 that can be exploited for this (i.e. is persistent and large enough), is available in the Arduino core and is available for all ESP32 variants, it the can be implemented for ESP32 instead of using the emulated EEPROM. cc @StevenCellist as the author of most of the LoRaWAN code, including the wear leveling mechanism. |
Beta Was this translation helpful? Give feedback.
-
Sometimes the simplest solution is eluding you... So if we just mark all the persistent data as RTC_DATA_ATTR, we are already magically done, right ? And then if people still call |
Beta Was this translation helpful? Give feedback.
-
Alright, ESP_RTC_EEPROM exists (🎉 🥳) and is tested now. I made it its own library complete with example for others to use, naturally we should not depend and just copy the files to utils/ in RadioLib. Plugging this in for ESP32 is easy, but that means people have no means of saving to flash anymore. Any opinions on whether to do that or continue writing to give both options and only submit that? And if we were to have both options, which should be the default? |
Beta Was this translation helpful? Give feedback.
-
Another thought: it's super easy to make a flash write that has exactly the same impact as what we do now: just save to RTC RAM and then write a |
Beta Was this translation helpful? Give feedback.
-
I personally think it would be a nice addition to give options for RTC memory to those that want to use it. Personally, I'd prefer it to be used in the following way:
As LW v1.1 expects full persistence, and especially during development a board is likely to reset quite often, EEPROM should IMO be the default. It also helps users in finding out if their EEPROM works from the start. Once a board is ready to be put in the wild, a user would switch Also, EEPROM is still an actual Arduino Library, not bound to the ESP32 only. |
Beta Was this translation helpful? Give feedback.
-
Love the love-in everyone, but we run the risk of ending up in LoRaMAC-node land with its inscrutable NVM saving functions that then have to shell out to a HAL. LoRaWAN in bulk deployment benefits from some considerable consideration & documentation if your devices aren't at the bottom of your garden. For testing on your desk you don't need to trouble the airwaves because it's a closed spec and there is no need to run the radio. Once you have everything working you can then turn the stack back on. ESP32 has always been the odd-one-out with it's deep sleep being the equivalent of a power down and LMIC wasn't really designed to fish the session out of memory to store so it's taken a considerable amount of time for various peeps to come up with their take on how to do it for ESP32, if you happen to need two cores at 240MHz for taking the temperature of something. And not having a pop at ESP32, but mostly this is an ESP32 problem, other devices sleep at the same level as the ESP32 deep sleep but retain RAM. I strongly recommend people bake their own solutions and then @jgromes can arbitrate over what's best for RadioLib vs having either something in the wiki or something somewhere else. The LW specs are great bedtime reading if you suffer from insomnia but are actually quite pithy, so those that haven't read it yet are strongly urged to do so so that we all realise what sort of swamp we are creating for users, many of which aren't going to want to get in to these weeds. From experience of supporting developer, lost uplinks due to f_cnt issues are some sort of disaster, so really do need saving, particularly for those uplinking every 12 hours where it could be a few days before they know if the device is lost or not. |
Beta Was this translation helpful? Give feedback.
-
I think I have just built the best solution because it leaves RadioLib essentially untouched. My ESP32_RTC_EEPROM now has two new functions: - #include <EEPROM.h>
+ #if defined(RADIOLIB_ESP32)
+ #include "utils/ESP32_RTC_EEPROM.h"
+ #else
+ #include <EEPROM.h>
+ #endif and adding the two files to utils/ |
Beta Was this translation helpful? Give feedback.
-
Thanks everyone for the discussion, I really appreciate it. After a bit of catching up, I think there are essentially two options:
Currently I lean more in favor of the second approach, because it's more generic, and it still allows ESP32 RTC RAM to be used. |
Beta Was this translation helpful? Give feedback.
-
OK. I'm not making it into a PR just yet because I'd like to hear what y'all think, but please check out my RadioLib fork. It has a few small diffs in In the new example |
Beta Was this translation helpful? Give feedback.
-
As you can see, I have just filed PR #1002 which adds the functionality described above. I understand you take time to test features, I just happened to have some time on my hands and as I'd like to use deep sleep without burning devices, this clearly needed fixing. I hope I have honored the concerns of y'all by dealing with the ESP32-specific issues as much outside of the existing RadioLib code as possible. I will continue testing also, so far everything seems stable and resilient against resets while only writing to flash very occasionally. I'd be happy to hear (in due time) what you think of the choices I made in implementing this. I'll close this thread now, but we can continue discussing (at a much slower and more deliberate pace) at the PR. |
Beta Was this translation helpful? Give feedback.
-
Clarifications: Other platforms = other MCU families @michapr, someone is focused on ESP32 but changes impact all other platforms / MCUs as well. And the reason for less haste is that a good LoRWAN device doesn't lose it's session - it's powered up and about two to seven years later it either gets its batteries changed, so does a second join or is disposed of. So constructing a scheme carefully is rather important. The ONLY reason all of the above occurs is because ESP32 doesn't retain its main RAM in deep sleep, which is why it has not been a recommended platform on the TTN forum. The existence of support for AVR EEPROM doesn't mean it's a good idea to just add more code. It would be better to leave what's there alone, mark it as deprecated and provide more flexible functionality that can use existing libraries for each MCU. I can't see this moving forward whilst there is focus on just one MCU type - it may be the one you love, but there are other MCU's and as above, we don't do the library users any favours by not coming up with a plan. |
Beta Was this translation helpful? Give feedback.
-
With agreement of @StevenCellist, closing as we are repeating & elaborating on something that needs work - best to get the job done and everyone can start with a clean slate. |
Beta Was this translation helpful? Give feedback.
-
Hi all,
I'm playing with LoRaWAN and RadioLib on ESP32. I'm new to both LoRaWAN and RadioLib, so please correct me if I'm getting anything wrong.
It seems to me that RadioLib writes the credentials, keys, nonces and counters to EEPROM, which on the ESP32 is emulated by writing them as a blob to an NVS key-value in flash. Actual EEPROMs, e.g. on PIC chips, typically guarantee a million write cycles, where SPI flash is anywhere between 10k and 100k writes, with stories of multiple orders of magnitude less if the temperature goes up, such as might happen in a sun-exposed device. If I want to wake up for a measurement every hour, even 10k writes means a device lifetime of around one year.
The ESP32 has 8kB of very low-power RAM in the real time clock that is kept alive during deep sleep, and I think that would be a much better place for the ephemeral stuff: the long-term secrets (
joinEUI
,devEUI
,appKey
,nwkKey
) can be in flash and it's OK to send a new join message every time the battery is replaced.I guess one could replace EEPROM.[c|h] code with a version that stores in RTC RAM, which would have the added benefit of being useful outside of RadioLib. But maybe it is cleaner and useful on more platforms if in addition to the option of using EEPROM.h, LoRaWANNode had something like
getStateData(uint8_t *data, size_t *len)
andputStateData(uint8_t *data, size_t len)
for a blob that the user can get and store wherever before sleeping and put back before callingjoin()
after waking up again.Beta Was this translation helpful? Give feedback.
All reactions