NVS partition size problem

Palonso
Posts: 25
Joined: Tue Sep 24, 2019 8:43 pm

NVS partition size problem

Postby Palonso » Fri Feb 07, 2020 11:39 pm

Hi,

I was programming a circular non-volatile buffer and i find out that when I open an NVS partition of size 0x1000 it seems that it can't save the values meanwhile when the size of the partition is 1M there is no problem with the saved values.

This is what i get when the partition size is 1M, every time it reboots it has the same quantity of used values:

Code: Select all

I (326) cpu_start: Pro cpu start user code
I (344) spi_flash: detected chip: gd
I (345) spi_flash: flash io: dio
I (345) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
W (353) adio-example: partition init: log_part
Count: UsedEntries = (152), FreeEntries = (64360), AllEntries = (64512)
BUT when the size of the partition is 0x1000 this is what happens:

FIRST TIME:

Code: Select all

W (353) adio-example: Inicializando Particion log_part
Count: UsedEntries = (0), FreeEntries = (126), AllEntries = (126)
W (403) adio-example: Writing first LOG element: log_0
Count: UsedEntries = (2), FreeEntries = (124), AllEntries = (126)
AFTER REBOOT:

Code: Select all

W (353) adio-example: Inicializando Particion log_part
Count: UsedEntries = (0), FreeEntries = (126), AllEntries = (126)
W (403) adio-example: Writing first LOG element: log_0
Count: UsedEntries = (2), FreeEntries = (124), AllEntries = (126)
I don't know whats happening and why it depends on the size of the partition to actually save.

here i share my partition table:

Code: Select all

# Name,             Type, SubType,  Offset,     Size,   Flags
  nvs,              data, nvs,      0x9000,     0x4000
  otadata,          data, ota,      ,           0x2000
  phy_init,         data, phy,      ,           0x1000
  factory,          app,  factory,  ,           3M
  ota_0,            app,  ota_0,    ,           3M
  ota_1,            app,  ota_1,    ,           3M
#  log_part,         data, nvs,      ,           2M
  log_part,         data, nvs,      ,           0x1000
And here the initialization in the main() :

Code: Select all

ESP_LOGW(TAG, "Inicializando Particion %s", nvs_partition_name);
    err = nvs_flash_init_partition(nvs_partition_name);
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase_partition(nvs_partition_name));
        err = nvs_flash_init_partition(nvs_partition_name);
    }
    ESP_ERROR_CHECK(err);
    NVS_PRINT_STATS(nvs_partition_name);

    sprintf(log_aux,"log_%d", log_val);
    ESP_LOGW(TAG, "Writing first LOG element: %s", log_aux);
    usintNVSwrite_from_partition(nvs_partition_name, nvs_name, nvs_log_handle, 10, log_aux);

    ESP_LOGW(TAG, "Reading first LOG element: %s. log_val vale: %d", log_aux, log_val);
    usintNVSread_from_partition(nvs_partition_name, nvs_name, nvs_log_handle, &log_val, log_aux);
    ESP_LOGW(TAG, "log_val after reading is: %d", log_val);
And here the task that actually save the values:

Code: Select all

static void log_save(void *args)
{
    adc_t *adc = args;
    char *TAG = "log task";

    ESP_LOGI(TAG,"log_save task: INIT");
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    ESP_LOGI(TAG,"log_save task: STARTED");

    while (1)
    {
        if(xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ))
        {
            //ESP_LOGW(TAG,"tengo semaforo en log");
            //Convert adc_reading to voltage in mV
            ESP_LOGW(TAG,"log_value to save is: %d", adc->analog_read);
            uint32_t voltage = esp_adc_cal_raw_to_voltage(adc->analog_read, adc->adc_chars);
            configASSERT(adc->adc_chars);
            ESP_LOGI(TAG,"Voltage: %dmV | Raw: %d", voltage, adc->analog_read);
            //ESP_LOGW(TAG,"suelto semaforo en log");

            sprintf(log_aux, "log_%d", log_index);
            ESP_LOGI(TAG, "saving %s = %d", log_aux, adc->analog_read);
            usintNVSwrite_from_partition(nvs_partition_name, nvs_name, nvs_log_handle, adc->analog_read, log_aux);

            log_index++;
            if (log_index>150)
                log_index=1;

            xSemaphoreGive( xSemaphore );
            vTaskDelay(pdMS_TO_TICKS(1000));
        }
    }
}
Does anyone have an idea on whats happening? did i missed something?

WiFive
Posts: 2887
Joined: Tue Dec 01, 2015 7:35 am

Re: NVS partition size problem

Postby WiFive » Sat Feb 08, 2020 12:55 pm

Minimum size to use nvs is 0x2000

Palonso
Posts: 25
Joined: Tue Sep 24, 2019 8:43 pm

Re: NVS partition size problem

Postby Palonso » Mon Feb 10, 2020 6:05 pm

Hi, It was that, but trying different sizes I realized that there are 126 entries that are not available and I can't find the reason why that's not possible.

Here is what i got when partition size is 0x3000:

Code: Select all

E (251833) custom_nvs: ERROR SETTING: (ESP_ERR_NVS_NOT_ENOUGH_SPACE)
Count: UsedEntries = (252), FreeEntries = (126), AllEntries = (378)
And when partition size is 0x2000:

Code: Select all

E (1853663) custom_nvs: ERROR SETTING: (ESP_ERR_NVS_NOT_ENOUGH_SPACE)
Count: UsedEntries = (126), FreeEntries = (126), AllEntries = (252)
I'm always saving uint16_t size data, so each entry (uint32_t size) should be more than enough to save tha data. Also. I'm not being able to find what is using those "free entries" nor why I can't use them.

The best explanation I could figure out was that each page has 1 header and a 1 state bitmap making a total of 64 "inaccessible" bytes, yet I don't know what happen with the other half. Also if those where inaccessible I guess they where already excluded from the "nvs_get_stats" function

Who is online

Users browsing this forum: MSN [Bot] and 35 guests