Skip to content

Wiki

Plugin Usage Tutorial

About 42 min read

Existing English translations were reused. 22 current source blocks remain in Simplified Chinese, without triggering paid translation.

1.CubeMX install FW

Click Help

Select Manage embedded software packages, and check the first latest firmware for STM32F1, F4, and H7.

Click install

You can choose without logging in to an account.do not ask me again

Then wait for the download and installation to complete

Just finish downloading it and you're good.

2.VScode install plugin

Then open VSCode and enter the following command in the terminal.

code

Then, an environment can be configured to be used exclusively by the CubeIDE plugin, avoiding conflicts with the default environment.

alt text

Configure some settings according to your own habits; it is also fine to temporarily follow mine for the ones you do not understand.

alt text

Select STM32

alt text

Then install some plugins

Find the followingSTM32CubeIDE for Visual Studio CodePlugin installation

alt text

On the right, this prompt appears and you need to select install (a goodscientific networkis required)

alt text

Next, some environment installations will be performed.

alt text

You can also install some other plugins, such as Codex and others. It's up to you.

alt text

3.OpenOCD Usage Notes

3.1.Select the debugger and MCU model.

OpenOCD generally determines through a .cfg configuration file: which debugger to use + which MCU to connect to

openocd -f interface/调试器.cfg -f target/芯片系列.cfg

First parameter: depends on which debugger you use

Debugger OpenOCD Configuration Description
ST-Link V2 / V2-1 / V3 "interface/stlink.cfg" Most common for STM32
DAPLink "interface/cmsis-dap.cfg" DAPLink implementation CMSIS-DAP
CMSIS-DAP "interface/cmsis-dap.cfg" Many third-party debuggers use
J-Link "interface/jlink.cfg" SEGGER J-Link
FTDI type JTAG/SWD "interface/ftdi/xxx.cfg" Select according to specific hardware

Second parameter: which STM32 series to look at

STM32 Series Common Model Examples OpenOCD Target
STM32C0 C011, C031, C071 "target/stm32c0x.cfg"
STM32F0 F030, F072 "target/stm32f0x.cfg"
STM32F1 F103C8, F103RC "target/stm32f1x.cfg"
STM32F2 F205, F207 "target/stm32f2x.cfg"
STM32F3 F303, F334 "target/stm32f3x.cfg"
STM32F4 F405, F407, F429, F446 "target/stm32f4x.cfg"
STM32F7 F746, F767 "target/stm32f7x.cfg"
STM32G0 G030, G070, G0B1 "target/stm32g0x.cfg"
STM32G4 G431, G474 "target/stm32g4x.cfg"
STM32H5 H503, H563, H573 "target/stm32h5x.cfg"
STM32H7 H743, H750, H745, H747 "target/stm32h7x.cfg"
STM32H7RS H7R3, H7S3 "target/stm32h7rsx.cfg"
STM32L0 L031, L073 "target/stm32l0.cfg"
STM32L1 L151, L152 "target/stm32l1.cfg"
STM32L4 / L4+ L432, L476, L496, L4R5 "target/stm32l4x.cfg"
STM32L5 L552, L562 "target/stm32l5x.cfg"
STM32N6 N657, etc. "target/stm32n6x.cfg"
STM32U0 U031, U073 "target/stm32u0x.cfg"
STM32U3 U385, etc. "target/stm32u3x.cfg"
STM32U5 U575, U585, U5A5 "target/stm32u5x.cfg"
STM32WB WB55, etc. "target/stm32wbx.cfg"
STM32WBA2 WBA2xx "target/stm32wba2x.cfg"
STM32WBA5 WBA5xx "target/stm32wba5x.cfg"
STM32WBA6 WBA6xx "target/stm32wba6x.cfg"
STM32WL WL55, WLE5 "target/stm32wlx.cfg"
STM32C5 C53, C54, C55, C56, C59, C5A See the explanation below

Pay special attention to the STM32C5:

For now, do not hardcode C5 astarget/stm32c5x.cfg, The reason is that OpenOCD support for STM32C5 is very new. It was only in July 2026 that a stm32c5x.cfg support patch was submitted to OpenOCD Gerrit; the filename in the patch is indeedtarget/stm32c5x.cfg。 However, it has not yet been fully released in OpenOCD, so we need to wait for a while.

