概述
ESP32 启动流程
- ESP32 启动流程详细分析
- ESP32启动总流程
- ESP32启动详细过程
- first-stage bootloader
- flash boot模式的二级bootloader
- 重点强调
ESP32 启动流程详细分析
ESP32启动总流程
ESP32开发程序中有且只能有一个app_main函数,该函数是用户程序的入口,相当于其它系统中的main函数。但在app_main之前,系统还有一段初始化的过程,其大致可以分为以下三个过程:
ROM中的第一级引导加载程序将闪存偏移0x1000的第二级引导加载程序映像加载到RAM(IRAM和DRAM);
第二级引导程序从闪存加载分区表和主应用程序映像,主应用程序包含RAM段和通过闪存缓存映射的只读段;
主应用程序执行,此时可以启动第二个CPU和RTOS调度程序。
ESP32启动详细过程
——————————————
first-stage bootloader
在esp32 上电运行后,芯片运行的第一个程序。这段程序是芯片设计与生产的时候,固化在硬件电路中的。所以它是不可修改的(Read Only Memory)。
esp32 的 ROM 负责检测芯片的strapping配置,来决定芯片应该处于什么状态。比如,esp32 上电后,ROM 程序会检查 [GPIO0, GPIO2, GPIO4, MTDO, GPIO5]的状态。如果 GPIO0 / GPIO2 同时为低电平,则会进入下载模式,等待串口通信信息。如果GPIO0为高电平,则会进入Flash 运行模式,启动SPI 驱动,并加载Flash中的程序段。
BOOT_MODE[5:0]:
(pull-up, pull-down, pull-down, pull-up, pull-up, SW4 /5/4/3/2/1/ )
[GPIO0, GPIO2, GPIO4, MTDO, GPIO5]
1 x x x x --> SPI Boot
0 0 x x x --> Download Boot (Jonit-Detection of UART0+UART1+SDIO_Slave)
下载模式的串口输出如下(115200), ROM默认会输出当前所处的模式。
rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download
其中,boot:0x3 表示的是芯片strapping pin脚的状态,
0x03对应 [GPIO0, GPIO2, GPIO4, MTDO, GPIO5] 的值为 [ 0, 0, 0, 1, 1]
所以处于 Download Boot 模式。
关于下载模式
当esp32处于下载模式时,会等待串口通信同步,并按照通信协议等待接收指令
(协议可参考该文档:https://github.com/espressif/esptool/wi ... l-Protocol)
通过esptool脚本,可以进行寄存器的读写,固件下载,程序运行等操作。
关于STUB
在ROM模式,由于芯片处于低频工作的状态,通信速率受限。
在esptool中,会将一段小程序加载到esp32的RAM中,并跳转执行RAM中的小程序。这段小程序包含了ROM中相同的串口通信协议,并对其进行了扩充。感兴趣的开发者,(可以参考这里https://github.com/espressif/esptool/tr ... asher_stub)
关于 Flash Boot
如果芯片启动时,GPIO0为高电平,芯片会进入Flash 运行模式。 此时,启动SPI 驱动,并加载Flash中的程序段。ROM 会读取外置 Flash 的0x1000地址,加载并运行二级bootloader。
关于 Bootloader
bootloader可以认为是一个独立的小程序,bootloader会对芯片频率进行初始化,并且读取系统SPI的配置信息,对Flash 运行模式以及频率进行配置,然后根据分区表的定义,从对应的地址加载应用程序,并且运行应用程序固件。
flash boot模式的二级bootloader
在 ESP-IDF 中,存放在 Flash 的 0x1000 偏移地址处的二进制镜像就是二级引导程序。二级引导程序的源码可以在 ESP-IDF 的 components/bootloader 目录下找到。请注意,对于 ESP32 芯片来说,这并不是唯一的安排程序镜像的方式。事实上用户完全可以把一个功能齐全的应用程序烧写到 Flash 的 0x1000 偏移地址处运行,但这超出本文档的范围。ESP-IDF 使用二级引导程序可以增加 Flash 分区的灵活性(使用分区表),并且方便实现 Flash 加密,安全引导和空中升级(OTA)等功能。
当一级引导程序校验并加载完二级引导程序后,它会从二进制镜像的头部找到二级引导程序的入口点(call_start_cpu0),并跳转过去运行。
30
void __attribute__((noreturn)) call_start_cpu0(void)
31
{
32
// 1. Hardware initialization
33
if (bootloader_init() != ESP_OK) {
34
bootloader_reset();
35
}
36
37
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
38
// If this boot is a wake up from the deep sleep then go to the short way,
39
// try to load the application which worked before deep sleep.
40
// It skips a lot of checks due to it was done before (while first boot).
41
bootloader_utility_load_boot_image_from_deep_sleep();
42
// If it is not successful try to load an application as usual.
43
#endif
44
45
// 2. Select the number of boot partition
46
bootloader_state_t bs = {0};
47
int boot_index = select_partition_number(&bs);
48
if (boot_index == INVALID_INDEX) {
49
bootloader_reset();
50
}
51
52
// 3. Load the app image for booting
53
bootloader_utility_load_boot_image(&bs, boot_index);
54
}
查看call_start_cpu0函数我们可以看到二级引导程序主要分为三个步骤:
这三个步骤的代码这个和具体平台相关
一 初始化硬件参数
bootloader_init
二 选择boot分区
select_partition_number(&bs);
三 加载boot镜像
bootloader_utility_load_boot_image(&bs, boot_index);
重点强调
二级引导程序从 Flash 的 0x8000 偏移地址处读取分区表。详细信息请参阅分区表文档 :doc:分区表 <partition-tables>
。二级引导程序会寻找出厂分区和 OTA 分区,然后根据 OTA 信息 分区的数据决引导哪个分区。
对于选定的分区,二级引导程序将映射到 IRAM 和 DRAM 的数据和代码段复制到它们的加载地址处。对于一些加载地址位于 DROM 和 IROM 区域的段,会通过配置 Flash MMU 为其提供正确的映射。请注意,二级引导程序会为 PRO CPU 和 APP CPU 都配置 Flash MMU,但它只使能了 PRO CPU 的 Flash MMU。这么做的原因在于二级引导程序的代码被加载到了 APP CPU 的高速缓存使用的内存区域,因此使能 APP CPU 高速缓存的任务就交给了应用程序。一旦代码加载完毕并且设置好 Flash MMU,二级引导程序会从应用程序二进制镜像文件的头部寻找入口地址,然后跳转到该地址处运行。
目前还不支持添加钩子函数到二级引导程序中以自定义应用程序分区选择的逻辑,但是可以通过别的途径实现这个需求,比如根据某个 GPIO 的不同状态来引导不同的应用程序镜像。此类自定义的功能将在未来添加到 ESP-IDF 中。目前,可以通过将 bootloader 组件复制到应用程序目录并在那里进行必要的更改来自定义引导程序。在这种情况下,ESP-IDF 的编译系统将编译应用程序目录中的组件而不是 ESP-IDF 组件目录。
最后
以上就是羞涩小兔子为你收集整理的ESP32 启动流程ESP32 启动流程详细分析的全部内容,希望文章能够帮你解决ESP32 启动流程ESP32 启动流程详细分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复