使用vscode开发stm32记录

it2025-02-14  5

目录

1.前言2.vscode优势3.参考文章4.工具链5.配置文件5.1.文件launch.json5.2.文件task.json5.3.文件H7-jlink.cfg内容5.4.文件H7-stlink.cfg内容 6.插件6.1BetterComments插件6.2.c/c++ intellisense插件 7.操作快捷键8.CubeMX生成工程9.makefile修改10.工程修改10.1工程重命名10.2.新增.c文件10.3.新增.h文件10.4.printf重定向10.5.链接文件修改(将数组定义到指定位置) 11.结束语

1.前言

使用vscode+gcc+Jlinkgdbserver来为stm32编写代码有一段时间了,将应用重点写下来给自己当备忘录,有缘人也可以看看。

之前在使用MDK编译CubeMX生成的Stm32H750工程的时候遇到了大麻烦: 使用armcc5正常编译,但巨慢无比,等到花儿都谢了。。。 使用armcc5去掉跳转编译,速度是快了,但是没跳转了怎么调代码???! 使用armcc6编译,速度更快了,但是兼容性有问题,研究了一下,armcc6竟然默认定义了GNU宏,不知道自己不是gcc吗?定义这个宏干嘛???不知道lwip就是靠这个宏来区分编译器的么?一编译一大堆错,搞什么飞机!!

类似这种

#if defined ( __ICCARM__ ) /*!< IAR Compiler */ ... #elif defined ( __CC_ARM ) /* MDK ARM Compiler */ ... #elif defined ( __GNUC__ ) /* GNU Compiler */ ... #endif 问题来了,怎样知道编译器有哪些预定义宏呢? 如果想知道armcc6编译器预定义宏 cmd输入 "C:\Program Files\Keil_v5\ARM\ARMCLANG\bin\armclang --target=arm-arm-none-eabi -E -dM d:\main.c" 发现里面有一行 #define __GNUC__ 4 如果想知道gcc预定义宏 cmd输入 "arm-none-eabi-gcc -dM -E d:\main.c" 里面对应的一行是 #define __GNUC__ 9

这就是armcc6(armclang)编译失败的根源

正好有点在linux下vscode工具链应用经验,被逼无奈,趁机换门。 看到有一些教程里面为了用gcc,竟然走了安装Mingw或者cygwin的路子,谁要是照做怕是要变成受害者。其实windows下可以全部搞定,不要去装什么劳什子Mingw。

2.vscode优势

vscode看代码跳转更加方便,按函数浏览,还有一些有用的插件。更重要的是使用vscode开发,配置文件一目了然。不像MDK,勾选一些选项到底有什么影响也缺少清楚的解释,总感觉和真实世界隔着一层,如果是编写windows程序倒是不在乎这些,但是单片机要求不一样,这样隔着一层没人喜欢。而当学会vscode后再回头用MDK,会更容易理解那些藏在角落里的小选项,或者一些所谓的骚操作是什么东东。 另外一个很重要的点是VScode+gcc-arm-none-eabi工具链是跨平台的,到linux下面完全没区别,我个人就是在linux下用过这套工具链,到windows下又重新捡起来。

3.参考文章

用VS Code开发STM32(一)——软件安装 用VS Code开发STM32(二)——编译 用VS Code开发STM32(三)——调试

4.工具链

vscode调试功能没有MDK多,比如不能实时看内存状态(后来证明可以,参见另外一篇博文),需要Jlink全家桶软件中的Jmem帮忙才能形成一套完整的调试环境。而且Jlink有RTT、SystemView、JFlash软件加持,功能又多又好,当了解到这些时果断收起STLinkV2.1,扶Jlink上位。 顺便记录一下: Openocd是跨平台通用片上调试软件,支持多种调试工具,其中包含stlink、Jlink。不过既然使用Jlink,那当然还是用Jlink提供的Jlinkgdbserver了,以前在linux下面使用的就是Openocd,试了一下windows下也可以正常应用。 so,最后我使用的工具链是VScode+gcc-arm-none-eabi+Jlinkgdbserver(没用到Openocd)

实测官方最新版的gcc-arm-none-eabi-10-2020-q4-major-win32编译cubemx生成的代码可能会报错,只能暂时使用我搬运的gcc-arm-none-eabi-9-2020-q2-update-win32 ,然后等待官方修复吧。