3.2.Test device connection

We use thestm32f103c8andst-link:

So use

openocd -f interface/stlink.cfg -f target/stm32f1x.cfg

You can plug it in and run a test:

As shown in the figure above, the connection has been successfully established.

Several key logs are explained respectively:

Info : STLINK V2J48S7 ...
→ OpenOCD 正常识别 ST-Link。

Info : Target voltage: 3.150483
→ 目标板供电正常,约 3.15 V。

Info : SWD DPIDR 0x1ba01477
→ SWD 通信已经建立。

Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
→ 已经真正识别并连接 MCU 核心。

Info : target has 6 breakpoints, 4 watchpoints
→ Cortex-M3 的硬件断点/数据观察点正常。

Info : Examination succeed
→ Target 初始化成功。

最后:
Info : [stm32f1x.cpu] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
→ OpenOCD 的 GDB Server 已经正式启动,可以给 VS Code / STM32Cube 调试器连接了。

4.Project Creation and Testing

4.1.Create a project using CubeMX

Click to enter the microcontroller selection button

Search for the corresponding chip and double-click the corresponding chip option.

Do some configuration. The following are all very basic things that you definitely already know before watching this video.

Just open any IO for testing, such as the GPIO of an LED.

FreeRTOS also needs to be configured.

本例在用户目录中实现 StartDefaultTask() 来替换默认任务函数,需要CubeMX生成的同名函数为弱定义。 可以在FreeRTOS的 Tasks and Queues 中,将 defaultTask 的 Code Generation Option 设为 As weak,重新生成后确认该函数带有 __weak,避免两个普通定义产生冲突。参考ST社区说明。

These folders also need to be configured properly. Finally, select CMake for Toolchain and GCC for the compiler (it is normal that there is no compiler selection option in versions 6.14.1 and earlier).

4.2.Configure and compile the project

Open a terminal in the project folder (or simply open VSCode here).

alt text

code .

After opening VSCode, remember to switch to the `STM32` configuration

alt text

Select Yes here to configure the CMake preset

alt text

Generally, selecting Debug is sufficient.

alt text

It may show a very long dialog box; this isSTM32Cube Coreprompted. You directly click Yes to start the download (this automatically deploys various environments).

Anyway, the bottom right corner isSTM32Cube Corea prompt asking you to install it. Just go ahead and install it. The prompt may differ across versions, but in any case, just install it.

After the above environment deployment is complete,

Find a C language code file and open it, then a prompt will appear in the bottom right corner to install a C/C++ extension. You can install it or not; it also provides code suggestions, but its code suggestions are simply pathetic compared to the built-in clangd. If you are a beginner and don't know how to set up code suggestions, I suggest you follow my steps below and just don't install this C/C++ extension.

By default, clangd code suggestions are used.

You can try out the code suggestions and see if they are really powerful.

alt text

For compilation, either of the two builds shown in the figure will work.

alt text

4.3.Port the standard C/C++ project template by author tungchiahui

Clone the repository with the git clone command:https://github.com/tungchiahui/STM32HAL_CMake_CPP_Template

git clone https://github.com/tungchiahui/STM32HAL_CMake_CPP_Template.git

把仓库里的除了.git以外的东西都复制到我们的STM32工程根目录。

alt text

模板中的用户代码按功能模块组织,每个模块的 .cpp、.hpp(或 .c、.h)放在同一个文件夹里。复制后的目录结构如下:

STM32工程根目录/
├── applications/
│   └── main/
│       ├── cpp_interface.cpp
│       └── cpp_interface.h
├── bsp/
│   └── boards/
│       ├── common/
│       │   └── struct_typedef.h
│       └── delay/
│           ├── bsp_delay.cpp
│           └── bsp_delay.hpp
└── cmake/
    ├── stm32cubemx/            # CubeMX生成的配置
    └── user/
        └── CMakeLists.txt     # 用户代码的配置

cmake/user/CMakeLists.txt 已经把 applications 和 bsp/boards 加入头文件搜索路径,所以引用用户头文件时统一使用“模块目录/头文件名”的写法:

#include "main/cpp_interface.h"
#include "delay/bsp_delay.hpp"
#include "common/struct_typedef.h"

在这两个目录下新增模块时,沿用这个写法即可,不需要为每个模块单独添加头文件搜索路径。

打开CubeMX生成的 Core/Src/main.c,在 USER CODE BEGIN Includes 和 USER CODE END Includes 之间加上:

#include "main/cpp_interface.h"

然后在 main() 的 USER CODE BEGIN 2 和 USER CODE END 2 之间调用 cpp_main(),此时系统时钟和外设已经初始化完成:

cpp_main();

注意 applications/main/cpp_interface.h 中的 isRTOS 设置:

  • 裸机使用默认值 0,业务代码可以写在 cpp_main() 的无限循环中;
  • 使用FreeRTOS时要改成 1,使 cpp_main() 执行完初始化后返回,程序才能继续创建任务并启动调度器。
  • 下面沿用前面配置了FreeRTOS的工程,因此先将 isRTOS 改为 1。

然后打开工程根目录的 CMakeLists.txt,在CubeMX原有的 add_subdirectory(cmake/stm32cubemx) 后面添加 add_subdirectory(cmake/user),引用用户代码的配置:

# Add STM32CubeMX generated sources
add_subdirectory(cmake/stm32cubemx)

# Add USER generated sources
add_subdirectory(cmake/user)

在同一个顶层 CMakeLists.txt 中,保留原有的C语言标准设置,并在 project() 之前增加C++标准设置(模板的 README-zh_CN.md 中也有说明):

# Setup compiler settings
set(CMAKE_C_STANDARD 11 CACHE STRING "C language standard")
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)

set(CMAKE_CXX_STANDARD 20 CACHE STRING "C++ language standard")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)

然后在 applications 下新建 led_task 文件夹,把 led_task.cpp 和 led_task.h 都放进去:

applications/
├── main/
│   ├── cpp_interface.cpp
│   └── cpp_interface.h
└── led_task/
    ├── led_task.cpp
    └── led_task.h

applications/led_task/led_task.cpp:

#include "led_task/led_task.h"
#include "cmsis_os.h"
#include "main.h"

int32_t t;

extern "C"
void StartDefaultTask(void *argument)
{
  for(;;)
  {
    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
    ++t;
    osDelay(500);
  }
}

applications/led_task/led_task.h:

#ifndef LED_TASK_H
#define LED_TASK_H

#include "main/cpp_interface.h"

#endif

然后打开 cmake/user/CMakeLists.txt,把刚才新建的源文件添加到 Applications_Src 列表中:

set(Applications_Src
    ${CMAKE_CURRENT_SOURCE_DIR}/../../applications/main/cpp_interface.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/../../applications/led_task/led_task.cpp
)

只需要登记新增的 .c、.cpp 文件,.h、.hpp 不需要列为编译源文件。因为 applications 已经是头文件搜索根目录,led_task 模块也不需要额外添加搜索路径。

详细介绍(可以不看):cmake/stm32cubemx/CMakeLists.txt 由CubeMX管理,重新生成代码时可能更新,因此用户代码的源文件列表和头文件搜索路径统一维护在 cmake/user/CMakeLists.txt 中,顶层 CMakeLists.txt 通过 add_subdirectory(cmake/user) 加载它。这个用户配置文件已经包含在模板里,前面复制时就已经带过来了。

The great task is accomplished; let's try compiling once. As shown in the figure below, all the newly added files have been compiled.

alt text

4.4.Download the program to the board

Before downloading, you must first configure:

If you are not using ST-Link or J-Link, continue reading below

Click according to the following image; see which debugger you are, and select that one.

If the corresponding device is not visible here, or if you encounter permission issues, please seeUSB permission issues on Linux.

You can update the ST-Link driver:

First install the bundle for jlink-gdbserver, as shown in the figure below:

alt text

4.4.2.Use the OpenOCD service to drive the native GDB debugger

When you want to use a debugger other thanST-LinkandJ-Link:

先点调试,让他生成launch.json:

openOCD接管SelectSTM32Cube: STM32 Launch GDB:

Then selectopenocd:

After a while, the debugging will definitely fail, and then it will prompt youopen launch.json

Then click STM32Cube: STM32 Launch GDB:

