The choice of an STM32WL microcontroller precludes the use of internal EEPROM, requiring the use of either an external EEPROM or the internal Flash memory for storing persistent data. The latter option is often favored in many designs (and modems) for cost reasons, though it comes with certain implications.
Using networks like LoRaWAN and Sigfox involves regular persistent writes. In the case of LoRaWAN, using OTAA (Over-The-Air Activation) mode, the devNonce must be recorded during each join procedure to ensure its uniqueness over network connections. Here, the number of persistent memory writes will theoretically be low (except for the battery end-of-life scenario discussed later). For an ABP (Activation By Personalization) connection, the situation differs significantly; the frame counter (FCnt) must be recorded so that it does not reset to zero in the event of a reboot. The same applies to Sigfox and its SeqId, which must increment with each communication. Without specific logic, LoRaWAN ABP and Sigfox will write to persistent memory with each data transmission.
While an EEPROM memory area has a lifespan of about 100,000 to 1,000,000 cycles (still potentially lower than the number of messages sent during the object’s lifecycle), a Flash memory area lasts only 10,000 writes, a number quickly reached in IoT communications. Therefore, using Flash as persistent storage requires a different approach compared to EEPROM in this context.
Flash memory specificities
The STM32WL, widely used for LoRaWAN and Sigfox connectivity, does not include EEPROM, and many designs rely on Flash. Typically, a memory area, usually at the end, is reserved for persistent storage. This involves an EEPROM emulator for simple access while ensuring good Flash memory protection.
First, Flash cannot be written byte by byte; more precisely, it cannot be erased byte by byte nor rewritten byte by byte. A memory area (64 bits) can only take three states: erased (all bits are 1), written (some bits switched from 1 to 0), and 0 (all bits are 0). Therefore, the only possible rewrite at the word size is changing bits to 0. To make a new write, a whole page, i.e., 2KB, must be erased. Using Flash as EEPROM would thus lead to rewriting an entire page for each byte modification, an inefficient solution.
STM32 EEPROM emulation
An EEPROM emulator virtualizes memory so that each write of a variable can be done in a new area of the same page, not yet written, without erasing the page. This decorrelates variable writing from page erasure, drastically reducing the number of erasures (and hence page wear). For this to work, more Flash space is needed than the size required in EEPROM. The more available space, the fewer memory erasures are necessary for each variable modification.
ST provides an EEPROM emulator generally used in their example projects and adopted in many packaged solutions. This driver is highly efficient, relatively universal, and somewhat heavy for an STM32WL but secure. However, mastering its use is crucial to properly adjust the reserved Flash memory size according to the number of writes, especially since implementations may not have optimized their code to avoid unnecessary writes, as discussed later.
According to ST, for 4KB of virtual EEPROM supporting 100,000 writes, 164KB of Flash must be allocated… far too much. But in practice, only a few bytes are updated, not 4KB. Understanding this is key.
Personally, I implemented my own emulator using 14-byte lines to achieve 127 write lines per Flash page, allowing a small data group (less than 14 bytes) to be written 1,200,000 times with only a 2KB Flash overhead.
A side effect of these mechanisms is that EEPROM access time varies depending on the need to clean memory areas for reuse, a potentially long operation to be considered in the object’s autonomy calculations.
Optimizing EEPROM Access and Avoiding Self-Destruction
Properly managing Flash life also involves making implementation decisions. Sigfox or LoRaWAN (ABP) stacks aim to store counters in EEPROM with each modification to continue the sequence in case of reboot. However, reboots are rare, and future jumps in sequences are not problematic since these networks support frequent frame loss. Thus, why not write these counters to EEPROM only once every 16 modifications, recording the next value while keeping the expected value in RAM? This simple method can significantly extend storage lifespan. Some adaptations will be needed to satisfy certification protocols that haven’t fully considered these needs.
For information like the DevNonce used by LoRaWAN in OTAA, the same optimization is unnecessary since its occurrence is low, normally once per JOIN. However, beware of end-of-life battery scenarios causing poorly written firmware to reboot, relaunch a JOIN Request, and crash due to lack of energy, then restart immediately until batteries are exhausted. My early experiences showed that an object can restart and transmit 50,000 times in less than 24 hours under such conditions, with as many Flash writes, leading to premature memory and system failure. This issue also arises with Sigfox and an immediate first emission.
Good practices include waiting several minutes before the first transmission or preferably controlling reboot reasons to limit problematic, dangerous writes.
Conclusion
Understanding Flash memory functioning and communication protocol details is key to developing embedded solutions using LPWAN. Mastery of these areas is crucial to avoid premature aging of objects, which can occur within six months to a year, drastically increasing the TCO for the end customer and posing a significant industrial risk for the supplier.
Seeing no information on the cycle count a modem using an STM32WL can handle, I question existing implementations. If you use them, I urge you to consider their impact in your designs.
As long as you don’t remove the power supply, you can use Backup Domain – few registers, where data are available to read after reboot – for storing e.g. devNonce and ABP keys.
Interesting ! thank you for sharing this tip