0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键

目录

1.1-综述

2-vscode实现一键下载stm32

2.1-jlink的下载与擦除的makefile修改

2.2-stlink的下载与擦除的makefile修改

 2.3-提升一点效率:使用tasks.json配置用户任务(下拉菜单)

1-tasks.json干啥用的

2-如何创建tasks.json?

 3-tasks.json的文件编辑

4-tasks的使用方法

 2.4-再提升一点效率:使用keybindings.json配置快捷键

 1-keybindings.json可以配置自定义快捷键

 2-打开keybindings.json

 3-keybindings.json文件的编译

3-实现vscode里在线调试stm32

3.1-调试原理及分层结构

 3.2-配置settings.json用于在线调试

1-配置vscode的settings.json

 2-Cortex-Debug介绍

 3-launch.json用于配置vscode的调试设置

4-测试运行

 4.1-结论


1.1-综述

这里介绍如何在vscode下实现jlink/stlink下载及在线调试;使用前面博客里的工程(参见0503,0504两个博文)里的名为may12的project,硬件也还是NUCLEO-F429ZI。在开发中,除了使用vscode进行酷炫的代码编辑,工程组织外,还有本文的重点:使用vscode对目标板进行下载(擦除、下载、复位)及调试(单步,查看寄存器),以及配置快捷键方便一键执行,毕竟调试个bug烧写800遍也不是啥丢人的事。

note: 我并不打算写一个step-by-step的说明,我尽量扩展一些原理性的东西,增加理解,如果需要可以直接参考附录的链接去DIY作为辅助,视频信息量并不中心支撑对系统的理解,因为如果不懂原理任意一个bug都要花费数小时。当然建议视频与博文都看一下。

2-vscode实现一键下载stm32

下载的前置准备工作已经在 0503和0504两个博文里准备完毕,命令行都测试OK,接下来就是要把命令行放到makefile里,这样就可以在vscode的命令行里通过make指令调用这一大串命令行,等于一条vscode指令执行一串其他软件的功能;这是基础,是后面使用用户快捷键的基础。本章节的重点是编辑makefile文件+编辑tasks.json文件。

note: 先在vscode命令行中进行测试,确认运行正常后,放到makefile里。

2.1-jlink的下载与擦除的makefile修改

注意jlink只能用批处理文件,不能像stlink那样。参考  J-Link Commander - SEGGER Wiki ,所有jlink.exe指令的使用,注意批处理也只能先造一个文件,然后再执行文件,参考链接里给的例子也是如此。
在makefile添加如下两个rule,第一条是创建一个/build/ jlink_flash_file文件,其中 jlink_flash_file是文件名可以是任意字符,这个rule依赖.bin文件,第一行touch是创建脚本文件,文件名即 $@指的是target,第二行echo 是将device 名写入target, 第三行设置接口为SWD,速度为10Mhz,第三行是loadbin指令,第四行r复位,g运行,qc退出。第二条rule是调用JLink指令来执行这个脚本文件。
#1- First create a file with all commands
$(BUILD_DIR)/jlink_flash_file: $(BUILD_DIR)/$(TARGET).bin
    @touch $@
    @echo device $(DEVICE) >> $@
    @echo -e si 1 '\n' speed 10000 >> $@
    @echo loadbin $< 0x08000000 >> $@
    @echo -e r'\n'g'\n'qc'\n' >> $@
#2- Flash with J-Link
jflash: $(BUILD_DIR)/jlink_flash_file
    JLink -commanderscript $<

通过make jflash指令就可以测试下载,指令执行时会先检查/build/jlink_flash_file文件是否存在,不存在的话就调用第一条rule来创建它,

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第1张图片

 打开build/jlink_flash_file,文件里是这样的,如下图

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第2张图片

 同理,有的时候我们还需要全片擦除操作,脚本文件类似,只是第三行用erase指令,默认不给参数的话表示全片擦除

$(BUILD_DIR)/jlink_erase:
    @touch $@
    @echo device $(DEVICE) >> $@
    @echo -e si 1 '\n' speed 10000 >> $@
    @echo erase >> $@
    @echo -e r'\n'g'\n'qc'\n' >> $@

