一、问题
使用 ESP32-WROOM-32E(4MB) 模组,同时使用了蓝牙模块、WIFI模块功能,编译的时候没问题,然后运行的时候报以下错误:
二、原因
ESP32 如果使同时使用了蓝牙模块、WIFI模块和OTA的话很有可能会导致程序过大(超过1M),系统无法启动的情况。这里提供一种通过修改分区表 扩大程序储存空间的方法来避免这一问题。这一解决方法同样只用于因为其他问题导致的程序过大的情况。
三、解决方法
3.1 分区表
每片 ESP32 的 Flash 可以包含多个应用程序,以及多种不同类型的数据(例如校准数据、文件系统数据、参数存储器数据等)。因此,引入分区表的概念。
具体来说,ESP32 在 Flash 的 默认偏移地址 0x8000 处烧写一张分区表。该分区表的长度为 0xC00 字节(最多可以保存 95 条分区表条目)。分区表数据后还保存着该表的 MD5 校验和,用于验证分区表的完整性。此外,如果芯片使能了安全启动功能,则该分区表后还会保存签名信息。
分区表中的每个条目都包括以下几个部分:Name(标签)、Type(app、data 等)、SubType 以及在 flash 中的偏移量(分区的加载地址)。
具体内容参见:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/api-guides/partition-tables.html
在 esp-idf/components/partition_table 有多个分区表文件供参考。
简单的来说,分区表就是对Flash进行划分,不同区域存放不同的东西。如下面一个是双OTA备份分区表文件partitions_two_ota_coredump.csv对应的是下图的划分。通过对比文件和图片,很容易理解分区表。每一行对应的内容顺序分别是Name, Type, SubType, Offset,Size。如果Offset没有填写则默认在上一个分区的末尾添加。
# Name, Type, SubType, Offset, Size
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, , 0x4000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
factory, app, factory, , 1M,
coredump, data, coredump, , 64K,
ota_0, app, ota_0, , 1M,
ota_1, app, ota_1, , 1M,
3.2 创建分区表文件
在项目下创建一个分区表 partitions.csv 这里提供一个我的分区表,程序存储空间应该是0x10000的整数倍:
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, , 0x4000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
factory, app, factory, , 0x140000,
ota_0, app, ota_0, , 0x140000,
ota_1, app, ota_1, , 0x140000,
注意: 1、分配分区表的时候空间一定要是 4k 的整数倍也就是:存储空间%4096=0。这是因为 Flash 的一个区块是 4k。 2、ota分区(ota_0,ota_1)的空间最好和原厂程序(factory)相同。
3.3 修改menuconfig
idf.py menuconfig
- 修改模块Flash大小(根据实际情况修改)
Serial flasher config --->Flash size - 修改分区表
Partition Table --->Partition Table --->(Custom partition table CSV)选择自定义分区表方式 (partitions.csv) Custom partition CSV file选择自定义分区表文件 - 重新编译运行
? 由 Leung 写于 2022 年 3 月 4 日
? 参考:esp32 同时打开蓝牙,wifi和ota后程序过大导致无法启动
|