[arduino]ArduinoISP, Hex & Bootloader(视频)

ArduinoISP

ArduinoISP 是直接在Arduino基础上实现的ISP(In-Sytem Programmer)编程器,源码包含在 Arduino 开发环境的示例代码中,不过一般不算太新,其代码托管在https://github.com/rsbohn/ArduinoISP官方教程提供连接方法。除了可以实现bootloader的下载以及以及熔丝位的设置,还可以配合avrdude,实现基本对AVR芯片的所有FLASH、EEPROM、FUSE的设置,是一个功能相对完备的AVR编程器。

接线图:

Photobucket

两片Arduino之间SPI接口基本实现了一对一的连接,除了从机的RST是接到ISP的第10脚。ISP这边在RST和GND之间,需要接上一个10uF的电容,以抵消复位电容。

Photobucket

Bootloader,顾名思义是芯片系统启动(复位)以后首先加载并运行的程序,位于AVR芯片Flash的末尾,其起始位置(大小),根据熔丝设置而定,在Arduino平台上,UNO是用的是optiboot的bootloader,大小只有256word(512byte),因为其精简的尺寸,所以其只能进行对flash中非bootloader区段的烧写,而无法对其自身以及熔丝位进行设置。因为所谓常用的基于ATmega328p的Arduino平台来说,基本就是一片预烧写好bootloader和熔丝位的AVR芯片,配合或多或少的外围电路。optiboot能实现flash的下载就已经足够满足一般环境下的使用。

而对于一不小心bootloader丢失,或者是刚买的空芯片来说,要将其在一般arduino开发环境下可用,就需要通过外部编程器的辅助,对于arduino的玩家来说,用另外一片UNO就能制作成这样的编程器,也就是ArduinoISP。

但是注意的是,如果使用ADE中的“Upload using Programmer”功能通过ArduinoISP下载程序(准确的说,是源代码经编译器编译得来的hex文件),因为是写入的Hex文件中并不会自动包含bootloader,所以原有的bootloader区会被FF覆盖,bootloader就此消失。我们来看看,hex文件的内容。

hex clip

正如Intel Hex的wiki 所示,hex文件其实是普通二进制文件(bin)的文本表达。hex和bin之间是可以实现相互转换的。二进制文件中包含不可打印的字符,所以一般需要使用特殊的工具进行浏览,比方说,hexdump,od,ultraedit,editplus等等。而hex文件全部由可打印字符构成,一般数据,从左到右为“:[字节数|1][地址|2][类型|1][数据|字节数][校验位|1]”。vim对hex文件的代码高亮做得很不错,几段分得很清楚,“|”左边指的是数据定义,右边值得是该段数据所占的字节数,其中每个字节由两个字符以十六进制表示。

hex文件的大部分数据都是由类型为00的数据构成,在文件末尾行,会有一行“:00000001FF”表示数据结束。分别查看bootloader和一般程序的hex文件,可以发现,自己写的程序编译出来的hex,数据起始位置从0x0000开始,而optiboot_atmega328.hex的起始位置从0x7e00开始。自己的hex文件中,并不会包含这段数据,所以会用0xff进行覆盖。

所以,一般情况下,使用编程器下载程序后,芯片就不能再像一般的arduino那样从USB串口下载程序。在一般环境下,制作预烧写好bootloader和应用程序的arduino作品,就需要两个步骤:首先,使用ISP烧写好bootloader和熔丝位;再使用串口进行连接,再使用正常的方法下载程序。能不能把两步合并起来呢?

当然可以,在视频中,我用到了一个appendBT的脚本。用于连接应用程序的hex和bootloader。其实这个任务可以在所有的文本编辑器中实现:删去应用程序hex的最后一行结束标记。贴上相应bootloader的hex文件。我在脚本中,还删去了表示bootloader起始区段的倒数第二行。因为,两个字节可以表示0x10000个地址,也就是说可以表示64k的flash数据,而这对于我们目前使用的ATmega8,ATmega168,ATmega328都足够了,显得多余。如果是要给Mega2560之类的烧写数据,则还需要另一番研究。

脚本中使用了gdialog工具,弹出gnome的选择对话框,而且不影响在标准输出stdout上的文本输出,所以这个脚本基本只使用于ubuntu之类的使用gnome的linux桌面系统。

制作好二合一的hex文件,接下来就使用avrdude配合arduinoISP实现一次性烧写。

avrdude -p m328p -c stk500v1 -P /dev/ttyACM0 -b 19200 -U flash:w:hex文件路径:i

avrdude的调用,我在《[raspberry pi|arduino]用ssh远程烧写arduino》一文中也提到过。

视频介绍:这回内容比较多,所以比较长……

视频中忽略了两点:

  1. 设置熔丝位的操作在burnloader中就完成了,后面再也没有设置熔丝位的操作,熔丝位也一样可以在avrdude中设置,ADE其实也是在后台盗用avrdude实现,程序的烧写
  2. 其实视频中调用的avrdude的,并不是ADE中自带的那个,版本可能更新一些。在命令行中直接调用avrdude中位于”/usr/bin/”中,而不是在ADE目录内的那个。

视频中出现的 Arduino UNO 由圣源电子提供。

关于aGuegu

阿古 真名:官微宏,技术Geek,玩Arduino,玩Linux,爱Google,爱开源;现居福州
此条目发表在内功心法分类目录,贴了, , , , , , 标签。将固定链接加入收藏夹。
  • Richard

    如果我直接用ISP烧写没有和bootlaoder合并的HEX,功能是正常的,只是不可以通过串口重写下载程序?这样理解有错吗?BOOTLOADER除了可以使AVR单片机实现串口下载,还有其他功能吗?

  • Richard

    还有就是图片挂了,看不到。