jerase: $(BUILD_DIR)/jlink_erase
    JLink -commanderscript $<

2.2-stlink的下载与擦除的makefile修改

st的下载指令要简单很多,一行搞定,在makefile里任意位置添加如下内容,这里是两条rule,第一条sterase,表示要擦除全片,因为是直接调用指令执行,所以没有任何依赖;第二条rule是stflash,依赖.bin文件存在,调用st-flash命令执行将bin文件下载到0x08000000的位置。

# st-util erase and flash
sterase:
    st-flash --freq=4000 erase

stflash: $(BUILD_DIR)/$(TARGET).bin
    st-flash --reset write $< 0x08000000

测试一下,在vscode的任意命令行里,打入make sterase 即可执行擦除,用时约半分钟,同理打入make stflash测试下载指令,下载完成后会自动复位运行,使用st进行下载的速度要远慢于使用jlink的速度。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第3张图片

 2.3-提升一点效率:使用tasks.json配置用户任务(下拉菜单)

1-tasks.json干啥用的

在这里( Tasks in Visual Studio Code)了解关于tasks.json的作用,简单来说,就是vscode设计的专门配置如何调用外部功能的接口,因为这些外部的功能如make, lint等是开发环节中的重要部分,而且大部分是命令行式的。这一段所描述的所有内容都可以在这个链接里找到,建议认真阅读原文,要查看具体字段如"group"使用说明可以直接在网页里搜索。再简单来说,有了tasks.json就可以配置用户自己的下接菜单。

2-如何创建tasks.json?

有两个方法,一、手动自己创建.vscode/tasks.json, 因为文件内容比较简单所以完全可以自己创建,省得记忆下面提到创建方法路径, 二、菜单的Terminal->configure tasks... 或者用CTRL+P 弹出输入框,输入‘>Task’列表显示一堆,选择“Tasks:Config Task”继续选择Creat tasks.json file from template 。 这里差别不大,因为我们只是要一个文件,然后里面内容删掉重写。

 3-tasks.json的文件编辑

针对stm32开发的用到的功能只是tasks.json中很简单的一块,这里一共定义了6个task,分别说明如下,

  1. 调用make指令执行编译,实际执行的命令行是‘make all -j4’调用4核全力执行

  2. 调用make指令执行清理工程,实际执行‘make clean’,删除build目录及内容

  3. jlink的下载,实际执行的是‘make -j4 jflash’

  4. jlink的擦除,实际执行的是‘make jerase’

  5. stlink的下载,实际执行的是 ‘make -j4 stflash’

  6. stlink的擦除,实际执行的是‘st-flash --freq=4000 erase’

这里注意,第6个task没有通过makefile执行,而是直接调用st-flash指令,当然也可以从makefile里执行,调用'make sterase'即可。这表明tasks.json可以让vscode调用任意外部功能,如make.exe和st-flash.exe。

{
    "version": "2.0.0",
    "tasks": [
        // MAKE(BUILD + CLEAN) 
        {
            "label": "task-build",
            "group": "build",
            "type": "shell",
            "command": "make",
            "args": [
                "all",
                "-j4"
            ]
        },
        {
            "label": "task-clean",
            "group": "build",
            "type": "shell",
            "command": "make",
            "args": ["clean"]
        },
        // JLINK (FLASH + ERASE)
        {
            "label": "task-jflash",
            "group": "build",
            "type": "shell",
            "command": "make",
            "args": [
                "-j4",
                "jflash"
            ]
        },
        {
            "label": "task-jerase",
            "group": "build",
            "type": "shell",
            "command": "make",
            "args": ["jerase"]
        },
        // STLINK (FLASH+ERASE)
        {
            "label": "task-stflash",
            "group": "build",
            "type": "shell",
            "command": "make",
            "args": ["-j4", "stflash"]
        },
        {
            "label": "task-sterase",
            "group": "build",
            "type": "shell",
            "command": "st-flash",
            "args": ["--freq=4000","erase"]
        },
    ]
}

4-tasks的使用方法

