Skip to content
| Marketplace
Sign in
Visual Studio Code>Debuggers>STM32 Cross Development ContainersNew to Visual Studio Code? Get it now.
STM32 Cross Development Containers

STM32 Cross Development Containers

Meddoks Developments

|
8 installs
| (0) | Free
Containerised build, flash and debug for CubeMX STM32 projects
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

STM32 Cross Development Containers

Build, flash and debug CubeMX STM32 projects inside containers, from VS Code.

Your machine needs Docker and, on Windows, usbipd-win. The compiler, OpenOCD and GDB live in the image — nothing is installed on the host, and a project builds the same way on every machine that opens it.

The problem it removes

A CubeMX project carries a Makefile with an absolute path to whoever generated it, a linker script, and an assumption that the right arm-none-eabi-gcc is somewhere on PATH. Getting a colleague to a working breakpoint usually costs an afternoon, and the result differs from yours in ways nobody notices until the firmware does.

Declare the project once in stm32cdc.json, and the tasks, launch configuration, IntelliSense settings and dev container are generated from it. Your own files are never edited — CubeMX rewrites its Makefile, linker script and sources whenever it regenerates, so everything the tool needs arrives from outside. Regenerating from the .ioc stays a no-op.

Requirements

Docker Desktop on Windows, or the engine on Linux
usbipd-win Windows only, to forward the debug probe into the container
Dev Containers the Microsoft extension, for opening a project in its container

macOS is not supported: Docker Desktop there has no USB passthrough into containers, so debugging cannot work.

Getting started

  1. Get the images — run STM32CDC: Build images from source. The recipe ships inside this extension, so no registry is involved. It downloads a Debian base, its packages and the Arm toolchain; a few minutes, once.
  2. Open a CubeMX project and run STM32CDC: Initialize project. It reads the device from the .ioc and the target from the build files, asks only for the probe and the image tags, and offers to fetch a matching SVD.
  3. Plug in the probe and run STM32CDC: Attach debug probe. On Windows the first use of each USB port raises a UAC prompt — binding needs it.
  4. Open the project in its dev container, then Ctrl+Shift+B to build and F5 to debug.

When something misbehaves, run STM32CDC: Diagnose environment before anything else. It checks the two dozen things that actually go wrong with this stack and names the command that fixes each one.

Prefer pulling to building? Set stm32cdc.imageRegistry to where the images are published and run STM32CDC: Pull images. Pulling is faster and gives everyone a byte-identical image; building is the path that works with no registry at all.

What it supports

  • Both CubeMX project shapes — Makefile and CMake, detected rather than configured.
  • Arm GNU Toolchain 14.3, pinned by version and SHA256.
  • ST-Link, CMSIS-DAP and J-Link, with the probe chosen explicitly when several are connected, remembered per workspace, and by device rather than by USB port — so the choice survives a replug.
  • Peripheral registers, with the SVD matched to your device and fetched on request; CubeMX does not ship one.

Commands

Command
Initialize project Writes stm32cdc.json for a CubeMX project
Project settings A form over that manifest
Init / fix project configuration Regenerates the VS Code and container files
Build project · Clean build output Through the generated tasks
Attach · Detach · Select debug probe usbipd, including the elevation prompt
Add peripheral register view (SVD) Fetches and installs the right SVD
Open project in its dev container Creates the container, checking the probe first
Pull images · Build images from source Either way of getting them
Clean up containers left behind Stopped dev containers accumulate one per project
Diagnose environment Start here when something is wrong

All of them are also in the activity bar, grouped by what you are doing, with the state on screen rather than behind a command: which project is active, which build driver it uses, whether an SVD is configured, whether the probe is forwarded right now.

Settings

Setting
stm32cdc.imageRegistry Where released images live, e.g. ghcr.io/acme; enables pulling instead of building
stm32cdc.toolchainTag Toolchain part of the image tag; the version part comes from the extension
stm32cdc.probes vid:pid values treated as debug probes — CMSIS-DAP ids differ per vendor, so add yours
stm32cdc.svdRepository · stm32cdc.svdRef Where SVDs come from, pinned to a commit
stm32cdc.wslDistro Distribution used for the usbipd attach
stm32cdc.showStatusBar · stm32cdc.refreshIntervalSeconds Status bar and how often probe state is polled

stm32cdc.json has a JSON schema registered for that filename, so completion, hover documentation and error checking work without a network round trip. Unknown fields are rejected — the point is to catch a misspelled key, which otherwise fails silently by being ignored.

Known limitations

  • One window reload the first time a dev container is created. VS Code installs the debug extensions after the extension host has started, and devcontainer.json has no way to ask for anything else.
  • An extension can be installed in the container and still disabled, because enablement lives in your client profile, keyed by extension id, and no API can change it. Use Enable (Workspace), which scopes the change to that folder.
  • amd64 only — the Dockerfile uses the x86_64 toolchain tarball.
  • Locally built images are not byte-identical across machines: only the toolchain is pinned by checksum, the Debian packages float. Pull published images when that matters.

How it works, briefly

The extension runs on the host, always — usbipd is a Windows program and the Docker CLI talks to the local daemon, and neither is reachable from inside a dev container. It builds nothing itself: builds go through the generated VS Code task, debugging through Cortex-Debug, and configuration through a generator that lives in the builder image.

That last point is what keeps one build path rather than two. A task runs wherever the window is — on the host for a local folder, inside the container for a remote one — so the same command works in both without knowing which it is in.

Licence

MIT.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft