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