Changchun Master Li

使用 gdb 调试 arduino uno 的一点人生经验

2018-06-21

arduino 现在已是大行其道,但玩玩还行,真正使用中有很多不便之处。其中,最影响我的一点就是调试很麻烦。以前我一直用avr模拟器simavr来调试,但缺点很明显,首先模拟器本身bug很多,而且无法方便的连接外设,聊胜于无。

子曰,工欲善其事,必先利其器,我们需要在 arduino 上使用 gdb 这种功能强大的东西。经过我的不懈努力,终于在 datasheet 上找到了线索(Atmel-42735B-ATmega328/P_Datasheet_Complete-11/2016 p327.),atmega328p 是支持 debugWIRE 的,有希望了!

下面记录一下我的一点用 gdb 调 arduino 的经验

准备

硬件

* arduino uno 兼容板
* 支持 debugWIRE 协议的仿真器

arduino uno 兼容板淘宝上买三十多块就可以用了。但别用二十几块的“改进版”,所谓“改进版”就是将 usb 转 ttl 芯片由 atmega16u2 替换为便宜的 ch340。寨板可能就不会引出 RESET EN 焊点,影响进一步操作。不过这种“改进”还是值得鼓励的,atmega16u2放这也是大材小用,ch340才更接地气,我国劳动人民又一次用勤劳和智慧造福了自己(一个正品能买十个山寨,太强大)。

支持 debugWIRE 协议的调试器有很多,我感觉用的比较多的是 avr dragon 和 jtagice mkii。我用的 mkii,原厂的太贵了所以从一家叫做“野芯科技”的店买了个高仿。。。据说可以上 avr studio,只能说技术太牛逼。

软件

* arduino IDE
* avrdude
* avarice
* avr-gdb

硬件操作

debugWIRE 接线

官网上说 debugWIRE 是 Atmel 公司为引脚少的单片机设计的,它只需要接上 RESET 一个脚就可以用了,半双工双向异步通信。

虽然一根线就能用,但我们还是将六针 SPI 接到 arduino 的引出的 ICSP 排针上,方便用 mkii 作为 isp 下载。这样,无论使用 mkii 进行下载还是调试,都不需要改变电路。

arduino schematic 割脉

连接好 debugWIRE 后,其实还是不能愉快使用的,笔者在这里卡了很久,屡战屡败。其实原因就在 arduino 的电路里, reset pin 接到两个东西上,一个是通过一个电容接到 16u2 的 PD7 上,另一个通过电阻 RN1D 接到 +5V 上。

通过这种设置,当 PD7 拉低时,由于电容的作用 RESET 也会瞬间拉低,之后电容缓慢充电,RESET 电压缓慢提升至 5V。网上有人说这样做的目的是为了消除抖动,我想这也是通过精确设置简化代码的办法(PD7只需要关心拉低就可以)。

所以,我们需要将 RESET EN 的连线割断,以防电容干扰 debugWIRE 的通信。

割脉成功的标识就是 arduino 不能自动复位了,用串口是无法烧程序的。

至此,硬件上的准备已全部完成。

软件操作

programmer

不用原本的串口烧程序,我们只能用编程器了,但如果是用较老的 arduino IDE,则并不支持 JTAGICE MKII。没关系,打开 arduino/hardware/arduino/programmers.txt 加上下面几行就搞定了。

1
2
3
4
# mkii
jtagicemkii.name=JTAGICE mkII
jtagicemkii.communication=usb
jtagicemkii.protocol=jtag2isp

接下来从 Tools -> Programmer -> JTAGICE MKII 就可以选择 MKII 作为编程器了。

弄个 demo,点一下 upload,so easy。

进入 gdb

首先,设置 熔丝位,使能 DWEN。

1
avrdude -c jtag2isp -p m328p -P usb -U hfuse:w:0x9E:m

然后,启动 avarice 作为 gdb 和 仿真器的接口

1
avarice -j usb -w -P atmega328p :4242

最后,启动 gdb,可以在log中找到 elf 文件的位置

1
gdb -ex "target remote :4242" -ex "set architecture avr" -ex "file /tmp/buildxxxx.elf"

这编起程来就很舒服了

重新烧程序的时候不要忘记清除 DWEN

1
avrdude -c jtag2isp -p m328p -P usb -U hfuse:w:0xDE:m

未解之谜

同时产生的问题列在这里,高手可以帮我解答一下

1. mac os x 下的bug
    
1
2
3
4
5
6
AVaRICE version 2.13svn20160229, Jun 16 2018 16:28:10

JTAG config starting.
Assertion failed: (ctx->pollfds_cnt >= internal_nfds), function handle_events, file io.c, line 2116.
[1] 43313 abort avarice -j usb -w -P atmega328p :4242

2. gdb看不到bootloader,讲道理,应该在 flash 0x7e00 的地方 3. gdb 给地址增加一个 0x800000 的 offset。虽然我知道这是 SRAM 的位置,但有时候我就是想看flash啊 4. gdb dump 命令失效

待解之谜

16u2这下用不到了,看看能不能干点别的

尝试一下mega2560原生jtag接口

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章