nRF52840 Dongle Settings / NVS / Flash doesn't work

If anyone has successfully stored and retrieved settings on the nRF52840 dongle using any method, please share your approach.

I'm trying to store and retrieve settings on an nRF52840 dongle, but the Settings, NVS, and Flash APIs are not working.

I suspect there may be an issue with the Flash configuration due to the nrf flash controller. How can I resolve this?

OS: Intel Mac 15.1.1(24B91)

IDE: nRF Connect for VS Code

nRF Connect SDK Toolchain: v2.8.0

nRF Connect SDK: v.2.8.99

Below is the code for using the NVS API, but when it enters nvs_mount, it never returns.

#include <zephyr/kernel.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 NVS_PARTITION storage_partition
#define NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(NVS_PARTITION)
#define NVS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(NVS_PARTITION)

int nvs_setup(void) {
  int err;
  struct flash_pages_info info;

  fs.flash_device = NVS_PARTITION_DEVICE;
  if (!device_is_ready(fs.flash_device)) {
    LOG_ERR("device_is_ready %s err", fs.flash_device->name);
    return -EIO;
  }

  fs.offset = NVS_PARTITION_OFFSET;
  err = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
  if (err) {
    LOG_ERR("flash_get_page_info_by_offs err=%d", err);
    return err;
  }

  fs.sector_size = info.size;
  fs.sector_count = 2U;

  LOG_INF("fs.flash_device->name=%s", fs.flash_device->name);
  LOG_INF("fs.offset=%lu", fs.offset);
  LOG_INF("fs.sector_size=%d", fs.sector_size);
  LOG_INF("fs.sector_count=%d", fs.sector_count);

  err = nvs_mount(&fs);
  if (err) {
    LOG_ERR("nvs_mount err=%d", err);
    return err;
  }

  return 0;
}

CONFIG_NVS=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

I found flash_flatten in nvs_flash_erase_sector causes the error in zephry/subsys/fs/nvs/nvs.c

Below is the log manually returns -999 before calling flash_flatten.

*** Booting nRF Connect SDK v2.8.99-13f9e6b6dc5b ***
*** Using Zephyr OS v3.7.99-4a84ea25c165 ***
[00:00:00.000,762] <inf> main: fs.flash_device->name=flash-controller@4001e000
[00:00:00.000,762] <inf> main: fs.offset=1040384
[00:00:00.000,793] <inf> main: fs.sector_size=4096
[00:00:00.000,793] <inf> main: fs.sector_count=2
[00:00:00.000,854] <dbg> fs_nvs: nvs_recover_last_ate: Recovering last ate from sector 0
[00:00:00.004,333] <inf> fs_nvs: No GC Done marker found: restarting gc
[00:00:00.004,333] <dbg> fs_nvs: nvs_flash_erase_sector: Erasing flash at fe000, len 4096
[00:00:00.004,364] <err> main: nvs_mount err=-999

Parents
  • Hi,

    I ran into the same issue and eventually tracked down what was happening.

    When checking the board’s default flash layout in
    C:\ncs\v2.8.0\zephyr\boards\nordic\nrf52840dongle\fstab-stock.dtsi, I noticed it defines the following partition:

    storage_partition: partition@dc000 {
        label = "storage";
        reg = <0x000dc000 0x00004000>;
    };
    

    This 16 KB region at 0xDC000 is the correct location for non-volatile storage on the nRF52840 dongle.

    However, during the build process I found that the actual partition layout generated by Partition Manager (shown in build/partitions.yml) looks like this:

    nvs_storage:
      address: 0xfa000
      end_address: 0x100000
      placement:
        before:
          - end
      region: flash_primary
      size: 0x6000
    

    Partition Manager automatically moved nvs_storage to the very end of flash and expanded it to 0x6000 bytes. This location (0xFA000) overlaps with the nRF52840 Dongle’s built-in bootloader region. As a result, any attempt to erase/write inside that area will cause the firmware to halt.

    I added a pm_static.yml file at the root of my application to override the auto-generated layout:

    nvs_storage:
      address: 0xdc000
      size: 0x4000
      region: flash_primary
    
    nrf5_boot:
      address: 0xe0000
      size: 0x20000     # 128 KB, covers 0xe0000–0x100000
      region: flash_primary
    

    Note that I also needed to explicitly reserve the bootloader region so partition manager does not treat it as unused space.

    This resolved the issue for me.

Reply
  • Hi,

    I ran into the same issue and eventually tracked down what was happening.

    When checking the board’s default flash layout in
    C:\ncs\v2.8.0\zephyr\boards\nordic\nrf52840dongle\fstab-stock.dtsi, I noticed it defines the following partition:

    storage_partition: partition@dc000 {
        label = "storage";
        reg = <0x000dc000 0x00004000>;
    };
    

    This 16 KB region at 0xDC000 is the correct location for non-volatile storage on the nRF52840 dongle.

    However, during the build process I found that the actual partition layout generated by Partition Manager (shown in build/partitions.yml) looks like this:

    nvs_storage:
      address: 0xfa000
      end_address: 0x100000
      placement:
        before:
          - end
      region: flash_primary
      size: 0x6000
    

    Partition Manager automatically moved nvs_storage to the very end of flash and expanded it to 0x6000 bytes. This location (0xFA000) overlaps with the nRF52840 Dongle’s built-in bootloader region. As a result, any attempt to erase/write inside that area will cause the firmware to halt.

    I added a pm_static.yml file at the root of my application to override the auto-generated layout:

    nvs_storage:
      address: 0xdc000
      size: 0x4000
      region: flash_primary
    
    nrf5_boot:
      address: 0xe0000
      size: 0x20000     # 128 KB, covers 0xe0000–0x100000
      region: flash_primary
    

    Note that I also needed to explicitly reserve the bootloader region so partition manager does not treat it as unused space.

    This resolved the issue for me.

Children
No Data
Related