Keep the settings stored in NVS in-between two different programs using Zephyr

Hello everyone,

I am working on device based on an nRF52832 that is close to pre-production phase and runs on Zephyr. I have a question because I would like to retain information between two different firmware.

1. Testing firmware. Does not use a bootloader and stores values using the settings API. Does other things for testing the custom board but that is not important.

2. Production firmware. This uses a bootloader (MCUboot) and the default memory map on zephyr for an nRF52832. I would like to use the settings API to load the information from the previous firmware.

For example, using the settings API with NVS API from Zephyr, I would write "TEST" on "device/param/one" using the testing firmware. And the production firmware would use the same implementation:

/* Static subtree handler */
SETTINGS_STATIC_HANDLER_DEFINE(param, "device/param", NULL,
                               NULL, NULL,
                               param_handle_export);

int param_handle_export(int (*cb)(const char *name,
                                  const void *value, size_t val_len))
{
    (void)cb("device/param/one", "TEST", strlen(TEST));
    return 0;
}

The idea would be that using "settings_load()" on the second firmware would fetch the value that was saved on the first firmware.

When testing this, it did not work. So I am wondering if both firmware need to use the same memory map and bootloader? Is there an alternative?

&flash0 {
 
     partitions {
         compatible = "fixed-partitions";
         #address-cells = <1>;
         #size-cells = <1>;
 
         boot_partition: partition@0 {
             label = "mcuboot";
             reg = <0x00000000 0xc000>;
         };
         slot0_partition: partition@c000 {
             label = "image-0";
             reg = <0x0000C000 0x32000>;
         };
         slot1_partition: partition@3e000 {
             label = "image-1";
             reg = <0x0003E000 0x32000>;
         };
         scratch_partition: partition@70000 {
             label = "image-scratch";
             reg = <0x00070000 0xa000>;
         };
         storage_partition: partition@7a000 {
             label = "storage";
             reg = <0x0007a000 0x00006000>;
         };
     };
 };

Thank you very much in advance for any help.

Best regards,

  • I also have a problem linked to that. One of the way I could solve that is to use the same flash map and bootloader on the 2 firmwares. But to do that I need to modify the flash map to reduce the size of the boot partition. So i tried putting this in my_board.dts:

     &flash0 {
     
        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;
    
            boot_partition: partition@0 {
                label = "mcuboot";
                reg = <0x00000000 0x6000>;
            };
            slot0_partition: partition@6000 {
                label = "image-0";
                reg = <0x00006000 0x37000>;
            };
            slot1_partition: partition@3d000 {
                label = "image-1";
                reg = <0x0003D000 0x37000>;
            };
            scratch_partition: partition@74000 {
                label = "image-scratch";
                reg = <0x00074000 0xa000>;
            };
            storage_partition: partition@7e000 {
                label = "storage";
                reg = <0x0007e000 0x00002000>;
            };
        };
    };

    But when I call west build, the result is that:

    The region sizes indicated seems to be wrong. The one for the bootloader (first table) should be 24KB.

    I went to the zephyr.dts generated by the build, and I got this in both the mcuboot folder and zephyr folder:

    flash_controller: flash-controller@4001e000 {
    			compatible = "nordic,nrf52-flash-controller";
    			reg = < 0x4001e000 0x1000 >;
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x1 >;
    			label = "NRF_FLASH_DRV_NAME";
    			flash0: flash@0 {
    				compatible = "soc-nv-flash";
    				label = "NRF_FLASH";
    				erase-block-size = < 0x1000 >;
    				write-block-size = < 0x4 >;
    				reg = < 0x0 0x80000 >;
    				partitions {
    					compatible = "fixed-partitions";
    					#address-cells = < 0x1 >;
    					#size-cells = < 0x1 >;
    					boot_partition: partition@0 {
    						label = "mcuboot";
    						reg = < 0x0 0x6000 >;
    					};
    					slot0_partition: partition@6000 {
    						label = "image-0";
    						reg = < 0x6000 0x37000 >;
    					};
    					slot1_partition: partition@3d000 {
    						label = "image-1";
    						reg = < 0x3d000 0x37000 >;
    					};
    					scratch_partition: partition@74000 {
    						label = "image-scratch";
    						reg = < 0x74000 0xa000 >;
    					};
    					storage_partition: partition@7e000 {
    						label = "storage";
    						reg = < 0x7e000 0x2000 >;
    					};
    				};
    			};
    		};

    When I call west build -t rom_report, this is what I get:

      flash_primary (0x80000 - 512kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x39000 - 228kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x38e00 - 227kB)-+
    | 0xc200: app (0x38e00 - 227kB)                   |
    +-------------------------------------------------+
    | 0x45000: mcuboot_secondary (0x39000 - 228kB)    |
    | 0x7e000: settings_storage (0x2000 - 8kB)        |
    +-------------------------------------------------+

    Would anyone happen to know why? This is putting a really hard stop on my development right now

  • I could not find why.

    However, the only solution I could find to insure that I can use the same parameters stored in one firmware (using the Settings API) in another firmware, is to have the same exact bootloader and flash map.

Related