尧图精选

ESP32 独立串口工具烧录 bin 文件:地址、参数与故障排查

🕒 发布时间:2026/10/2 8:55:48 📁 来源:尧图网络
一个做硬件的朋友上周给我发来一个压缩包里面躺着三个文件bootloader.bin、partition-table.bin、myapp.bin外加一句麻烦帮我烧到这批板子上。他手上有二十块刚贴片回来的 ESP32 模块工作在客户现场既没装 Arduino也没配 ESP-IDF只有一个 Windows 笔记本和一根 USB 线。这种场景下IDE 那一套一键下载的流程完全用不上能救场的只有官方那个独立的串口烧录工具。这篇文章就把这条路走通从工具的获取、bin 文件和烧录地址的对应关系到点击 START 之后每一步在发生什么再到烧录失败时怎么一层层往外剥。关键词就三个——ESP32、串口工具、bin 文件烧录摸清这三样你拿到任何一份别人编译好的固件包都能自己灌进板子。1. 明明 IDE 能一键下载为什么还要折腾独立的烧录工具1.1 三种下代码路径的真实差异先说清楚一件事不管你是用 Arduino IDE 点那个向右的箭头还是在 ESP-IDF 里敲idf.py flash或者用本文说的这个独立工具底层跑的都是同一个东西——esptool。它做的事情本质上是通过串口把芯片拉进下载模式Download Mode然后按地址往 Flash 里写数据写完再复位。区别只在于谁帮你在前面把参数填好了。Arduino IDE编译完自动生成一份 esptool 命令行参数是 IDE 根据你选的开发板型号推出来的你基本看不见也改不了。ESP-IDF / platformio编译目录里会留下flash_args文件里面列着每个 bin 的名字和地址烧录命令就是照着它拼的。Flash Download Tool官方独立烧录工具所有参数都摊在你面前地址、波特率、SPI 模式、Flash 容量全靠手填。灵活但也意味着填错就是你的锅。理解了这层关系你就不会觉得独立工具原始了。它只是把自动化那一层的假设全部拿掉换成了手动控制。1.2 只有独立烧录工具才顺手的三类场景第一类是批量烧录。工厂里一台电脑带多个 USB 口同时开几个工具实例各自占一个 COM 口互相不干扰。IDE 那边就不行了工程目录、编译缓存、串口占用全搅在一起开第二个实例都费劲。第二类是只有 bin 没有源码。客户给你一个编译好的固件包或者你从别人的板子上读出来一份完整镜像这时候你根本没有工程可以打开唯一的路就是拿工具按地址往里写。第三类是要精确定位每一个 bin 的位置。比如你想把应用固件放在 0x10000 以外的地址或者要往 NVS 分区、SPIFFS 镜像里塞数据这些操作在 IDE 里要靠改分区表、重新编译才能实现而在独立工具里就是表格里多加一行的事。注意独立工具不会帮你编译也不会帮你校验分区表和 bin 是否匹配。它只负责照着地址写。所以前面那些信息必须你自己准备好这也是后面几节的重点。2. Flash Download Tool 的获取与串口链路自查2.1 版本选择与目录结构这个工具在官方文档站的工具栏目下能直接下到是一个免安装的压缩包解压后双击flash_download_tool_*.exe就能跑。版本上我一般建议用较新的几版原因很现实新版本才认新芯片。你拿一个老版本去烧 ESP32-C3、C6 这类较新的型号工具界面里压根就没有对应的芯片选项硬选 ESP32 会直接烧废。解压后的目录大致是这几块主程序 exe 和几个 dll别单独把 exe 拎出来用缺文件会报错。一个bin子目录里面放着官方的出厂固件或者一些辅助镜像。部分版本还带一个combine目录里面是 bin 合并相关的小工具。我踩过的坑是把 exe 从压缩包里双击打开运行看起来能用但因为没有正常解压某些动态库没释放出来烧到一半工具直接闪退。所以老老实实先完整解压到一个纯英文路径下别放在桌面中文目录里某些版本的路径解析对中文支持不好。2.2 驱动、线材与板上那两个按键Windows 下绝大多数 ESP32 开发板用的是 USB 转串口芯片常见的是 CP2102、CH340/CH343 这两类。CH34x 需要单独装驱动装完设备管理器里才会出现 COM 口。判断驱动装没装好有个很直观的办法插上板子看设备管理器里有没有新增的端口拔掉再插上端口号跟着消失又出现就说明链路通了。线材这块我要单独强调。很多人烧录失败排查半天最后发现是那根线只能充电不能传数据。这种线外表和正常线一模一样唯一的区别是里面少了 D 和 D- 两根数据线。判断方法很简单换一根平时给手机传文件的线试一下如果突然就通了那就是线的问题。再说板子上那两个按键。ESP32 芯片进下载模式靠的是几个 strapping 引脚的组合状态而绝大多数开发板把它们接到了两个按键上一个标着BOOT或者IO0一个标着EN或者RST。手动进下载模式的标准动作是按住BOOT不放。短按一下EN然后松开。松开BOOT。这套动作做完芯片就被锁在下载模式里等待接收数据了。有些板子在 USB 转串口电路上做了自动复位用 DTR/RTS 控制那两个引脚工具点 START 时它自己会完成这一套动作你就什么都不用按。但自动复位不是所有板子都有尤其是自己画的板子或者便宜的模块经常需要手动来一遍。3. 搞错地址是烧录失败的头号原因先认清楚 bin 和它的地址3.1 一个固件工程到底会产出哪几个 bin很多人第一次打开工具看到表格里可以填好几行就懵了——我到底该填几个文件答案取决于你的固件结构但一个标准的、带 OTA空中升级功能的 ESP32 应用通常会产出一组固定的 binbootloader.bin二级引导程序。芯片上电后ROM 里的固化代码先跑起来然后把这段 bootloader 加载到 RAM 里执行由它负责初始化 Flash、加载分区表和主应用。它必须放在 Flash 最前面。partition-table.bin分区表。它是一张地图告诉系统 Flash 的哪一段是应用区、哪一段是 NVS 参数区、哪一段是文件系统。它占 0x1000 大小紧跟 bootloader 之后。boot_app0.bin这段小镜像配合 OTA 机制工作通常和 OTA data 初始化数据一起烧。如果你不用 OTA有些流程可以省掉但省掉之后某些 IDF 版本启动会报错所以我一般建议留着。ota_data_initial.binOTA 数据分区的初始内容。它决定芯片第一次启动时从哪个 app 分区引导。主应用 bin名字可能是firmware.bin、myapp.bin、project.bin也可能是 Arduino 自动命名的一长串。这是你真正的业务代码体积最大。五个文件、五个地址少一个、错一位板子要么启动不了要么启动起来跑的是旧代码。3.2 各型号芯片的地址速查先上表再讲怎么验证。下表是按官方模板工程在常见 ESP-IDF 版本下的默认值整理的文件ESP32ESP32-S2ESP32-S3 / C3 / C6 / H2bootloader.bin0x10000x10000x0partition-table.bin0x80000x80000x8000boot_app0.bin0xe0000xe0000xe000ota_data_initial.bin0xf0000xf0000xd000主应用 bin0x100000x100000x10000注意这张表只是常见默认值不是真理。自定义分区表会把应用区起点改掉不同 IDF 版本对 bootloader 偏移也可能调整。动手前一定用下面说的方法拿到你自己工程的真实地址别照抄。表里有两个地方特别容易翻车。一个是 bootloader 的偏移老 ESP32 是 0x1000而 S3、C3 这一代变成了 0x0把 0x1000 的规则套到 S3 上bootloader 就写到空白区去了芯片上电找不到引导程序串口只会吐一串乱码或者干脆没输出。另一个是ota_data_initial.bin的地址ESP32 是 0xf000S3/C3 是 0xd000这两个值互换了的话OTA 分区数据会覆盖到别的东西上。3.3 不靠记忆从编译产物里精确拿到地址记不住没关系工程自己会告诉你。如果你是 ESP-IDF 编译的打开编译输出目录一般是工程根目录下的build文件夹里面有个叫flash_args的文件内容长这样--flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0xf000 ota_data_initial.bin 0x10000 myapp.bin这个文件就是给 esptool 用的参数清单每一行前面的十六进制数就是地址后面是相对路径。照着它往工具的表格里填一个字都不会错。有的 IDF 版本还会生成一个flash_project_args内容更全包含 boot_app0同样可以用。如果你是 Arduino IDE 编译的打开的姿势是文件 首选项把显示详细输出里的上传过程勾上然后正常点一次上传。IDE 下方的输出窗口会打印出完整的 esptool 命令行里面带write_flash和后面一长串地址 文件名把它们抄下来就行。最后面的--flash_mode dio --flash_freq 40m --flash_size detect这几个参数也别丢它们对应工具界面右侧的 SPI 配置。还有一种情况就是你手上只有 bin 文件没有任何工程。这时候只能靠经验判断文件类型体积在 4KB 到 8KB 之间、文件名带 bootloader 的基本都是引导程序大小正好 3KB 左右的大概率是分区表剩下体积最大的那个就是应用。地址按芯片型号套上面那张表再用串口日志验证结果。4. 界面上的每一项参数到底在决定什么4.1 从串口号到波特率的填写顺序打开工具第一件事是选芯片类型。这个下拉框必须和你的板子严格对应选错不是烧不进去而是能烧进去但跑不起来更隐蔽。ESP32 和 ESP32-S3 的 bootloader 偏移不同选错了地址也跟着错。接下来选工作模式绝大多数情况就是Develop加UART。Factory模式是给产线做整片烧录用的配合合并后的单个 binHSPI模式在现在的工具版本里基本已经废弃了。然后填 COM 口和波特率。COM 口在设备管理器里看注意插拔板子前后对比确认哪个是新增的。波特率默认 115200这个值偏保守是为了兼容性。实际用起来我一般直接上 921600速度快接近八倍烧一个 1MB 的固件一两秒就完事。如果你的板子或线材质量一般高波特率下容易报校验错误那就退回 460800 或者 115200。4.2 多文件填写的行顺序与 DoNotChgBin表格部分是最关键的。左边有个复选框中间是文件路径右边是地址。每一行都要勾上复选框否则那一行会被忽略这一点新手极容易漏——文件填了、地址填了就是没勾然后烧录成功了但板子跑不起来因为根本就没写进去。行顺序本身不影响烧录结果esptool 内部会按地址排序但我习惯按地址从小到大排方便核对bootloader、partition-table、boot_app0、ota_data、app。右侧的 SPI 配置区有三项要填参数推荐值说明SPI SPEED40MHz与固件编译时的 flash_freq 保持一致SPI MODEDIO与 flash_mode 一致QIO 更快但需硬件支持Flash SIZE与芯片实际容量一致常见 4MB32Mbit看模块丝印或手册这里有个非常重要的勾选项DoNotChgBin。它的作用是告诉工具别动我的 bin 文件头。默认不勾的情况下工具会根据你选的 SPI SPEED / MODE / SIZE 去修改第一个 bin也就是 bootloader的头部字节把参数写进去。如果你勾上工具就原样写入使用 bin 里自带的参数。那到底勾不勾我的经验是如果你是从flash_args里抄来的参数并且已经在工具里填了同样的值勾不勾都一样因为两者一致。但如果你不清楚 bin 里原本的参数是什么那就勾上 DoNotChgBin让 bin 自己说了算。反过来如果 bin 是别人给的、参数未知而你知道自己的板子必须用 DIO 40MHz那就不勾让工具强行覆盖。4.3 点 START 之后日志里该出现什么点下 START右侧的日志区会开始滚动。正常的流程是这样几步工具尝试连接串口打印Connecting...。芯片被复位进下载模式日志里出现SYNC字样。如果这一步卡住不动说明没进下载模式需要手动按 BOOT 和 EN。读取芯片信息显示 MAC 地址、芯片型号、晶振频率。这一步是验证你芯片类型选对了没有的关键如果工具显示的 MAC 是乱码或者读不到说明通信有问题。开始逐段写入每写一段打印一个进度条和校验结果。全部写完显示FINISH然后自动复位芯片。整个过程里我最关注的是第 3 步读出来的 MAC 地址。能正常读出 MAC说明串口链路、芯片型号选择、下载模式这三个环节全都对了后面的写入基本不会出问题。如果这一步就失败别急着点第二次 START先回去检查前面那些设置。提示工具里有个STOP按钮注意不要把它和START搞混。我见过有人点错了然后盯着屏幕纳闷为什么没反应。5. 把一堆 bin 压成一个文件量产和远程升级的省事做法5.1 merge_bin 与 flash_args烧一块板子填五行还行烧二十块板子就是重复劳动而且每换一台电脑都要重新填一遍很容易填错。这时候就该把多个 bin 合并成一个整片镜像。ESP-IDF 里自带了这个能力两种用法。一种是用 esptool 的 merge_bin 子命令esptool.py --chip esp32 merge_bin \ -o merged.bin \ --flash_mode dio \ --flash_freq 40m \ --flash_size 4MB \ 0x1000 bootloader/bootloader.bin \ 0x8000 partition_table/partition-table.bin \ 0xf000 ota_data_initial.bin \ 0x10000 myapp.bin另一种更省事直接让 IDF 帮你合idf.py merge-bin它会把build目录下的镜像按正确地址合成一个merged-flash.bin。合完之后你在烧录工具里就只需要填一行地址填0x0文件选这个合并后的镜像勾上复选框点 START。合并镜像的起始地址永远是 0x0因为它内部已经包含了从 bootloader 开始的全部内容。这一点搞错的话比如你填了 0x1000整个镜像会往后平移 4KBbootloader 就跑偏了。5.2 合并后的坑地址偏移与 flash 参数头合并镜像有两个隐蔽的坑。第一个是地址必须严格递增且不重叠。merge_bin 会按你给的顺序往里拼如果你把 0x8000 的分区表写在 0x1000 的 bootloader 前面工具不会报错但生成的文件内容是错乱的。第二个是合并后的文件体积。merged.bin 的大小等于最后一个镜像的地址 它的长度不是所有文件大小简单相加。比如应用在 0x10000大小 700KB那合并文件就是 0x10000 700KB 左右中间 bootloader 到分区表之间的空白区域会用 0xFF 填充。这意味着合并镜像会比分散烧录多占一点传输时间但换来的是流程上的一步到位量产时非常值得。第三个合并时给的那些--flash_mode、--flash_size参数会被写进合并文件头部。所以合的时候用什么参数板子上就必须用什么参数两者对不上会出现能烧进去、开机就崩的情况。我自己的习惯是合之前先确认板子手册上的 Flash 型号是 DIO 还是 QIO、多大容量然后命令行参数和烧录工具里的下拉框保持完全一致。6. 烧录不成功的完整排查链路6.1 现象一串口列表里根本没有 COM 口这是最外层的问题压根没到芯片那一层。排查顺序我一般这样走先换 USB 口尤其是台式机前面板的 USB 口供电和数据质量都不稳定直接插到主板后面板。然后换线用一根确定能传数据的线。再然后装驱动CH34x 和 CP210x 各装一次装完拔插板子看设备管理器有没有反应。还有一种情况是设备管理器里出现了一个带黄色感叹号的设备。这说明硬件层面认到了但驱动不对或者安装失败。右键卸载设备拔插一次重新装驱动通常能解决。最后一种比较少见但确实存在的板子的 USB 转串口芯片坏了或者 USB 口虚焊。判断方法是拿万用表量一下 USB 座的 VBUS 有没有 5V或者换一块同款板子对比。6.2 现象二一直卡在等待上电同步串口能选到但点 START 之后日志停在Connecting...或者一直重试SYNC。这说明串口是通的但芯片没被拉进下载模式。手动按 BOOT EN 那个序列来一遍注意顺序和时序先按住 BOOT短按 EN 并松开再松开 BOOT。有些板子的按键手感很硬短按可能没触发用力一点、按住时间稍长一点再试。如果手动操作也不行那就要怀疑串口被占用了。最常见的是同时开了 IDE 的串口监视器或者别的串口工具它们独占了 COM 口烧录工具连不上。把所有可能占用串口的软件关掉包括后台隐藏的。再往下就得看硬件了。ESP32 有自动下载电路需要 USB 转串口的 DTR 和 RTS 分别控制 EN 和 IO0中间通过两个三极管做电平转换。自己画的板子如果这部分电路没做或者三极管方向焊反了就只能全程手动按按键。这种情况下有个临时办法先在按住 BOOT 的状态下点上工具的 START等日志出现 SYNC 再松开 BOOT相当于手动接管了自动同步的过程。6.3 现象三提示烧录成功但板子毫无反应这个最让人抓狂因为工具给了你成功反馈但结果不对。按可能性从高到低排地址错了。尤其是 bootloader 偏移S3/C3 用了 0x1000或者应用固件的地址和分区表里定义的起始地址不一致。回到第 3 节用flash_args核对一遍。bin 文件不完整或者类型放错。比如把分区表当成了应用烧到 0x10000或者漏烧了boot_app0.bin导致 OTA 引导标志异常。复选框没勾。前面提过最冤的一种。Flash 参数不匹配。固件编译时用的是 QIO 80MHz而你在工具里选了 DIO 40MHz 并且没勾 DoNotChgBin工具把参数覆盖写成了错的。排查这个现象串口日志是唯一的抓手。把烧录工具的串口监视功能打开或者用另一个串口工具连上波特率 115200然后按一下 EN 复位看输出什么全是乱码波特率不对或者晶体频率配置不对。输出invalid header: 0xffffffff那个地址上是空的说明 bootloader 没写进去回去查地址。输出invalid header: 0x...后面是一个非 ffffffff 的值那个地址上有东西但不是引导程序说明写错文件了。输出一段正常的启动信息然后卡住或者反复重启地址都对问题在应用本身比如 NVS 分区数据异常、看门狗超时。这时候可以试着手动擦除整片 Flash 再重烧。工具界面上有个 ERASE 按钮擦除会花几秒到十几秒但能排除掉旧数据残留的干扰。7. 几个我在项目里反复验证过的实用习惯第一个习惯是在文件夹里留一份地址清单。每次交付固件包给同事或者客户我都习惯在同一个目录里放一个文本文件写清楚芯片型号、每个 bin 对应的地址、SPI 参数最好再附上一条完整的合并命令。这样别人拿到包不用问就知道怎么烧也不需要猜参数。这个小动作省下的沟通时间远超写它的成本。第二个习惯是先烧再测别先测再烧。有些板子出厂时 Flash 里带着测试固件直接上电看串口是有输出的容易让人误以为可以正常烧录。实际上先做一次完整烧录看到FINISH和下发后的正常日志再去做功能测试顺序不能反。第三个习惯是准备一份最小可用的验证固件。就是那种开机往串口打印一行固定字符串的简单程序编好之后把 bin 存起来。当你不确定板子到底是硬件坏了还是固件有问题时烧这个最小固件进去。它如果跑起来能打印说明芯片、Flash、串口这条链路全部正常问题就在原来的固件上如果它也跑不起来那就是硬件层面的问题不用再折腾软件了。这份固件我换了好几个项目一直是排查问题的第一把钥匙。关于波特率还有个细节值得说如果你用 921600 烧录成功但偶尔出现校验失败有时候不是线材问题而是电脑 USB 口供电波动。换到主机后面板直连的口或者换一根带磁环的线往往就稳了。这种偶发性故障最难查因为它十次里只失败一次让人总以为是自己的操作问题。最后工具版本这件事值得反复提醒。新芯片层出不穷烧录工具更新也比较频繁遇到板子是新买的、工具是两年前下的这种组合第一反应应该是去下个新版本而不是怀疑自己的操作。我自己就曾在 C6 上折腾了一个多小时最后发现是工具版本太老压根不支持换了版本之后两分钟搞定。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →