This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Halt on nvs_init()

We are implementing on nRF52840 with latest NCS version the following code:

config.fs.offset = FLASH_AREA_OFFSET(storage);
  res = flash_get_page_info_by_offs(
          device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL),
          config.fs.offset, &config.info);
  if (RET_OK != res) {
          LOG_ERR("Unable to get page info");
  }
  config.fs.sector_size = config.info.size;
  config.fs.sector_count = 3U;

  if(RET_OK == res)
  {
    res = nvs_init(&config.fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
    if (RET_OK != res) {
      LOG_ERR("Flash Init failed\n");
    }
  }

The nvs_init() function is halting due to an error at flash_sync_mpsl.c within nrf_flash_sync_exe function when attempting to call mpsl_timeslot_request()

errcode = MULTITHREADING_LOCK_ACQUIRE();
__ASSERT_NO_MSG(errcode == 0);
ret = mpsl_timeslot_request(_context.session_id, req);
__ASSERT_EVAL((void)ret, (void)ret, ret == 0,
     "mpsl_timeslot_request failed: %d", ret);
MULTITHREADING_LOCK_RELEASE();

We set at prj.conf proper settings from the nvs example. But we are implementing NVS within the Zigbee Light Switch example (with FOTA activated which involves mcuboot).

Is there any special consideration to handle in this case? Are we missing something?

Thanks in advance,

Santiago

  • Hi Santiago,

    Sorry for the late reply. The zigbee stack may be using NVS to stored some network parameters and keys. I have asked our developers for what special considerations should you have when using NVS + Zigbee so I hope to come back to you soon with an answer. Thanks for your patience.

    Best regards,

    Marjeris

  • Hi again,

    I hear back from the developers. Zigbee does not use NVS, but it stores network data through ZBOSS specific NVRAM. It does affect the partition placement inside the flash memory, so they would like if you could share your prj.conf file with us to understand the issue.

    Best regards,

    Marjeris

  • Hi Marjeris,

    Please find below the prj.conf file

    # Copyright (c) 2020 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    CONFIG_NCS_SAMPLES_DEFAULTS=y
    
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_SERIAL=y
    CONFIG_GPIO=y
    
    # Make sure printk is not printing to the UART console
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    
    CONFIG_HEAP_MEM_POOL_SIZE=2048
    
    CONFIG_ZIGBEE=y
    CONFIG_ZIGBEE_APP_UTILS=y
    CONFIG_ZIGBEE_ROLE_END_DEVICE=y
    
    # Enable API for powering down unused RAM parts
    CONFIG_RAM_POWER_DOWN_LIBRARY=y
    
    # Enable DK LED and Buttons library
    CONFIG_DK_LIBRARY=n
    
    # This example requires more workqueue stack
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    
    # Enable nRF ECB driver
    CONFIG_CRYPTO=y
    CONFIG_CRYPTO_NRF_ECB=y
    
    # Cryptocell is not supported through CSPRNG driver API: NCSDK-4813
    CONFIG_ENTROPY_CC3XX=n
    
    # Enable API for powering down unused RAM parts
    CONFIG_RAM_POWER_DOWN_LIBRARY=y
    
    #Networking
    CONFIG_NET_IPV6_MLD=n
    CONFIG_NET_IPV6_NBR_CACHE=n
    CONFIG_NET_IPV6_RA_RDNSS=n
    CONFIG_NET_IP_ADDR_CHECK=n
    CONFIG_NET_UDP=n
    
    # CUSTOM SETTINGS
    # Enable cJSON lib (for JSON parsing)
    CONFIG_NEWLIB_LIBC=y
    CONFIG_CJSON_LIB=y
    
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    
    CONFIG_NVS=y
    CONFIG_NVS_LOG_LEVEL_DBG=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y

    We've been able to move forward. But the code halts on nvs_write() always.

    We tested the nvs sample code embedded in this project (that includes Zigbee) and keeps halting on MPU fault (Hard fault).

    On the same board with just the nvs sample (no Zigbee included) it works properly.

    . Remarks: We've already set CONFIG_MPU_ALLOW_FLASH_WRITE=y and tried to align buffer data passed as parameters... but nothing works.

    Need help asap, please.

    Regards,

  • Hi again,

    I am sorry for not coming back to you earlier. Thanks for sharing the prj.conf file, I have forwarded it to the Zigbee team. Could it also be possible to share a small version of your project with zigbee + nvs that can allow us to reproduce the issue at our end?

  • Hi,

    I have got a reply for you from the Zigbee team:

    NVS does not conflict with Zigbee NVRAM. Flash partitioning is done by the Partition Manager, which is by default used by zigbee samples, but not by nvs sample in Zephyr (as the Partition Manager is a Nordic's tool). If flash is used by various subsystems (for examples: settings, zigbee nvram, nvs), the partition manager takes care of providing separate partition for each one.

    To initialize NVS, a proper configuration is needed. This one can be obtained from the flash area of partition assigned to nvs. I am attaching an example of doing this. The nvs_storage lable was taken from partitions.yml, which is generated by partition manager (more information here).

    int enable_nvs(struct nvs_fs *fs)
    {
        int rc;
        const struct flash_area *flash_area;
        static struct flash_sector flash_sectors[6];
        uint32_t sector_cnt = ARRAY_SIZE(flash_sectors);
    
        rc = flash_area_open(FLASH_AREA_ID(nvs_storage), &flash_area);
        if (rc) {
            LOG_ERR("Failed to open flash area(nvs_storage)->rc(%d)", rc);
            return rc;
        }
        rc = flash_area_get_sectors(FLASH_AREA_ID(nvs_storage), &sector_cnt,
                                    flash_sectors);
        if (rc) {
            LOG_ERR("Failed to get area(nvs_storage) sectors->rc(%d)", rc);
            return rc;
        }
        fs->sector_size = flash_sectors[0].fs_size;
        fs->offset = flash_area->fa_off;
        fs->sector_count = 0;
        for (size_t nvs_size = 0; nvs_size < flash_area->fa_size; fs->sector_count++) {
            nvs_size += fs->sector_size;
        }
        LOG_INF("Attempt to init (nvs_storage) in %s\n"
                "\tsector_size: (%d)\tsector_cnt: (%d)\tfs_offset: (%ld)",
                flash_area->fa_dev_name, fs->sector_size, fs->sector_count, fs->offset);
        return nvs_init(fs, flash_area->fa_dev_name);
    }

    Let me know if this resolves your issue.

    Best regards,

    Marjeris

Related