• ESP32 读写内部flash参数存储


    前言:关于参数存储,是一个程序必要的功能,而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多了一个分区表的概念。

    设计自定义参数表 (这里可以看看我以前的文章)

    1. union para_tab
    2. {
    3. struct nv_tab
    4. {
    5. unsigned char init_flag; //是否初始化
    6. unsigned char data_1;
    7. unsigned char data_2;
    8. unsigned char data_3;
    9. }nv_tab;
    10. //保存所有数据的数组
    11. unsigned char flash_buf[sizeof(struct nv_tab)]; //自适应大小
    12. };
    13. extern union para_tab Pra;

     实现读写函数:

    1. #define PARA_FLASH_NAME "user_save"
    2. static const char *TAG = "user_flash";
    3. static esp_partition_t *partition;
    4. union para_tab Pra={0};
    5. void init_mflash()
    6. {
    7. //寻找分区表
    8. partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARA_FLASH_NAME);
    9. assert(partition != NULL);
    10. }
    11. //在指定地址写入数组
    12. void FLASH_WriteByte()
    13. {
    14. uint8_t err=0;
    15. //擦除flash
    16. err=esp_partition_erase_range(partition, 0, partition->size);
    17. if(err!=0)
    18. {
    19. ESP_LOGI(TAG, "user flash erase error %d",err);
    20. }
    21. //写入flash
    22. err = esp_partition_write(partition, 0,Pra.flash_buf,sizeof(Pra.flash_buf));
    23. if(err!=0)
    24. {
    25. ESP_LOGI(TAG, "user flash write error %d",err);
    26. }
    27. }
    28. //在指定地址读出数组
    29. void FLASH_ReadByte()
    30. {
    31. uint8_t err =0;
    32. //读取flash
    33. err=esp_partition_read(partition, 0, Pra.flash_buf , sizeof(Pra.flash_buf));
    34. if(err!=0)
    35. {
    36. ESP_LOGI(TAG, "user flash read erro %d",err);
    37. return ;
    38. }
    39. }

    如何使用:具体测试代码就不多讲了。

    1. init_mflash();
    2. // Pra.nv_tab.init_flag =1;
    3. // Pra.nv_tab.data_1 =2;
    4. // Pra.nv_tab.data_2 =3;
    5. // Pra.nv_tab.data_3 =4;
    6. // FLASH_WriteByte();
    7. FLASH_ReadByte();
    8. ESP_LOGI("flash log","flash %d %d %d
    9. %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方便不少,使用起来也非常的简单。

  • 相关阅读:
    ASP.NET Core 6.0 启动方式
    自从看了谷歌大神拼S强撸的Spring源码笔记,我从渣渣练成了钢铁
    [CISCN2019 华东南赛区]Web11
    Collectors.groupingBy()
    ELK极简上手
    服务器杀掉死进程
    【C++】类和对象——拷贝构造函数
    ✨✨使用vue3打造一个el-form表单及高德地图的关联组件实例✨
    1944. 队列中可以看到的人数 单调栈
    国内外AI programmer 大全集--持续更新
  • 原文地址:https://blog.csdn.net/HES_C/article/details/126461405