如何使用STM32CubeMX和VSCode编译烧录stm32

在上一届的许多项目都采用了STM32CubeMX与VSCode进行开发的工作流,为了方便新人能够快速上手,下面将会介绍如何使用STM32CubeMX与VSCode配合GCC或Keil开发STM32项目。(默认你已经安装了STM32CubeMX与VSCode,详细安装请自行上网搜索)

  • 目标人群:战队新人
  • 教程目标:能够使用STM32CubeMX与VSCode进行stm32的开发
  • 教程难度:简单
  • 预计用时:1小时
  • 前置条件:安装STM32CubeMX与VSCode以及keil
  • 教程内容:环境搭建、创建工程、编译烧录、调试

1. 环境搭建

为了实现能够在VSCode中编译烧录stm32,我们需要安装一些插件: Embedded IDE, Cortex-Debug, C/C++等插件。安装方法如下:在VSCode侧边栏中打开或按下Ctrl+Shift+X,然后在搜索框中输入插件名,点击安装即可。
插件安装eide
插件安装cortex-debug
插件安装c/c++

1.1 EIDE环境配置

在下载插件后,我们还需要进行一些简单的配置,以便能够正常的编译以及烧录STM32代码。

在windos中,插件通常会自动插件将自动下载并安装 eide-binaries.NET6 X64 Runtime,请耐心等待,待安装完成后,需要重启VSCode。

在Linux中,需要手动下载并安装.NET6 X64 Runtime,下载地址为:.NET6 X64 Runtime,下载完成后,解压并安装即可。

上述操作完成后,我们会看到侧边栏出现了EIDE的图标,打开后看到如下界面(*ps: 忽略电脑管家^^):

EIDE界面

随后我们选择下方的安装实用工具,我们需要安装一些工具链以便于编译我们的代码,一共有4个,如下图所示:

EIDE工具链

随后,我们点击打开插件设置,找到你的keil的安装路径下的ARM文件夹,然后找到ARMCC文件夹,将路径复制到Armcc v5 toolchain安装目录中,如下图所示:

EIDE工具链路径

随后,继续在该页面下滑,找到并勾选Axf to Elf,如下图所示:

EIDE工具链路径

至此,EIDE的环境配置已经完成。

2. 开始创建工程

2.1 利用gcc-arm-none-eabi创建 (推荐)

2.1.1 STM32CubeMX创建工程

打开STM32CubeMX,建议不要使用中文路径以及中文项目名称,在配置完所需的引脚以及时钟等参数后,我们在生成代码时选择生成Makefile,如下图所示:

生成Makefile

在生成完成后,打开生成的文件夹

2.1.2 导入工程到VSCode

在当前文件夹中打开VSCode,在侧边栏中选择EIDE,然后选择新建项目空项目,如下图所示:

EIDE新建项目

继续选择Cotex-M项目,如下图所示:

EIDE新建项目

随后输入项目名称,注意这里需要与刚才在STM32CubeMX中创建的工程名称一致,如果忘记了,可以打开侧边栏的资源管理器 查看当前的文件夹名称,如下图所示:

EIDE新建项目

然后点击确定,选择存放路径,特别注意需要返回上一级目录保存,比如我的路径为a/b/demo2,那么我需要返回到a/b,然后保存,如下图所示:

EIDE新建项目

当我们看到VSCode报出警告*警告: 项目文件夹已存在 !, 是否直接将项目创建在已存在的目录中 ?*,选择yes,如下图所示:

EIDE新建项目

此时我们已经成功导入工程到VSCode中

2.1.3 EIDE配置以及编译

当我们打开EIDE插件后,发现项目资源空空如也,这是因为我们还没有添加文件,点击添加源文件夹,先选择普通文件夹,然后选择”Drivers” “Inc” “Middlewares” “Src” 这四个文件夹,如下图所示:

EIDE添加文件夹
EIDE添加文件夹

然后再次点击添加源文件夹,选择虚拟文件夹,随便给这个文件夹起个名字,然后先把他晾着(为什么?这是好事,先别管^^),如下图所示(仔细看s和其他文件夹的区别):

EIDE添加文件夹

随后,我们从侧边栏资源管理器中找到Makefile,此时我们需要将该文件的部分内容修改至EIDE的配置中,我们根据Makefile中的内容从上往下看:

  1. 找到ASM_SOURCES,可以看到:

    1
    2
    3
    # ASM sources
    ASM_SOURCES = \
    startup_stm32f407xx.s

    我们要将这个文件添加到刚刚创建的虚拟文件夹中,右键虚拟文件夹,点击添加文件,找到.s文件,如下图所示:

    EIDE添加文件夹

    注意,如果要使用arm-math库加速运算,我们还需要在虚拟文件夹中加入,其静态链接库文件,路径为\Middlewares\ST\ARM\DSP\Lib\libarm_cortexM4lf_math.a,其后缀为.a而不是.s,然后还需在预处理宏定义中加入ARM_MATH_CM4

  2. 找到CPU,FPU,FLOAT-ABI,这三个变量,我们需要将其添加到构建配置: GCC中,如下图所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # cpu
    CPU = -mcpu=cortex-m4

    # fpu
    FPU = -mfpu=fpv4-sp-d16

    # float-abi
    FLOAT-ABI = -mfloat-abi=hard

    EIDE修改构建配置

    选择相应的CPU类型。

    之后刚刚的位置出现了硬件浮点选项,我们修改为single,如下图所示:

    EIDE修改构建配置

    继续修改下方的构建器选项,找到全局选项,将硬件浮点ABI修改为hard,保存,如下图所示:

    EIDE修改构建配置

  3. 找到C_DEFS, C_INCLUDES:
    将这些内容添加到EIDE的项目属性中,注意他们的格式不一样,Makefile中的C_DEFS是以-D开头的,C_INCLUDES是以-I开头的:

    1
    2
    3
    4
    5
    6
    7
    8
    # C defines
    C_DEFS = \
    -DUSE_HAL_DRIVER \
    -DSTM32F407xx
    # C includes
    C_INCLUDES = \
    -IInc \
    -IDrivers/STM32F4xx_HAL_Driver/Inc \

    但是在项目属性中,他们不是以-D或者-I开头的,而是 - (注意前后的空格,没看明白就复制下面的),以下为一个简单的例子:

    1
    2
    3
    4
    # Preprocessor Definitions
    Defines:
    - USE_HAL_DRIVER
    - STM32F407xx

    我们可以先将Makefile中的内容复制到项目属性中,然后再修改为-开头的,有个快速修改的小技巧(复制到对应位置后按下ctrl+f,然后输入-D或者-I,然后替换为 - (Markdown不太支持空格,记住这个 - 前面有4个空格,后面1个)即可),如下图所示:

    EIDE修改构建配置

    修改Define同理,再继续查找-D即可。

  4. 返回Makefile中,找到LDSCRIPT,我们需要在EIDE中添加相应的链接器脚本。如下图所示:

    1
    2
    # link script
    LDSCRIPT = STM32F407IGHx_FLASH.ld

    我们需要在构建配置: GCC中找到链接脚本路径,复制粘贴,然后添加相应的链接器脚本,如下图所示:

    EIDE修改构建配置

  5. 点击右上角的构建或者按下F7,我们就可以看到我们的代码已经成功的编译了,如下图所示:

    EIDE编译成功

  6. 可能的报错解决方法:在第一次编译时明明什么文件都没加,怎么编译就显示缺少头文件呢?

    EIDE编译缺少头文件

    出现这种情况可能是你的CubeMX在生成代码时生成了一些多余代码,我们并不需要,delete掉就好了,如下图所示:

    EIDE删除多余文件

    选上的这些全部删除,然后打开STM32CubeMX,到Project Manager中,找到Code Generator中的Stm32Cube MCU packages and embedded software packes

    • Copy all used libraries into the project folder
    • Copy only the necessary library files

    STM32CubeMX生成文件选择

    这样选择就好,返回Vsode,将EIDE刚刚包含的源文件夹全部删除(不包括虚拟文件夹),然后重新添加,根据Makefile修改一下包含的头文件,再次编译,应该就不会报错了。

2.2 在现有的keil工程中创建

2.2.1 STM32CubeMX创建keil工程

打开STM32CubeMX,正常生成项目,建议不要使用中文路径以及中文项目名称,在生成代码前选择生成keil工程,如下图所示:

生成keil工程

这里我们选择MDK-ARM V5,然后点击Generate Code,生成代码后,我们会看到在工程文件夹下生成了一个.uvprojx文件,稍后我们会用到。

2.2.2 导入keil工程到VSCode

在EIDE的操作栏中,选择导入项目,然后选择MDK工程文件,如下图所示:

EIDE导入项目

随后找到刚刚生成的.uvprojx文件路径:

EIDE导入keil路径

选择后弹出,是否与原有的 KEIL 项目共存于同一目录下,此处选择yes,随后切换工作区,如下图所示:

EIDE导入keil路径

切换工作区后,我们会看到在EIDE的项目栏中出现了我们刚刚导入的项目,如下图所示:

EIDE导入keil路径

