Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt

Use this file to discover all available pages before exploring further.

Visual Studio 2022 extends its C++ IDE to embedded and IoT development through a dedicated toolset built for microcontrollers and real-time operating systems. The Linux and embedded development with C++ workload adds the Peripheral View for inspecting hardware registers, the Serial Monitor for UART communication, and the RTOS Object View for inspecting thread and kernel object state — all within the same IDE you use for desktop development.
Starting with Visual Studio 2026 (version 18.0), the Embedded and IoT tools — RTOS Viewer, Serial Monitor, Peripheral Viewer, and ST Project Import — are deprecated and will be removed in a future update. The underlying debugging infrastructure (GDB, OpenOCD integration) continues to work. For ongoing embedded development, consider migrating to the Embedded Tools extension for VS Code.

Installing the Embedded Tooling

1

Open the Installer

Search for Visual Studio Installer in the Windows search box and open it.
2

Select the workload

Click Modify next to Visual Studio 2022. On the Workloads tab, scroll to Other toolsets and select Linux and embedded development with C++.The workload includes:
  • Visual C++ for Linux development (GCC/Clang remote compiler support)
  • CMake support for cross-compilation
  • Peripheral View and RTOS View debugger extensions
  • Serial Monitor extension
3

Apply changes

Click Modify to install. No restart is required.

Use Cases for Embedded C++ Development

Embedded development covers a wide range of targets and use cases:

Microcontrollers (MCUs)

Bare-metal or RTOS-based firmware for STM32, NXP i.MX RT, Nordic nRF, and similar Cortex-M / Cortex-A targets. No OS — your C++ code runs directly on the hardware.

IoT Devices

Connected devices with wireless stacks (Wi-Fi, BLE, LoRa, Cellular). Often run lightweight RTOSes such as FreeRTOS, Azure RTOS (ThreadX), or Zephyr.

Industrial Control

PLCs, motor controllers, and real-time control systems with strict timing requirements. Frequently use RTOS scheduling with hard deadlines.

Embedded Linux

Linux-based embedded boards (Raspberry Pi, NVIDIA Jetson, BeagleBone). These are debugged with GDB over SSH using the Linux development workload.

Peripheral View

The Peripheral View allows you to inspect and modify hardware peripheral registers while paused at a breakpoint during a debug session. It reads SVD (System View Description) files — an industry-standard XML format published by chip vendors — to display peripherals, registers, and bitfields with their names, descriptions, and current values.

Opening the Peripheral View

In Visual Studio, the Peripheral View appears automatically during a debug session on embedded hardware. Navigate to DebugWindowsPeripheral View if it isn’t already docked.

Peripheral View Capabilities

CapabilityDescription
Navigate peripheralsExpand and collapse the peripheral tree. Use arrow keys to scroll through peripheral groups, registers, and bitfields.
Edit register valuesClick a writeable register value and press Enter to submit a new value. Press F2 to enter edit mode, Esc to cancel.
Access memoryClick a linked memory address to open that location in the Memory window.
Pin peripheralsClick the pin icon next to frequently-used peripherals to keep them at the top of the view.
SearchType in the search bar to filter the peripheral tree by name or description.

Providing an SVD File

Most chip vendors publish SVD files on their product pages or in their SDK. Load an SVD file in your launch.json or OpenOCD configuration:
// launch.json (VS Code / Visual Studio CMake project)
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug (OpenOCD)",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/build/firmware.elf",
      "miDebuggerServerAddress": "localhost:3333",
      "miDebuggerPath": "arm-none-eabi-gdb",
      "svdPath": "${workspaceFolder}/STM32F407.svd",
      "setupCommands": [
        { "text": "target remote localhost:3333" },
        { "text": "monitor reset halt" },
        { "text": "load" }
      ]
    }
  ]
}
When the SVD file is loaded, every peripheral defined in your chip’s reference manual is browsable in the Peripheral View during debugging.

Serial Monitor

The Serial Monitor lets you configure, monitor, and communicate with serial (UART) ports — the primary communication channel for most microcontrollers. It is essential for reading debug printf output, testing AT commands, and sending configuration data to a device.

Installing the Serial Monitor

In Visual Studio: go to ExtensionsManage Extensions, search for Serial Monitor 2, and click Install. Restart Visual Studio to complete the installation.

Key Serial Monitor Settings

SettingDescriptionCommon Values
PortThe COM port connected to your deviceCOM3, COM4, /dev/ttyUSB0
Baud RateMust match the UART baud rate in your firmware9600, 115200, 250000
Line EndingAppended to messages you sendNone, LF, CR, CRLF
Data bitsBits per serial frame8 (standard)
ParityError detection bitNone (standard)
TimestampPrefix received lines with PC timestampOn / Off
AutoscrollAuto-scroll to latest dataOn / Off
File LoggingSave all serial output to a fileOn / Off