launch.jsonThe content is as follows:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "stgdbtarget",
            "request": "launch",
            "name": "STM32Cube: Launch Generic GDB Server",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
            "gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
            "deviceName": "${command:st-stm32-ide-debug-launch.get-device-name}",
            "deviceCore": "${command:st-stm32-ide-debug-launch.get-core-name}",
            "deviceTrustzone": "${command:st-stm32-ide-debug-launch.get-trustzone-status}",
            "serverExe": "",
            "serverParameters": [],
            "serverHost": "localhost",
            "serverPort": "",
            "serverCwd": "",
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "imageOffset": "",
                    "symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "symbolOffset": ""
                }
            ]
        },
        {
            "type": "stgdbtarget",
            "request": "attach",
            "name": "STM32Cube: Launch GDB Client",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
            "gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
            "serverHost": "localhost",
            "serverPort": "${command:st-stm32-ide-debug-launch.get-server-port}",
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "imageOffset": "",
                    "symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "symbolOffset": ""
                }
            ]
        }
    ]
}

Where do we need to make changes?

Mainly:

  • serverExe : Just enter the binary program name openocdoropenocd.exe
  • serverParameters : enter those two OpenOCD parameters, refer to The two -f parameters of openocd
  • serverHost : The OpenOCD GDB Server listens on localhost by default, generally no need to change
  • serverPort : The default GDB port of OpenOCD is 3333
  • serverCwd : EnterserverExeWhich directory is this binary program located in
  • AddliveWatchparameter (important)
  1. serverExe:

For Linux, enter openocd For Windows, enter openocd.exe

  1. serverParametersFollow this format:

Those two-fThe parameters are given bythe two -f parameters of OpenOCDIt can be seen that:

  • interface/stlink.cfg
  • target/stm32f1x.cfg

However, in addition to these two, some parameters are also required:

            "serverParameters": [                
                "-f",
                "interface/stlink.cfg",

                "-c",
                "transport select swd",

                "-f",
                "target/stm32f1x.cfg",

                "-c",
                "$_TARGETNAME configure -gdb-max-connections 2"],

Here it is recommended to arrange the parameters in the order above: first the probe → then the communication protocol → then the MCU → and finally modify the parameters of this MCU target

Here-c transport select xxxis the protocol selection:

Actual debugging method Configuration
STM32 commonly used SWD transport select swd
JTAG transport select jtag

We generally useswdso choosetransport select swd.

Whereas this-c $_TARGETNAME configure -gdb-max-connections 2allows this OpenOCD target to simultaneously accept at most 2 GDB client connections.

Normal debugging already occupies one:

OpenOCD :3333
    ↑
    └── GDB #1
         普通 Debug

We also need to useLive Watch,so set the parameter to2after:

                  ┌─ GDB #1:普通 Debug
STM32 ← OpenOCD ──┤
                  └─ GDB #2:Live Watch
  1. serverCwd:

Directly search using terminal commands:

# Linux
which openocd

# Windows
where.exe openocd

Linux, as shown in the figure above, is/usr/bin/openocdthereforeserverCwdfill in/usr/bin.

Windows is as shown aboveC:\xpack-openocd-0.12.0-7\bin\openocd.exe,soserverCwdfill inC:\xpack-openocd-0.12.0-7\bin。 But you cannot directly fill inC:\xpack-openocd-0.12.0-7\bin,because injson中\is an escape character, so stupid Windows should fill inC:/xpack-openocd-0.12.0-7/binor double backslashesC:\\xpack-openocd-0.12.0-7\\bin。

  1. AddliveWatchParameters

AtserverCwd later,runEntry prefix with:

            "liveWatch": {
                "enabled": true,
                "samplesPerSecond": "4"
            },

Finally:

