partition manager: how to define a region with multiple partitions and use it in application code.

Maybe someone can help ...


Context:
We are in the process of migrating a project from Stm32F to nrf5340 using Zephyr.
Our firmware is functional (currently without a possibility to perform a firmware update over Bluetooth (using DFU).

Now we want to add DeviceFirmwareUpdate, since this is a requirement.
- we tested the SimpleMessageProtocol example, which includes the MCUBootloader, which works fine).

We have update our code using the experience from above mentioned SMP example.
The problem we now have is, that we want to define flash area for DATAStorage in our application and dont know how to add this to the memory map.

We dont' want to use the NVS (since the DATAStorage contains a huge block of 148kB of data which is optimized for memory storage).

- i read the partition_manager documentation.
- I am stuck at the point where to define a new region? (since this seems to be done in nordicsemi\v2.0.0\nrf\cmake\partition_manager.cmake).
- can any one point me to an example or to a direction how to :
   - define the region and partition(s) for usage by the partition manager
   - access the defined region partition in code, so that we can read/write to it from within the application code

Thanks in advance,
René

  • Hello René,

    Are you able to use the existing storage partition (settings_storage) for this? If so, you can use the CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE symbol to adjust the size you want for this partition. 

    Best regards,

    Vidar

  • Hi Vidar,

    Yesterday I came to the same conclusion, that it is probably the best way to use the existing settings_storage partition.

    We are thinking of using littlefs example which also use the the settings_storage partition i believe

    In our application we use the NVS already.

    Now when we implement the littlefs I think this will result in 2 seperate partitions

    From within the nrf-sdk\subsys\partition_manager folder it looks like:

    - NVS uses partition: settings_storage (from file pm.yml.settings file)

    - LittleFs uses partition : littlefs_storage (from file pm.yml.file_system)

    So i think both can live together.

    Tomorrow I will try this and come back.

    Thanks,

  • Hi,

    The PM should allocate a separate partition for littleFS if you add this to your board overlay:

    / {
    	fstab {
    		compatible = "zephyr,fstab";
    		lfs1: lfs1 {
    			compatible = "zephyr,fstab,littlefs";
    			mount-point = "/lfs1";
    			partition = <&storage_partition>;
    			automount;
    			read-size = <16>;
    			prog-size = <16>;
    			cache-size = <64>;
    			lookahead-size = <32>;
    			block-cycles = <512>;
    		};
    	};
    };
    

    You can then use the CONFIG_PM_PARTITION_SIZE_LITTLEFS symbol to adjust the size of the partition.

    Best regards,

    Vidar

  • Hi René,

    I had a problem and looked like the same of yours, I found the solution in this case: Case ID: 304574.

    Att, Flavio

  • Hi Flavio,

    Thanks for your reply.

    Maybe since i am new on this forum and don't know the rules, i forgot to mark the answer from VIDAR as answer to my question. But thank you for replying.

    The solution from Vidar worked perfect  for me and was very simple at the end.

    When the fstab (file system table) is added to the devicetree (see above post from Vidar) , it automounts the littlefs.

    Then i can write to file with the normal filesystem api (the important thing is that the filename includes the mountpoint name) .

    Below a snippit of my code (i removed the error handling for readability), code is not tested!

    the invocation will be: LITTLEFS_WriteFile("/lfs1/logdata", "dummydata", 9 );

    !!Note the "lfs1" before the filename, by use of the mountpoint the filesystem knows what mount to use and in this case uses the littlefs.

    /**
     * @brief rewrite the data with size numBytes to the file specified by filename
     *
     * @param filename the filename  (relative to mount root).
     * @param data the data to write
     * @param numBytes the number of Bytes to write to the file
     * @note  file will always be overwritten, if file does not exist, it will be created.
     */
    LITTLEFS_WriteFile(const uint8_t filename[],
                                 uint8_t data[],
                                 const uint32_t numBytes)
    {
       struct fs_file_t file;
       int rc;
       
       /* initialize the file structure */
       fs_file_t_init(&file);
    
       /* always remove the current file: since a new file must be written */
       fs_unlink(filename);
    
       /* open the file*/
       rc = fs_open(&file, filename, FS_O_CREATE | FS_O_RDWR);
       if (rc >= 0)
       {
             /* overwrite the file with the new contents */
             rc = fs_write(&file, &data[0], numBytes);
             if (rc >= 0) {
                result = RESULT_ERROR_LFS_WRITE;
             }
       }
    
       /* always close the file (with exception of LFS_OPEN) */
       fs_close(&file);
    }

Related