Set NVM Size

Hello,

  I need to persist ~200K of data on the internal flash of an NRF52832 chip.  I've run a memory report and I'm current taking up 185Kb and the chip has 512 Kb of flash so there is the space.  I've taken the code from teh sample nvm project to init that nvm filesystm as below:

int init_storage(){
    LOG_INF("Init storage");
    int rc = 0;
    	/* define the nvs file system by settings with:
	 *	sector_size equal to the pagesize,
	 *	3 sectors
	 *	starting at NVS_PARTITION_OFFSET
	 */
	fs.flash_device = NVS_PARTITION_DEVICE;
	if (!device_is_ready(fs.flash_device)) {
		LOG_ERR("Flash device %s is not ready\n", fs.flash_device->name);
		return -1;
	}

	fs.offset = NVS_PARTITION_OFFSET;
	rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
	if (rc) {
		LOG_ERR("Unable to get page info, rc=%d\n", rc);
		return -1;
	}
    LOG_INF("Storage initialized size is %" PRIu32 " index is %" PRIu32, info.size, info.index);
    

	fs.sector_size = info.size;
	fs.sector_count = 2U;
    
    rc = nvs_mount(&fs);
	if (rc) {
		LOG_ERR("Flash Init failed, rc=%d\n", rc);
		return 0;
	}

    return 0;
}

  This works fine but it only gives me 4K worth of memory space.  If I increase the sector count to more than 3 I get an invalid address: 0x00080ff8 error on runtime.  How can I set the nvm filesystem to be 200Kb in size?

Cheers,

