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

How to use nvs_read and nvs_write in aws_fota app?

I would like to use nvs_read and nvs_write in aws_fota app to store a mode value inside, but it doesn't work. Any help?

I added the following lines to aws_fota prj.conf

<prj.conf>

CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y

I added the following code to aws_fota maiin.c

#include <drivers/flash.h>
#include <storage/flash_map.h>
#include <fs/nvs.h>
#define NVS_ID_MODE 1

int8_t init_nvs_sys()
{
    u8_t rc;
    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)
	 */
	nvs_fs.offset = FLASH_AREA_OFFSET(storage);
	rc = flash_get_page_info_by_offs(
		device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL),
		nvs_fs.offset, &info);
	if (rc) {
		printk("Unable to get page info");
        return -1;
	}
	nvs_fs.sector_size = info.size;
	nvs_fs.sector_count = 3U;

	rc = nvs_init(&nvs_fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
	if (rc) {
		printk("Flash Init failed\n");
        return -1;
	}
}

void main(void)
{
	int err;

    /***************/
	/* Write and read params */
    int ret;
    u8_t mode;
	ret = init_nvs_sys();
	if (ret < 0) {
        printk("Error: init_nvs_sys\n");
	}
    // Write mode
	mode = 0;
	if(nvs_write(&nvs_fs, NVS_ID_MODE, &mode, 1) < 0){ // This causes Error -22
        printk("Error: nvs_write NVS_ID_MODE\n");
    }
    mode = 2;

    // Read mode
	ret = nvs_read(&nvs_fs, NVS_ID_MODE, &mode, 1);
	printk( "nvs_read ret = %d, id = %d, mode = %u\n", ret, NVS_ID_MODE, mode);
	if (ret < 0) {
		printk("Error: nvs_read NVS_ID_MODE\n");
	}

    .
    .
    .
        

	

I have inspected a while and it seems that this line in prj.conf causes the issue.

CONFIG_SETTING=y

Can you tell me how to solve this issue?

Parents
  • Hi Yusuke

    The settings loader module is enabled for every nRF Desktop device with Zephyr's :ref:`zephyr:settings_api` enabled. The :ref:`zephyr:settings_api` subsystem is enabled with the :option:`CONFIG_SETTINGS` Kconfig option. Zephyr's Bluetooth stack does not load the zephyr:settings_api data on its own, as Zephyr assumes that the application will call :cpp:func:`settings_load` after completing all necessary initialization. This function is called on the settings loader module initialization.

    Please also make sure that you write CONFIG_SETTINGS=y, not SETTING. 

    Best regards,

    Simon

  • Hi,

    Thank you for the detail and I'm reading this page

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/applications/nrf_desktop/doc/settings_loader.html

    but I'm not really understanding the settings loader module.. The settings loader module seems to be similar to nvs library.

    https://docs.zephyrproject.org/latest/reference/storage/nvs/nvs.html 

    >Please also make sure that you write CONFIG_SETTINGS=y, not SETTING. 

    oh, sorry it's typo. Yes, it's CONFIG_SETTINGS=y.

    I tried aws_fota app commenting out these two lines and it apparently works out.

    <prj.conf>

    # CONFIG_SETTINGS=y
    # CONFIG_SETTINGS_NVS=y

    Do you think it is ok to remove these lines. If so, we can use nvs in aws_fota app.

  • u8_t mode = 2;
    ret = nvs_write(&nvs_fs, NVS_ID_MODE, &mode, 1);
    if (ret < 0) {
    	return;
    }

    I get -22 errno in nvs_write when I add it to aws_fota.

    This comes from line 179 in ncs\v1.3.0\zephyr\drivers\flash\soc_flash_nrf.c

    is_regular_addr_valid(addr, len) apparently fails. 

    static int flash_nrf_read(struct device *dev, off_t addr,
    			    void *data, size_t len)
    {
    	if (is_regular_addr_valid(addr, len)) { /* This fails */
    		addr += DT_REG_ADDR(SOC_NV_FLASH_NODE);
    	} else if (!is_uicr_addr_valid(addr, len)) {
    		return -EINVAL; /* HERE */
    	}
    
    	if (!len) {
    		return 0;
    	}
    
    #if CONFIG_ARM_NONSECURE_FIRMWARE && CONFIG_SPM && USE_PARTITION_MANAGER
    	if (addr < PM_APP_ADDRESS) {
    		return spm_request_read(data, addr, len);
    	}
    #endif
    
    	memcpy(data, (void *)addr, len);
    
    	return 0;
    }

    In addition, I printed out parameters.

    static inline bool is_regular_addr_valid(off_t addr, size_t len)
    {
    	size_t flash_size = nrfx_nvmc_flash_size_get();
    
            printk("flash_size = %u\n", flash_size); /* ADD HERE */
            printk("addr = %ld\n", addr); /* ADD HERE */
            printk("len = %u\n", len); /* ADD HERE */
    
    	if (addr >= flash_size ||
    	    addr < 0 ||
    	    len > flash_size ||
    	    (addr) + len > flash_size) {
    		return false;
    	}
    
    	return true;
    }
    

    * without CONFIG_SETTINGS = y

    flash_size = 1048576
    addr = 1028040
    len = 8
    flash_size = 1048576
    addr = 1028048
    len = 8
    flash_size = 1048576
    addr = 1028056
    len = 8
    flash_size = 1048576
    addr = 1028064
    len = 8
    flash_size = 1048576
    addr = 1028072
    len = 8
    flash_size = 1048576
    addr = 1024004
    len = 1

    * with CONFIG_SETTINGS = y

    flash_size = 1048576
    addr = 1044464
    len = 8
    flash_size = 1048576
    addr = 1052664
    len = 8
    
    => errno -22 occurs

    The following formula fails with CONFIG_SETTINGS = y.

    (addr) + len > flash_size

    Any advice to solve this issue?

Reply
  • u8_t mode = 2;
    ret = nvs_write(&nvs_fs, NVS_ID_MODE, &mode, 1);
    if (ret < 0) {
    	return;
    }

    I get -22 errno in nvs_write when I add it to aws_fota.

    This comes from line 179 in ncs\v1.3.0\zephyr\drivers\flash\soc_flash_nrf.c

    is_regular_addr_valid(addr, len) apparently fails. 

    static int flash_nrf_read(struct device *dev, off_t addr,
    			    void *data, size_t len)
    {
    	if (is_regular_addr_valid(addr, len)) { /* This fails */
    		addr += DT_REG_ADDR(SOC_NV_FLASH_NODE);
    	} else if (!is_uicr_addr_valid(addr, len)) {
    		return -EINVAL; /* HERE */
    	}
    
    	if (!len) {
    		return 0;
    	}
    
    #if CONFIG_ARM_NONSECURE_FIRMWARE && CONFIG_SPM && USE_PARTITION_MANAGER
    	if (addr < PM_APP_ADDRESS) {
    		return spm_request_read(data, addr, len);
    	}
    #endif
    
    	memcpy(data, (void *)addr, len);
    
    	return 0;
    }

    In addition, I printed out parameters.

    static inline bool is_regular_addr_valid(off_t addr, size_t len)
    {
    	size_t flash_size = nrfx_nvmc_flash_size_get();
    
            printk("flash_size = %u\n", flash_size); /* ADD HERE */
            printk("addr = %ld\n", addr); /* ADD HERE */
            printk("len = %u\n", len); /* ADD HERE */
    
    	if (addr >= flash_size ||
    	    addr < 0 ||
    	    len > flash_size ||
    	    (addr) + len > flash_size) {
    		return false;
    	}
    
    	return true;
    }
    

    * without CONFIG_SETTINGS = y

    flash_size = 1048576
    addr = 1028040
    len = 8
    flash_size = 1048576
    addr = 1028048
    len = 8
    flash_size = 1048576
    addr = 1028056
    len = 8
    flash_size = 1048576
    addr = 1028064
    len = 8
    flash_size = 1048576
    addr = 1028072
    len = 8
    flash_size = 1048576
    addr = 1024004
    len = 1

    * with CONFIG_SETTINGS = y

    flash_size = 1048576
    addr = 1044464
    len = 8
    flash_size = 1048576
    addr = 1052664
    len = 8
    
    => errno -22 occurs

    The following formula fails with CONFIG_SETTINGS = y.

    (addr) + len > flash_size

    Any advice to solve this issue?

Children
Related