Zigbee persistent data management and non-volatile memory

1. Introduction

In a Zigbee network, if a node is turned off due to a power shutdown or any other reason, the network data stored in its Random-Access Memory (RAM) will be lost. This can result in the loss of important information and affect the functioning of the network, which is why we need to store some data, called persistent data, in a Non-Volatile Memory (NVM). These data can be network settings, security keys, or other configuration information.
This wiki describes the dedicated persistent data APIs used for storing data in the STM32WB flash memory.

2. STM32WB persistent data management

By saving critical data in the NVM each time they change, the Zigbee network node ensures that they are always up-to-date and that the node can quickly recover from a power failure or other unexpected event.

The end user has two options:

  • Manually manage when to save data in the NVM.
  • Rely on the stack notification.

If the end user chooses to manage the saving of data in the NVM, they need to determine the appropriate time to call the save data function based on their specific use case and application requirements. On the other hand, if the end user chooses to rely on the stack notifications, they can use these notifications as triggers to automatically save critical data in the NVM, ensuring that the data is always up-to-date and persistent.

2.1. Stack notification

The STM32WB Zigbee stack notifies the application each time the persistent data change. First, the application must enable notifications by registering the persistent data change notification.

 /* Register persistent data change notification */
 ZbPersistNotifyRegister(zigbee_app_info.zb, APP_ZIGBEE_persist_notify_cb, NULL);

Once the persistent data change notification has been registered, the end user needs to implement the callback function to handle the notification. This function is called every time a persistent data change occurs in the Zigbee network.

  

 /*
 * @brief notify to save persistent data callback
 * @param zb: zigbee context pointer, cbarg: callback arg pointer
 * @retval: None
 */
 static void APP_ZIGBEE_persist_notify_cb(struct ZigbeeT * zb, void *cbarg)
 {
    APP_DBG("Notification to save persistent data requested from stack");
    /* Save the persistent data */
    APP_ZIGBEE_persist_save();
 }

To disable the notification, the application calls the stack API with NULL parameters:

 /* Disable Notification */
 ZbPersistNotifyRegister(zigbee_app_info.zb, NULL, NULL);

2.2. STM32WB memory mapping

As shown in the figure below, there are two APIs used to store and retrieve the persistent data:

  • The ZbPersistGet API allows the application to get data and its length from an internal stack buffer in the RAM. They are then copied into a RAM cache and written in the flash memory through the EEPROM emulator.
  • The ZbStartupPersist API allows the Zigbee stack to initialize/start, using persistent data from the buffer (previously copied from the flash memory through the EEPROM emulator).

It is important to note that both APIs are at M0 level and only manipulate the internal stack buffers in the RAM.

Memory mapping
Connectivity NVM MemoryMapping.png

Note: Cluster attributes are not persistent data by default. An attribute must be declared using the ZCL_ATTR_FLAG_PERSISTABLE flag to declare data as persistent.

 const struct ZbZclAttrT zcl_onoff_server_attr_list[] = 
 {
   {
       ZCL_ONOFF_ATTR_ONOFF, ZCL_DATATYPE_BOOLEAN,
       ZCL_ATTR_FLAG_REPORTABLE|ZCL_ATTR_FLAG_PERSISTABLE, 0, NULL, {0, 0}, {0, 0}
   },
 };

3. EEPROM emulator

The NVM is typically implemented using flash memory or EEPROM technology, which allows data to be written and rewritten many times, providing long-term data storage capabilities. In a Zigbee network, the EEPROM emulator is made up of three parts: the EEPROM emulation header, the NVM layer, and the application layer.

The STM32WB NVM uses the EEPROM emulator, which impacts the real size available for the persistent data. The STM32WB internal flash memory unit is the page; a page size is 4 Kbytes and its width is 64 bits.

It is important to note that the available size of the EEPROM emulator is limited and care should be taken to use this storage space efficiently to ensure the stable and reliable operation of the Zigbee network.

As the figure below shows, the first header of four U64 words is taken for the page, followed by a second EE header for each record that sizes U32 words (2032 bytes). Thus, the remaining size per page for data is 2032 bytes.

Flash memory example with EEPROM emulator
Connectivity NVM EE.png

The end user must declare the allocated flash memory dedicated to the NVM in the scatter file. It must range between the M0 starting address and the M4 starting address, and must be a multiple of two pages.

4. STM32WB NVM application example

An example of an NVM application is provided in the STM32CubeWB MCU Package[1]. This example is based on the On/Off cluster.

4.1. STM32WB API descriptions

To use persistent data management in Zigbee networks, we need to implement a set of APIs that allow devices to read and write data to the non-volatile memory. The following table describes the list of APIs that we have implemented in this application example.

API Description
Persistent data application APIs
APP_ZIGBEE_persistent_save Starts the persistent data saving procedure.
APP_ZIGBEE_persistent_load Starts the persistent data loading procedure.
APP_ZIGBEE_persistent_delete Starts the persistent data clearing procedure.
NVM application APIs
APP_ZIGBEE_NVM_Init Initializes the NVM.
APP_ZIGBEE_NVM_Write Starts to write the persistent data to the NVM form cache.
APP_ZIGBEE_NVM_Read Starts to read the persistent data from the NVM and load the cache.
APP_ZIGBEE_NVM_Erase Starts to erase the NVM and clear the cache.
EE APIs
EE_Init Initializes the EE. If format variable is set the NVM Erase is triggered.
EE_Write Writes the persistent data to NVM adding EE header.
EE_Read Reads the persistent data from NVM stripping EE header off.

4.2. STM32WB application setup

We provide two projects on STM32WB, one for the coordinator and the other for the router.

To test the application, we need at least two STM32WB boards. Both boards are programmed with stm32wb5x_Zigbee_FFD_fw.bin for the wireless coprocessor. For the application, the first board is programmed with the Zigbee_OnOff_Coord_NVM binary and the second board with the Zigbee_OnOff_Router_NVM binary.

The goal of this application is to enable the NVM capability for storing persistent data. The OnOff attributes are defined with the ZCL_ATTR_FLAG_PERSISTABLE flag, so their last values are stored in the NVM. If the router is powered off and back on, it starts from its persisted state (green LED light on) and restores its previous red LED state.

Application use case
Connectivity NVM usecase.png

5. The importance of NVM

  • Activating the NVM feature is recommended to store binding information. Binding[2] information includes details about which devices are bound together, how they are bound together, and what settings are used for communication between them. Ideally, this information must be retained even if the device loses power.
    For example, if a light switch control is bound to a light bulb, the binding information would be stored in the NVM of both devices. If the light switch is turned off or the light bulb loses power, the binding information is still retained in the NVM of both devices, so they are still be able to communicate with each other and resume their previous states when power is restored.
  • Typically, a reporting configuration for a particular attribute is stored in the NVM of the device. This means that even if the device loses power or is reset, the reporting configuration for that attribute will be retained.
    For example, if a temperature sensor is configured to report its temperature reading every 15 seconds, this configuration would be stored in the NVM of the device. If the device loses power and is restarted, it will automatically resume reporting its temperature reading every 15 seconds without needing to be reconfigured.
  • OTA updates[3] of the device firmware also need NVM technology.
    When an OTA update is received, it can be stored in the NVM of the device until the device is restarted or reprogrammed to apply the update.

Hence, NVM helps to ensure reliable and consistent communication between devices in a Zigbee network.

For more details, refer to the application note Persistent data management ZigBee® and non-volatile memory in STM32WB Series (AN5492).[4]

6. References