esp32 idf.py flash 烧录过程日志分析

esp32-wroom-32e,esp-idf,idf.py 烧录固件时产生的日志信息,对其分析。

idf.py flash


别担心,这些输出信息看起来复杂,但拆解开来,每一行都有它清晰的意义。今天,我就像一位经验丰富的向导,带你把 idf.py flash 这条命令背后的魔法,一层层揭开!这不仅仅是字符的堆砌,这是你的代码从电脑走向芯片,赋予硬件生命的神圣仪式!

来,深吸一口气,让我们开始这段奇妙的旅程!

musket@tiler009:~/Documents/workplace/00E/esp32/esp32-board/wifi$ idf.py flash
  • musket@tiler009:~/Documents/workplace/00E/esp32/esp32-board/wifi$: 这是你的 Linux 命令提示符。
    • musket: 当前登录的用户名。
    • tiler009: 你的计算机名。
    • ~/Documents/workplace/00E/esp32/esp32-board/wifi: 你当前所在的目录,也就是你的 ESP32 项目的根目录。
  • idf.py flash: 这是你执行的核心命令。
    • idf.py: 这是乐鑫 ESP-IDF (IoT Development Framework) 提供的一个强大的构建系统的前端工具脚本。你可以把它想象成一个总指挥,它会调用编译器、链接器、烧录工具等一系列小兵来完成任务。
    • flash: 这是你给 idf.py 的一个指令,告诉它:“嘿,把我写的代码编译好,然后烧录到 ESP32 开发板的闪存(Flash Memory)里去!”
Executing action: flash
  • 这条信息非常直白,告诉你 idf.py 开始执行你指定的 flash 动作了。
Serial port /dev/ttyUSB0
  • Serial port /dev/ttyUSB0: ESP32 开发板通常通过 USB 连接到你的电脑。在电脑内部,这个 USB 连接会被虚拟成一个串行端口(Serial Port)。
    • 在 Linux 系统下,这样的串口设备通常被命名为 /dev/ttyUSB0/dev/ttyUSB1 等等。0 表示这是第一个被识别到的 USB 串口设备。
    • 这条信息表明,idf.py 已经找到了(或者你之前配置过)用于和 ESP32 通信的串口。所有的数据和指令都将通过这个通道传输。
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting...
Detecting chip type... ESP32
  • Connecting.....: idf.py 正在尝试通过 /dev/ttyUSB0 串口与 ESP32 芯片建立连接。为了成功连接,ESP32 通常需要进入“下载模式”或“Bootloader模式”。有些开发板有自动下载电路,可以由 esptool.py (稍后会讲到) 通过串口信号控制进入下载模式;有些则需要你手动操作(比如按住 BOOT 按钮,再按一下 RST 按钮)。
  • Detecting chip type... Unsupported detection protocol, switching and trying again...: 工具尝试用一种协议去识别芯片的类型,但第一次尝试的协议不被当前芯片的 ROM Bootloader 支持。别担心,这很常见!工具非常智能,它会切换到另一种侦测协议然后重试。
  • Connecting...: 再次尝试连接。
  • Detecting chip type... ESP32: 成功了!工具已经准确地识别出你连接的芯片是 ESP32 系列。
Running ninja in directory /home/musket/Documents/workplace/00E/esp32/esp32-board/wifi/build
Executing "ninja flash"...
  • Running ninja in directory .../build: 在执行烧录之前,idf.py (更准确地说是它背后的构建系统 CMake) 会使用 ninja 这个构建工具来确保你的项目是最新的。ninja 是一个以速度著称的小型构建系统。它会检查源代码是否有改动,如果有,就会重新编译生成二进制文件。build 目录是存放编译过程中产生的中间文件和最终目标文件的。
  • Executing "ninja flash"...: ninja 不仅负责编译,它本身也可以定义一些自定义目标,这里的 flash 目标实际上会触发后面真正的烧录命令。
