1、烧录速度瓶颈分析:为什么你的固件烧得这么慢?

大家好,我是你们的老朋友。做嵌入式这些年,我见过太多工程师在烧录器前面干等——进度条走得像蜗牛,一杯咖啡喝完了还没到 50%。

你想想看,明明芯片支持高速烧录,为什么实际速度就是上不去?

今天咱们就从三个维度来拆解:波特率、协议开销、驱动能力。这三个点,基本覆盖了 90% 的烧录慢问题。

核心观点:烧录速度不是由「理论波特率」决定的,而是由「有效数据传输率」决定的。说白了,你设了 115200,实际可能连 30% 的带宽都没用上。

烧录速度瓶颈三维分析 烧录速度瓶颈 ① 波特率限制 ② 协议开销 ③ 驱动能力 时钟源精度 / 分频误差 线缆长度 / 寄生电容 帧格式 / 应答机制 校验 / 重传策略 电平转换 / 驱动芯片 MCU 内部 Flash 写入速度 有效烧录速度 = min(波特率有效带宽, 协议效率 × 波特率, 驱动响应速度) 三个维度中最低的那个,就是你的实际瓶颈

1.1 波特率:你以为设了就能跑?

波特率是串口通信的「车速」。115200 bps 听起来很快,但实际能跑多少,取决于几个硬条件。

第一个坑:时钟源精度。

我遇到过好几次,工程师把波特率设到 921600,结果烧录一半就报错。为什么?因为 MCU 内部 RC 振荡器精度不够。比如某些国产 MCU,内部 RC 误差 ±3%,在 115200 以下还能忍,到了 460800 以上,误差直接导致采样点偏移,数据就全乱了。

我的经验:用外部晶振(8MHz 或 16MHz)做时钟源,波特率可以稳定跑到 921600。内部 RC 振荡器的话,建议最高只用到 115200,再高就是赌运气。

第二个坑:分频误差。

串口波特率是靠系统时钟分频得到的。举个例子,系统时钟 16MHz,要得到 115200,分频系数 = 16000000 / (16 × 115200) ≈ 8.68。取整后实际波特率是 16000000 / (16 × 9) = 111111,误差 3.5%。

这个误差在短时间通信里问题不大,但烧录固件动辄几十 KB,累积下来就会丢字节。

目标波特率 16MHz 实际波特率 误差 烧录稳定性
9600 9615 0.16% ✅ 非常稳定
115200 111111 3.5% ⚠️ 短包可用
460800 444444 3.6% ❌ 容易丢包
921600 888888 3.6% ❌ 基本不可用

避坑指南:我曾经在一个项目里,为了追求速度把波特率设到 2Mbps,结果 10 块板子有 3 块烧录失败。查了两天才发现是某批次 MCU 的 RC 振荡器偏了 5%。从那以后,我养成了习惯——量产前先测一批芯片的实际波特率误差。

1.2 协议开销:你传的 1 个字节,真的只占 1 个字节?

很多人以为串口传 1 个字节就是 8 个 bit。其实不是。

标准 UART 帧格式是:1 个起始位 + 8 个数据位 + 1 个校验位(可选)+ 1 个停止位。也就是说,传 1 个有效字节,实际要发 10 到 11 个 bit。

这还只是物理层的开销。更狠的是协议层的开销。

常见的烧录协议开销:

  • 应答机制:每发一包数据,要等 MCU 回 ACK。一来一回,时间翻倍。
  • 校验字段:CRC16 或 CRC32,每包多占 2~4 个字节。
  • 地址/长度头:很多协议每包要带 4 字节地址 + 4 字节长度。
  • 帧间隔:MCU 处理完一包需要时间,这期间总线是空闲的。

我算过一笔账:一个典型的 YModem 协议,有效数据载荷只有 128 字节,但加上头、校验、应答,实际传输量接近 200 字节。协议效率只有 64%。

关键数据:波特率 115200,理论每秒传 11520 字节。但扣除协议开销后,实际有效数据吞吐量往往只有 4000~6000 字节/秒。你想想看,一个 256KB 的固件,光传输就要 40~60 秒。

怎么优化?

  • 用大包传输(比如 1KB 一包),减少头校验占比。
  • 取消逐包应答,改用连续发送 + 批量校验。
  • 去掉不必要的校验字段(如果物理链路可靠)。

我个人的习惯:在开发阶段用完整协议(带 CRC 和应答),方便调试。量产时切换到「快速模式」——去掉应答,只做帧尾校验。速度能提升 30%~50%。

1.3 驱动能力:信号到了,MCU 接不住

这个维度最容易被忽略。很多人觉得波特率设高了,线接好了,速度自然就快。其实不然。

线缆长度和寄生电容。

串口信号是电压型的。线缆越长,寄生电容越大,信号边沿就越缓。当波特率超过 115200 时,如果线长超过 1 米,上升沿可能已经占了一个 bit 的 30%~50%。这时候接收端采样到的电平就是错的。

我做过测试:3 米长的杜邦线,115200 波特率下,眼图已经闭合了 40%。

电平转换芯片的驱动能力。

很多开发板用 CH340G、CP2102 这类 USB 转串口芯片。它们的驱动能力有限,在 3.3V 电平下,最大只能稳定驱动 1 米左右的线缆。如果板子离烧录器远,信号质量会急剧下降。

MCU 内部 Flash 写入速度。

这是最容易被忽视的瓶颈。MCU 收到数据后,要写入 Flash。Flash 写入是有时序要求的——比如 STM32F103,单字节写入需要约 50μs,页写入(256 字节)需要约 1ms。

你算一下:如果每收到 1 个字节都要等 50μs,那 115200 波特率下,MCU 的处理速度反而成了瓶颈。因为 1 个字节的传输时间只有约 87μs,MCU 处理就要 50μs,留给协议处理的时间就很少了。

MCU 型号 Flash 写入方式 单次写入时间 最大吞吐量
STM32F103 半页写入 (128B) ~1ms ~128 KB/s
GD32F303 页写入 (256B) ~0.8ms ~320 KB/s
ESP32 块写入 (1024B) ~3ms ~341 KB/s

避坑指南:我曾经在一个项目里,把波特率从 115200 提到 460800,结果烧录时间反而变长了。查了半天才发现——MCU 的 Flash 写入速度跟不上,数据在缓冲区里堆积,导致溢出丢包。后来我把写入方式从单字节改成页写入,速度才真正提上来。

小结:三个维度,一个短板

烧录速度的瓶颈,说白了就是「木桶效应」。波特率、协议开销、驱动能力,哪个最差,哪个就是你的实际速度。

  • 波特率:时钟源精度和分频误差决定了你能跑多快。
  • 协议开销:帧格式、应答、校验,这些「隐形字节」吃掉了一半带宽。
  • 驱动能力:线缆、电平转换、Flash 写入速度,硬件底子决定了上限。