增加了Jlink GDB Server的支持,可以使用J-Scope 和 SEGGER RTT了。
2020年7月3日更新:改为了使用Cortex-Debug插件来进行调试;
详细研究了c_cpp_properties.json该如何配置,保证消灭红色波浪线;
修改了一些细节使其适应最新的软件;
1. openocd配置【希望使用Jlink GDB Server的,跳过这条即可】
直接在项目文件夹下新建一个openocd.cfg文件,内容如下
# 选择调试器为jlink source [find inte ** ce/jlink.cfg] #source [find inte ** ce/cmsis-dap.cfg] # 选择接口为SWD transport select swd # 选择目标芯片 source [find target/stm32f4x.cfg]openocd启动时,会自动在当前目录下寻找名为openocd.cfg的文件作为配置文件。
本配置文件中引用到的其他配置文件,都在openocd安装目录下的share/openocd/scripts目录下。其中inte ** ce目录下都是接口相关配置文件、target目录下都是芯片相关的配置文件。
2. 下载svd文件在<这个链接>寻找STM32F4的svd文件。CMSIS-SVD是CMSIS的一个组件,它包含完整微控制器系统(包括外设)的程序员视图的系统视图描述 XML 文件。简单来说,VS Code可以通过它来知道外设寄存器的地址分布,从而把寄存器内容展示到窗口中。
下载好的STM32F407.svd文件放在项目文件夹根目录即可。
3. 配置VS Code的调试功能【openocd版】在.vscode文件夹中新建一个launch.json,内容如下:
{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Cortex Debug", "cwd": "${workspaceRoot}", "executable": "${workspaceRoot}/build/${workspaceFolderBasename}.elf", "request": "launch", "type": "cortex-debug", "device":"STM32F407VE", //使用J-link GDB Server时必须;其他GBD Server时可选(有可能帮助自动选择SVD文件)。支持的设备见 "svdFile": "./STM32F407.svd", //svd文件,有这个文件才能查看寄存器的值,每个单片机都不同。可以在以下地址找到 "servertype": "openocd", //使用的GDB Server "configFiles": [ "${workspaceRoot}/openocd.cfg" ], "preLaunchTask": "build" "armToolchainPath": "C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update/bin/" } ] }解释几个重要选项:
"executable":编译出的二进制文件,也就是最终烧录到单片机中的,这里是elf文件。根据芯片的不同,可能产生不同的名称和后缀(例如TI的TM4C123芯片编译出来的名称是" ** in.axf")"request":可以选launch或attach。launch是指启动调试时同时开始执行程序;attcah是指程序已经在运行了,然后开始调试。我没过attach。"type":调试的类型,选cortex-debug,这是我们装的插件。其实也可以填cppdbg之类的,但是那样我们就得自己配置gdb了,配置起来将会非常麻烦。"device":目标芯片。如果你使用J-LINK GDB Server时必须要设置这个选项。然而我们的GDB Server是openocd,J-Link只用来连接芯片。"svdFile":svd文件的路径。"servertype":要选择的gdb server。我们用openocd。"configFiles":gdb server的配置文件路径。其实openocd会自动读当前目录下的openocd.cfg文件,这个选项不填也行。但是如果你想把openocd.cfg放在别处,就可以用这个选项指定配置文件的路径。"preLaunchTask":在启动调试前,预先执行的任务。在这里我们设置为前一篇文章里配置的build任务。这样每次调试前都会先自动编译好"armToolchainPath":工具链的路径。配置了全局环境变量的情况下好像不设置也行。【注】希望使用Jlink GDB Server的,直接看本系列第四篇文章。
4. 使用保存以上所有文件后,目录结构应该是这样:
直接按F5,或者左边的Debug按钮:
点击运行:
应该已经可以设置断点、单步执行和暂停了。
左边可以看到变量窗口、调用堆栈、断点、外设寄存器、CPU寄存器。
配置已经全部完成,开始你的全新体验吧!
好用的话你就点个赞呗!链接:
- 用VS Code开发STM32(一)——软件安装
- 用VS Code开发STM32(二)——编译
- 用VS Code开发STM32(三)——调试
- 用VS Code开发STM32(四)——增加SEGGER RTT日志输出支持
【注】虽然已经改为Cortex-Debug调试。但原来使用gdb调试的教程还是具有一定的学习价值,因此我不打算删除,而是留在下方,仅供参考。1.gdb调试的流程如图,PC上需要运行GDB和GDB Server两个程序,它们之间通过TCP/IP协议通讯。GDB Server通过USB连接仿真器(J-link,ST-link等),仿真器再通过JTAG、SWD等接口连接到MCU。
这样的结构的好处是,可以支持远程调试,比如说调试远程服务器上的代码,所以要用TCP/IP来通讯。当然更深的我说就说不下去了,因为不是我专业所学,我也不太懂。
在本例中,有如下对应关系:
GDB——————arm-none-eabi-gdb.exeGDB Server————OpenOCD仿真器——————JlinkMCU——————STM32F407ZGT62.openocd配置要运行openocd这个gdb server,需要配置如下几个参数:
用什么仿真器?(J-link, ST-link…)用什么接口?(JTAG, SWD…)目标芯片是什么?(STM32F4x, tm4c123g…)首先我们打开openocd的安装目录,打开share/openocd/scripts,里面有很多提前写好的配置文件。
target里存放目标芯片的配置文件,例如stm32f4.cfg
inte ** ce里存放仿真器相关的配置文件,例如jlink.cfg
当我们启动openocd时,可以用-f参数来指定一个配置文件。例如:
openocd –f inte ** ce/jlink.cfg –f target/stm32f4.cfg【注】配置仿真器的参数必须在配置目标MCU的参数之前,否则将报错。
如果我们不带参数启动,openocd就会自动查找当前目录下有没有名为openocd.cfg的文件,并把它作为配置文件来启动。因此,我们就在当前工程下创建一个名为openocd.cfg的文件。
我们选择使用Jlink,SWD接口,目标芯片为stm32f4x。
这样,我们连好板子上好电,直接在终端里敲openocd,即可启动。
openocd运行时,这个shell终端就被占用了,我们一会要新开一个终端。
【注】还记得上一节配置的build任务吗?其实这里也可以在tasks.json中配置一个openocd任务来启动openocd
3. openocd试运行openocd默认TCP/IP的3333端口作为gdb端口,4444作为telnet端口。在连接gdb之前,我们可以先用telnet连上试用一下。
如果你的电脑没有开启telnet功能,可以让小娜帮你打开“启用或关闭Windows功能”,然后在里面找到“telnet客户端”,启动即可。
然后点击终端窗口右上角的“+”号新建一个终端,输入
telnet localhost 4444就连接到本机的4444端口,也就是GDB Server了。
在GDB Server上,我们可以直接执行一些操作,例如烧写程序(支持hex,bin等),挂起(halt,不挂起不能烧写flash),reset,或者擦除flash等,具体可查阅openocd的手册。
下面演示了reset,挂起,烧写hex文件最后退出telnet连接的流程:
4.用gdb连接上openocd(1)直接启动gdb,参数为编译好的调试文件(.elf)(2)使gdb连接上openocd前面已经说过openocd留给gdb的TCP/IP端口是3333,因此输入:
target remote localhost:3333(3)下载代码和之前一样的流程,要先reset,再halt,最后下载代码。
后面就和普通的gdb一样操作了,加断点,单步运行什么的,网上可以搜到很多教程。
【注】最后记得输入q来退出gdb,以免影响后面的配置。
5.配置VS Code的调试功能大家使用VS Code,肯定是图方便,图好看。所以我肯定不会让大家靠敲命令来调试,这样岂不是开倒车,还不如用回keil。因此,这里要配置VS Code的调试功能,相当于对gdb的一个图形化吧。
在VS Code内选择debug(就是左边那个虫子图标),选择“添加配置”,类型为GDB。就会在.vscode文件夹下生成launch.json配置文件。
按照下面来配置:
{ "version": "0.2.0", "configurations": [ { "name": "ARM Debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/${workspaceRootFolderName}.elf", // 要调试的程序(在下面的参数中指定了,这里的没有意义) "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, // 调试时是否显示控制台窗口 "MIMode": "gdb", "miDebuggerPath": "C:\\Program Files (x86)\\GNU Tools Arm Embedded\\7 2018-q2-update\\bin\\arm-none-eabi-gdb.exe", //调试工具原始路径 "targetArchitecture": "arm", //目标架构,此参数必须要有 "setupCom ** nds": [ // 进入GDB以后,自动执行的一些配置 { "description": "选择调试文件(.elf)到gdb", "text": "file D:/Project/STM32HAL/controller/build/controller.elf", //此处不能使用${workspaceFolder},因为windows下分隔符是'\\',gdb识别不出来 "ignoreFailures": false }, { "description": "连接GDB Server", "text": "target remote localhost:3333", "ignoreFailures": false }, { "description": "Reset MCU", "text": "monitor reset", "ignoreFailures": false }, { "description": "Halt", "text": "monitor halt", "ignoreFailures": false }, { "description":"下载代码到MCU", "text": "load" , "ignoreFailures": false } ], "preLaunchTask": "build", // 在调试前预先执行的任务,此处是tasks.json中的 } ] }可以看到,setupCom ** nds里面就是我们之前试用gdb时操作过的流程:连接GDB Server——reset——halt——下载代码。
而preLaunchTask中是我们之前在tasks.json中配置的build任务。它可以让我们每次调试时都先编译一遍。
保存后,随便打几个断点,按下F5,就可以快乐调试了。可以看到功能还是很齐全的。
【注】这里有一个问题我一直没有解决,就是setupCom ** nds里,用file选择调试用的elf文件时,必须用文件的绝对路径。我试过用${workspaceFolder}/build/xxx.elf和./build/xxx.elf都不行,都找不到文件,不知道是不是windows路径分割符是”\\”导致的,希望知道的大佬能在评论区告诉我一下。