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;

  • Hi

    The error message -22 points to an invalid argument being entered in whatever function is returning this error message. Can you share the log, what function returns error -22, and what you are inputting into this function on your end.

    Best regards,

    Simon

  • The error is from

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

    (ignore typo mybuff in original post)

    It works 100% fine if my build setting is "no sysbuild", but fails if I build using sysbuild.

  • Hi

    The parameters of nvs_write() should be: a pointer to the file system, id of the entry to be written, pointer to the data to be written and number of bytes to be written. If either of these are invalid in your application, that will return a -22 error.

    Since it's only an issue when using sysbuild, please go through the Sysbuild migration guide available here, as there are some changes necessary. https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/migration/migration_sysbuild.html 

    Best regards,

    Simon

  • 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