前文讲到zephyr内核编译后在stm32-f411re nucleo平台上运行以及调试,其实除了上文提到的这款st平台,最新的zphyer sdk已经支持很多种开源硬件开发板,arduino-due就是其中的另一块.不过与st平台不同的是,arduino-due并没有st-link那样的板载调试器供开发调试,所以调试时需要连接调试器进行调试,本文就介绍如何使用jlink和openOCD来调试运行zephyr内核的arduino-due平台.
开发环境:
ubuntu-14.04, kernel 4.4.0
arduino-due开发板
segger j-link adaptor. (固件v9.4, clone版某宝采购),支持swd+jtag
OpenOCD v1.0版
步骤
如何下载zephyr内核代码,准备开发环境前文有讲述,这里不再详细叙述,直接进编译步骤.
step 1: 编译运行于arduino_due开发版的zephyr内核
执行完环境变量初始化步骤后, 进入到zephyr/samples/hello_world目录,执行 make BOARD=arduino_due
./outdir/arduino_due/zephyr.bin就是要烧写进flash的二进制文件.
step2: 烧写:
连接host PC和arduino平台, Micro-B口连接到目标板的programing port, 也就是距离电源口近的那个口.
连接后,如果一切顺利,/dev/目录下会生成 /dev/ttyACM0,这个是usb虚拟的串口设备节点.
接着执行下面的命令,设置 ttyACM0设备的波特率为1200, 根据平台手册,1200波特率为执行erase flash必须的参数配置.
stty -F /dev/ttyACM0 speed 1200 cs8 -cstopb -parenb
波特率配置成功后,在hello_word目录下,执行命令
bossac -p ttyACM0 -e -w -v -b ./outdir/arduino_due/zephyr.bin
进行平台烧录, bossac是用于arduion_due的开源烧录工具, 其代码可以到github下载:
git clone https://github.com/shumatech/BOSSA.git
经过简单的./configure, make,install后,即可使用.
下图展示的是烧写过程:
烧写完成后,新开一个shell会话,执行 sudo minicom -D /dev/ttyACM0 -o命令连接串口, 然后按平台复位键对平台进行复位, 便可以在串口终端看到内核的打印输出:
注意: 使用usb串口看打印,执行烧写命令时候必须关闭minicom和/dev/ttyACM0的连接,否则会有干扰导致烧录失败(“SAM-BA operation failed”,要避免此问题可以使用usb转串口的板卡跳线到平台tx0,gnd,miniCOM连接/dev/ttyUSBx即可(原因可能是原理图上tx0和 ATMEGA16U2-MU tx是同一个网络,有冲突).
debug环境搭建:
本文介绍的调试链路示意图如下所示:
先上图:
关于跳线连接,按照arduino-due原理图和jlink引脚排布图逐一连接 tms, tck, tdi, tdo四条线, due的jtag口非常小, 要注意跳线焊接处不要短路.
openOCD自带的jlink.cfg无法直接使用,报错大部分是因为脚本漏掉某些配置,google了老半天,再加上自己的一些理解, 修改成下面这样子:
OpenOCD tcl目录自带的配置文件jlink.cfg原本只有一行(第7行),一开始时openOCD报告很多error 和warning,后来几经周折,逐个的去google, baidu找答案,CPU tap配置时考虑到due使用的是sam3x8e主控,看了一下只有target/at91sam3XXX.cfg比较靠谱, 一步步的修改成上图的样子,过程不再赘述.修改完毕后,执行 命令 openocd -f ./interface/jlink.cfg, 如下图所示,无错误无警告, 表示连接成功
新开一个shell, 执行gdb会话, 如下图的命令序列.
ok,gdb和目标平台连接成功,此时可以执行基本的gdb命令调试zephyr内核了, 是不是很爽?
arduino_due平台有上的自带10 pin的mini jtag connector公口,国内很难找到与之对应的connector, 所以试验的时候跳了线, swd口和jtag口是复用pin的,本试验原本打算使用jtag口功能,所以拉了四根主要信号线(TMS,TDO,TDI, TCK),
对应jlink.cfg文件
transport select jtag
后面在gdb调试的时候, 发现jtag连接不是很稳定,openOCD与gdb的连接经常掉线,于是就改jlink.cfg为swd模式尝试,没想到这一试结果非常满意.
#transport select jtag
transport select swd
现在还不清楚jtag模式为什么不稳定,猜测或许是有些线没有接上,比如jtag规定的reset, vcc, gnd等等,这也要看tap, 有些主控仅仅接上面4条线即可.
swd模式下,需要的引脚数目比jtag要少,主要有两条
MCU的JTMS/SWDIO接JTAG口的TMS;
MCU的JTCK/SWCLK接JTAG口的TCK。
jtag和swd接口这样的定义,无论是配置采用swd或者jtag模式,都不需要重新跳线,两种模式切换不依赖硬件电路,非常方便.发现jlink脚本只要对jlink.cfg稍作修改,注明调试接口,其他配置用 -f 选项再次导入文件.
执行openOCD时候,用-f选项后跟配置文件, 即可在jlink.cfg文件的基础上再导入额外配置, 变成 openocd -f interface/jlink.cfg -f target/at91sam3XXX.cfg (或者openocd -f interface/jlink.cfg -f board/atmel_sam3x_ek.cfg 导入板级配置文件也可)
openOCD -f 选项可以多次使用,可以使多个的配置文件生效.
openOCD连接成功后,默认情况下并不复位CPU,直接gdb登录3333端口连接,会出现"WARNING! The target is already running. >All changes GDB did to registers will be discarded! Waiting for target to halt."警告, 如果想从_reset处从头开始debug, 可以给利用 >openOCD的 -c 选项发送复位命令给处理器,完整的命令是 openocd -f ./tcl/interface/jlink.cfg -f ./tcl/target/at91sam3XXX.cfg -c >‘init’ -c ‘reset halt’, 如果是attach模式,只执行 init, halt 两个命令就可以了.
ok ,done.
J-link接口定义
|仿真器端口|连接目标板|备注|
|--------|---------|----|
|1. VCC |MCU电源VCC| VCC|
|2. VCC |MCU电源VCC| VCC|
|3. TRST| TRST| Test ReSeT/ pin
|4. GND |GND或悬空|
|5. TDI |TDI |Test Data In pin
|6. GND |GND或悬空|
|7. TMS|SWIO|TMS, SWIO JTAG:Test Mode State pin ; SWD: Data I/O pin|
|8. GND|GND或悬空|
|9. TCLK| SWCLK| TMS, SWCLK JTAG: Test Clock pin ; SWD: Clock pin|
|10. GND| GND或悬空|
|11. RTCK| RTCK|
|12. GND| GND或悬空|
|13. TDO| TDO| Test Data Out pin|
|14. GND| GND或悬空|
|15. RESET| RESET| RSTIN pin|
|16. GND| GND或悬空|
|17. NC| NC |
|18. GND| GND或悬空|
|19. NC| NC |
|20. GND| GND或悬空|
segger jlink引脚排列: