cancel
Showing results for 
Search instead for 
Did you mean: 

How to configure STM32 VS Code extension to use OpenOCD

STM_Thirty2
ST Employee

Summary

The STM32 VS Code extension doesn’t natively support OpenOCD, but with some simple configuration, you can integrate it into your debugging workflow. This article covers how to set up OpenOCD (either Streamline or ST’s fork) with the extension by modifying the launch.json file, allowing you to maintain a consistent GDB server setup across tools and frameworks like Zephyr.

Introduction

Using VS Code for STM32 development offers a powerful and flexible environment for embedded projects, with the added advantage of being cross-platform, running seamlessly on Windows, macOS, and Linux. However, while the STM32CubeCLT is designed to integrate closely with the STM32 VS Code extension, it doesn’t include STMicroelectronics' fork of OpenOCD by default. This omission can pose challenges for developers who prefer OpenOCD, as it’s widely used in other tools and frameworks.

Despite this, VS Code’s robust flexibility and extensive customization options make it a great choice for automating workflows, including building, flashing, and debugging STM32 projects. The combination of VS Code and STM32CubeCLT is especially powerful for integrating CI/CD workflows, enabling developers to standardize their toolchains across operating systems while maintaining consistency and efficiency. In this article, I’ll guide you through the steps to configure the STM32 VS Code extension to work with OpenOCD. This helps you to take full advantage of an efficient and versatile development environment.

1. Prerequisites

In this article, I use a Nucleo-U083RC with the STM32 VS Code extension found in the VS Marketplace. I’m working in a Linux environment, but all content covered here is the same across different operating systems.

2. OpenOCD Options: Streamline vs. ST's fork

When customizing the STM32 VS Code extension, you have two main options for OpenOCD: the community-maintained Streamline version or STMicroelectronics' fork. Both are capable of supporting debugging with STM32 devices, but there are key differences to consider:

  • Streamline OpenOCD
    The Streamline version of OpenOCD is widely used across different platforms and frameworks, making it a popular choice for developers who prefer consistency. However, this version often lags behind in adding support for newer STM32 devices, as it relies on contributions from ST and the open-source community.
  • ST’s OpenOCD fork
    ST’s fork of OpenOCD is updated more frequently to support the latest microcontrollers and features. It ensures compatibility with ST tools.

Both options are valid, but developers targeting newer STM32 chips or features might prefer ST’s fork to ensure seamless support. Those working across diverse platforms may choose Streamline for its broader integration.

For this article I use ST's fork of OpenOCD which is included with STM32CubeIDE, albeit heavily buried in the file system.

3. Integrating OpenOCD into VS Code launch

3.1 Project setup

This article assumes preexisting knowledge on how to use the STM32 VS Code extension to build and debug projects.

For a quick refresh you can watch and read these short tutorials:

First, we can start off by making a simple project. For this article a Nucleo-U083RC is used, and the project made is based off of the board selector.

STM_Thirty2_0-1732844454636.png

 

 

 

 

 

 

 

 

 

 

 

 

We initialize all the BSP peripherals code to their defaults.

STM_Thirty2_1-1732844636529.png

The important bit here is that we set Toolchain/IDE to CMake so that we can import this project into the STM32 VS Code extension

STM_Thirty2_2-1732844759012.png

Generate the project and import it using the STM32 VS Code extension per the video tutorial seen here.

scrnshot.jpg

Add simple blink LED code into the main function so we can have a visual representation that the code is running on our hardware

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
    BSP_LED_Toggle(LED_GREEN);
    HAL_Delay(1000); 
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
 }

You can now launch a debug session per the tutorial video above and verify everything works as expected.

3.2 Customizing the launch json

The launch.json file in VS Code is used to configure debugging sessions, specifying how the debugger connects to your target device. For STM32 development, this file defines parameters such as the GDB server, target interface, and any specific initialization commands. By customizing launch.json, you can adapt your debugging setup to work with different tools, like OpenOCD, and tailor the experience to your specific requirements.

In the image below, you'll notice that the available debug sessions, [Build & Debug Microcontroller - ST-Link] and [Attach to Microcontroller - ST-Link] correspond directly to the two configurations defined in the launch.json file. The name element in each configuration determines what appears in the dropdown menu for selecting a debug session.

STM_Thirty2_4-1732845866151.png

Before we can modify the json file we need to get our hands on a configuration file that is generated by STM32CubeIDE, since it does support OpenOCD by default.

3.2.1 Steps to generate an OpenOCD config file

  • Make a STM32CubeIDE project for the same device/board.
  • Open the debug configuration and change the debug probe setting from [ST-Link GDB-Server] to [ST-Link Openocd].
    In the image below you can see that once the debug probe is changed a new file is generated on the left-hand side of Project Explorer.
  • Copy the contents of the Debug.cfg file (my project is called temp, which is why it says "temp Debug.cfg"). In a few steps, we paste it into a new file.
  • Furthermore, if you plan to use the STM32CubeIDE included OpenOCD fork, press the [Show Command Line] button to show the command line arguments. Take note of the path for the OpenOCD executable and the path for the scripts folder. Copy and paste those somewhere for use in the next step.

debugconfig.png

3.2.2 Add new config file to existing VS Code project

  • Make a new file in the root of the VS Code project and name it whatever you want with a .cfg extension.
  • Paste into it the contents of the Debug.cfg file from the STM32CubeIDE project.

3.2.3 Adding a new debug session to launch.json

In the code below, I’ve added the entire launch.json as not to cause confusion about json syntax. The only new item is the last section is the OpenOCD debug session. I’ll go over each element below.