openocd下载地址(如果不用,可以不安装)

相关path环境变量

C:\Program Files (x86)\GNU Arm Embedded Toolchain\OpenOCD-20200729-0.10.0\bin C:\Program Files (x86)\GNU Arm Embedded Toolchain\9 2020-q2-update\arm-none-eabi\bin C:\Program Files (x86)\GNU Arm Embedded Toolchain\9 2020-q2-update\bin C:\Program Files (x86)\GNU Arm Embedded Toolchain\9 2020-q2-update\arm-none-eabi\include

5.配置文件

5.1.文件launch.json

实际上,按按钮自动进入调试的过程是通过插件cortex-debug实现的,所以launch.json里面的一些参数是在配置cortex-debug插件。小技巧:输入"会自动跳出支持的参数,然后再去研究其含义。

{ "version": "0.2.0", "configurations": [ {//Jlink "name": "Jlink-Debug", "cwd": "${workspaceRoot}", "executable": "./build/${workspaceRootFolderName}.elf", "serverpath": "C:/Program Files (x86)/SEGGER/JLink/JLinkGDBServerCL.exe", "serverArgs": ["-speed", "50000"], //JLinkGDBServerCL的参数,设定Jlink速度,要是不设定这个弄个龟速,你就亏了 "request": "launch", "type": "cortex-debug", "preLaunchTask": "build",//调用自定义的task "rtos": "FreeRTOS", //不加这个调试时候不会显示任务,只会像正常程序一样显示断点位置 "runToMain": true, //调试时运行到main函数 "servertype": "jlink",//或者openocd,有固定支持选项,输入时候有选项提示。 "interface":"swd",//调试接口 "device": "STM32H750VB", "svdFile": "${workspaceRoot}/user/STM32H750x.svd", //在stm网站下载,没有svd文件不能看外设寄存器名称 "configFiles": [ "${workspaceRoot}/user/H7-jlink.cfg"//自定义的,后面有这个文件的内容 ], }, {//STLINKV2 "name": "Stlink-Debug", "cwd": "${workspaceRoot}", "executable": "./build/${workspaceRootFolderName}.elf", "request": "launch", "type": "cortex-debug", "preLaunchTask": "build", "runToMain": true, "servertype": "openocd", "interface":"swd", "device": "STM32H750VB", "svdFile": "${workspaceRoot}/user/STM32H750x.svd", "configFiles": [ "${workspaceRoot}/user/H7-stlink.cfg" ], }, ] }

launch.json每个工程都要用,它的位置在.vscode下,每建立一个新工程就把这个配置文件拷贝过去。

5.2.文件task.json

{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "make -j4" }, { "label": "RTT", "type": "shell", "command": "JLinkRTTClient.exe", "args": [], "problemMatcher": [] }, ] }

这里写了两个任务,一个用来对工程进行make,一个用来启动RTTClicent,RTT是Jlink带的类似swo一样的东西,当虚拟串口用。build任务供launch.json调用或者task插件调用。 task.json每个工程都要用,它的位置在.vscode下,每建立一个新工程就把这个配置文件拷贝过去。

5.3.文件H7-jlink.cfg内容

source [find interface/jlink.cfg] source [find target/stm32h7x.cfg] reset_config none

每个工程都要用,把它放在user文件夹下,供launch.json引用。

5.4.文件H7-stlink.cfg内容

source [find interface/stlink-v2-1.cfg] source [find target/stm32h7x.cfg] reset_config none

每个工程都要用,把它放在user文件夹下,供launch.json引用。

6.插件

我使用了以上插件,vs主题用是vue。

6.1BetterComments插件

这个插件需要配置一下 插件上点击齿轮-扩展设置-在setting.json中编辑,改写为:

"better-comments.tags": [ "better-comments.tags" { "tag": "y-tag", "color": "#000000", "strikethrough": false, "underline": false, "backgroundColor": "#FFFF80", "bold": true, "italic": false }, { "tag": "o-tag", "color": "#FFFFFF", "strikethrough": false, "underline": false, "backgroundColor": "#FF8C00", "bold": false, "italic": true }, { "tag": "r-tag", "color": "#FFFFFF", "strikethrough": false, "underline": false, "backgroundColor": "#FF0000", "bold": false, "italic": true }, { "tag": "g-tag", "color": "#FFFFFF", "strikethrough": false, "underline": false, "backgroundColor": "#408080", "bold": false, "italic": true }, { "tag": "B-tag", "color": "#FFFFFF", "strikethrough": false, "underline": false, "backgroundColor": "#3498DB", "bold": false, "italic": true }, ],

实现彩条注释效果,如图:

6.2.c/c++ intellisense插件

这个插件是必须装的,但是它的配置恶心到了很多人,全网也没几个人解决的,被我解决了,哈!右下角双击win32,进入ui配置:

1.编译器路径

C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update/bin/arm-none-eabi-gcc.exe

2.include路径

${workspaceFolder}/** C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update/**

两个*意思是递归,只要给定上层目录,下面自动就全包含了。 3.预处理宏

_DEBUG UNICODE _UNICODE USE_HAL_DRIVER STM32H750xx

设置这些都是为了实现命令提示,代码补全。和MDK不同,在vscode里面编译链接和代码补全跳转是平行的两条线,互不影响。 配置完成以后即可以正常补全跳转,但是还是可能会出现讨厌的红色波浪线,这时可以进行如下操作,注意,这里厉害了:ctrl+shift+p 输入restart选择 Developer: restart extension host 红色波浪线给我消失! 和MDK一样,所要配置的就是上面两个必要的宏和两个递归引用目录,代码量再巨大也不怕,都能正常跳转。

7.操作快捷键

vs常用的快捷键: ctrl+shift+p 打开命令面板。比如输入restart / task等。 ctrl+shif+o 按函数名称浏览,快速定位。 F12 跳转到定义 Alt+左箭头 再跳回来,Alt+右箭头 再跳过去。

8.CubeMX生成工程

CubeMX生成makefile的基本工程不再多说,随便一个教程都有。

9.makefile修改

windows下make程序需要gnu make for windows下载地址 编译窗口输出的东西过多,对makefile做简单修改。

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ @echo compiling $(notdir $(<:.c=.o)) $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) @$(AS) -c $(CFLAGS) $< -o $@ @echo compiling $(notdir $(<:.s=.o)) $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ @echo ------------------------------------- @echo linking... $(SZ) $@ clean: powershell rm $(BUILD_DIR) -r -Fo

clean也需要简单改动以适应powershell规定。 使用cubemx重新生成工程,会保留makefile的更改,不用担心。但是在inuclude下面可能会多生成一个目录,造成编译错误,如果出现删除即可。 这样就可以在终端窗口里面, 输入make -j4编译; 输入make clean完成编译文件删除; 或者点击task插件里面的buid执行编译; 或者ctrl+shift+p输入task点击buid执行编译。

10.工程修改

10.1工程重命名

如果需要重命名工程: 1.将工程文件夹名字重命名; 2.将makefile的第一行进行如下修改:

TARGET = 新的工程名

10.2.新增.c文件

如果有新增.c文件,需要修改makefile:

#C sources C_SOURCES = \ Core/Src/main.c \ Core/Src/gpio.c \ ...

10.3.新增.h文件

如果有新增.h文件,需要修改makefile:

C_INCLUDES = \ -ICore/Inc \ -IDrivers/STM32H7xx_HAL_Driver/Inc \ -IDrivers/STM32H7xx_HAL_Driver/Inc/Legacy \ ...

10.4.printf重定向

gcc的重定向和armcc不一样,需要重定义的是_write函数:

int _write(int file, char *data, int len) { HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 400); return 0; }

注意使用printf时,后面一定要加上\r\n,不然不输出。

10.5.链接文件修改(将数组定义到指定位置)

如果需要指定数组在内存中的位置: 1.定义数组时指定段名称。

uint8_t Rx_Buff[2][2] __attribute__((section(".RxArraySection")));

2.链接文件指定段位置。

.lwip_sec (NOLOAD) : { . = ABSOLUTE(0x30040000); *(.RxDecripSection) . = ABSOLUTE(0x30040060); *(.TxDecripSection) . = ABSOLUTE(0x30040200); *(.RxArraySection) } >RAM_D2 AT> FLASH

11.结束语

经过这些操作,vscode基本上已经没有遗憾点。其实大部分时候,gcc编译速度落后于armcc,但是正如前言里面说的,armcc有bug,至少对于H7+lwip来说,vs+gcc工具链效率是远远超越mdk的,节省太多不能忍的时间。对了,别忘了使用Jmem~~

最新回复(0)