CTRL+SHIFT+B 或 Terminal->Run Build Task... 即可调出‘下拉菜单’,通过方向键选择并按回车执行。‘下拉菜单’中各项名称就是tasks.json中对应的"label"参数配置的。‘下拉菜单’的执行效果等同于键入对应的命令行。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第4张图片

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第5张图片

 2.4-再提升一点效率:使用keybindings.json配置快捷键

 1-keybindings.json可以配置自定义快捷键

上面的tasks是方便了一些,但是还不够,因为比如之前用KEIL的,是可以直接按F7编译,按F8下载的,所以为了让开发更简单一点,这里研究一下如何配置vscode的快捷键,注意和所有工程相关的配置不一样,快捷键的配置是工程无关的。

更多信息可以在 链接( Tasks in Visual Studio Code)里找到,搜索关键字“Binding keyboard shortcuts to tasks”,关于vscode的全局的快捷键的使用在这个链接( Visual Studio Code Key Bindings)里查询,这里建议初学者尤其是对系统原理不清楚的,尽量少用快捷键。

下面截图说明用户的keybindings.json文件的位置在哪里可以找到。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第6张图片

 2-打开keybindings.json

有两个方法打开keybindings.json 。可以用快捷键 (Ctrl+Shift+P) 选择Preferences: Open Keyboard Shortcuts (JSON)打开;或者File->Preferences->Keyboard shortcuts再点下图所示的图标打开。(此截图来自对应官网)

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第7张图片

 3-keybindings.json文件的编译

// Place your key bindings in this file to override the defaults
[
    {
        "key": "ctrl+f6",
        "command": "workbench.action.tasks.runTask",
        "args": "task-clean"
    } ,
    {
        "key": "f6",
        "command": "workbench.action.tasks.runTask",
        "args": "task-build"
    },
    
    //for jlink
    {
        "key": "ctrl+f7",
        "command": "workbench.action.tasks.runTask",
        "args": "task-jerase"
    },    
    {
        "key": "f7",
        "command": "workbench.action.tasks.runTask",
        "args": "task-jflash"
    },

    //for st-util
    {
        "key": "ctrl+f8",
        "command": "workbench.action.tasks.runTask",
        "args": "task-sterase"
    },    
    {
        "key": "f8",
        "command": "workbench.action.tasks.runTask",
        "args": "task-stflash"
    }  
]

参照上面的示例文件,这里是把前面的tasks.json里面的任务给予对应的快捷键定义,简单的分类就是用f功能键表示创建操作,ctrl+f功能键表示对应的销毁操作。有了这个文件之后,就实现和keil一样的,F7一键编译

  1. f6 = 编译工程

  2. ctrl+f6 = 清除工程

  3. f7 = jlink下载

  4. ctrl+f7 = jlink擦除

  5. f8 = stlink下载

  6. ctrl+f8 = stlink擦除

3-实现vscode里在线调试stm32

读者最好了解在线调试的原理,否则可能对这里用到的各个文件或依赖感到很困惑。vscode是通过配置launch.json和settings.json,实现对其debug功能的配置。主要配置的对象是cortex-debug插件和下载器。

3.1-调试原理及分层结构

调试的原理简要说明一下。debug原理早在最早的GNU时代就确立了,现在仍然在使用GNU框架(其实好像就没有听说过GNU之外的)。简要的知识如下4点。

  1. GDB: GDB是GNU中的调试框架设计,定义了调试的功能组件,如单步,断点,寄存器查看等功能,这也是为啥GDB框架下的调试界面基本相同(这就是‘标准’的力量)。

  2. vscode是一个文件编辑器,也是一个容器,执行各种插件或调用外部应用如make等

  3. Cortex-Debug是你在vscode下调试cortex核芯片的GDB,

  4. GDB之下是接口,如JTAG协议接口,这通过jlink gdb server实现,其实就是给IDE的通用GDB调用接口;再之下就是对应的协议接口及硬件,如jlink及stlink,通过它们连接到对应的目标板。大概的访问路径是 vscode->cortex debug->jlink gdb server->jlink|swd |usb-> target chip。分层分得是很好很合理,就是层数有点多了,初学者很容易见此放弃。

  5. 参考: Home · Marus/cortex-debug Wiki (github.com) 和 Cortex Debug Under the hood · Marus/cortex-debug Wiki (github.com)

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第8张图片

 3.2-配置settings.json用于在线调试

