官网链接:https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/general-notes.html
应用程序的启动流程
本文将会介绍 ESP32 从上电到运行 app_main
函数中间所经历的步骤(即启动流程)。
宏观上,该启动流程可以分为如下 3 个步骤:
- 一级引导程序被固化在了 ESP32 内部的 ROM 中,它会从 Flash 的
0x1000
偏移地址处加载二级引导程序至 RAM(IRAM & DRAM) 中。 - 二级引导程序从 Flash 中加载分区表和主程序镜像至内存中,主程序中包含了 RAM 段和通过 Flash 高速缓存映射的只读段。
- 主程序运行,这时第二个 CPU 和 RTOS 的调度器可以开始运行。
下面会对上述过程进行更为详细的阐述。
一级引导程序
SoC 复位后,PRO CPU 会立即开始运行,执行复位向量代码,而 APP CPU 仍然保持复位状态。在启动过程中,PRO CPU 会执行所有的初始化操作。APP CPU 的复位状态会在应用程序启动代码的 call_start_cpu0
函数中失效。复位向量代码位于 ESP32 芯片掩膜 ROM 的 0x40000400
地址处,该地址不能被修改。
复位向量调用的启动代码会根据 GPIO_STRAP_REG
寄存器的值来确定 ESP32 的工作模式,该寄存器保存着复位后 bootstrap 引脚的电平状态。根据不同的复位原因,程序会执行不同的操作:
- 从深度睡眠模式复位:如果
RTC_CNTL_STORE6_REG
寄存器的值非零,并且RTC_CNTL_STORE7_REG
寄存器中的 RTC 内存的 CRC 校验值有效,那么程序会使用RTC_CNTL_STORE6_REG
寄存器的值作为入口地址,并立即跳转到该地址运行。如果RTC_CNTL_STORE6_REG
的值为零,或者RTC_CNTL_STORE7_REG
中的 CRC 校验值无效,又或者跳转到RTC_CNTL_STORE6_REG
地址处运行的程序返回,那么将会执行上电复位的相关操作。 注意 :如果想在这里运行自定义的代码,可以参考 :doc:`深度睡眠 <deep-sleep-stub>` 文档里面介绍的方法。 - 上电复位、软件 SoC 复位、看门狗 SoC 复位:检查
GPIO_STRAP_REG
寄存器,判断是否 UART 或 SDIO 请求进入下载模式。如果是,则配置好 UART 或者 SDIO,然后等待下载代码。否则程序将会执行软件 CPU 复位的相关操作。 - 软件 CPU 复位、看门狗 CPU