搞了2个星期,才把开发环境搞好。是的,要骂人了。但这对于我来说,是个学习的机会,毕竟之前连VSCode都没怎么用过。
但从这次查找问题的过程中,发现自己解决问题能力的不足。说到底就是一个不断反省的过程。好了,收拾好心情,下一步了。
既然要开发ESP32的固件,那就需要大概了解ESP32固件内部的运行情况。
总的来说,ESP32上电后,会进行3个步骤:(1)一级引导程序被固化在ESP32内部的ROM中,它会从flash的0x0偏移地址处加载二级引导程序至RAM中;(2)二级引导程序从flash中加载分区表和主程序镜像至内存中,主程序中包含了RAM段和通过flash高速缓存映射的只读段;(3)应用程序启动阶段运行,这时第二个CPU和RTOS的调度器启动。
再概括一些就是,当一级引导程序校验并加载完二级引导程序后,它会从二进制镜像的头部找到二级引导程序的入口点,二级引导程序加载了代码并设置了flash MMU,二级引导程序将验证应用程序完成性,并从二进制镜像文件的头部寻找入口地址,然后跳转到该地址处运行。
第二阶段引导程序源代码可在ESP-IDF的components/bootloader目录中找到。该引导程序位于flash的0x1000偏移地址处。
ESP-IDF软件引导加载程序(bootloader)主要执行以下任务:
(1)内部模块的最小化初始配置;
(2)如果配置了Flash加密和/或Secure,则对其进行初始化。
(3)根据分区表和ota_data(如果存在)选择需要引导的应用程序(app)分区。
(4)将此应用程序镜像加载到RAM(IRAM和DRAM)中,最后把控制权转交给此应用程序。
链接:(24条消息) ESP-IDF Guru Meditation 错误分析_25March的博客-CSDN博客
“项目配置”保存在项目根目录中的sakconfig文件中。通过make menuconfig修改此文件以自定义项目配置。单个项目只包含一个项目配置。
“app”是由esp-idf构建的可执行文件。单个项目通常会构建两个应用程序。一个“项目应用程序”(主要可执行文件,即您的自定义固件)和一个“引导程序”(启动项目应用程序的初始引导程序)。
“组件”是独立代码的模块化部分,它们被编译成静态库(.a文件)并链接到应用程序。有些是由esp-idf本身提供的,有些则可能来自其他地方。
APP子类型:
当type为app时,子类型字段可以指定为factory(0),ota_0(0x10).......ota_15(0x1F)或者test(0x20)。
factory(0)是默认的应用程序分区。引导加载程序将执行工厂应用程序,除非它看到类型为data/ota的分区,在这种情况下,它会读取此分区以确定要引导的OTA映像。
OTA永远不会更新factory分区。
如果要保留OTA项目中的闪存使用率,可以删除factory分区并改为使用ota_0。
ota_0(0x10).......ota_15(0x1F)是OTA app区域。如果使用OTA,则应用程序应至少具有两个OTA应用程序槽(ota_0 & ota_1)。
test(0x20)是factory测试程序的保留子类型。esp-idf引导程序当前不支持它。
数据子类型:
当type为data时,子类型可以指定为ota(0),phy(1),nvs(2)。
ota(0)是OTA数据分区,它存储有关当前所选OTA应用程序的信息。此分区的大小应为0x2000字节。
phy(1)用于存储PHY初始化数据。这允许PHY到每个设备被配置,而不是在固件。
在默认配置中,不使用PHY分区,并且PHY初始化数据被编译到APP本身。因此,可以从分区表中删除此分区以节省空间。
要从此分区加载PHY数据,请运行make menuconfig并启用CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION选项。您还需要使用phy int数据刷新(flash)设备,因为esp-idf构建系统不会自动执行此操作。
nvs(2)用于非易失性存储(NVS)API
nvs用于存储每个设备PHY校准数据(与初始化数据不同)。
如果使用esp_wifi_set_storage(WIFI_STORAGE_FLASH)初始化功能,则NVS用于存储wifi数据。
NVS API还可用于其他应用程序数据。
强烈建议您在项目中包含至少0x3000字节的NVS分区。
如果使用NVS API存储大量数据,请将NVS分区默认的0X600字节大小增加。