【ESP32入门学习 四 】ESPTOOL 简析

esptool.py 是一个基于 python 的开源,用于和 ESP8266 & ESP32 产品的 ROM bootloader 进行通信的工具,不依赖于任何平台。

1. 功能概述

esptool.py 是一个基于 python 的开源,用于和 ESP8266 & ESP32 产品的 ROM bootloader 进行通信的工具,不依赖于任何平台。当前维护 esptool 的总负责人是 Angus。

esptool 已经成为了 python 的一个官方模块,适用于 python 2.6 或 python 3.4 及以上版本。它可以通过 pip 直接安装,命令为pip install esptool。安装完成后,esptool.py 会出现在默认 python 可执行路径中,可在 python 命令行中直接 import。

2. 使用指导

2.1. HELP 指令

在 esptool.py 后面跟参数 -h,可以查看 esptool 可以使用的所有功能。命令得到的返回如下:

要查看某特定指令后跟的参数,也可以在指令后跟 -h 查看。

2.2. 通用选项

使用 esptool.py 需要添加三个通用选项:

  1. 芯片类型:
    该选项在只有一个设备时可以省略,格式为 --chip esp8266。选择当前操作的芯片类型作为传参。

  2. 串口:
    该选项指定当前操作的设备串口号,格式为 -p com2 (对于 windows 系统) 或 -p /dev/ttyUSB0 (对于 linux/OSX 系统),也可以将 -p 写作 --port。

  3. 波特率:
    该选项可以省略,默认为 115200,格式为 -b 921600 或 --baud 921600。可以通过设置 ESPTOOL_BAUD 配置默认波特率,以提高读写 flash 操作时的速度。
    在同步的时候,波特率必须为 115200,仅当数据传输时才可以提高波特率。
    大多数的硬件设备可以支持 230400 的波特率,还有的可以支持到 460800、921600、1500000 或更高。波特率也可以低于 115200,例如 74880 就是 ESP8266 设备打印 boot 信息的波特率。

2.3. ESPTOOL 指令

2.3.1. ELF 转成二进制文件

elf2image 命令可以将 ELF 文件转变成可以下载的二进制文件。命令示例:esptool.py --chip esp8266 elf2image my_app.elf。
该指令不需要与串口连接。该指令可以跟 --flash_freq 和 --flash_mode 参数,将此配置参数写入固件头中。这样就可以将生成的固件直接下载到芯片中。不过 write_flash 指令可以改变固件中的配置参数。

  1. 对于 ESP8266:
    elf2image 命令会生成两个二进制文件:my_app.elf-0x00000.bin 和 my_app.elf-0x40000.bin。可以通过 --output/-o 选项将输出二进制文件重命名。
    此外,该指令也可以生成二级 boot 文件。但是二级 boot 文件必须与其他 bootloader 或 乐鑫官方的 bootloader 同时下载。
    指令示例如下:esptool.py --chip esp8266 elf2image --version=2 -o my_app-ota.bin my_app.elf
  2. 对于 ESP32:
    lf2image 命令会生成单一的二进制文件,默认与 ELF 文件同名,后缀为 .bin。
    指令示例如下:esptool.py --chip esp32 elf2image my_esp32_app.elf

2.3.2. 下载 flash

由 elf2image 和 make image 生成的二进制文件可以通过串口 write_flash 指令写到芯片中。指令示例如下:esptool.py --port com2 write_flash 0x1000 my_app-0x01000.bin。
该命令也可以下载多个固件,指令示例如下:esptool.py --port com2 write_flash 0x00000 my_app.elf-0x00000.bin 0x40000 my_app.elf-0x40000.bin。
参数顺序依次是 chip (只有一个芯片连接时可以省略),port,随后是各个固件的起始地址与名称。当生成 ESP8266 一级 boot 固件时,由 elf2image 指令生成的固件名称会包含固件起始地址。对于其他类型的固件而言,从 SDK 中找到固件下载地址。
同时,还可以添加 flash mode 和 flash size 作为参数,用于修改默认 flash 启动配置。指令示例如下:esptool.py --port com2 write_flash --flash_mode qio --flash_size 32m 0x0 bootloader.bin 0x1000 my_app.bin。

串口传输数据的性能默认通过压缩提升。如果不需要压缩数据,通过 -u/--no-compress 来配置。

2.3.3. 确认 flash

写 flash 后会通过验证数据的 MD5 值来确认下载,并不需要人工再次确认。如果一定要验证,则通过 verify_flash 指令来完成。指令示例如下:esptool.py --port com2 verify_flash 0x40000 my_app.elf-0x40000.bin

注:如果需要验证的是 boot 固件,那通过 --flash_mode、--flash_size 和 --flash_freq 配置的参数均需要在确认 flash 命令后面给出,否则确认会失败。

2.3.4. 手动生成固件

固件可以通过几个二进制段来合成。指令示例如下:esptool.py --chip esp8266 make_image -f app.text.bin -a 0x40100000 -f app.data.bin -a 0x3ffe8000 -f app.rodata.bin -a 0x3ffe8c00 app.flash.bin。
该指令无需串口连接,目前只适用于 ESP8266。

