MacOS下通过GDB开发嵌入式程序

最近换了MacOS平台,之前常用的IAR除了用虚拟机似乎是没有什么办法可以在MAC中使用了,而我又算是一名嵌入式程序开发着,所以还是有在MAC中开发嵌入式程序的需求。

因为不能用IAR,所以首先要将编译平台换到GCC上面,这里可以直接在ARM官网下载相应的安装包,安装包下载完成之后,只需要设置好相应的PATH环境变量就可以直接使用了。工程的建立也不能在IAR中进行,而是需要编写相应的MakeFile通过GCC进行编译,MakeFile是make命令的输入文件,相当于一个工程配置文件,它可以对我们的源文件进行监控,只在需要的时候增量编译C程序,得到的结果可以用于调试或者直接下载到芯片内部运行。有关于MakeFile的语法,因为比较复杂,这里就不做赘述了。

其实MAC中问题的关键在于调试,而不是程序的编译,对于调试,我现在探索到了以下几种方法:

Ozone调试

这个是从IAR切换之后最为方便的,也是上手最快的调试方式,Ozone调试必须使用Jlink调试器,软件本身是免费的,并且支持三大平台,软件用起来比较方便,但是就是硬件有点贵,并且每次都要带个调试器,也不是很方便。

ozone.PNG

Ozone调试界面和IAR,Ozone调试的时候,偶尔会碰到指令乱跳的情况,这个可能是和编译优化等有关系,具体的原因我也没有细究。其实,这个软件功能真的是挺齐全的,比如可以查看变量,程序执行计数,堆栈分析,Jlink接口,内存查看等等,也就是一般调试该有的功能它都有。并且添加相应寄存器的svd文件之后,可以直接查看模块的寄存器配置信息,十分方便。

这个软件唯一让我不爽的是必须使用Jlink调试软件,或者用Seggeropensda,对于一些比较新的芯片,SEGGER的opensda可能并不支持,或者并没有板载调试器的固件,而用Jlink工具,每次调试的时候都要带一个大个的Jlink debugger,这个确实十分影响使用体验。

Jlink自带的GDB软件

其实既然用到了ARM的GCC工具,就不可避免的需要了解一下arm的gdb工具,gdb是Linux下常用的调试软件,其实很多调试软件都是基于GDB这个工具实现调试的,比如我们之前常用的Eclipse就是通过GDB下载调试的,这个工具是基于命令行的,上手稍微有点复杂,不过用多了,其实也挺方便,基本的功能也都是支持的。不过用Jlink自带的GDB服务器调试,依然摆脱不了大大的调试器,并且方便性还不如Ozone,所以这条调试方法也并不靠谱。

jlinkGDB.PNG

CMSIS-DAP调试

ARM其实还是很靠谱的,要出东西就出全套,比如针对嵌入式调试,ARM就推出了一个CMSIS-DAP的调试方案,并且是完全开源的,用户可以根据需要将这个调试工具porting到自己的debugger芯片上,不过一般厂家也会提供修改好的下载固件。IAR本身就可以通过CMSIS-DAP进行调试。

CMSIS-DAP调试是一个比较好的解决方案,因为它通过一条USB线就可以实现软件调试,串口收发和电源供电,使用起来特别方便。

不过在MACOS中,因为不能用IAR软件,所以要想使用CMSIS-DAP调试,我们还需要借助一个pyocd的软件,这个可以直接在pip源中进行安装:

sudo -H pip3 install pyocd

安装完成之后,连接上我们的开发板之后就以通过如下命令查看固件支持芯片了:

$ pyocd list --targets
  Name    Vendor    Part Number    Families   Source
-----------------------------------------------------
  k22f    NXP        K22F                     builtin
  k22fa12 NXP        K22FA12                  builtin
  k28f15  NXP        K28F15                   builtin
  ....

上面的列表中可以看出固件支持的芯片,里面如果有我们的芯片,那么就可以通过如下的命令开启一个GDB的服务:

─$ pyocd gdbserver -t mimxrt1050 --allow-remote --persist
0000533:WARNING:common:STLink and CMSIS-DAPv2 probes are not supported because no libusb library was found.
0000541:INFO:board:Target type is mimxrt1050
0000599:INFO:dap:DP IDR = 0x6ba02477 (v2 rev6)
0000630:INFO:ap:AP#0 IDR = 0x84770001 (AHB-AP var0 rev8)
0000657:INFO:ap:AP#1 IDR = 0x24770011 (AHB-AP var1 rev2)
0000683:INFO:ap:AP#2 IDR = 0x54770002 (APB-AP var0 rev5)
0000752:INFO:rom_table:AP#0 ROM table #0 @ 0xe00fd000 (designer=00e part=88c)
0000772:INFO:rom_table:[0]<e00fe000:ROM class=1 designer=43b part=4c8>
0000772:INFO:rom_table:  AP#0 ROM table #1 @ 0xe00fe000 (designer=43b part=4c8)
0000788:INFO:rom_table:  [0]<e00ff000:ROM class=1 designer=43b part=4c7>
0000795:INFO:rom_table:    AP#0 ROM table #2 @ 0xe00ff000 (designer=43b part=4c7)
0000807:INFO:rom_table:    [0]<e000e000:SCS-M4 class=14 designer=43b part=00c>
0000820:INFO:rom_table:    [1]<e0001000:DWT class=14 designer=43b part=002>
0000834:INFO:rom_table:    [2]<e0002000:FPB class=14 designer=43b part=00e>
0000848:INFO:rom_table:    [3]<e0000000:ITM class=14 designer=43b part=001>
0000861:INFO:rom_table:  [1]<e0041000:ETM-M7 class=9 designer=43b part=975 devtype=13 archid=4a13 devid=0:0:0>
0000928:INFO:rom_table:  [2]<e0042000:CTI class=9 designer=43b part=906 devtype=14 archid=0000 devid=0:0:40800>
0000944:INFO:rom_table:[1]<e0043000:CSTF class=9 designer=43b part=908 devtype=12 archid=0000 devid=0:0:28>
0000965:ERROR:ap:Transfer error while reading AP#1 ROM table:
0000980:INFO:cortex_m:CPU core #0 is Cortex-M7 r1p2
0001023:INFO:cortex_m:FPU present: FPv5
0001051:INFO:dwt:4 hardware watchpoints
0001066:INFO:fpb:8 hardware breakpoints, 1 literal comparators
0001176:INFO:server:Semihost server started on port 4444
0001177:INFO:gdbserver:GDB server started on port 3333

上述就是开启了一个IMXRT1050的调试,这样我们就可以通过arm gdb连接我们的服务器进行调试了,虽然只能是命令行调试,但是聊胜于无,习惯了之后也是非常方便的,并且,现在IAR越来越臃肿,而这个命令行的小工具运行很快,比起IAR动不动就死机,也能节省不少时间的。

总结

这里列出了几种MAC下面的嵌入式软件调试方式,分析了各种调试的优缺点,最终我还是选择了命令行下GDB+CMSIS-DAP的调试方式,习惯之后用起来感觉还不错,至于GUI界面,其实可以尝试配置VScode实现,这个后面有需求在研究吧。


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

相关文章

已有 2 条评论
  1. Daniel

    Hi there! Following some troubles while using my own i.MXRT1020 EVK board, I reached your blog. I followed the steps provided by you and I am able to connect to the board and open a gdb session. When I try to "load" a FLASH resident program (led_blinky example) I have an output on pyocd terminal attesting the loading task (0019507:INFO:loader:Erased 16384 bytes (4 sectors), programmed 16384 bytes (4 pages), skipped 0 bytes (0 pages) at 8.26 kB/s). Nevertheless when I try to reset the board, the LED doesn't blink and I loose the connection to the board. To regain access I need to do a mass erase in Fuses boot mode and flash again through MCUXpressoIDE and in internal boot mode.

    Were you capable to flash the board through GDB/pyocd ?
    Thank you!

    Daniel 回复
    1. Major

      @Daniel

      Hi, does loading program to SRAM(TCM) works? I have not tried to download code to external flash via pyocd, for RT series, I always use the bootrom to download program. by the way, have you checked if boot mode configuration correct?

      Major 回复
发表新评论取消回复