Neil

  • Hi Neil, 
    Could you show how you set up  the nvs_fs in the code ? 
    Which flash partition you assign it to ? 
    For example here is the code in the nvs sample: 

    #define NVS_PARTITION		storage_partition
    #define NVS_PARTITION_DEVICE	FIXED_PARTITION_DEVICE(NVS_PARTITION)
    #define NVS_PARTITION_OFFSET	FIXED_PARTITION_OFFSET(NVS_PARTITION)
    
    ...
    fs.flash_device = NVS_PARTITION_DEVICE;
    	if (!device_is_ready(fs.flash_device)) {
    		printk("Flash device %s is not ready\n", fs.flash_device->name);
    		return 0;
    	}
    	fs.offset = NVS_PARTITION_OFFSET;
    	rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
    	if (rc) {
    		printk("Unable to get page info, rc=%d\n", rc);
    		return 0;
    	}
    	fs.sector_size = info.size;
    	fs.sector_count = 5U;
    
    	rc = nvs_mount(&fs);

  • Hello,

     I actually took it straight from that example, please see below:

    #include "include/bw_storage.h"
    #include <zephyr/logging/log.h>
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/flash.h>
    #include <zephyr/storage/flash_map.h>
    #include <zephyr/fs/nvs.h>
    
    #define LOG_MODULE_NAME brikwiz_storage
    LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG);
    
    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)
    #define NVS_PARTITION_SIZE	FIXED_PARTITION_SIZE(NVS_PARTITION)
    
    struct flash_pages_info info;
    
    uint16_t vid_file_id;
    
    int init_storage(){
        LOG_INF("Init storage");
        int rc = 0;
        	/* define the nvs file system by settings with:
    	 *	sector_size equal to the pagesize,
    	 *	3 sectors
    	 *	starting at NVS_PARTITION_OFFSET
    	 */
    	fs.flash_device = NVS_PARTITION_DEVICE;
    	if (!device_is_ready(fs.flash_device)) {
    		LOG_ERR("Flash device %s is not ready\n", fs.flash_device->name);
    		return -1;
    	}
    
    	fs.offset = NVS_PARTITION_OFFSET;
    	rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
    	if (rc) {
    		LOG_ERR("Unable to get page info, rc=%d\n", rc);
    		return -1;
    	}
        LOG_INF("Storage size is %" PRIu32 " index is %" PRIu32, info.size, info.index);
        
        LOG_INF("Partition size is %" PRIu32 " offset is %" PRIu32, NVS_PARTITION_SIZE, NVS_PARTITION_OFFSET);
    	fs.sector_size = info.size;
    	fs.sector_count = 2U;
        
        rc = nvs_mount(&fs);
    	if (rc) {
    		LOG_ERR("Flash Init failed, rc=%d\n", rc);
    		return 0;
    	}
    
        return 0;
    }

      However that is the only thing I took directly; I also copied over the CONFIG options from the prj.conf file in the nvs example to my project's prj.conf file.

    Cheers,

    Neil

  • Hi Neil, 
    It seems that SETTINGS and your own nvs flash is sharing the same partition settings_storage. You may want to define your own partition for your nvs flash storage. 
    I would suggest to take a look at this sample from Sigurd: 
    RE: Setting and using NVS and BT Settings with Static Partition Manager

    To have your own dedicated partition for nvs, you can create a file named pm_static.yml and put the custom_nvs_storage there. 

  • Hello,

      Thanks for that; I followed the example and included the pm_static.yml file as follows:

    custom_nvs_storage:
      address: 0x80000
      end_address: 0x88000
      region: flash_primary
      size: 0x8000
    

    The code to initalise the storage is as follows:

    #include "include/bw_storage.h"
    #include <zephyr/logging/log.h>
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/flash.h>
    #include <zephyr/storage/flash_map.h>
    #include <zephyr/fs/nvs.h>
    
    #define LOG_MODULE_NAME brikwiz_storage
    LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG);
    
    static struct nvs_fs fs;
    
    #define NVS_PARTITION		custom_nvs_storage
    #define NVS_PARTITION_DEVICE	FIXED_PARTITION_DEVICE(NVS_PARTITION)
    #define NVS_PARTITION_OFFSET	FIXED_PARTITION_OFFSET(NVS_PARTITION)
    #define NVS_PARTITION_SIZE	FIXED_PARTITION_SIZE(NVS_PARTITION)
    
    struct flash_pages_info info;
    
    uint16_t vid_file_id;
    
    int init_storage(){
        LOG_INF("Init storage");
        int rc = 0;
        	/* define the nvs file system by settings with:
    	 *	sector_size equal to the pagesize,
    	 *	3 sectors
    	 *	starting at NVS_PARTITION_OFFSET
    	 */
    	fs.flash_device = NVS_PARTITION_DEVICE;
    	if (!device_is_ready(fs.flash_device)) {
    		LOG_ERR("Flash device %s is not ready\n", fs.flash_device->name);
    		return -1;
    	}
    
    	fs.offset = NVS_PARTITION_OFFSET;
    	rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
    	if (rc) {
    		LOG_ERR("Unable to get page info, rc=%d\n", rc);
    		return -1;
    	}
        LOG_INF("Storage size is %" PRIu32 " index is %" PRIu32, info.size, info.index);
        
        LOG_INF("Partition size is %" PRIu32 " offset is %" PRIu32, NVS_PARTITION_SIZE, NVS_PARTITION_OFFSET);
    	fs.sector_size = info.size;
    	fs.sector_count = 2U;
        
        rc = nvs_mount(&fs);
    	if (rc) {
    		LOG_ERR("Flash Init failed, rc=%d\n", rc);
    		return 0;
    	}
    
        return 0;
    }

     Upon compiling the storage seems correctly allocated:

    app:
      address: 0x0
      end_address: 0x7e000
      region: flash_primary
      size: 0x7e000
    custom_nvs_storage:
      address: 0x80000
      end_address: 0x88000
      region: flash_primary
      size: 0x8000
    settings_storage:
      address: 0x7e000
      end_address: 0x80000
      placement:
        align:
          start: 0x1000
        before:
        - end
      region: flash_primary
      size: 0x2000
    sram_primary:
      address: 0x20000000
      end_address: 0x20010000
      region: sram_primary
      size: 0x10000
    

      However when the code executes I get the following error:

    *** Booting nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    [00:00:00.008,850] <inf> brikwiz_base: Starting BrikWiz Base Peripheral
    
    [00:00:00.008,850] <inf> brikwiz_storage: Init storage
    [00:00:00.008,850] <err> brikwiz_storage: Unable to get page info, rc=-22
    
    [00:00:00.008,880] <err> brikwiz_base: Failed to initialize storage
    

      There seems to be something going wrong on the line

    rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);

      I'm not sure what I can do to find more information on the error?

    Cheers,

    Neil

  • Hi Neil, 
    I think you are defining something outside of the flash area. The chip has only 512kB meaning 0x80000 is the last address of it. 
    You need to define custom_nvs_storage behind settings_storage and after app. 
    Try to squeeze the custom_nvs_storage between them (make app partition 0x8000 smaller and put custom_nvs_storage  in there)

Related