1-配置vscode的settings.json

按上面的原理,如果你使用stlink,需要告诉vscode一些信息,如gdb在哪里,stlink的gdb server在哪里,其他的信息如stlink的接口等因为都在stlink里集成了,所以不需要额外告知。下面截图中指示3个执行文件的路径,随便放在哪里都可以,但是要确认路径正确,不然肯定会报错的。第一行是gdb地址,第二三行是jlink和stlink对应的gdb server的地址,本章节例子中可以使用jlink或stlink进行调试。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第9张图片

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第10张图片

 trouble shooting:  注意如果使用jlink,注意对应的gdb server是以‘CL’结尾的,表示是给命令行(即vscode shell)调用的程序。否则的话会报如下截图的错,一直显示“cortex-gdb无法连接到jlink的gdb server”。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第11张图片

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第12张图片

 2-Cortex-Debug介绍

在插件的主页可以看一下了它的功能与参数设置 ,这些settings的参数定义在Extensions边栏(按CTRL+SHIFT+X)找到,在Cortex-Debug这里虽然有46个参数,但是简单浏览下都是几大调试器的(jlink, openocd, pyocd, stlink, etc.)支持设计,重复的很多,而且主要是路径设置。参考如下

>>参数使用说明  cortex-debug/debug_attributes.md at master · Marus/cortex-debug · GitHub

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第13张图片

 3-launch.json用于配置vscode的调试设置

更多信息可参考:

1- 介绍 Configure launch.json for C/C++ debugging in Visual Studio Code 

2- 详细配置说明 Debugging in Visual Studio Code

launch.json是用于配置vscode中的debugger的,debugger功能是vscode重要功能模块。如果没有launch.json的话,首次需要创建,因为它是工程相关的,所以在.vscode目录下。创建可以手动创建,也可以点下图中所示的链接创建。简单对launch.json分析如下。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第14张图片

// Configure debug launch settings
// Feel free to copy these and modify them for your debugger and MCU
{
    "version": "0.2.0",
    "projectName": "MAY12",
    "configurations": [
        {
            "name": "JLink launch",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceRoot}/build/may12.elf",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "jlink",
            "device": "STM32F429ZI",
            "interface": "swd",
            "runToMain": true, // else it starts at reset handler - not interested
            "preLaunchTask": "task-build", // configured in tasks.json
            "svdFile": "", // Include svd to watch device peripherals
            "swoConfig":
            {
                "enabled": true,
                "cpuFrequency": 168000000,
                "swoFrequency": 10000000,
                "source": "probe",
                "decoders":
                [
                    {
                        "label": "ITM port 0 output",
                        "type": "console",
                        "port": 0,
                        "showOnStartup": true,
                        "encoding": "ascii"
                    }
                ]
            }
        },
        {
            "name": "JLink attach",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceRoot}/build/may12.elf",
            "request": "attach",
            "type": "cortex-debug",
            "servertype": "jlink",
            "device": "STM32F429ZI",
            "interface": "swd",
            "runToEntryPoint": "main", // else it starts at reset handler - not interested
            "preLaunchTask": "task-build", // configured in tasks.json
            "svdFile": "", // Include svd to watch device peripherals
            "swoConfig":
            {
                "enabled": true,
                "cpuFrequency": 160000000,
                "swoFrequency": 4000000,
                "source": "probe",
                "decoders":
                [
                    {
                        "label": "ITM port 0 output",
                        "type": "console",
                        "port": 0,
                        "showOnStartup": true,
                        "encoding": "ascii"
                    }
                ]
            }
        },
        {
            "name": "STlink launch",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceRoot}/build/may12.elf",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "stutil",
            "device": "STM32F429ZI",
            "interface": "swd",
            "runToMain": true, // else it starts at reset handler - not interested
            "preLaunchTask": "task-build", // configured in tasks.json
            "svdFile": "", // Include svd to watch device peripherals
            "swoConfig": {} // currently (v1.7.0) not supported
        },
        
        {
            "name": "STlink attach",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceRoot}/build/may12.elf",
            "request": "attach",
            "type": "cortex-debug",
            "servertype": "stutil",
            "device": "STM32F429ZI",
            "interface": "swd",
            "runToEntryPoint": "main", // else it starts at reset handler - not interested
            "preLaunchTask": "task-build", // configured in tasks.json
            "svdFile": "", // Include svd to watch device peripherals
            "swoConfig": {} // currently (v1.7.0) not supported
        },
    ]
}

