ESP8266 创建自己的NVS分区

此文权当学习开发笔记,如有错误,敬请读者指出!如果读者要用于自己的项目,出现bug请责任自负。

用ESP8266来开发项目,需要存储用户信息,看了乐鑫关于NVS操作的说明,发现NVS操作很是方便快捷,而且有读写均衡,自动校验、自动避开坏区、NVS加密等功能,好处很多。

但就是乐鑫IDF3.2目前单纯支持NVS_DEFAULT_PART_NAME的操作,再细看它底层封装是#define NVS_DEFAULT_PART_NAME  "nvs"

再看看函数的实现:

extern "C" esp_err_t nvs_flash_erase()
{
    return nvs_flash_erase_partition(NVS_DEFAULT_PART_NAME);
}
extern "C" esp_err_t nvs_flash_init(void)
{
    return nvs_flash_init_partition(NVS_DEFAULT_PART_NAME);
}

extern "C" esp_err_t nvs_open(const char* name, nvs_open_mode open_mode, nvs_handle *out_handle)
{
    if (s_nvs_storage_list.size() == 0) {
        return ESP_ERR_NVS_NOT_INITIALIZED;
    }

return nvs_open_from_partition(NVS_DEFAULT_PART_NAME, name, open_mode, out_handle);
}

都是基于NVS_DEFAULT_PART_NAME来实现的。

好了,要创建自己的NVS分区,首先要把这些函数改了:

先定义自己的分区名字:

#ifndef USER_PARTITION_NAME
    #define USER_PARTITION_NAME         "user"
#endif

extern "C" esp_err_t my_nvs_flash_erase()
{
    return nvs_flash_erase_partition(USER_PARTITION_NAME);
}

extern "C" esp_err_t my_nvs_open(const char* name, nvs_open_mode open_mode, nvs_handle *out_handle)
{
    if (s_nvs_storage_list.size() == 0) {
        return ESP_ERR_NVS_NOT_INITIALIZED;
    }

    return nvs_open_from_partition(USER_PARTITION_NAME, name, open_mode, out_handle);
}

extern "C" esp_err_t my_nvs_flash_init(void)
{
    return nvs_flash_init_partition(USER_PARTITION_NAME);
}

 

把这几个函数添加到nvs_falsh.h头文件中

再修改partitions_two_ota.csv中的分区表,增加一个名为user的分区

ESP8266 创建自己的NVS分区_第1张图片

写个小程序测试一下:基于乐鑫的demo改的

void nvs_write_data_to_flash(void)
{
    nvs_handle handle;
    static const char *NVS_CUSTOMER = "customer data";
    static const char *DATA1 = "param 1";
    static const char *DATA2 = "param 2";
    static const char *DATA3 = "param 3";

    int32_t value_for_store = 666;

     wifi_config_t wifi_config_to_store = {
        .sta = {
            .ssid = "store_ssid:hello_kitty",
            .password = "store_password:1234567890",
        },
    };

    ESP_LOGI(TAG,"set size:%u\r\n", sizeof(wifi_config_to_store));

    if( my_nvs_open( NVS_CUSTOMER, NVS_READWRITE, &handle) !=ESP_OK)
        {
        ESP_LOGI(TAG, "my_nvs_open error ");
        return;
    }

    if( nvs_set_str( handle, DATA1, "i am a string.") !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_set_str error ");
        return;
    }

    if( nvs_set_i32( handle, DATA2, value_for_store) !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_set_i32 error ");
        return;
    }
    if( nvs_set_blob( handle, DATA3, &wifi_config_to_store, sizeof(wifi_config_to_store)) !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_set_blob error ");
        return;
    }
    if( nvs_commit(handle) !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_commit error ");
        return;
    }

    
    nvs_close(handle);

}