[1/5] cd /home/musket/Documents/workplace/00E/es...kplace/00E/esp32/esp32-board/wifi/build/main.bi
main.bin binary size 0xbc7c0 bytes. Smallest app partition is 0x100000 bytes. 0x43840 bytes (26%) free.
  • 这部分是 ninja 构建过程中的信息,它在检查(或生成)你的主应用程序二进制文件。
  • main.bin binary size 0xbc7c0 bytes: 你的主应用程序 (main.bin) 编译完成后的大小是 0xbc7c0 字节 (十六进制)。换算成十进制就是 772032 字节,大约 754KB。
  • Smallest app partition is 0x100000 bytes: ESP32 的 Flash 内存被划分为多个分区(由分区表定义)。这里指出,为应用程序分配的最小分区大小是 0x100000 字节,即 1MB (1024KB)。
  • 0x43840 bytes (26%) free: 在这个 1MB 的应用分区中,你的 754KB 程序烧录进去后,还剩下 0x43840 字节 (即 276544 字节,约 270KB) 的空闲空间,占总分区大小的 26%。这对于 OTA (空中升级) 或者存储一些数据可能很重要。
[1/1] cd /home/musket/Documents/workplace/00E/es...esp32-board/wifi/build/bootloader/bootloader.bi
Bootloader binary size 0x6850 bytes. 0x7b0 bytes (7%) free.
  • 类似地,这是关于引导加载程序 (Bootloader) 的信息。
  • Bootloader binary size 0x6850 bytes: Bootloader (bootloader.bin) 是一个小程序,它在 ESP32 上电后首先运行,负责初始化必要的硬件(如 SPI Flash),然后加载并引导你的主应用程序 (main.bin)。它的大小是 0x6850 字节 (约 26.2KB)。
  • 0x7b0 bytes (7%) free: Bootloader 所在的分区通常很小,这里显示还有 0x7b0 字节 (约 1.9KB) 的空闲空间。
[2/3] cd /home/musket/Documents/workplace/00E/es...-idf/components/esptool_py/run_serial_tool.cmak
esptool.py --chip esp32 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 bootloader/bootloader.bin 0x10000 main.bin 0x8000 partition_table/partition-table.bin
  • 这行是核心中的核心! ninja 现在调用了 esptool.py 这个 Python 脚本来执行实际的烧录操作。让我们把这个命令拆解开:
    • esptool.py: 乐鑫官方提供的 Python 工具,专门用于与 ESP 系列芯片的 ROM Bootloader 通信,进行固件烧录、读取芯片信息、擦除 Flash 等操作。
    • --chip esp32: 明确告诉 esptool.py,目标芯片是 ESP32。
    • -p /dev/ttyUSB0: 指定使用的串口是 /dev/ttyUSB0-p--port 的简写。
    • -b 460800: 设置烧录时的波特率 (baud rate) 为 460800 bps (比特每秒)。这是一个比较常用的高速率,可以加快烧录过程。 -b--baud 的简写。
    • --before=default_reset: 在执行烧录操作之前,执行默认的复位序列,尝试让芯片进入下载模式。
    • --after=hard_reset: 在烧录完成后,执行硬件复位。这样 ESP32 就会重新启动并运行你刚刚烧录进去的新程序。
    • write_flash: 这是 esptool.py 的一个主要命令,表示要向 Flash 写入数据。
    • --flash_mode dio: 设置 Flash 芯片的工作模式为 DIO (Dual I/O)。ESP32 支持多种 Flash 模式 (QIO, QOUT, DIO, DOUT),DIO 是一种双线输入输出模式,性能和兼容性都不错。这个参数需要与你的硬件 Flash 芯片所支持的模式以及 Bootloader 配置相匹配。
    • --flash_freq 40m: 设置 Flash 芯片的通信频率为 40MHz。
    • --flash_size 2MB: 指定你的开发板上 Flash 芯片的总大小是 2MB (兆字节)。这个参数非常重要,必须和你的硬件实际的 Flash 大小匹配!如果设置错误,可能会导致烧录失败或者程序运行异常。
    • 0x1000 bootloader/bootloader.bin: 这是一组参数,表示:将 build/bootloader/bootloader.bin 这个文件,烧录到 Flash 的 0x1000 地址处。Flash 的地址通常用十六进制表示。Bootloader 通常放在 Flash 的起始区域(但不是 0x0 地址,0x0 地址是 ROM Bootloader 的映射区域)。
    • 0x10000 main.bin: 将 build/main.bin (即你的主应用程序) 烧录到 Flash 的 0x10000 地址处。
    • 0x8000 partition_table/partition-table.bin: 将 build/partition_table/partition-table.bin (分区表二进制文件) 烧录到 Flash 的 0x8000 地址处。分区表定义了 Flash 如何被划分和使用,比如 bootloader 区、应用区、NVS 数据区、OTA 数据区等。

