跳到主要内容

图 2 - 启动时序图

ESP32 从按下开关到设备进入"待机听唤醒词"状态,中间到底发生了多少件事?

如果上方图无法显示,点这里看 PNG 版本

一眼看懂启动顺序

整个启动序列总共约 3-8 秒(取决于 Wi-Fi 是否要走配网、OTA 是否要拉资源):

阶段时长内容
Bootloader → 跳固件100msFlash 校验 + 时钟设置 + PSRAM 上电
Board 构造200-400ms板子专属的 I²C / SPI / 显示屏 / 按键 / codec 初始化
Application::Initialize500ms音频任务创建 + 状态机注册 + MCP 工具注册
Application::Run + StartNetwork1-3s连 Wi-Fi 或拨 4G(视信号而定)
OTA 检查 + Protocol 建链500-2000msPOST 设备信息、可选下载新资源、协议 hello 握手
进入 Idle即时状态机 → kDeviceStateIdle,唤醒词监听开始

三个关键设计点

1. Board 在 Application 之前构造

为什么?Application 需要先知道板子有什么硬件(麦克风/喇叭/屏幕的具体引脚),才能调对应驱动。所以 Board::GetInstance() 一定先于 Application::GetInstance().Initialize()

2. Initialize 和 Run 是两步

  • Initialize():只做"准备工作"(注册回调、创建任务);
  • Run():进入主事件循环,开始处理状态变更、网络事件、MCP 调用。

分开的好处:测试时可以 Initialize 后 mock 一些状态再 Run。

3. 网络初始化是异步的

StartNetwork() 返回后并不代表已连上 Wi-Fi——它启动连接尝试就返回。真正连上后通过回调 OnNetworkEvent(Connected) 通知 Application,Application 再决定接下来做什么(启动 OTA 任务、打开音频通道等)。

一句话讲清

"Bootloader 跳到固件 → Board 把硬件初始化好 → Application 把软件子系统接好 → 开始联网 → 网通了去 OTA 检查并建协议链 → 进 Idle 状态等用户喊它。"

关联章节

  • /02-main-application §2.3-2.5(Initialize / ActivationTask / InitializeProtocol)
  • /03-state-machine(状态枚举的语义)
  • /09-boards(Board 构造里干了啥)