1.前言
为什么需要将flash分区映射到内存区域
在某些情况下,我们需要在单片机中保存一个较大的数组,比如字库、图片等,使用const将其编译到代码中,可以指针访问他们。但是,在线刷或者OTA更新时,也不可避免的需要更新他们,造成了时间或者空间上的浪费。但是如果将其按照静态数据存放在flash中,只能读和写,不能按照指针访问这些数据,很不方便。因此,可以使用esp32 SDK中的mmap功能,新建一个分区,将静态数据存放在对应的分区中,并且将其映射在内存中,使用指针读取
2.实现
2.1 新建工程 修改分区表
首先新建一个空白工程,并且在menuconfig中使用自定义分区表,并且将分区表修改如下示例:
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
test_data, data, , , 512k,
这个分区表最后一个512K的test_data分区就是我们要存放数据的区域,后面需要使用命令行将数据线刷到该分区
2.2 获取分区地址
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,16K,
otadata,data,ota,0xd000,8K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
test_data,data,undefined,0x110000,512K,
首先编译一下固件,在编译信息中,我们可以看到test_data这个分区的起始地址,0x110000
就是该分区的起始地址,也是我们后面需要使用线刷烧录文件的地址
当然,也可以使用手动计算的方式计算test_data的起始地址
2.3 分区内烧录文件
在vscode底部打开一个终端,连接开发板,在终端中输入
python -m esptool --chip esp32s3 --port COM6 --baud 921600 write_flash 0x110000 xxxxxx.bin
按下回车就可以将xxxxxx.bin文件烧录到该分区中
2.4 编码测试
我们在app_main中增加以下代码用来测试:
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "test_data");
assert(partition != NULL);
const void *map_ptr;
esp_partition_mmap_handle_t map_handle;
// Map the partition to data memory
ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, 512*1000, ESP_PARTITION_MMAP_DATA, &map_ptr, &map_handle));
ESP_LOGI(TAG, "Mapped partition to data memory address %p", map_ptr);
char read_data[128];
memcpy(read_data, map_ptr, sizeof(read_data));
代码中,使用esp_partition_find_first
寻找分区,前两个参数为分区类型,第三个参数为分区的名称
如果可以成功的找到这个分区,使用esp_partition_mmap
映射此分区,包含6个传参,第三个参数为你希望映射多长的区域,map_ptr指针为映射成功后的数据指针
映射成功后,就可以使用map_ptr指针读该分区的内容了,请注意,mmap的分区只能读,不能写
3.结论
使用idf的分区映射功能,可以较为方便的读取flash中的静态资源,并且可以使用esp32的dcache进行加速,比用传统的spi_read更快,不仅如此,也可以节省掉可能存在的OTA静态资源的时间或者空间消耗。
标签:map,flash,映射,ESP,esp32,partition,内存,data,分区 From: https://www.cnblogs.com/shumei52/p/18610629