Arduino 烧录 Boot Loader

Boot Loader,或「引导程序」,是一个特殊的固件。对于 Arduino 单片机而言,每次按下复位键,或者编译上传新的程序时,都会先加载烧录的 Boot Loader;随后 Boot Loader 再来执行程序,或者根据电脑的指令,将新程序的代码写入闪存中。
在我们平常使用的 Arduino 开发板上,Boot Loader 是预置好的,用户只需要写程序然后上传,而不用关心其它的问题。但在有些情况下,还是需要用户自己来烧录 Boot Loader。例如,Arduino Nano 板有新旧两种 Boot Loader,升级旧的固件就需要重新烧录 Boot Loader。一些第三方厂家根据 Arduino 开源的电路图修改制造的开发板,也需要向其中的 ATmega 微控制器刷 Boot Loader 才能正常工作。

烧录 Boot Loader 的方式有很多种。在 Arduino IDE 的菜单中,选择「工具」 → 「编程器」,即可查看官方支持的方法:

本文将介绍其中的一种方法:使用另一块 Arduino 开发板,作为 ISP(即 in-system programmer),来进行烧录。为了避免歧义,我们将功能正常的版称为「ISP 板」,而需要烧录 Boot Loader 的版称为「空板」。在具体的例子中,将一块「Arduino Leonardo」作为「ISP 板」,一块「Arduino Mega 2560」作为「空板」。

上传程序

将「ISP 板」连接到电脑,并移除其它所有线缆。打开 Arduino IDE,在菜单中选择「文件」 → 「示例」 → 「11.ArduinoISP」 → 「ArduinoISP」。这是一个将 Arduino 变为 AVRISP 的程序,将其编译上传到「ISP 板」即可。

连接线缆

接下来需要连接「ISP 板」和「空板」,这需要用到六根杜邦线。为了避免出现问题,务必在断电(拔掉「ISP 板」上的 USB 线缆等任何电源)的情况下操作。
首先,我们来确定要连接的引脚 ——ICSP 接口。ICSP 即 In Circuit Serial Programming,它的针脚定义如下图所示

在每块 Arduino 板靠近微控制器的地方,都能找到这个 2x3 的 ICSP 接口。注意,不同 Arduino 板 ICSP 接口的方向可能不同,这时需要先确定 1 号引脚的位置。有的开发板会直接印上数字「1」标记 1 号引脚;有的会在电路板上注明 ICSP 字样,在它附近用一个小圆圈指示 1 号引脚。

对于 Mega 2560 和 UNO 这些使用了 ATmega8U2 或 ATmega16U2 芯片的 Arduino 板,在靠近 USB 接口处还有另一个 2x3 的接口,这是用来给 USB 芯片烧录固件的,不要弄错了。

随后,将「ISP 板」和「空板」上的 ICSP 接口一一对应地连接起来,除了 5 号引脚,即 RST 引脚。将「ISP 板」上的数字 I/O 10 连接到「空板」上 ICSP 的 5 号引脚,如下图所示

完成前面的步骤后,就可以来进行烧录了。

进行烧录

再次将「ISP 板」连接到电脑,这时「空板」将通过「ISP 板」获得供电,电源指示灯应当亮起(否则就需要再确认一下连线的问题)。在 Arduino IDE 的菜单中,点击「工具」,设置「开发板」和「处理器」为「空板」的型号,下方的「编程器」选择「Arduino as ISP」(如果「ISP 板」的微控制器是 ATmega32U4,例如 Arduino Leonardo,则选择「Arduino as ISP (ATmega32U4)」)。
设置完成后,点击最下方的「烧录引导程序」,Arduino IDE 会调用 avrdude 自动完成烧录过程,耐心等待就行了。

报错

如果在烧录过程中,Arduino IDE 提示「烧录引导程序出错」,并且控制台显示

1
avrdude: Yikes! Invalid device signature.

这时可以开启详细报错来 debug。打开 Arduino IDE 的首选项,勾选「显示详细输出」后的两个选项。

随后,再次进行烧录,控制台中会显示报错信息,例如

1
avrdude: Device signature = 0x000000

或者

1
avrdude: Device signature = 0xffffff (probably .avr8x_mega) (retrying)

这可能是接线错误导致,也有可能是芯片损坏了。具体的错误原因本文无法解答,如果确实出现了这种情况,可以求助于国内外的 Arduino 社区。


参考文章:
https://www.arduino.cc/en/Hacking/Bootloader
https://www.arduino.cc/en/tutorial/arduinoISP