NVS write fails error -22 when building with sysbuild

nRF54L15 - ncs 3.02 - toolchain 3.02

I changed my build settings from no sysbuild to sysbuild in order to use serial recovery and/or FOTA. I thought everything was OK until I tried saving settings to NVS where I now get error -22

(Before asking why I'm using NVS not ZMS I was advised to as ZMS is still buggy and it gives problems)

Do I need to manually change partitioning to make this work?

Here is the NVS write code:


	struct nvs_fs fs;
	struct flash_pages_info info;

	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 1;
	}

	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 rc;
	}

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

	rc = nvs_write(&fs, NVS_SETTINGS_ADDR, &mybuff, sizeof(mybuf));

	return rc;

Parents Reply Children
  • Migrating from multi-image builds to sysbuild

    I've had a look at that, it's not a whole lot of help. My application wasn't a multi-image build to start with until I changed to sysbuild. The Serial Recovery & DFU mechanisms obviously now generate multiple images but that's done under the hood as far as I can tell.

    This all works fine for Blinky in the Dev Academy samples but not for NVS which needs to address a particular area of memory.

    The section that does reference DFU also doesn't say much. Here it is in its entirety:

    Multi-image builds for DFU
    Support for creating multi-image build files for Device Firmware Update (DFU) was moved to sysbuild. The following Kconfig options are available:

    Kconfig option

    Description

    SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_BUILD

    Enables building a DFU multi-image package

    SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_APP

    Include application update in package

    SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_NET

    Include network core image update in package

    SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_MCUBOOT

    Include MCUboot update in package

    SB_CONFIG_DFU_MULTI_IMAGE_PACKAGE_WIFI_FW_PATCH

    Include nRF70 firmware patch update in package

    You must update your application to select the required Kconfig options at the sysbuild level to have this file generated.

    I do recall partition management was mentioned in one of the training presentations but can't find it in the DevAcademy course.

    Also why does flash_get_page_info_by_offs() and nvs_mount() return successfully but not nvs_write()?

  • I've spent several hours looking at this now. There was a potential issue where I was compiling for 54L15 but my prototypes actually had 54L10 due to component shortages, but that's now fixed (am building for 54L10) and it doesn't make any difference.

    NVS_PARTITION_DEVICE maps correctly to /soc/rram-controller@5004b000
    NVS_PARTITION_OFFSET matches the offset of the storage partition
    My app compiles to 205k, so smaller than the partition slots. I am writing only 50 bytes or so to flash so no danger of overflow.
    I hacked my code to write a simple array like so:
    	struct nvs_fs fs;
    	struct flash_pages_info info;
    
    	fs.flash_device = NVS_PARTITION_DEVICE; //&__device_dts_ord_122 maps to /soc/rram-controller@5004b000
    
    	if (!device_is_ready(fs.flash_device)) {
    		printk("Flash device %s is not ready\n", fs.flash_device->name);
    		return 1;
    	}
    
    	fs.offset = NVS_PARTITION_OFFSET; //0xfd000 matches storage in ram report
    	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 rc;
    	}
    
    	fs.sector_size = info.size;
    	fs.sector_count = 3U;
    	rc = nvs_mount(&fs);
    
    	if (rc) {
    		printk("Flash Init failed, rc=%d\n", rc);
    		return rc;
    	}
    
    	printk("FS nvs mount rc %d\n",rc);
    	uint8_t test[100]={0x55};
    
    	rc = nvs_write(&fs, 1, &test, sizeof(test));
    	printk("NVS write rc %d\n",rc);
    
    	return rc;

    But I always get invalid argument error -22....?

    Here are the prj.conf entries related to flash

    #NVRAM / Flash
    CONFIG_FLASH=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    CONFIG_FLASH_MAP=y
    # Explicitly disable external flash drivers
    CONFIG_SPI_NOR=n
    CONFIG_NORDIC_QSPI_NOR=n
    
    CONFIG_NVS=y
    CONFIG_ZMS=n

    Just for fun I tried reverting back to ZMS but that doesn't work either.

    Now I can't think of anything else that may be the cause? 

Related