void nvs_read_data_from_flash(void)
{
    nvs_handle handle;
    static const char *NVS_CUSTOMER = "customer data";
    static const char *DATA1 = "param 1";
    static const char *DATA2 = "param 2";
    static const char *DATA3 = "param 3";

    uint32_t str_length = 32;
    char str_data[32] = {0};
    int32_t value = 0;
    wifi_config_t wifi_config_stored;
    memset(&wifi_config_stored, 0x0, sizeof(wifi_config_stored));
    uint32_t len = sizeof(wifi_config_stored);
    
    if( my_nvs_open(NVS_CUSTOMER, NVS_READWRITE, &handle) !=ESP_OK)
        {
        ESP_LOGI(TAG, "my_nvs_open error ");
        return;
    }

    if( nvs_get_str(handle, DATA1, str_data, &str_length) !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_get_str error ");
        return;
    }

    if( nvs_get_i32(handle, DATA2, &value) !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_get_i32 error ");
        return;
    }
    if( nvs_get_blob(handle, DATA3, &wifi_config_stored, &len) !=ESP_OK)
        {
        ESP_LOGI(TAG, "nvs_get_blob error ");
        return;
    }

    ESP_LOGI(TAG, "[data1]: %s len:%u ", str_data, str_length);
    ESP_LOGI(TAG, "[data2]: %d ", value);
    ESP_LOGI(TAG, "[data3]: ssid:%s passwd:%s ", wifi_config_stored.sta.ssid, wifi_config_stored.sta.password);

    nvs_close(handle);
}

 

编译通过,上电测试一下:

[0;32mI (105) boot: compile time 15:10:01[0m
[0;32mI (113) qio_mode: Enabling default flash chip QIO[0m
[0;32mI (117) boot: SPI Speed      : 40MHz[0m
[0;32mI (126) boot: SPI Mode       : QIO[0m
[0;32mI (134) boot: SPI Flash Size : 2MB[0m
[0;32mI (142) boot: Partition Table:[0m
[0;32mI (149) boot: ## Label            Usage          Type ST Offset   Length[0m
[0;32mI (164) boot:  0 nvs                WiFi data        01 02 00009000 00004000[0m
[0;32mI (179) boot:  1 otadata          OTA data         01 00 0000d000 00002000[0m
[0;32mI (194) boot:  2 phy_init         RF data          01 01 0000f000 00001000[0m
[0;32mI (209) boot:  3 ota_0            OTA app          00 10 00010000 000e0000[0m
[0;32mI (225) boot:  4 ota_1            OTA app          00 11 00100000 000e0000[0m
[0;32mI (240) boot:  5 user              WiFi data        01 02 001f0000 00010000[0m
[0;32mI (255) boot: End of partition table[0m

试着读写,再掉电重启,数据依旧保存着,然后擦除nvs分区,user分区的数据还在,试着擦除user分区,nvs的数据还在。2个分区的数据是没有关联性。也就是说创建自己的分区成功了,函数修改也凑效了。

[11:03:35.175]发→◇User_PartW□
[11:03:35.181]收←◆[0;32mI (650231) uart_events: uart[0] event:[0m
[0;32mI (650232) uart_events: [UART DATA]: 10[0m
[0;32mI (650234) uart_events: [DATA EVT]: User_PartW[0m
[0;32mI (650246) app: Got sys_uart0_queue message: User_PartW [0m
[0;32mI (650247) app: Got USER_PART_WRITE order, system write user data to partition [0m
[0;32mI (650250) my_mvs: set size:124
[0m

[11:03:37.409]发→◇User_PartR□
[11:03:37.415]收←◆[0;32mI (652461) uart_events: uart[0] event:[0m
[0;32mI (652462) uart_events: [UART DATA]: 10[0m
[0;32mI (652463) uart_events: [DATA EVT]: User_PartR[0m
[0;32mI (652470) app: Got sys_uart0_queue message: User_PartR [0m
[0;32mI (652471) app: Got USER_PART_READ order, system read user data from partition [0m
[0;32mI (652480) my_mvs: [data1]: i am a string. len:15 [0m
[0;32mI (652484) my_mvs: [data2]: 666 [0m
[0;32mI (652488) my_mvs: [data3]: ssid:store_ssid:hello_kitty passwd:store_password:1234567890 [0m

 

你可能感兴趣的:(ESP8266 创建自己的NVS分区)