前言:关于参数存储,是一个程序必要的功能,而esp32其实是只带NVS库的,少量的变量数据其实还是比较方便的,如果我们的参数很多,还有一些字符串,那NVS库显然不太能满足我们了。那么我们就需要自己去读写flash,设计自己的参数表。
esp32 分区表:(需要了解详细可以查阅相关内容)
esp32的flash一般而言我们不能直接去操作地址,首先需要我们定义或修改分区表。
进入menuconfig,选择自定义的表。


这个文件可以从D:\ESP32\esp-idf-v3.3\components\partition_table目录中拷贝一个到自己的工程下。名字改成partitions.csv,当然你可以自己取。

修改分区表:添加用户保存的区域,大小只能是8K的倍数,因为flash每页是8K,其它值会出错。

基本流程
接下来就是代码部分,整体也比较简单,主要分如下几个步骤:
1-寻找分区表
2-读flash
3-写flash
4-擦除flash
基本上也是正常的flash读写过程。只是esp32多了一个分区表的概念。
设计自定义参数表 (这里可以看看我以前的文章)
- union para_tab
- {
- struct nv_tab
- {
- unsigned char init_flag; //是否初始化
- unsigned char data_1;
- unsigned char data_2;
- unsigned char data_3;
-
- }nv_tab;
-
- //保存所有数据的数组
- unsigned char flash_buf[sizeof(struct nv_tab)]; //自适应大小
- };
- extern union para_tab Pra;
实现读写函数:
- #define PARA_FLASH_NAME "user_save"
- static const char *TAG = "user_flash";
- static esp_partition_t *partition;
-
-
-
- union para_tab Pra={0};
-
- void init_mflash()
- {
-
- //寻找分区表
- partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARA_FLASH_NAME);
- assert(partition != NULL);
- }
-
- //在指定地址写入数组
- void FLASH_WriteByte()
- {
-
- uint8_t err=0;
-
- //擦除flash
- err=esp_partition_erase_range(partition, 0, partition->size);
- if(err!=0)
- {
- ESP_LOGI(TAG, "user flash erase error %d",err);
- }
- //写入flash
- err = esp_partition_write(partition, 0,Pra.flash_buf,sizeof(Pra.flash_buf));
- if(err!=0)
- {
- ESP_LOGI(TAG, "user flash write error %d",err);
- }
-
- }
-
- //在指定地址读出数组
- void FLASH_ReadByte()
- {
-
- uint8_t err =0;
- //读取flash
- err=esp_partition_read(partition, 0, Pra.flash_buf , sizeof(Pra.flash_buf));
-
- if(err!=0)
- {
- ESP_LOGI(TAG, "user flash read erro %d",err);
- return ;
- }
-
-
- }
如何使用:具体测试代码就不多讲了。
- init_mflash();
-
- // Pra.nv_tab.init_flag =1;
- // Pra.nv_tab.data_1 =2;
- // Pra.nv_tab.data_2 =3;
- // Pra.nv_tab.data_3 =4;
- // FLASH_WriteByte();
-
- FLASH_ReadByte();
-
- ESP_LOGI("flash log","flash %d %d %d
- %d\r\n",Pra.nv_tab.init_flag,Pra.nv_tab.data_1,Pra.nv_tab.data_2,Pra.nv_tab.data_3);
总结:整体上使用起来会比ESP32内置的NVS方便不少,使用起来也非常的简单。