{
    // 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": [
        {
            "name": "Build & Debug Microcontroller - ST-Link",
            "cwd": "${workspaceFolder}",
            "type": "cortex-debug",
            "executable": "${command:cmake.launchTargetPath}",
            // Let CMake extension decide executable: "${command:cmake.launchTargetPath}"
            // Or fixed file path: "${workspaceFolder}/path/to/filename.elf"
            "request": "launch",
            "servertype": "stlink",
            "device": "STM32U083RCTx", //MCU used
            "interface": "swd",
            "serialNumber": "",        //Set ST-Link ID if you use multiple at the same time
            "runToEntryPoint": "main",
            "svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32U083.svd",
            "v1": false,               //Change it depending on ST Link version
            "serverpath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",
            "stm32cubeprogrammer":"${config:STM32VSCodeExtension.cubeCLT.path}/STM32CubeProgrammer/bin",
            "stlinkPath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",   
            "armToolchainPath": "${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin",
            "gdbPath":"${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb",            
            "serverArgs": [
                "-m","0",
            ],
            //"preLaunchTask": "Build + Flash"
            /* If you use external loader, add additional arguments */
            //"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
        },
        {
            "name": "Attach to Microcontroller - ST-Link",
            "cwd": "${workspaceFolder}",
            "type": "cortex-debug",
            "executable": "${command:cmake.launchTargetPath}",
            // Let CMake extension decide executable: "${command:cmake.launchTargetPath}"
            // Or fixed file path: "${workspaceFolder}/path/to/filename.elf"
            "request": "attach",
            "servertype": "stlink",
            "device": "STM32U083RCTx", //MCU used
            "interface": "swd",
            "serialNumber": "",        //Set ST-Link ID if you use multiple at the same time
            "runToEntryPoint": "main",
            "svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32U083.svd",
            "v1": false,               //Change it depending on ST Link version
            "serverpath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",
            "stm32cubeprogrammer":"${config:STM32VSCodeExtension.cubeCLT.path}/STM32CubeProgrammer/bin",
            "stlinkPath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",   
            "armToolchainPath": "${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin",
            "gdbPath":"${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb",            
            "serverArgs": [
                "-m","0",
            ],
            /* If you use external loader, add additional arguments */
            //"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
        },
        {
            "name": "OpenOCD",
            "cwd": "${workspaceFolder}",
            "type": "cortex-debug",
            "executable": "${command:cmake.launchTargetPath}",
            "request": "launch",
            "servertype": "openocd",
            "serverpath": "/home/eddie/st/stm32cubeide_1.16.0/plugins/com.st.stm32cube.ide.mcu.externaltools.openocd.linux64_2.3.200.202404091248/tools/bin/openocd",
            "configFiles": [
                "debugConfig.cfg"
            ],
            "serverArgs": [
                "-s","${env:SCRIPTS_PATH}",
                "-d3"

            ],
            "device": "STM32U083RCTx",
            "runToEntryPoint": "main",
            "svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32U083.svd",
             "showDevDebugOutput": "raw"
        }
            ]
}

Here’s a breakdown of each element in the OpenOCD configuration section in launch.json a lot of the settings are copied over from the default configurations, like device name and SVD path etc.

3.2.4 General configuration

  • name: Specifies the name of the debug configuration, which appears in the VS Code dropdown menu when selecting a debug session.
  • cwd: Defines the working directory for the debugging session. ${workspaceFolder} sets it to the root of your project.
  • type: Indicates the debugger type, with cortex-debug used for STM32 development.
  • executable: Specifies the path to the compiled binary to be debugged, resolved dynamically with ${command:cmake.launchTargetPath}.
  • request: Determines the type of debugging session, where "launch" starts the program and "attach" connects to a running process.

3.2.5 OpenOCD specific configuration

  • servertype: Specifies the type of GDB server to use, set to "openocd" for OpenOCD debugging.
  • serverpath: Defines the path to the OpenOCD executable. Using ${env:SERVER_PATH} allows you to set this path via an environment variable. Here you set the path to your streamline OpenOCD or the ST fork.
  • configFiles: Lists OpenOCD configuration files, which define target-specific settings like the MCU type and debugging interface.
  • serverArgs: Additional arguments for OpenOCD, such as -s to specify the search path for OpenOCD scripts (for example, ${env:SCRIPTS_PATH} for flexibility) and -d3 to set the debug verbosity level. Here, the path varies if you are using the streamline OpenOCD or the ST fork.

3.2.6 Target specific options

  • device: Specifies the target STM32 microcontroller to ensure proper initialization for debugging.
  • runToEntryPoint: Defines the entry point function where debugging pauses automatically, typically set to "main".
  • svdFile: Path to the system view description (SVD) file for the MCU, which provides peripheral register definitions for enhanced debugging.

3.2.7 Debugging output

  • showDevDebugOutput: Controls the verbosity of debug output in the VS Code debug console, with "raw" showing unprocessed output from the debugger.

At this point, you should be able to debug you application per usual.

STM_Thirty2_0-1732849430755.png

Conclusion

While the STM32 VS Code extension doesn’t officially support OpenOCD by default, the flexibility of VS Code allows developers to integrate tools like OpenOCD with a bit of configuration. This adaptability ensures you can create a tailored debugging setup that works seamlessly across different frameworks and tools. By taking advantage of this flexibility, you can streamline your workflow and maintain consistency, whether you’re working on STM32 projects or across multiple embedded platforms. With your environment now configured, you’re ready to debug efficiently and focus on building great solutions. Happy debugging!

Related links

Version history
Last update:
‎2025-01-30 4:35 AM
Updated by: