介绍

目前大家用 KeilIAR 工具来开发 STM32 的比较多,而 Keil 和 STM 都是 ARM 的自己产品,适配做的不错,目前大家也是用 Keil 的居多,Keil 有优点也有缺点,Keil 调试方面做的很好,但是编辑器做的一般,在编辑器使用体验上 VS Code 会好用很多,Keil 6 已经做成了 VS Code 的插件形式,名字叫 STM32 VS Code Extension,不过目前还没正式上线,使用起来问题较多,今天介绍另一种方式在 VS Code 上开发 STM32。

调试效果图

编辑器最底部的状态条有两个快捷按钮:BuildLoad,添加教程查看 增加快捷按钮

安装依赖

VS Code

  1. 安装 VS Code 编辑器
  2. 安装 Cortex Debug 调试插件

OpenOCD

1
brew install openocd

安装成功后测试下

1
2
3
4
5
$ openocd --version
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html

GCC (ARM)

安装指定版本 GCC,可以在官网查看有哪些版本 GNU Arm Embedded Toolchain Downloads,例如我的项目用的是 6-2017-q2-update 版本,以下为安装步骤

  1. 执行 brew tap-new $USER/local-tap
  2. 进入 /usr/local/Homebrew/Library/Taps/$USER/homebrew-local-tap 目录
  3. 新建 arm-none-eabi@6-2017-q2-update.rb(注意文件名版本号)
  4. 写入下方内容,类名 AT 后、urlversion 修改为指定版本号,sha256 修改为当前版本文件计算出来的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
require 'formula'

class ArmNoneEabiAT62017Q2Update < Formula
homepage 'https://developer.arm.com/downloads/-/gnu-rm'
version '6-2017-q2-update'

url 'https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-mac.tar.bz2'
sha256 '7d3080514a2899d05fc55466cdc477e2448b6a62f536ffca3dd846822ff52900'

def install
(prefix/"gcc").install Dir["./*"]
Dir.glob(prefix/"gcc/bin/*") { |file| bin.install_symlink file }
end
end

执行以下命令安装 GCC 库

1
brew install $USER/local-tap/arm-none-eabi@6-2017-q2-update

安装成功后测试下

1
2
3
4
5
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 (release)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1
2
3
4
5
6
$ arm-none-eabi-gdb --version
GNU gdb (GNU Arm Embedded Toolchain 10.3-2021.10) 10.2.90.20210621-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

配置调试环境

配置 OpenOCD

在项目根目录创建 ./vscode/openocd.cfg,以下配置调试器为 cmsis-dap,芯片为 stm32f4x,可以根据自己项目实际使用情况进行修改

  1. 查看支持的调试器 https://github.com/openocd-org/openocd/tree/master/tcl/interface 列表
  2. 查看支持的芯片 https://github.com/openocd-org/openocd/tree/master/tcl/target 列表
1
2
3
4
5
6
7
8
9
source [find interface/cmsis-dap.cfg]

transport select swd

source [find target/stm32f4x.cfg]

$_TARGETNAME configure -event gdb-detach {
resume
}

配置 tasks.json

在项目根目录创建 ./vscode/tasks.json 文件,配置两个任务,一个是编译源代码,另一个是把编译的固件下载到芯片中,可根据自己的项目情况修改 commandargs 参数来指定编译和下载命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": "make",
"args": [],
"problemMatcher": "$gcc",
"group": "build",
"detail": "编译源码"
},
{
"label": "Load",
"type": "shell",
"command": "openocd",
"args": [
"-f",
".vscode/openocd.cfg",
"-c",
"program build/Project.bin 0x08000000 verify reset exit"
],
"dependsOn": [
"Build"
],
"detail": "下载固件"
}
]
}

配置 launch.json

  1. 下载 STM32F407x.svd 文件到 ./vscode 目录下,这里查看所有支持的 芯片列表
  2. 在项目根目录创建 ./vscode/launch.json 文件,写入下方数据,可以根据自己的项目进行修改相关参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"type": "cortex-debug",
"request": "launch",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Load",
"executable": "${workspaceRoot}/build/project.elf",
"servertype": "openocd",
"configFiles": [
".vscode/openocd.cfg"
],
"device": "STM32F407ZGT6",
"interface": "swd",
"svdFile": "./.vscode/STM32F407x.svd",
"gdbPath": "/usr/local/bin/arm-none-eabi-gdb",
"runToEntryPoint": "main",
"liveWatch": {
"enabled": true,
"samplesPerSecond": 4
}
}
]
}

增加快捷按钮

  1. 安装 Task Buttons 插件
  2. 在项目根目录创建 ./vscode/settings.json 文件,展示两个按钮,一个编译,一个下载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"VsCodeTaskButtons.tasks": [
{
"label": "$(notebook-open-as-text) Build",
"task": "Build",
"tooltip": "Build target files"
},
{
"label": "$(notebook-move-down) Load",
"task": "Load",
"tooltip": "Download code to flash memory"
}
]
}

效果查看 调试效果图 编辑器最底部的状态条,有两个按钮:BuildLoad

Dev Container

使用 Dev Container 可以实现只需配置一次开发环境,以后换别的开发机器只需要点几下就可快速启动一个一摸一样的开发环境,避免了每次配置开发环境所浪费的时间。还有就是开发环境可以和本机完全隔离,当不需要这个开发环境时,只需要在 Docker 中一键删除就行,非常的清爽、干净

安装依赖

  1. 安装 Docker Desktop
  2. 安装 Dev Containers VS Code 插件

配置 devcontainer.json

在项目根目录创建 ./.devcontainer/devcontainer.json 文件,写入下方数据

如果想要安装其它版本的 gcc,可以在 安装 gcc 中查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// For format details, see https://aka.ms/vscode-remote/devcontainer.json
{
"name": "STM32",
"build": {
"dockerfile": "Dockerfile"
},
"runArgs": [],

// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {},

// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"marus25.cortex-debug",
"ms-vscode.cpptools-extension-pack",
"spencerwmiles.vscode-task-buttons"
]
}
}
}

在项目根目录创建 ./.devcontainer/Dockerfile 文件,配置一个容器,使用 ubuntu 系统,安装 gcc 编译环境

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM ubuntu:20.04

RUN apt-get update && \
apt-get install wget -y \
apt-get clean

RUN cd /tmp && \
wget -q https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 && \
tar xf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 && \
mv gcc-arm-none-eabi-6-2017-q2-update /opt/gcc-arm-none-eabi && \
rm gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2

ENV PATH="${PATH}:/opt/gcc-arm-none-eabi/bin"

使用快捷键 Command + Shift + P 打开命令板面(或者点击左下角 Open a Remote Window 快捷图标),搜索 Rebuild and Reopen in Container 命令并执行,VS Code 就会连接到刚刚创建的容器中

问题列表

  1. 调试区域的 VARIABLESWATCH 板面变量不会自动更新,断点停止的时候才会刷新,可以使用 CORTEX LIVE WATCH 板面添加变量,添加到这里的会定时刷新,刷新周期可以在 配置 launch.jsonliveWatch 字段中配置
  2. 调试区域的 XPERIPHERAL 板面外设点击刷新报错 peripheral-viewer: readMemory failed @ 0x40021000 for 40 bytes: CodeExpectedError: Busy,好像是 Peripheral Viewer 插件有 BUG
  3. 如果断点结束后芯片停止运行,确认 配置 OpenOCD 环节是否忽略了以下内容,添加后即可恢复
    1
    2
    3
    $_TARGETNAME configure -event gdb-detach {
    resume
    }