电脑识别出了 USB 编程器,排线另一端的微控制器却仍然无法访问。AVRDUDE 的架构容纳了这种棘手的情况:编程器与目标芯片各有自己的标识,存储操作则指定两者之间要传递什么。沿着这些区分读下去,一条简短的上传命令就展开成了工作台上各个部件的说明。本文依据 AVRDUDE 8.1 的手册与配置文件展开。[1][2]
编译完成后,文件才交给 AVRDUDE
AVRDUDE 操作的是 AVR 微控制器的存储区。根据芯片和编程接口的组合,它可以读写闪存(flash)、EEPROM、熔丝位和锁定位。它既可以经由独立的硬件编程器访问目标芯片,也可以借助芯片上已经运行的引导程序(bootloader)完成访问。具体能执行哪些操作,取决于这组搭配。[1]
前面的构建过程有自己的职责。Pololu 的命令行示例先用 AVR GCC 编译 C 代码,经链接生成程序,再用 avr-objcopy 生成 Intel HEX 文件,之后才调用 AVRDUDE。示例程序还指定了驱动 LED 的引脚,以及延时函数所依据的时钟频率。[3]
刚烧录好的电路板毫无动静时,这种分工就显得很实际。即使上传成功,源代码是否选对了 LED 引脚仍要另行核实。程序可以完整无误地传入芯片,却仍带着对运行环境的错误假定。因此,排查还要回到构建过程与电路本身,即使最后一个看得见的动作是上传。
两个标识,一个连接地址
以通过 Pololu v2 编程器读取 ATmega32U4 的闪存为例。这里用 /dev/ttyACM0 代表编程器在 Linux 上实际使用的编程端口,命令如下:[1][2][3]
avrdude -c stk500v2 -p m32u4 -P /dev/ttyACM0 \
-U flash:r:before.hex:i
其中,-c 选择编程器协议,-p 标识目标微控制器,-P 选择主机端的连接。最后的操作将闪存读入 before.hex,采用 Intel HEX 格式。若要操作 EEPROM 等其他存储区,就要另行指定。[1]
这些名称对应着具体的设备安排。Pololu 编程器向电脑呈现一个兼容 STK500 的接口,其指南在 AVRDUDE 命令中使用 stk500v2,并区分了编程端口与用于普通串口通信的第二个端口。如果仅因第二个端口与第一个一起出现便选中它,访问到的就是同一台 USB 设备上的另一项服务。[3]
读取闪存所得文件的范围也很明确:它记录的是选定的存储区。要还原电路板的完整状态,还得分别考虑其他存储区与配置。命令本身已经说明,这份记录覆盖的只是其中一部分。
器件名称背后是一份硬件描述
配置文件为这些简短的名称补上了具体内容。在 8.1 版源码中,stk500v2 编程器条目指定了驱动类型和串口连接。与之分开的 m32u4 器件(part)条目标明芯片为 ATmega32U4,给出其签名字节,并描述闪存和 EEPROM。其中,闪存定义列出容量为 0x8000 字节,共 256 页;EEPROM 定义列出容量为 1,024 字节。[2]
更一般地说,AVRDUDE 的器件定义可以包含存储容量、页大小、编程指令和时序信息。编程器定义则描述通信方式以及支持的编程模式。芯片的存储布局和访问芯片的方式回答的是两类问题,因此也分别描述。[1]
这种分离也限定了扩展能力的范围。如果已有相应的编程机制,添加器件描述就能表达另一款芯片的要求。至于连接着的适配器,配置描述无法补上其硬件缺少的编程接口。手册明确提醒:即使某款编程器与某款器件分别受到支持,也不能保证两者的任意组合都能工作。[1]
排线上还有另一套时钟
Pololu 的故障排查指南将“无法连接编程器”和“无法连接目标 AVR”分开讨论。对于目标芯片一侧,指南指出要检查供电、接线和编程速度。本文讨论的是传统 ISP(在系统编程)连接,指南要求其 ISP 频率低于目标芯片时钟频率的四分之一。[3]
AVRDUDE 用不同的选项对应这两段连接:-b 控制串口连接的波特率,-B 则为支持该选项的编程器设置编程接口的位时钟。两项参数分别起作用,调整其中一项,另一项未必随之改变。[1]
设想 USB 通信正常,编程器也有响应,但芯片运行得比预期更慢。反复重试同一个固件文件,时序仍然不匹配。此时应当检查的是:在目标芯片的实际条件下,编程器能够与它交换哪些信息。与适配器成功通信,只确认了这段传输过程的前半程。
校验有确切的含义
AVRDUDE 通常会在写入后校验数据;-V 可以关闭这项检查。显式指定 v 存储操作,则会将选定的器件存储区与文件内容比较。擦除是另一项独立操作:传统 AVR 芯片的闪存写入可触发整片擦除;若器件的熔丝配置未设置为保留 EEPROM,擦除也可波及这部分存储。[1]
因此,熔丝位也值得单独说明。SparkFun 独立撰写的引导程序教程将熔丝设置、闪存映像和锁定位分开讲解。教程中的实例把熔丝值与特定电路板配置对应起来,其中包括时钟安排;同时提醒,这组值需要调整才能用于对应的 3.3 伏、8 MHz 版本。[4]
把这些资料放在一起,就能看清校验的价值及其适用范围。它给出的是有关已存数据的证据。功能检查回答另一组问题:程序是否启动,是否驱动了预定的引脚,以及能否配合所连接的硬件工作。对于维护 AVR 工装的小团队,将确切的器件、编程器、构建时的假定条件和存储操作随固件一并保存,日后便于重新核对这两类检查各自说明了什么。
最后再看照片中的两块板子。一块负责提供编程接口,另一块最终要运行写入的程序。AVRDUDE 把两者之间的通信过程展现得足够清楚,让人能够分辨哪一段已经连通,哪一段还在等待回应。
资料来源
- AVRDUDE 8.1 用户手册——简介、命令行选项、编程器定义与器件定义。
- AVRDUDE v8.1,src/avrdude.conf.in——固定于该版本的编程器与器件配置,含 stk500v2 和 m32u4。
- Pololu,USB AVR Programmer v2 用户指南——连接方式、独立串口、AVRDUDE 构建示例与目标端故障排查,尤其是第 4.5 节及第 5.1–5.6 节。
- SparkFun Learn,《安装 Arduino 引导程序》——独立撰写的实用教程,讲解引导程序安装、熔丝设置、闪存与锁定位。
- Pololu,USB AVR Programmer v2.1 图片库——本文照片来源,并确认图中连接 A-Star 32U4 Prime SV 的编程器为 v2。