2.3.5. DUMP MEM 命令

dump_mem 指令会将芯片内存中的一片区域保存出来。示例指令展示了从 ESP8266 ROM 保存出 64KB 数据:esptool.py --port com2 dump_mem 0x40000000 65536 iram0.bin。

2.3.6. 读 MAC 地址命令

该指令经常被用来验证是否能与芯片进行通信,在 RMA 阶段很常见。通常客户返回硬件问题时,会先读取 MAC 地址确保芯片内部正常。指令示例如下:esptool.py --port com2 read_mac。

2.3.7. 读 flash 信息命令

读 flash id 指令示例如下:esptool.py --port com2 flash_id。
指令返回如下:

Manufacturer: e0
Device: 4016
Detected flash size: 4MB

读 flash 寄存器指令示例如下:esptool.py --port com2 read_flash_status。
指令会返回当前 flash 的状态寄存器,将状态寄存器与 datasheet 作比较,可以定位当前 flash 问题的原因。

2.4. 串口连接

ESP8266 与 ESP32 通过 3.3V 的 UART 建立与 ROM 的通信连接。连接需要遵循以下规则:


ESP32/ESP8266 Pin
Serial Port Pin
TX (aka GPIO1)
RX (receive)
RX (aka GPIO3)
TX (transmit)
Ground
Ground

注:不要将芯片连接到 5V TTL 电平,尤其是高电平的 RS-232!

2.5. 进入 bootloader

ESP8266 和 ESP32 进入 bootloader 之前均需要保证上电模式正确。
对于某些开发板(包括 NodeMCU, WeMOS, HUZZAH Feather, Core Board, ESP32-WROVER-KIT),esptool.py 可以自动地将上电启动模式配置正确。如果您使用的是上述开发板,可以跳过这一节。
在进入 bootloader 之前,需要做以下几件事:断电、将 pin 脚电平设置正确、GPIO 电平拉低,最后上电。

ESP8266 和 ESP32 每次上电重启时,均会重新选择工作模式。重启可以由以下几种方式触发:

  1. 通过控制芯片供电
  2. 通过给 nRESET 引脚一个低电平脉冲(只对 ESP8266 有效)
  3. 通过给 CH_PD/EN 引脚一个低电平脉冲

注:对于 ESP8266,在工作状态时,nRESET 和 CH_PD 必须保持高电平。

3. 常见问题及解答

3.1. bootloader 没有响应

如果你看到 ‘Failed to connect’ 字样,证明芯片没有进入到 bootloader。可以通过以下操作确认:

  1. 检查是否输入了正确的串口号
  2. 检查是否能访问串口,是否有别的软件占用
  3. 检查外部供电是否为稳定的 3.3V 电压
  4. 检查引脚是否对应连接,tx/rx 是否接反,io0是否接地
  5. 如果与上述提到的 GPIO 连接,先断开再用 esptool.py 尝试
  6. 用低波特率尝试,确认是否是波特率引起的问题,最低可用 9600

3.2. 写 flash 中途失败

如果写 flash 中途出现问题,用较低波特率尝试。供电不稳定也有可能造成这个问题。

3.3. 写 flash 成功但无法运行

  1. 选错 flash 模式
    • 很多设备仅支持 DIO 模式,用 QIO 模式烧写也会成功,但芯片无法读取到 flash 内容。用 DIO 模式再尝试下载
  2. 供电不足
    • ESP8266 与 ESP32 不仅要求供电电压达到 3.3 V,还需要供电电流平均能达到 70 mA,最高能达到 200-300 mA,ESP32 的尖峰电流还要更高。需要提高供电能力
  3. 缺少 bootloader
    • ESP8266 和 ESP32 会用一段二级 bootloader 程序。ROM 中的硬件 bootloader 会将这段 bootloader 从 flash 中加载出来,并继续运行程序。对于 ESP8266,固件(名称类似于 boot_v1.x.bin)需要被下载到 flash 的 0 地址。对于 ESP32,需要被下载到 0x1000 地址。没有 bootloader 则程序无法运行
  4. SPI 引脚问题
    • 如果设置 flash QIO 模式,GPIO 7-10 用于访问 SPI flash,必须与其他连接断开
    • 如果设置 flash DIO 模式,GPIO 7-8 用于访问 SPI flash,必须与其他连接断开
    • 除了上述的引脚之外,GPIO 6&11 也会用于访问 SPI flash。不过如果这两个脚接错,下载会直接失败
  5. 初步运行即 crash
    • 用串口调试助手观察上电的信息(ESP8266 使用 74880 的波特率,ESP32 使用 115200 的波特率)。如果程序刚启动就 crash 或打印出错误信息,根据信息反推代码的问题
  • 发表于 2020-09-11 14:47
  • 阅读 ( 136 )

0 条评论

请先 登录 后评论
淡若清风
淡若清风

35 篇文章

作家榜 »

  1. 淡若清风 35 文章
  2. 杨杨 2 文章
  3. seaky 0 文章
  4. 15139236712 0 文章
  5. selectcc 0 文章
  6. 温志亮 0 文章
  7. jamesfan007 0 文章
  8. Gavin 0 文章