Linux:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "stgdbtarget",
            "request": "launch",
            "name": "STM32Cube: Launch Generic GDB Server",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
            "gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
            "deviceName": "${command:st-stm32-ide-debug-launch.get-device-name}",
            "deviceCore": "${command:st-stm32-ide-debug-launch.get-core-name}",
            "deviceTrustzone": "${command:st-stm32-ide-debug-launch.get-trustzone-status}",
            "serverExe": "openocd",
            "serverParameters": [                
                "-f",
                "interface/stlink.cfg",

                "-c",
                "transport select swd",

                "-f",
                "target/stm32f1x.cfg",

                "-c",
                "$_TARGETNAME configure -gdb-max-connections 2"],
            "serverHost": "localhost",
            "serverPort": "3333",
            "serverCwd": "/usr/bin",
            "liveWatch": {
                "enabled": true,
                "samplesPerSecond": "4"
            },
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "imageOffset": "",
                    "symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "symbolOffset": ""
                }
            ]
        },
        {
            "type": "stgdbtarget",
            "request": "attach",
            "name": "STM32Cube: Launch GDB Client",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
            "gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
            "serverHost": "localhost",
            "serverPort": "${command:st-stm32-ide-debug-launch.get-server-port}",
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "imageOffset": "",
                    "symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "symbolOffset": ""
                }
            ]
        }
    ]
}

Windows:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "stgdbtarget",
            "request": "launch",
            "name": "STM32Cube: Launch Generic GDB Server",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
            "gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
            "deviceName": "${command:st-stm32-ide-debug-launch.get-device-name}",
            "deviceCore": "${command:st-stm32-ide-debug-launch.get-core-name}",
            "deviceTrustzone": "${command:st-stm32-ide-debug-launch.get-trustzone-status}",
            "serverExe": "openocd.exe",
            "serverParameters": [                
                "-f",
                "interface/stlink.cfg",

                "-c",
                "transport select swd",

                "-f",
                "target/stm32f1x.cfg",

                "-c",
                "$_TARGETNAME configure -gdb-max-connections 2"],
            "serverHost": "localhost",
            "serverPort": "3333",
            "serverCwd": "C:/xpack-openocd-0.12.0-7/bin",
            "liveWatch": {
                "enabled": true,
                "samplesPerSecond": "4"
            },
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "imageOffset": "",
                    "symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "symbolOffset": ""
                }
            ]
        },
        {
            "type": "stgdbtarget",
            "request": "attach",
            "name": "STM32Cube: Launch GDB Client",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "program": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
            "gdb": "${command:st-stm32-ide-debug-launch.get-gdb-executable}",
            "serverHost": "localhost",
            "serverPort": "${command:st-stm32-ide-debug-launch.get-server-port}",
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "imageOffset": "",
                    "symbolFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}",
                    "symbolOffset": ""
                }
            ]
        }
    ]
}

4.4.3.How to enter debug

4.4.3.1.Display 1

If you are like the figure below, please do as follows:

If not, please scroll down to see display 2 below.

alt text

After clickingRun and Debug,the figure is as follows:

  • ST-LinkSelectSTM32cube: STM32 Launch STLink GDB Server
  • J-LinkSelectSTM32Cube: STM32 LaunchJLink GDB Server
  • openOCD接管SelectSTM32Cube: Launch Generic GDB Server

alt text

4.4.3.2.Display 2

If you are like the figure below, please do as follows:

alt text

The reason you see the above is probably that you already have a generatedlaunch.jsonnow. (You can simply click it directly.)

alt text

4.4.4.Enter debug

Then this bar will appear, and it will download the program to the board (only J-link) alt text

Then the program was successfully downloaded and entered Debug

alt text

As shown in the figure below, enter the variable you want to monitor in the top box, and it will be added to the real-time watch box.

Structs can also:

4.4.5.Change debugger software tocortex debug(Optional, not really necessary):

4.4.5.1.Installcortex debugPlugin

Search in VScode forcortex debugand install

4.4.5.2.进行launch.json的配置

New.vscode/launch.json:

{
    "version": "0.2.0",

    "configurations": [
        {
            // 调试配置名称
            "name": "STM32 - OpenOCD - Cortex Debug",

            // Cortex-Debug 固定写法
            "type": "cortex-debug",

            // 下载程序并开始调试
            "request": "launch",

            // 工程工作目录
            "cwd": "${workspaceFolder}",

            // ★ 必改:编译生成的 ELF
            "executable": "${workspaceFolder}/build/Debug/TEST.elf",

            // 使用 OpenOCD
            "servertype": "openocd",

            // ★ OpenOCD 可执行文件
            // Linux 下用 which openocd 查询
            "serverpath": "/usr/bin/openocd",

            // ★ 根据调试器和 MCU 修改
            //
            // ST-Link:
            // interface/stlink.cfg
            //
            // STM32F1:
            // target/stm32f1x.cfg
            //
            // STM32F4 则是:
            // target/stm32f4x.cfg
            "configFiles": [
                "interface/stlink.cfg",
                "target/stm32f1x.cfg"
            ],

            // ★ ARM GNU Toolchain 的 bin 目录
            // 建议不要直接写 "~"
            // 用 ${env:HOME} 更稳
            "armToolchainPath": "${env:HOME}/.local/share/stm32cube/bundles/gnu-tools-for-stm32/14.3.1+st.2/bin",

            // 启动后运行到 main()
            "runToEntryPoint": "main",

            // ★ Cortex Live Watch
            // OpenOCD 下可用
            // samplesPerSecond 最大 20
            // 先用 4Hz 足够
            "liveWatch": {
                "enabled": true,
                "samplesPerSecond": 4
            }


            // ============================================================
            // 以下为可选配置
            // ============================================================


            // 如果 Cortex-Debug 找不到 OpenOCD,
            // Linux:
            // which openocd
            //
            // 一般 Fedora 是:
            // /usr/bin/openocd
            //
            // "serverpath": "/usr/bin/openocd",


            // 如果 OpenOCD 找不到 interface/*.cfg 或 target/*.cfg,
            // Fedora 一般脚本目录在:
            // /usr/share/openocd/scripts
            //
            // 可以显式增加:
            //
            // "searchDir": [
            //     "/usr/share/openocd/scripts"
            // ],


            // 调试 Cortex-Debug / OpenOCD 问题:
            //
            // "showDevDebugOutput": "raw"
        }
    ]
}

Currently, we need to know three things:configFiles,executable,armToolchainPathandserverpath:

  1. configFiles:

Reference Two -f parameters of OpenOCD

We usedstm32f103c8andst-link: So"configFiles": ["interface/stlink.cfg","target/stm32f1x.cfg"].

  1. executable:

Use the terminal command in VS Code to search directly, or look directly in the VS Code file explorer:

# Linux
find build -name "*.elf"
# Windows
gci build -Recurse -File -Filter "*.elf"

Note that Windows uses powershell but cannot use cmd.

As shown in the figure above, inbuild/Debug/TEST.elf.

Thereforeexecutable = ${workspaceFolder}/build/Debug/TEST.elf.

  1. armToolchainPath:

Directly search using the terminal command in VSCode:

cube bundle show --project

This output indicates that I am usinggnu-tools-for-stm32@14.3.1+st.2

Use a command to find where he is:

# Linux
find ~/.local/share/stm32cube/bundles/gnu-tools-for-stm32 \
  -type f -name "arm-none-eabi-gdb"
