Hello,
I am working with the nrf52840 chip, and would like to store a serial number on the device that persists across boots and OTA-DFU. I have integrated the nvs sample into my code, and it seems to work, except for when I try to use a separate partition to ensure that bluetooth settings do not overwrite the serial number. I have created a separate partition in the devicetree file, and when I try to use that partition, I get build errors. If I do not need to use that partition, then it may work, but I am not sure. The reason I am doing this is is due to the suggestions of this thread:
Problem to read back flash with NVS when concurrent use with Bluetooth
I have also considered using the partition manager, but I am unsure how to go about this, and the documentation is very sparse on how to create these pm.yaml files.
Basically, I need to store a 32-digit string on a section of the flash that will not be touched by OTA-DFU, and can be read at boot. I am still kind of new to nordic development, so any suggestions are appreciated!
Here is my dts file:
&flash0 { /* * For more information, see: * https://docs.zephyrproject.org/latest/guides/dts/legacy-macros.html#legacy-flash-partitions */ partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; boot_partition: partition@0 { label = "mcuboot"; reg = <0x000000000 0x0000C000>; }; slot0_partition: partition@c000 { label = "image-0"; reg = <0x0000C000 0x00067000>; }; slot1_partition: partition@73000 { label = "image-1"; reg = <0x00073000 0x00067000>; }; scratch_partition: partition@da000 { label = "image-scratch"; reg = <0x000da000 0x0001e000>; }; /* * The flash starting at 0x000f8000 and ending at * 0x000fffff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ storage_partition: partition@f8000 { label = "storage"; reg = <0x000f8000 0x00004000>; }; user_partition: partition@fC000{ label = "user_storage"; reg = <0x000fC000 0x00004000>; }; }; };
And here is my prj.conf file, where the CONFIG_BOOTLOADER_MCUBOOT=y is commented out as the line that causes build errors.
CONFIG_BT=y CONFIG_BT_DEBUG_LOG=y CONFIG_BT_SMP=y CONFIG_BT_PERIPHERAL=y CONFIG_LOG=y CONFIG_LOG_PRINTK=y CONFIG_RTT_CONSOLE=y CONFIG_BT_DIS=y CONFIG_BT_DIS_PNP=n CONFIG_BT_DIS_MODEL="Calisto Insight" CONFIG_BT_DIS_MANUF="Calisto" CONFIG_BT_DIS_SERIAL_NUMBER=y CONFIG_BT_DIS_SERIAL_NUMBER_STR="beta_2" CONFIG_BT_DIS_FW_REV=y CONFIG_BT_DIS_HW_REV=y CONFIG_BT_DIS_SW_REV=y CONFIG_BT_DIS_FW_REV_STR="1.0.0" CONFIG_BT_DIS_HW_REV_STR="1.0.0" CONFIG_BT_DIS_SW_REV_STR="1.0.0" CONFIG_BT_DEVICE_NAME="Calisto_Insight_2" CONFIG_MCUBOOT_IMAGE_VERSION="1.0.0+0" CONFIG_BT_BAS=y CONFIG_ADC=y CONFIG_ADC_ASYNC=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_BT_BUF_ACL_RX_SIZE=251 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_L2CAP_TX_MTU=247 CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 CONFIG_MCUMGR=y # CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_MCUMGR_CMD_OS_MGMT=y CONFIG_MCUMGR_CMD_IMG_MGMT=y CONFIG_MCUMGR_SMP_BT=y CONFIG_MCUMGR_SMP_BT_AUTHEN=n CONFIG_IMG_ERASE_PROGRESSIVELY=y CONFIG_DEBUG_OPTIMIZATIONS=y CONFIG_DEBUG_THREAD_INFO=y CONFIG_DFU_TARGET=y CONFIG_DFU_TARGET_MCUBOOT=y CONFIG_IMG_ERASE_PROGRESSIVELY=y CONFIG_IMG_MANAGER=y CONFIG_MCUBOOT_IMG_MANAGER=y CONFIG_SIGN_IMAGES=y CONFIG_HWINFO=y CONFIG_STDOUT_CONSOLE=y CONFIG_PRINTK=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_NVS=y CONFIG_NVS_LOG_LEVEL_DBG=y CONFIG_REBOOT=y CONFIG_MPU_ALLOW_FLASH_WRITE=y
Here is the part of my main() that sets up and reads the flash:
#include <zephyr/zephyr.h> #include <zephyr/sys/reboot.h> #include <zephyr/device.h> #include <string.h> #include <zephyr/drivers/flash.h> #include <zephyr/storage/flash_map.h> #include <zephyr/fs/nvs.h> static struct nvs_fs fs; #define STORAGE_NODE_LABEL user_storage /* 1000 msec = 1 sec */ #define SLEEP_TIME 100 /* maximum reboot counts, make high enough to trigger sector change (buffer */ /* rotation). */ #define MAX_REBOOT 400 #define ADDRESS_ID 1 #define KEY_ID 2 #define RBT_CNT_ID 3 #define STRING_ID 4 #define LONG_ID 5 void main(void) { int rc = 0, cnt = 0, cnt_his = 0; char buf[16]; uint8_t key[8], longarray[128]; uint32_t reboot_counter = 0U, reboot_counter_his; struct flash_pages_info info; /* define the nvs file system by settings with: * sector_size equal to the pagesize, * 3 sectors * starting at FLASH_AREA_OFFSET(STORAGE_NODE_LABEL) */ fs.flash_device = FLASH_AREA_DEVICE(STORAGE_NODE_LABEL); if (!device_is_ready(fs.flash_device)) { printk("Flash device %s is not ready\n", fs.flash_device->name); return; } fs.offset = FLASH_AREA_OFFSET(STORAGE_NODE_LABEL); rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info); if (rc) { printk("Unable to get page info\n"); return; } fs.sector_size = info.size; fs.sector_count = 3U; rc = nvs_mount(&fs); if (rc) { printk("Flash Init failed\n"); return; } /* ADDRESS_ID is used to store an address, lets see if we can * read it from flash, since we don't know the size read the * maximum possible */ rc = nvs_read(&fs, ADDRESS_ID, &buf, sizeof(buf)); if (rc > 0) { /* item was found, show it */ printk("Id: %d, Address: %s\n", ADDRESS_ID, buf); } else {/* item was not found, add it */ strcpy(buf, "192.168.1.5"); printk("No address found, adding %s at id %d\n", buf, ADDRESS_ID); (void)nvs_write(&fs, ADDRESS_ID, &buf, strlen(buf)+1); }
Thanks for any suggestions/help you might be able to provide!
Best,
Andrew