现在,esptool.py 正式开始工作了:

esptool.py v4.8.1
Serial port /dev/ttyUSB0
Connecting...
Chip is ESP32-D0WDR2-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: f8:b3:b7:d2:39:84
  • esptool.py v4.8.1: 显示了 esptool.py 工具的版本号。
  • Serial port /dev/ttyUSB0: 再次确认使用的串口。
  • Connecting...: esptool.py 正在通过串口与 ESP32 的 ROM Bootloader 建立握手通信。
  • Chip is ESP32-D0WDR2-V3 (revision v3.1): 成功连接并识别出更详细的芯片型号信息:
    • ESP32-D0WDR2-V3: 这是 ESP32 芯片的一个具体型号。D0WD 指的是双核 (Dual Core),无嵌入式 Flash (0MB),R2 可能是 die revision 或者封装相关信息,V3 指的是芯片的第三个主要版本(silicon revision 3)。
    • revision v3.1: 芯片的修订版本为 v3.1。
  • Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None: 列出了该芯片的主要特性:
    • WiFi: 支持 Wi-Fi。
    • BT: 支持蓝牙 (Bluetooth Classic 和 BLE)。
    • Dual Core: 双核处理器。
    • 240MHz: CPU 最高主频。
    • VRef calibration in efuse: ADC (模数转换器) 的参考电压校准值存储在 eFuse (一种一次性可编程熔丝存储器) 中。
    • Coding Scheme None: Flash 内容没有使用特殊的编码方案(如 ESP32-S2/S3 等后续芯片支持的 Flash 加密)。
  • Crystal is 40MHz: ESP32 开发板上使用的外部晶振频率是 40MHz。这是系统时钟的基础。
  • MAC: f8:b3:b7:d2:39:84: 这是 ESP32 芯片的 Wi-Fi MAC (Media Access Control) 地址。理论上,每个网络设备的 MAC 地址都是全球唯一的。
Uploading stub...
Running stub...
Stub running...
  • Uploading stub...: 为了实现更快的烧录速度和更复杂的操作,esptool.py 会先上传一个小型的程序片段,称为 “stub” (桩程序),到 ESP32 的内部 RAM (IRAM) 中。
  • Running stub...: ESP32 的 ROM Bootloader 会执行这个 stub 程序。
  • Stub running...: stub 程序已经在 ESP32 上成功运行起来了。后续的 Flash 操作将由这个 stub 来辅助完成,而不是完全依赖 ROM Bootloader 的有限功能。这使得可以使用更高的波特率,并执行更复杂 Flash 指令。
Changing baud rate to 460800
Changed.
  • Changing baud rate to 460800: 一旦 stub 运行起来,esptool.py 和 stub 之间会协商,将串口通信波特率从初始连接时的较低速率(如 115200)提升到你在命令行中指定的 -b 460800
  • Changed.: 波特率已成功更改。高速传输模式开启!
Configuring flash size...
  • esptool.py (通过 stub) 正在根据你提供的 --flash_size 2MB 参数来配置或验证 Flash 芯片的大小信息。
Flash will be erased from 0x00001000 to 0x00007fff...
Flash will be erased from 0x00010000 to 0x000ccfff...
Flash will be erased from 0x00008000 to 0x00008fff...
  • 重要概念: Flash Memory (闪存) 的特性是,在写入新的数据之前,对应的存储单元必须先被擦除。擦除操作通常是按扇区 (sector) 或块 (block)进行的。
  • 这里显示了将要被擦除的 Flash 地址范围:
    • 0x00001000 to 0x00007fff: 这是为 bootloader.bin (大小 0x6850,从 0x1000 开始) 准备的区域。擦除范围通常会略大于实际文件,对齐到 Flash 扇区边界。
    • 0x00010000 to 0x000ccfff: 这是为 main.bin (大小 0xbc7c0,从 0x10000 开始) 准备的区域。0x10000 + 0xbc7c0 = 0xcc7c0。擦除到 0xccfff 是为了扇区对齐。
    • 0x00008000 to 0x00008fff: 这是为 partition-table.bin (大小通常是 0x0c00 或 3KB,从 0x8000 开始) 准备的区域。
