news 2026/6/12 10:26:04

esp32开发与应用(内部flash的读写)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
esp32开发与应用(内部flash的读写)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

对于一些大批量的数据,比如音视频,这种数据一般是用tf卡进行保存。但是对于一些参数、配置文件,或者是算法类的参数,这种还是倾向于用esp32内部flash进行保存。今天,就来看下,对于esp32来说,怎么用内部flash进行数据读写。

1、还是不用外部信号连接

和上一章wifi的测试一样,这一章只是内部数据读写,不涉及到外部信号读写。

2、弄清楚nvs和flash

esp的nvs是建立在flash基础之上的。也就是说,如果地址不对,操作flash的时候,有可能误操作nvs的内容。另外,flash本身是合封在esp32内部的,并不是挂在总线上面,这一点的话,速度略有差异,不过不影响我们使用。

3、适用范围

大多数情况下,nvs的操作已经够我们使用,比如开机次数、wifi密码、算法参数、用户自定义配置等等。只有数据稍大,但是又没有大到需要外置tf卡的时候,才需要flash读取。

4、ai编写代码

这一次ai编写代码的时候,提示我们首先需要修改CMakeLists.txt,内容是这样的,

idf_component_register(SRCS "main.c" INCLUDE_DIRS "." REQUIRES spi_flash nvs_flash)

其次就是编写具体的函数内容,比如main.c,它的内容是这样的,

#include <stdio.h> #include <string.h> #include <stdint.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "nvs_flash.h" #include "esp_flash.h" #include "esp_system.h" // Flash test parameters #define TEST_DATA_SIZE 256 #define TEST_SECTOR_OFFSET 0x180000 // Test sector offset (1.5MB position, after factory app) #define TEST_SECTOR_SIZE 4096 // Flash sector size (4KB) static const char *TAG = "FLASH_DEMO"; // NVS operation example static esp_err_t nvs_test(void) { esp_err_t err; nvs_handle_t my_handle; // Open NVS namespace err = nvs_open("storage", NVS_READWRITE, &my_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "Error opening NVS: %s", esp_err_to_name(err)); return err; } // Write data int32_t boot_count = 0; err = nvs_get_i32(my_handle, "boot_count", &boot_count); if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) { ESP_LOGE(TAG, "Error reading NVS: %s", esp_err_to_name(err)); nvs_close(my_handle); return err; } boot_count++; ESP_LOGI(TAG, "Boot count: %d", boot_count); err = nvs_set_i32(my_handle, "boot_count", boot_count); if (err != ESP_OK) { ESP_LOGE(TAG, "Error writing NVS: %s", esp_err_to_name(err)); nvs_close(my_handle); return err; } // Commit write err = nvs_commit(my_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "Error committing NVS: %s", esp_err_to_name(err)); nvs_close(my_handle); return err; } // Write string char test_str[] = "Hello from NVS!"; err = nvs_set_str(my_handle, "message", test_str); if (err != ESP_OK) { ESP_LOGE(TAG, "Error writing string to NVS: %s", esp_err_to_name(err)); nvs_close(my_handle); return err; } err = nvs_commit(my_handle); // Read string char read_str[32] = {0}; size_t len = sizeof(read_str); err = nvs_get_str(my_handle, "message", read_str, &len); if (err == ESP_OK) { ESP_LOGI(TAG, "Read from NVS: %s", read_str); } nvs_close(my_handle); return ESP_OK; } // SPI Flash direct operation example static esp_err_t spi_flash_test(void) { esp_err_t err; uint8_t write_buffer[TEST_DATA_SIZE]; uint8_t read_buffer[TEST_DATA_SIZE]; esp_flash_t *flash_chip = (esp_flash_t *)esp_flash_default_chip; // Prepare test data for (int i = 0; i < TEST_DATA_SIZE; i++) { write_buffer[i] = i % 256; } // Erase region (sector) ESP_LOGI(TAG, "Erasing flash region at offset 0x%x", TEST_SECTOR_OFFSET); err = esp_flash_erase_region(flash_chip, TEST_SECTOR_OFFSET, TEST_SECTOR_SIZE); if (err != ESP_OK) { ESP_LOGE(TAG, "Error erasing flash: %s", esp_err_to_name(err)); return err; } // Write data ESP_LOGI(TAG, "Writing %d bytes to flash at offset 0x%x", TEST_DATA_SIZE, TEST_SECTOR_OFFSET); err = esp_flash_write(flash_chip, write_buffer, TEST_SECTOR_OFFSET, TEST_DATA_SIZE); if (err != ESP_OK) { ESP_LOGE(TAG, "Error writing flash: %s", esp_err_to_name(err)); return err; } // Read data ESP_LOGI(TAG, "Reading %d bytes from flash at offset 0x%x", TEST_DATA_SIZE, TEST_SECTOR_OFFSET); err = esp_flash_read(flash_chip, read_buffer, TEST_SECTOR_OFFSET, TEST_DATA_SIZE); if (err != ESP_OK) { ESP_LOGE(TAG, "Error reading flash: %s", esp_err_to_name(err)); return err; } // Verify data bool data_ok = true; for (int i = 0; i < TEST_DATA_SIZE; i++) { if (read_buffer[i] != write_buffer[i]) { ESP_LOGE(TAG, "Data mismatch at offset %d: expected 0x%02x, got 0x%02x", i, write_buffer[i], read_buffer[i]); data_ok = false; break; } } if (data_ok) { ESP_LOGI(TAG, "SPI Flash read/write test PASSED"); } return data_ok ? ESP_OK : ESP_FAIL; } void app_main(void) { // Initialize NVS esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } ESP_ERROR_CHECK(err); // Test NVS operations ESP_LOGI(TAG, "=== Testing NVS ==="); nvs_test(); // Test SPI Flash direct operations ESP_LOGI(TAG, "=== Testing SPI Flash ==="); spi_flash_test(); ESP_LOGI(TAG, "Flash demo completed!"); }

编写过程可能不顺利,比如说idf版本不对、缺少库、地址存在错误、测试不通过等等,这些都是正常的,直接发给ai,再来一次就可以了。

5、编译、测试和阅读代码

前面说过,本身代码是否可以顺利编译是非常重要的,如果有问题,需要直接通知ai修改。只有可以编译、可以执行的代码才值得我们去阅读和修改。编译好了,直接烧入,看看能不能跑起来,有没有错误。有错误的话,还是继续发送日志给ai。直到测试全ok为止。

最后就是开始阅读代码,保存起来,下次作为项目代码使用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 10:23:57

第十篇:《健康检查与自愈:探针(Probe)机制》

Kubernetes 能够自动重启失败的容器、替换无响应的 Pod&#xff0c;这一切依赖 探针&#xff08;Probe&#xff09; 机制。通过配置存活探针&#xff08;livenessProbe&#xff09;、就绪探针&#xff08;readinessProbe&#xff09;和启动探针&#xff08;startupProbe&#x…

作者头像 李华
网站建设 2026/6/12 10:22:53

深度解析AzurLaneAutoScript:重构碧蓝航线自动化生态的技术架构

深度解析AzurLaneAutoScript&#xff1a;重构碧蓝航线自动化生态的技术架构 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研&#xff0c;全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript …

作者头像 李华
网站建设 2026/6/12 10:20:51

1MRK002122-ABR01接口模块

ABB 1MRK002122-ABR01 接口模块产品特点开头&#xff1a; ABB 1MRK002122-ABR01 是一款专为 Relion 670/650 系列保护装置设计的光纤通信与二进制 I/O 接口模块&#xff0c;用于实现保护装置与变电站自动化系统之间的数据交换和信号处理。中间&#xff08;15条特点&#xff09;…

作者头像 李华
网站建设 2026/6/12 10:18:52

多维聚合中的立方体原生操作:从pandas到xarray的范式升级

1. 这不是简单的“加总求平均”——多维聚合中的数据操作到底在动什么筋骨你有没有遇到过这样的场景&#xff1a;销售报表里要同时按“省份产品线季度”三个维度看销售额&#xff0c;还要算出每个省的累计占比、每个产品线的环比变化、每个季度的滚动3期平均&#xff1f;这时候…

作者头像 李华
网站建设 2026/6/12 10:17:55

3-流形伪同构与基本群无限性的拓扑研究

1. 3-流形伪同构研究概述 在低维拓扑学领域&#xff0c;3-流形&#xff08;即三维流形&#xff09;的研究一直是核心课题之一。3-流形是指局部同胚于三维欧几里得空间的拓扑空间&#xff0c;这类流形在数学和物理中都有广泛应用。伪同构&#xff08;pseudo-isotopy&#xff09;…

作者头像 李华