这时,我们已经成功通过STM32CubeMX与VSCode导入了keil工程。此时我们还需要进行一些简单的配置,以便于我们的编译以及烧录。

2.2.3 EIDE配置以及编译

我们先点击左侧边栏的资源管理器,此时应该会看到以下文件结构:

EIDE导入keil路径

当我们只看到MDK-ARM文件夹时,说明我们此时的工作区中只有该文件夹,若我们需要在该文件夹外添加新的文件,会出现头文件无法找到、无法编译等情况。因此我们需要修改文件MDK-ARM.dode-workspace,将其中的

1
2
3
4
5
"folders": [
{
"path": "."
}
],

修改为

1
2
3
4
5
6
7
8
"folders": [
{
"path": "."
},
{
"path": ""
}
],

随后我们尝试编译一下,点击右上角构建或按下F7,然后我们就会发现它报了一万个错^^.

EIDE第一次报错

虽然报错了,但还是恭喜你至少前面的环境配置成功了,根据错误提示,我们看到这是在链接阶段出现的错误,它提示我们在代码和内存分配时遇到了没有空间的情况,这是因为我们还没有分配RAM/ROM,此时我们应该打开EIDE插件中的构建配置: AC5找到RAM/FLASH布局点击修改 ,现在,你需要打开 Keil 项目,复制 ram/rom 布局数据(点击keil的魔法棒然后点击Target)到 eide 的 存储器布局编辑器 中,然后保存,具体操作如下图所示:

EIDE第一次报错

将keil的数据复制到EIDE中,注意RAM对齐RAM,ROM对齐ROM,然后保存。

再次编译^^,这次应该就不会报错了,如下图所示:

EIDE第一次构建成功

但是,为什么没看到ELF文件呢?明明说了Axf to Elf,不会是这个插件问题吧?那我是不是不能调试了?

别急,我们只需要在构建配置: AC5中找到构建器选项,点击修改,然后在链接器中找到不生成Hex\Bin文件,取消勾选,保存,如下图所示:

EIDE构建器选项

再次编译,我们就生成了ELF文件,如下图所示:

EIDE生成ELF

至此,我们已经成功的导入了keil工程,并且成功的编译了代码。接下来我们就可以进行烧录以及调试了。

2.3 烧录

不知道下一届选择的是什么烧录器,不过大概率还是9块9的包邮的ST-LINK,那么我就默认用ST-LINK来进行烧录。

烧录配置中选择切换烧录器然后选择OpenOCD,如下图所示:

EIDE烧录配置

接着继续在烧录配置的菜单栏下切换芯片配置到你所使用的芯片型号,A/C板都是stm32f4x.cfg

此时我们点击右上角的烧录选项或者ctrl+shift+D,选择下载,就可以进行烧录了,由于我这里没有设备,所以就不演示了。

2.4 调试

我们可以在VSCode中借助Cortex-Debug插件进行调试,同样的在EIDE插件的项目中右键,找到生成调试器配置模板,根据你的烧录器选择,如果是ST-LINK就选择OpenOCD,如下图所示:

EIDE调试配置

在新打开的页面中根据需要选择(跟烧录差不多),然后新建

这时我们打开左侧边栏中的运行和调试,理论上已经可以直接调试了,但为了能够实时检测变量的变化,我们还需要对launch.json,进行一些简单的配置。

点开运行和调试旁边的齿轮,我们可以看到如下图所示的配置文件:

EIDE调试配置

我们加上liveWatch的选项,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceRoot}",
"type": "cortex-debug",
"request": "launch",
"name": "C_Board_Standard_Robot: OpenOCD",
"servertype": "openocd",
"executable": "build/C_Board_Standard_Robot/C_Board_Standard_Robot.elf",
"runToEntryPoint": "main",
"configFiles": [
"interface/stlink.cfg",
"target/stm32f4x.cfg"
],
"liveWatch": {
"enabled": true,
"samplesPerSecond": 4
}
}
]
}

这时,大部分人都可以进行调试了,但是有些人可能会遇到一些路径错误,可能的原因是之前你已经安装了arm-none-eabi-或者mingw64等工具链,但是后来进行了删除,我们此时最好使用从EIDE实用工具下载的工具链,这时我们需要在settings.json中添加一些路径,如所示:

1
2
3
{
"cortex-debug.gdbPath": "your path", // 通常在C:\Users\yourname\.eide\\tools\\gcc_arm\\bin\\arm-none-eabi-gdb.exe
}

在检测实时变量时,我们需要在运行和调试中找到live Watch,然后点击+,添加你想要监视的变量,注意不能实时监视函数中的局部变量