Firmware Example: Debug Output via UART

// Typical embedded debug printf redirected to UART
// (HAL-based example for STM32 with STM32CubeMX-generated HAL)

#include "stm32f4xx_hal.h"
#include <cstdio>

extern UART_HandleTypeDef huart2;

// Override _write() so printf routes to UART2
extern "C" int _write(int file, char* data, int len) {
    HAL_UART_Transmit(&huart2,
                      reinterpret_cast<uint8_t*>(data),
                      static_cast<uint16_t>(len),
                      HAL_MAX_DELAY);
    return len;
}

int main() {
    HAL_Init();
    SystemClock_Config();
    MX_USART2_UART_Init();

    uint32_t counter = 0;
    while (true) {
        printf("Tick %lu: sensor = %d mV\r\n", counter++, ReadSensor());
        HAL_Delay(1000);
    }
}
Open the Serial Monitor, select the COM port at 115200 baud, and you will see the tick output in real time while your device runs.

RTOS Object View

The RTOS Object View lets you inspect the live state of RTOS kernel objects — threads, queues, semaphores, timers, and memory pools — while paused at a breakpoint. It replaces manual memory inspection with a structured, named view of your system’s concurrency state.

Supported RTOSes

All features work out of the box with no special build flags. Inspectable objects include:
  • Threads — name, state, priority, stack usage
  • Queues, Semaphores, Mutexes, Event Flags
  • Block pools and Byte pools
  • Timers
Most features are available. Additional build flags unlock more detail:
  • configUSE_MUTEXES=1 — enables thread base priority reporting
  • configGENERATE_RUN_TIME_STATS=1 — enables per-thread run-time counters
  • configRECORD_STACK_HIGH_ADDRESS=1 — enables stack end-address reporting
  • configMAX_PRIORITIES — set to the minimum value your app requires for faster thread-list retrieval
Inspectable objects: Threads (Tasks), Queues
Requires specific Kconfig options in your board configuration:
  • CONFIG_DEBUG_THREAD_INFO=y — all thread information
  • CONFIG_INIT_STACKS=y + CONFIG_THREAD_STACK_INFO=y — stack usage
  • CONFIG_TRACING=y + CONFIG_TRACING_OBJECT_TRACKING=y — non-thread objects
Inspectable objects: Threads, Mutexes, Semaphores, Queues, Message queues, Mailboxes, Timers, Memory slabs, Stacks, Pipes

Using the RTOS Object View

During a debug session paused at a breakpoint:
  1. The RTOS Object View panel populates automatically with detected kernel objects.
  2. Use the Up / Down arrow keys to navigate objects. Press Enter to follow a linked memory address to the Memory window.
  3. Click a thread name to jump to its current state in the Watch window.
  4. Object values update each time the debugger pauses (breakpoint, step, or manual halt).

Example: CMake Project for Bare-Metal ARM

cmake_minimum_required(VERSION 3.21)
project(EmbeddedFirmware C CXX ASM)

# Toolchain is set via CMakePresets.json or -DCMAKE_TOOLCHAIN_FILE
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# Source files
add_executable(firmware.elf
    src/main.cpp
    src/uart.cpp
    src/startup_stm32f407xx.s
    src/system_stm32f4xx.c
)

# Include directories for CMSIS and HAL
target_include_directories(firmware.elf PRIVATE
    include
    Drivers/CMSIS/Include
    Drivers/CMSIS/Device/ST/STM32F4xx/Include
    Drivers/STM32F4xx_HAL_Driver/Inc
)

# Linker script
target_link_options(firmware.elf PRIVATE
    -T${CMAKE_SOURCE_DIR}/STM32F407VGTx_FLASH.ld
    -Wl,--gc-sections
    -Wl,-Map=firmware.map
    --specs=nosys.specs
)

# Post-build: generate .bin and .hex for flashing
add_custom_command(TARGET firmware.elf POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -O binary firmware.elf firmware.bin
    COMMAND ${CMAKE_OBJCOPY} -O ihex  firmware.elf firmware.hex
    COMMENT "Generating firmware.bin and firmware.hex"
)
Configure this project with the arm-none-eabi.cmake toolchain file shown in the CMake Cross-Platform guide and add it as a preset to get full Visual Studio IDE support, IntelliSense, and the Peripheral View during debug sessions.

Build docs developers (and LLMs) love