# Windows
gci "$env:LOCALAPPDATA\stm32cube\bundles\gnu-tools-for-stm32" `
  -Recurse -File -Filter "arm-none-eabi-gdb.exe"

Note that Windows uses powershell but cannot use cmd.

Copy output result:

/home/tungchiahui/.local/share/stm32cube/bundles/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-gdb

But remove the final execution programarm-none-eabi-gdb; only up tobinis needed:

/home/tungchiahui/.local/share/stm32cube/bundles/gnu-tools-for-stm32/14.3.1+st.2/bin

ThereforearmToolchainPath = /home/tungchiahui/.local/share/stm32cube/bundles/gnu-tools-for-stm32/14.3.1+st.2/bin.

  1. serverpath:

Directly search using terminal commands:

# Linux
which openocd

As for Windows, you should know where you installed it yourself...

Finallaunch.json:

{
    "version": "0.2.0",

    "configurations": [
        {
            // 调试配置名称
            "name": "STM32 - OpenOCD - Cortex Debug",

            // Cortex-Debug 固定写法
            "type": "cortex-debug",

            // 下载程序并开始调试
            "request": "launch",

            // 工程工作目录
            "cwd": "${workspaceFolder}",

            // ★ 必改:编译生成的 ELF
            "executable": "${workspaceFolder}/build/Debug/TEST.elf",

            // 使用 OpenOCD
            "servertype": "openocd",

            // ★ OpenOCD 可执行文件
            // Linux 下用 which openocd 查询
            "serverpath": "/usr/bin/openocd",

            // ★ 根据调试器和 MCU 修改
            //
            // ST-Link:
            // interface/stlink.cfg
            //
            // STM32F1:
            // target/stm32f1x.cfg
            //
            // STM32F4 则是:
            // target/stm32f4x.cfg
            "configFiles": [
                "interface/stlink.cfg",
                "target/stm32f1x.cfg"
            ],

            // ★ ARM GNU Toolchain 的 bin 目录
            // 建议不要直接写 "~"
            // 用 ${env:HOME} 更稳
            "armToolchainPath": "/home/tungchiahui/.local/share/stm32cube/bundles/gnu-tools-for-stm32/14.3.1+st.2/bin",

            // 启动后运行到 main()
            "runToEntryPoint": "main",

            // ★ Cortex Live Watch
            // OpenOCD 下可用
            // samplesPerSecond 最大 20
            // 先用 4Hz 足够
            "liveWatch": {
                "enabled": true,
                "samplesPerSecond": 4
            }
        }
    ]
}
4.4.5.3.Debug and LiveWatch

Compile first

Click to enter debug:

Successfully entered:

Copy a global variable from your program; in my case it is cmd_vel2:

fill in tocortex live watchnote it is notstm32cube live watch;

Then click Run to look at the variables.cmd_vel2

is constantly changing:

5.Frequently Asked Questions

5.1.USB permission issues under Linux

If you have already successfully recognized the device, there is no need to perform this step.

If you encounter it and can't solve it, let AI solve it; AI will get it done for you in a few seconds

If the debugger can be seen in lsusb after it is plugged in, but VS Code cannot find the device, or the following error appears in the debug output, it is usually because the current user does not have permission to access the USB device node:

libusb couldn't open USB device /dev/bus/usb/001/008, errno=13
libusb requires write access to USB device nodes
ST-Link enumeration failed

First run lsusb in the terminal to confirm that the debugger has been recognized by the system. The /dev/bus/usb/001/008 in the error message is only an example; the actual path should be based on your own output. You can use ls -l to check the permissions of that node:

lsusb
ls -l /dev/bus/usb/001/008

**使用 ST-Link:**先按上文点击插件中的 install ST-Link udev rules。如果仍然报权限错误,检查规则是否装到了系统中:

find /etc/udev/rules.d /usr/lib/udev/rules.d -maxdepth 1 -iname '*stlink*.rules' -print 2>/dev/null

如果没有找到规则,可以从 ST 官方的 STSW-LINK007 下载页获取安装包。解压后进入 AllPlatforms/StlinkRulesFilesForLinux,按其中的 readme.txt 安装与你的发行版对应的 udev 规则包。在这个目录中,Fedora 使用 .rpm 包,Ubuntu/Debian 使用 .deb 包:

# Fedora:只运行这一行
sudo dnf install ./st-stlink-udev-rules-*.rpm

# Ubuntu/Debian:只运行这一行
sudo apt install ./st-stlink-udev-rules-*.deb

If the downloaded package name differs, refer to the actual file name and the instructions included with the package. ST's release notes also state that the corresponding ST-Link USB access rules need to be installed under Linux.

**Use J-Link:** The previously installed jlink-gdbserver bundle is used to start the debug service; USB permissions also require SEGGER's udev rules. When installing the SEGGER J-Link Software and Documentation Pack, the .rpm or .deb package for the corresponding distribution will install the rules along with it. If using the extracted version, follow the README.txt included in the package to copy 99-jlink.rules to /etc/udev/rules.d/. For specific steps, see SEGGER's Linux troubleshooting instructions.

After installing the rule, run:

sudo udevadm control --reload-rules

Thenunplug the debugger and plug it back in,rerun lsusb,and check the /dev/bus/usb/... node using the new bus number and device number. You can substitute the actual path into the command below to check whether the current user can read and write:

test -r /dev/bus/usb/001/008 && test -w /dev/bus/usb/001/008 && echo 'USB 设备节点可读写'

After unplugging and replugging, the device number may change. Do not copy the 001/008 from the example. After confirming permissions, return to VS Code and reselect the debugger. If lsusb still cannot see the debugger, first check the USB cable, port, and power supply; this is not a udev permission issue.

Here, what is being checked is /dev/bus/usb/.... If additionally the onboard virtual serial port /dev/ttyACM* needs to be opened, that involves the permissions of the serial device and must be investigated separately.