1.. _retention_api: 2 3Retention System 4################ 5 6The retention system provides an API which allows applications to read and 7write data from and to memory areas or devices that retain the data while the 8device is powered. This allows for sharing information between different 9applications or within a single application without losing state information 10when a device reboots. The stored data should not persist in the event of a 11power failure (or during some low-power modes on some devices) nor should it be 12stored to a non-volatile storage like :ref:`flash_api`, :ref:`eeprom_api`, or 13battery-backed RAM. 14 15The retention system builds on top of the retained data driver, and adds 16additional software-level features to it for ensuring the validity of data. 17Optionally, a magic header can be used to check if the front of 18the retained data memory section contains this specific value, and an optional 19checksum (1, 2, or 4-bytes in size) of the stored data can be appended to the 20end of the data. Additionally, the retention system API allows partitioning of 21the retained data sections into multiple distinct areas. For example, a 64-byte 22retained data area could be split up into 4 bytes for a boot mode, 16 bytes for 23a timestamp, 44 bytes for a last log message. All of these sections can be 24accessed or updated independently. The prefix and checksum can be set 25per-instance using devicetree. 26 27Devicetree setup 28**************** 29 30To use the retention system, a retained data driver must be setup for the board 31you are using, there is a zephyr driver which can be used which will use some 32RAM as non-init for this purpose. The retention system is then initialised as a 33child node of this device 1 or more times - note that the memory region will 34need to be decremented to account for this reserved portion of RAM. See the 35following example (examples in this guide are based on the 36:ref:`nrf52840dk_nrf52840` board and memory layout): 37 38.. code-block:: devicetree 39 40 / { 41 sram@2003FC00 { 42 compatible = "zephyr,memory-region", "mmio-sram"; 43 reg = <0x2003FC00 DT_SIZE_K(1)>; 44 zephyr,memory-region = "RetainedMem"; 45 status = "okay"; 46 47 retainedmem { 48 compatible = "zephyr,retained-ram"; 49 status = "okay"; 50 #address-cells = <1>; 51 #size-cells = <1>; 52 53 /* This creates a 256-byte partition */ 54 retention0: retention@0 { 55 compatible = "zephyr,retention"; 56 status = "okay"; 57 58 /* The total size of this area is 256 59 * bytes which includes the prefix and 60 * checksum, this means that the usable 61 * data storage area is 256 - 3 = 253 62 * bytes 63 */ 64 reg = <0x0 0x100>; 65 66 /* This is the prefix which must appear 67 * at the front of the data 68 */ 69 prefix = [08 04]; 70 71 /* This uses a 1-byte checksum */ 72 checksum = <1>; 73 }; 74 75 /* This creates a 768-byte partition */ 76 retention1: retention@100 { 77 compatible = "zephyr,retention"; 78 status = "okay"; 79 80 /* Start position must be after the end 81 * of the previous partition. The total 82 * size of this area is 768 bytes which 83 * includes the prefix and checksum, 84 * this means that the usable data 85 * storage area is 768 - 6 = 762 bytes 86 */ 87 reg = <0x100 0x300>; 88 89 /* This is the prefix which must appear 90 * at the front of the data 91 */ 92 prefix = [00 11 55 88 fa bc]; 93 94 /* If omitted, there will be no 95 * checksum 96 */ 97 }; 98 }; 99 }; 100 }; 101 102 /* Reduce SRAM0 usage by 1KB to account for non-init area */ 103 &sram0 { 104 reg = <0x20000000 DT_SIZE_K(255)>; 105 }; 106 107The retention areas can then be accessed using the data retention API (once 108enabled with :kconfig:option:`CONFIG_RETENTION`, which requires that 109:kconfig:option:`CONFIG_RETAINED_MEM` be enabled) by getting the device by 110using: 111 112.. code-block:: C 113 114 #include <zephyr/device.h> 115 #include <zephyr/retention/retention.h> 116 117 const struct device *retention1 = DEVICE_DT_GET(DT_NODELABEL(retention1)); 118 const struct device *retention2 = DEVICE_DT_GET(DT_NODELABEL(retention2)); 119 120When the write function is called, the magic header and checksum (if enabled) 121will be set on the area, and it will be marked as valid from that point 122onwards. 123 124.. _boot_mode_api: 125 126Boot mode 127********* 128 129An addition to the retention subsystem is a boot mode interface, this can be 130used to dynamically change the state of an application or run a different 131application with a minimal set of functions when a device is rebooted (an 132example is to have a buttonless way of entering mcuboot's serial recovery 133feature from the main application). 134 135To use the boot mode feature, a data retention entry must exist in the device 136tree, which is dedicated for use as the boot mode selection (the user area data 137size only needs to be a single byte), and this area be assigned to the chosen 138node of ``zephyr,boot-mode``. See the following example: 139 140.. code-block:: devicetree 141 142 / { 143 sram@2003FFFF { 144 compatible = "zephyr,memory-region", "mmio-sram"; 145 reg = <0x2003FFFF 0x1>; 146 zephyr,memory-region = "RetainedMem"; 147 status = "okay"; 148 149 retainedmem { 150 compatible = "zephyr,retained-ram"; 151 status = "okay"; 152 #address-cells = <1>; 153 #size-cells = <1>; 154 155 retention0: retention@0 { 156 compatible = "zephyr,retention"; 157 status = "okay"; 158 reg = <0x0 0x1>; 159 }; 160 }; 161 }; 162 163 chosen { 164 zephyr,boot-mode = &retention0; 165 }; 166 }; 167 168 /* Reduce SRAM0 usage by 1 byte to account for non-init area */ 169 &sram0 { 170 reg = <0x20000000 0x3FFFF>; 171 }; 172 173The boot mode interface can be enabled with 174:kconfig:option:`CONFIG_RETENTION_BOOT_MODE` and then accessed by using the 175boot mode functions. If using mcuboot with serial recovery, it can be built 176with ``CONFIG_MCUBOOT_SERIAL`` and ``CONFIG_BOOT_SERIAL_BOOT_MODE`` enabled 177which will allow rebooting directly into the serial recovery mode by using: 178 179.. code-block:: C 180 181 #include <zephyr/retention/bootmode.h> 182 #include <zephyr/sys/reboot.h> 183 184 bootmode_set(BOOT_MODE_TYPE_BOOTLOADER); 185 sys_reboot(0); 186 187API Reference 188************* 189 190Retention system API 191==================== 192 193.. doxygengroup:: retention_api 194 195Boot mode interface 196=================== 197 198.. doxygengroup:: boot_mode_interface 199