Hi
I am working with the zephyr ZMS sample application.
I am using SDK 2.9.0, and I built the application for the nRF54L15DK (nrf54l15dk/nrf54l15/cpuapp).
The sample works.
The problem I am having is when I try and port this code to my existing nRF54L15DK project.
Apologies, this is a long read, with the issue detailed near the end.
When I build the sample application, this is the partion.yml after the build:
app: address: 0x0 end_address: 0x15f000 region: flash_primary size: 0x15f000 otp: address: 0xffd500 end_address: 0xffd9fc region: otp size: 0x4fc sram_primary: address: 0x20000000 end_address: 0x2002f000 region: sram_primary size: 0x2f000 zms_storage: address: 0x15f000 end_address: 0x165000 placement: after: - app before: - end region: flash_primary size: 0x6000
And the code works – the filing system is mounted etc.
I want to bring some of this code in to my own nRF54L15DK project, and to do this, I want to specify the location of the zms_storage, so that I know it will be at a fixed location, always.
So, as an experiment, in the sample application I created a pm_static.yml file, with the addresses that the partition manager craeted before there was a pm_static.yml file:
zms_storage: address: 0x15f000 size: 0x6000 end_address: 0x165000 placement: before: - end region: flash_primary
The only update to the partition.yml file, is that for the zms_storage, the placement is now:
placement: before: - end
And not:
placement: after: - app before: - end
And it no surprise that the code still works, because no addresses have been changed etc.
So now I go to my project. Before I try and add ZMS, this is my partition.yml:
app: address: 0x0 end_address: 0x163000 region: flash_primary size: 0x163000 otp: address: 0xffd500 end_address: 0xffd9fc region: otp size: 0x4fc settings_storage: address: 0x163000 end_address: 0x165000 placement: after: - app before: - end region: flash_primary size: 0x2000 sram_primary: address: 0x20000000 end_address: 0x2002f000 region: sram_primary size: 0x2f000
So where should I place the zms storage?
I tried to tag it on to the end of settings_storage, with this pm_static.yml:
zms_storage: address: 0x15f000 size: 0x6000 end_address: 0x165000 placement: before: - end region: flash_primary
This results in the following partition.yml:
app: address: 0x0 end_address: 0x163000 region: flash_primary size: 0x163000 otp: address: 0xffd500 end_address: 0xffd9fc region: otp size: 0x4fc settings_storage: address: 0x163000 end_address: 0x165000 placement: after: - app before: - end region: flash_primary size: 0x2000 sram_primary: address: 0x20000000 end_address: 0x2002f000 region: sram_primary size: 0x2f000 zms_storage: address: 0x165000 end_address: 0x16b000 placement: before: - end region: flash_primary size: 0x6000
I also made the following modification to the zms code, to use the defined zms_storage:
// #define ZMS_PARTITION storage_partition // #define ZMS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZMS_PARTITION) // #define ZMS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(ZMS_PARTITION) #define ZMS_PARTITION zms_storage #define ZMS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZMS_PARTITION) #define ZMS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(ZMS_PARTITION)
However, when I run my code, the following line fails:
rc = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &info);
(fs.offset is 0x165000)
I get error -22.
Here’s the complete function:
int zms_try(void)
{
int rc = 0;
char buf[16];
//uint8_t key[8] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF}, longarray[128];
uint8_t key[8] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF}, longarray[32];
uint32_t i_cnt = 0U;
uint32_t i;
uint32_t id = 0;
ssize_t free_space = 0;
struct flash_pages_info info;
for (int n = 0; n < sizeof(longarray); n++) {
longarray[n] = n;
}
/* define the zms file system by settings with:
* sector_size equal to the pagesize,
* 3 sectors
* starting at ZMS_PARTITION_OFFSET
*/
fs.flash_device = ZMS_PARTITION_DEVICE;
if (!device_is_ready(fs.flash_device)) {
printk("Storage device %s is not ready\n", fs.flash_device->name);
return -1;
}
fs.offset = ZMS_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 -2;
}
fs.sector_size = info.size;
fs.sector_count = 3U;
for (i = 0; i < MAX_ITERATIONS; i++) {
rc = zms_mount(&fs);
if (rc) {
printk("Storage Init failed, rc=%d\n", rc);
return -3;
}
printk("ITERATION: %u\n", i);
/* IP_ADDRESS_ID is used to store an address, lets see if we can
* read it from flash, since we don't know the size read the
* maximum possible
*/
rc = zms_read(&fs, IP_ADDRESS_ID, &buf, sizeof(buf));
if (rc > 0) {
/* item was found, show it */
buf[rc] = '\0';
printk("ID: %u, IP Address: %s\n", IP_ADDRESS_ID, buf);
}
/* Rewriting ADDRESS IP even if we found it */
strncpy(buf, "172.16.254.1", sizeof(buf) - 1);
printk("Adding IP_ADDRESS %s at id %u\n", buf, IP_ADDRESS_ID);
rc = zms_write(&fs, IP_ADDRESS_ID, &buf, strlen(buf));
if (rc < 0) {
printk("Error while writing Entry rc=%d\n", rc);
break;
}
/* KEY_VALUE_ID is used to store a key/value pair , lets see if we can read
* it from storage.
*/
rc = zms_read(&fs, KEY_VALUE_ID, &key, sizeof(key));
if (rc > 0) { /* item was found, show it */
printk("Id: %x, Key: ", KEY_VALUE_ID);
for (uint8_t n = 0; n < 8; n++) {
printk("%x ", key[n]);
}
printk("\n");
}
/* Rewriting KEY_VALUE even if we found it */
printk("Adding key/value at id %x\n", KEY_VALUE_ID);
rc = zms_write(&fs, KEY_VALUE_ID, &key, sizeof(key));
if (rc < 0) {
printk("Error while writing Entry rc=%d\n", rc);
break;
}
/* CNT_ID is used to store the loop counter, lets see
* if we can read it from storage
*/
if (i == 0)
{
rc = zms_write(&fs, CNT_ID, &i, sizeof(i));
if (rc < 0) {
printk("Error while writing Entry rc=%d\n", rc);
break;
}
} else {
rc = zms_read(&fs, CNT_ID, &i_cnt, sizeof(i_cnt));
if (rc > 0) { /* item was found, show it */
printk("Id: %d, loop_cnt: %u\n", CNT_ID, i_cnt);
if (i_cnt != (i - 1)) {
break;
}
}
printk("Adding counter at id %u\n", CNT_ID);
rc = zms_write(&fs, CNT_ID, &i, sizeof(i));
if (rc < 0) {
printk("Error while writing Entry rc=%d\n", rc);
break;
}
}
/* LONG_DATA_ID is used to store a larger dataset ,lets see if we can read
* it from flash
*/
rc = zms_read(&fs, LONG_DATA_ID, &longarray, sizeof(longarray));
if (rc > 0) {
/* item was found, show it */
printk("Id: %d, Longarray: ", LONG_DATA_ID);
for (uint16_t n = 0; n < sizeof(longarray); n++) {
printk("%x ", longarray[n]);
}
printk("\n");
}
/* Rewrite the entry even if we found it */
printk("Adding Longarray at id %d\n", LONG_DATA_ID);
rc = zms_write(&fs, LONG_DATA_ID, &longarray, sizeof(longarray));
if (rc < 0) {
printk("Error while writing Entry rc=%d\n", rc);
break;
}
/* Each DELETE_ITERATION delete all basic items */
if (!(i % DELETE_ITERATION) && (i)) {
rc = delete_basic_items(&fs);
if (rc) {
break;
}
}
}
if (i != MAX_ITERATIONS) {
printk("Error: Something went wrong at iteration %u rc=%d\n", i, rc);
return 0;
}
while (1) {
/* fill all storage */
rc = zms_write(&fs, id, &id, sizeof(uint32_t));
if (rc < 0) {
break;
}
id++;
}
if (rc == -ENOSPC) {
/* Calculate free space and verify that it is 0 */
free_space = zms_calc_free_space(&fs);
if (free_space < 0) {
printk("Error while computing free space, rc=%d\n", free_space);
return -4;
}
if (free_space > 0) {
printk("Error: free_space should be 0, computed %u\n", free_space);
return -5;
}
printk("Memory is full let's delete all items\n");
/* Now delete all previously written items */
for (uint32_t n = 0; n < id; n++) {
rc = delete_and_verify_items(&fs, n);
if (rc) {
printk("Error deleting at id %u\n", n);
return -6;
}
}
rc = delete_basic_items(&fs);
if (rc) {
printk("Error deleting basic items\n");
return -7;
}
}
/*
* Let's compute free space in storage. But before doing that let's Garbage collect
* all sectors where we deleted all entries and then compute the free space
*/
for (i = 0; i < fs.sector_count; i++) {
rc = zms_sector_use_next(&fs);
if (rc) {
printk("Error while changing sector rc=%d\n", rc);
}
}
free_space = zms_calc_free_space(&fs);
if (free_space < 0) {
printk("Error while computing free space, rc=%d\n", free_space);
return -8;
}
printk("Free space in storage is %u bytes\n", free_space);
/* Let's clean the storage now */
rc = zms_clear(&fs);
if (rc < 0) {
printk("Error while cleaning the storage, rc=%d\n", rc);
}
printk("Sample code finished Successfully\n");
return 0;
}
