使用vscode开发stm32记录

目录

    • 1.前言
    • 2.vscode优势
    • 3.参考文章
    • 4.工具链
    • 5.配置文件
      • 5.1.文件launch.json
      • 5.2.文件task.json
      • 5.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:\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
如果想知道armcc5的预定义宏
"C:\Keil_v5\ARM\ARMCC\bin\armcc.exe  --list_macros"
输入ctrl+z

这就是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.插件

使用vscode开发stm32记录_第1张图片
我使用了以上插件,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
        },

    ],

实现彩条注释效果,如图:
使用vscode开发stm32记录_第2张图片

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
ctrl+shift+p 输入reset选择 Reset IntelliSense database
ctrl+shift+p 输入rescan选择 Rescan Workspace

和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~~

你可能感兴趣的:(嵌入式学习)