和stm32调试有关的内容有很多,但是迅速跑起来的话,东西并不多,我们以及使用stlink为例说明一下,stlink的比较短。下面12个配置项中,有的是关于vscode的,有的是关于cortex-debug的。

  1. name = 就是显示在启动调试里的配置方案的名称,因为我们这里提供了4个方案,分别是jlink两个,stlink两个

  2. cwd = 当前目录,搜索其他文件的起点位置

  3. excuteable = .elf文件,有变量名称表和完整程序信息,内容包含.map, .bin , .ld文件。

  4. request = 调试启动方式,是launch 还是 attach。attatch:强行进入调试,不下载,你自己确认vscode里界面的代码和目标板里的代码一样,不影响程序运行;launch: 重新下载,全新开始调试,确保.elf文件与目标板里是相同的,目标芯片被复位。

  5. type = 表示是为哪个gdb配置的,这里肯定是用cortex-debug,我们用的是这个插件

  6. servertype = gdb服务器名称,这里是用的stutil

  7. device = 芯片详细名称,

  8. interface = 所用的接口

  9. runtoEntryPoing = 是否是从main开始,还是从复位开始,一般是从main开始,除非调试中断与操作系统

  10. preLaunchTask = 启动vscode的调试前调用的命令,这里执行了build命令确保.elf文件是和代码完全一致的

  11. svdFile = 芯片外设寄存器配置文件,如果要显示对应的如串口或CAN口寄存器,需要提供文件目录

  12. swoConfig = jlink才有,配置swo的时钟频率的,stlink暂时没有

4-测试运行

上面的配置准备完毕后就可以运行,建议先测试stlink,虽然慢,但是不复杂不容易出错,jlink可能会麻烦一些。

自动的会在绿三角启动按钮旁边显示已经配置好的debugger方案,点绿色按钮启动。最终调试界面如本章节开始的所示。vscode提供的调试按钮如下图所示,这是标准的gdb的调试‘配方’,甚至对应的快捷键在各个软件如KEIL中都是完全一样的。

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第15张图片

 

到此通过配置launch.json和settings.json,实现对vscode的配置,最终调试界面如下,截图中使用的是'JLink launch'的配置

note:(在jlink下,可以在调试的同时看到swo的输出,而stlink并不支持,这算是jlink的一个优势,当然也可以麻烦一点搞一个串口跳过对swo的依赖)

0505-stm32的调试工具:vscode下jlink或stlink下载及调试+设置快捷键_第16张图片

 4.1-结论

总结一下,使用vscode进行stm32的完全开发,是一个系统工程。在前面博文的基础上,在vscode上实现了stm32的自定义菜单下载和一键下载,第二个重点是实现stm32的在线调试,支持jlink和stlink两种方式。主要的配置文件是launch.json, settings.json, tasks.json三个项目相关文件,还有keybindings.json文件。至此,已经实现vscode对keil/iar等IDE的替换,从原理上,GNU框架(或叫‘配方’更好)确实是一个非常好的设计,回看keil/iar等IDE,它们也是很忠实遵循GNU配方的。

note: 后续博文继续讨论关于OpenOCD和platformIO的使用。

note2: 一直没讨论c_cpp_properties.json,是因为如果可以完全保证工程完整的话,可以不需要c/c++插件的辅助,而且它与编译、下载、调试无关。在后续博文中讨论这个json文件。

参考:

1-Debugging STM32 in VSCODE with stlink and jlink | VIDEO 45 

2-jlink swo用法及示例代码 J-Link SWO Viewer (segger.com)

你可能感兴趣的:(stm32,vscode,单片机)