How to check if partition has already been erased?

rocotocloc
Posts: 13
Joined: Tue May 07, 2024 5:47 am

How to check if partition has already been erased?

Postby rocotocloc » Fri Oct 18, 2024 7:05 am

Hello,

I am following this example to implement my own partition and store some statistical data in my project: https://github.com/espressif/esp-idf/bl ... ain/main.c

It's simple enough and it works just fine but I have a doubt.

The documentation says that you must first call esp_partition_erase_range() before esp_partition_write()

How do I know if the partition has already been erased? Since I am gonna use this partition to save statistical data from my project, I want to check if this is the first time I am gonna save data and only that time erase the entire partition. Otherwise just save the new data.

Should I store another variable like "partionErased" in the NVS? I cannot find how to check this in the documentation.

Also I modified that example and added another data partition. From this:

Code: Select all

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,        data, nvs,      0x9000,  0x6000,
phy_init,   data, phy,      0xf000,  0x1000,
factory,    app,  factory,  0x10000, 1M,
storage,    data, ,             , 0x40000,
To this:

Code: Select all

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,        data, nvs,      0x9000,  0x6000,
phy_init,   data, phy,      0xf000,  0x1000,
factory,    app,  factory,  0x10000, 1M,
storage,    data, ,             , 0x40000,
storage2,    data, ,             , 0x40000,
And I was able to write and read back data to that new "storage2" partion without first erasing it despite what it's indicated in the documentation.

I just added this code at the end:

Code: Select all

    const esp_partition_t *partition2 = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage2");
    assert(partition2 != NULL);
    ESP_LOGI(TAG, "partition2 found");

    static char store_data2[] = "PARTITION 2 DATA";
    static char read_data2[sizeof(store_data2)];

    esp_err_t err = esp_partition_write(partition2, 0, store_data2, sizeof(store_data2));
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "Error (%s) al escribir!\n", esp_err_to_name(err));
    }
    else
    {
        ESP_LOGI(TAG, "Written data to partition2: %s", store_data2);
    }

    ESP_ERROR_CHECK(esp_partition_read(partition2, 0, read_data2, sizeof(read_data2)));
    assert(memcmp(store_data2, read_data2, sizeof(read_data2)) == 0);
    ESP_LOGI(TAG, "Read data2: %s", read_data2);
And this is the output:
2024-10-18 09 12 18.png
2024-10-18 09 12 18.png (3.47 KiB) Viewed 856 times
Why is this working?

Thank you.

MicroController
Posts: 1724
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: How to check if partition has already been erased?

Postby MicroController » Fri Oct 18, 2024 7:47 am

Erased data in the flash is indistinguishable from 'all bits set', i.e. every byte reads as 0xff.
So, you can write to any location in flash which contains 0xff before the write; and after an erase, every byte is 0xff.

If you know or make sure the data you write contains at least one byte which is not 0xff, you can check for the presence of the non-0xff byte value to determine if the partition is erased or not.

rocotocloc
Posts: 13
Joined: Tue May 07, 2024 5:47 am

Re: How to check if partition has already been erased?

Postby rocotocloc » Fri Oct 18, 2024 10:50 am

Ok so let's say I reserve the first 4 bytes of the partition just to check whether it's erased or not. If I understand you correctly, can I assume that if I read those 4 bytes and they're not all 1, then the partition is not erased?

Would it be correct something like this? Can I guarantee that if checksum is different from UINT32_MAX then the partition is not initialized?

Code: Select all

void check_storage_partition()
{
    const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, STORAGE_PARTITION);

    uint32_t checksum;
    ESP_ERROR_CHECK(esp_partition_read(partition, 0, &checksum, 4));
    ESP_LOGI(TAG_STORAGE, "storage checksum is: %lu ", checksum);
    if (checksum != UINT32_MAX)
    {
        ESP_LOGW(TAG_STORAGE, "storage partition NOT INITIALIZED, let's erase it...");
        ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
        ESP_LOGW(TAG_STORAGE, "storage partition SUCCESSFULLY ERASED");
    }
    else
    {
        ESP_LOGI(TAG_STORAGE, "storage partition already initialized");
    }
}
Thank you.

MicroController
Posts: 1724
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: How to check if partition has already been erased?

Postby MicroController » Fri Oct 18, 2024 7:52 pm

rocotocloc wrote:
Fri Oct 18, 2024 10:50 am
can I assume that if I read those 4 bytes and they're not all 1, then the partition is not erased?
Yes.
Can I guarantee that if checksum is different from UINT32_MAX then the partition is not initialized?
Yeah, well, "initialized" would be the operative word here. If the value you read is not all-1s, (that location in) the partition is not erased. It may still contain 'garbage' though. If, for example, you insert a new partition or resize another partition, your data partition may land in some location where there was some other data/code, i.e. not 0xff, located previously.
An easy way to reasonably likely detect this scenario is to define some 'magic value' and write it to a known location in the partition when that partition is "initialized". Like:

Code: Select all

static const uint32_t MAGIC_VALUE = 0xDA7AC0DE;
static const uint32_t MAGIC_VALUE_LOCATION = 0;

esp_partition_read(partition, MAGIC_VALUE_LOCATION, &checkValue, 4)
if(checkValue != MAGIC_VALUE) {
  // The partition is not initialized. Erase and initialize it now.
  erasePartition(partition);
  // Do any other initialization of the partition data that may be needed...
  writeToPartition(partition, MAGIC_VALUE_LOCATION, MAGIC_VALUE); // Mark the partition as 'initialized'.
}

rocotocloc
Posts: 13
Joined: Tue May 07, 2024 5:47 am

Re: How to check if partition has already been erased?

Postby rocotocloc » Sat Oct 19, 2024 10:18 am

It's clear now, I was thinking about that magic value too as an alternative.

Thank you for the help.

Who is online

Users browsing this forum: No registered users and 87 guests