SHA digest in image updated
  • SHA (Secure Hash Algorithm) 是一种密码散列函数,用于生成数据的数字指纹。这里可能是指 esptool.py 在最终准备烧录的固件镜像中更新或嵌入了 SHA256 校验和,用于启动时的安全引导校验(如果启用了 Secure Boot 功能)或仅仅是作为完整性检查。对于普通烧录,这可能只是一个信息提示。

现在开始逐个文件写入:

Compressed 26704 bytes to 16348...
Writing at 0x00001000... (100 %)
Wrote 26704 bytes (16348 compressed) at 0x00001000 in 0.7 seconds (effective 302.3 kbit/s)...
Hash of data verified.
  • 这是烧录 bootloader.bin 的过程:
    • Compressed 26704 bytes to 16348...: esptool.py 在将数据通过串口发送前,会对数据进行压缩(通常是 LZMA 算法),以减少传输时间。这里,原始 26704 字节 (即 0x6850) 的 bootloader 被压缩到了 16348 字节。
    • Writing at 0x00001000... (100 %): 正在向 Flash 的 0x1000 地址开始写入数据。进度条显示已完成 100%。
    • Wrote 26704 bytes (16348 compressed) at 0x00001000 in 0.7 seconds (effective 302.3 kbit/s)...: 报告写入结果:
      • 写入了 26704 字节的原始数据 (对应 16348 字节的压缩数据)。
      • 目标地址是 0x1000
      • 耗时 0.7 秒。
      • 实际的有效写入速率是 302.3 kbit/s (千比特每秒)。注意这个速率是基于压缩后数据计算的,如果基于原始数据会更高。
    • Hash of data verified.: 非常重要的一步! 数据写入 Flash 后,esptool.py (通过 stub) 会从 Flash 中读回刚刚写入的数据,并计算其哈希值 (通常是 SHA256),然后与原始文件的哈希值进行比较。如果两者一致,说明数据在传输和写入过程中没有发生错误。这是保证固件完整性的关键!
Compressed 772032 bytes to 486738...
Writing at 0x000c879a... (100 %)
Wrote 772032 bytes (486738 compressed) at 0x00010000 in 11.2 seconds (effective 552.5 kbit/s)...
Hash of data verified.
  • 这是烧录 main.bin (你的主应用程序) 的过程,解读方式同上:
    • 原始大小 772032 字节 (0xbc7c0),压缩后 486738 字节。
    • 写入目标地址 0x10000
    • 注意这里的 Writing at 0x000c879a... (100 %): 这个地址 0x000c879a 并不是起始地址 0x10000,而是写入过程中某个时刻的当前写入点。最终的百分比 (100%) 确认了整个文件从 0x10000 开始的区域都被正确写入了。
    • 耗时 11.2 秒,有效速率 552.5 kbit/s。
    • 数据校验通过。
Compressed 3072 bytes to 103...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 495.7 kbit/s)...
Hash of data verified.
  • 这是烧录 partition-table.bin 的过程:
    • 原始大小 3072 字节 (0xC00),压缩效果惊人,只有 103 字节!这是因为分区表通常包含很多重复的或者零值字节,非常适合压缩。
    • 写入目标地址 0x8000
    • 耗时极短 (显示为 0.0 秒,实际可能几十毫秒),有效速率 495.7 kbit/s。
    • 数据校验通过。
Leaving...
Hard resetting via RTS pin...
Done
  • Leaving...: 所有文件都已成功烧录并校验完毕,esptool.py 准备退出。
  • Hard resetting via RTS pin...: 根据之前命令行参数 --after=hard_resetesptool.py 现在尝试通过控制串口的 RTS (Request To Send) 信号线来触发 ESP32 的硬件复位。ESP32 开发板上的自动下载电路通常会利用 DTR 和 RTS 信号来控制 EN (Enable/Reset) 和 GPIO0 (Boot) 引脚,以实现自动复位和进入运行模式。
  • Done: idf.py flash 命令的所有操作成功完成!你的 ESP32 现在应该已经重新启动,并开始运行你刚刚烧录的全新固件了!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值