前言:关于参数存储,是一个程序必要的功能,而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方便不少,使用起来也非常的简单。