How to create a workspace in VS Code with global settings for AVR and STM32 microcontrollers and project-specific settings within each?
Setting Up VS Code Workspace for AVR and STM32 Microcontrollers
Setting up a VS Code workspace for AVR and STM32 microcontrollers requires creating a hierarchical structure of configuration files, where global settings define common parameters, and project-specific settings override them for particular projects.
Contents
- Understanding VS Code Workspace Structure
- Creating Global Settings for AVR and STM32
- Configuring Project-Specific Configurations
- Integration with Microcontroller Extensions
- Configuration File Examples
- Managing Multiple Projects
- Workflow Optimization
Understanding VS Code Workspace Structure
VS Code uses a flexible configuration system that allows separation of global and local settings. For AVR and STM32 microcontroller development, this structure becomes particularly important.
A workspace in VS Code can consist of multiple levels:
- Global settings (
settings.json) - applied to all projects - Workspace settings (
workspace.json) - applied to all projects in the current folder - Project-specific settings (
.vscode/settings.json) - applied only to this project
For AVR and STM32 development, the following structure is recommended:
~/.vscode/
├── settings.json (global settings)
MyProjects/
├── .vscode/
│ ├── settings.json (settings for all projects in folder)
│ └── extensions.json
├── AVR_Projects/
│ ├── Project1/
│ │ ├── .vscode/settings.json
│ │ └── ...
│ └── Project2/
│ ├── .vscode/settings.json
│ └── ...
└── STM32_Projects/
├── ProjectA/
│ ├── .vscode/settings.json
│ └── ...
└── ProjectB/
├── .vscode/settings.json
└── ...
Creating Global Settings for AVR and STM32
Global settings define common parameters that will be used across all microcontroller development projects.
Basic Global Configuration
Create a file ~/.vscode/settings.json with the following content:
{
"files.associations": {
"*.c": "c",
"*.h": "c",
"*.cpp": "cpp",
"*.hpp": "cpp",
"*.s": "arm",
"*.S": "arm",
"*.asm": "arm"
},
"C_Cpp.default.configurationProvider": "ms-vscode.cpptools",
"terminal.integrated.defaultProfile.linux": "bash",
"terminal.integrated.defaultProfile.osx": "bash",
"terminal.integrated.defaultProfile.windows": "PowerShell",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
"cSpell.words": [
"STM32",
"HAL",
"LL",
"LLD",
"CMSIS",
"UART",
"GPIO",
"I2C",
"SPI",
"ADC",
"DMA",
"NVIC",
"SysTick",
"USART",
"TIM",
"RCC",
"PWR",
"FLASH",
"SRAM",
"CRC",
"IWDG",
"WWDG"
],
"git.ignoreLimitWarning": true,
"search.exclude": {
"**/build": true,
"**/obj": true,
"**/.git": true,
"**/node_modules": true,
"**/Debug": true,
"**/Release": true,
"**/dist": true
},
"files.exclude": {
"**/build": true,
"**/obj": true,
"**/.git": true,
"**/node_modules": true,
"**/Debug": true,
"**/Release": true,
"**/dist": true,
"**/.vscode/settings.json": true
}
}
Microcontroller Development Specific Settings
Add to global settings parameters specific to AVR and STM32:
{
"avr-tools.path": "/usr/bin/avr-gcc",
"avr-tools.makePath": "/usr/bin/make",
"stm32cube.ide.path": "/opt/STM32CubeIDE",
"stm32cube.ide.toolchain.path": "/opt/st/STM32CubeIDE_1.15.0/STM32CubeIDE",
"platformio-ide-terminal.integrated.env.windows": {
"PATH": "${env:PATH};C:\\Program Files (x86)\\Atmel Studio\\7.0\\toolchain\\avr8\\avr8-gnu-toolchain\\bin"
},
"platformio-ide-terminal.integrated.env.linux": {
"PATH": "${env:PATH}:/usr/bin/avr-gcc:/opt/STM32CubeIDE_1.15.0/STM32CubeIDE/plugins/ctools/arm-none-eabi-gcc/bin"
}
}
Configuring Project-Specific Configurations
For each AVR or STM32 project, create a separate configuration in the .vscode folder.
Example AVR Project Configuration
In the root of an AVR project, create a .vscode folder with a settings.json file:
{
"cmake.configureOnOpen": true,
"cmake.generator": "Unix Makefiles",
"tasks": {
"version": "2.0.0",
"tasks": [
{
"label": "Build AVR Project",
"type": "shell",
"command": "make",
"args": [
"all"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": "$gcc"
},
{
"label": "Clean AVR Project",
"type": "shell",
"command": "make",
"args": [
"clean"
],
"group": "build"
},
{
"label": "Flash AVR",
"type": "shell",
"command": "avrdude",
"args": [
"-p",
"${input:mcu}",
"-c",
"${input:programmer}",
"-U",
"flash:w:build/main.hex:i",
"-P",
"${input:port}",
"-b",
"${input:baudrate}"
],
"group": "build",
"problemMatcher": []
}
]
},
"inputs": [
{
"id": "mcu",
"type": "pickString",
"description": "Select microcontroller",
"options": [
"atmega328p",
"atmega2560",
"atmega168",
"atmega88"
],
"default": "atmega328p"
},
{
"id": "programmer",
"type": "pickString",
"description": "Select programmer",
"options": [
"arduino",
"usbasp",
"avrisp",
"stk500"
],
"default": "arduino"
},
{
"id": "port",
"type": "promptString",
"description": "Connection port",
"default": "/dev/ttyUSB0"
},
{
"id": "baudrate",
"type": "pickString",
"description": "Port speed",
"options": [
"19200",
"38400",
"57600",
"115200"
],
"default": "115200"
}
]
}
Example STM32 Project Configuration
For an STM32 project, the configuration will be more complex due to the need to work with STM32CubeIDE:
{
"cmake.configureOnOpen": true,
"cmake.generator": "Unix Makefiles",
"tasks": {
"version": "2.0.0",
"tasks": [
{
"label": "Generate STM32 Project",
"type": "shell",
"command": "${workspaceFolder}/scripts/generate_project.sh",
"args": [
"${input:mcu}",
"${input:core}"
],
"group": "build",
"problemMatcher": []
},
{
"label": "Build STM32 Project",
"type": "shell",
"command": "make",
"args": [
"-j4"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": "$gcc"
},
{
"label": "Flash STM32",
"type": "shell",
"command": "${workspaceFolder}/scripts/flash.sh",
"args": [
"${input:interface}",
"${input:port}"
],
"group": "build",
"problemMatcher": []
}
]
},
"inputs": [
{
"id": "mcu",
"type": "pickString",
"description": "Select STM32 microcontroller",
"options": [
"STM32F103C8T6",
"STM32F103ZET6",
"STM32F407VGT6",
"STM32F411CEU6",
"STM32L476RG"
],
"default": "STM32F103C8T6"
},
{
"id": "core",
"type": "pickString",
"description": "Select processor core",
"options": [
"M0",
"M3",
"M4",
"M7"
],
"default": "M3"
},
{
"id": "interface",
"type": "pickString",
"description": "Programming interface",
"options": [
"stlink",
"jlink",
"serial"
],
"default": "stlink"
},
{
"id": "port",
"type": "promptString",
"description": "Programmer port",
"default": "/dev/ttyACM0"
}
]
}
Integration with Microcontroller Extensions
Required Extensions
For effective work with AVR and STM32 in VS Code, install the following extensions:
- C/C++ (Microsoft) - extension for C/C++ development
- PlatformIO IDE - for managing microcontroller projects
- STM32 for VS Code - specialized extension for STM32
- Arduino - for Arduino-compatible projects
- Makefile Tools - for working with Makefile
- CMake Tools - for managing CMake projects
Extension Configuration
Create a file ~/.vscode/extensions.json to manage extensions:
{
"recommendations": [
"ms-vscode.cpptools",
"platformio.platformio-ide",
"stm32-for-vscode.stm32-for-vscode",
"vsciot-vscode.vscode-arduino",
"ms-vscode.makefile-tools",
"ms-vscode.cmake-tools",
"streetsidesoftware.code-spell-checker",
"ms-python.python",
"ms-vscode.vscode-json"
]
}
For automatic extension installation, use an extensions.json file in the workspace root:
{
"recommendations": [
"ms-vscode.cpptools",
"platformio.platformio-ide",
"stm32-for-vscode.stm32-for-vscode"
]
}
Configuration File Examples
AVR Compiler Flags
Create a .vscode/c_cpp_properties.json file to configure the compiler:
{
"configurations": [
{
"name": "AVR",
"includePath": [
"${workspaceFolder}/**",
"/usr/lib/avr/include",
"${workspaceFolder}/lib",
"${workspaceFolder}/src"
],
"defines": [
"F_CPU=16000000UL",
"AVR_ATmega328P",
"__AVR_ATmega328P__"
],
"compilerPath": "/usr/bin/avr-gcc",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
STM32 Compiler Flags
{
"configurations": [
{
"name": "STM32",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/Drivers/CMSIS/Include",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32F1xx/Include",
"${workspaceFolder}/Drivers/STM32F1xx_HAL_Driver/Inc",
"${workspaceFolder}/Core/Inc"
],
"defines": [
"USE_HAL_DRIVER",
"STM32F103xx",
"DEBUG"
],
"compilerPath": "/opt/st/STM32CubeIDE_1.15.0/STM32CubeIDE/plugins/ctools/arm-none-eabi-gcc/bin/arm-none-eabi-gcc",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}
Managing Multiple Projects
For effective management of multiple projects, use workspace files.
Creating a Workspace File
Create a file microcontroller.code-workspace:
{
"folders": [
{
"path": "./AVR_Projects"
},
{
"path": "./STM32_Projects"
},
{
"path": "./Shared_Libraries"
}
],
"settings": {
"cmake.configureOnOpen": true,
"files.associations": {
"*.c": "c",
"*.h": "c"
}
},
"extensions": {
"recommendations": [
"ms-vscode.cpptools",
"platformio.platformio-ide",
"stm32-for-vscode.stm32-for-vscode"
]
}
}
Hierarchical Settings System
Implement a settings inheritance system:
- Global settings (
~/.vscode/settings.json) - basic parameters - Workspace settings - common parameters for all projects in the folder
- Project-specific settings - unique parameters for each project
Example of inheritance structure:
~/.vscode/settings.json (global)
├── MyProjects/.vscode/settings.json (common for all projects)
├── AVR_Projects/Project1/.vscode/settings.json
├── AVR_Projects/Project2/.vscode/settings.json
├── STM32_Projects/ProjectA/.vscode/settings.json
└── STM32_Projects/ProjectB/.vscode/settings.json
Workflow Optimization
Automating Build and Flashing Processes
Create scripts to automate routine operations:
Build AVR project:
#!/bin/bash
# scripts/build_avr.sh
MCU=${1:-atmega328p}
F_CPU=${2:-16000000}
make MCU=$MCU F_CPU=$F_CPU clean
make MCU=$MCU F_CPU=$F_CPU all
Flash STM32:
#!/bin/bash
# scripts/flash_stm32.sh
INTERFACE=${1:-stlink}
PORT=${2:-/dev/ttyACM0}
if [ "$INTERFACE" = "stlink" ]; then
openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c "program build/main.elf verify reset exit"
elif [ "$INTERFACE" = "jlink" ]; then
JLinkExe -if SWD -device STM32F103C8 -autoconnect 1 -speed 4000 -CommanderScript flash.jlink
fi
Integration with Version Control System
Configure .gitignore for microcontroller projects:
# AVR projects
*.hex
*.elf
*.o
*.d
build/
obj/
# STM32 projects
*.elf
*.bin
*.hex
*.map
*.d
Debug/
Release/
build/
# Generated files
*.dep
*.i
*.s
# IDE files
.project
.cproject
.settings/
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
Development Profiles
Create profiles for different development scenarios:
Debug profile:
{
"configurations": [
{
"name": "AVR Debug",
"includePath": [
"${workspaceFolder}/**",
"/usr/lib/avr/include"
],
"defines": [
"F_CPU=16000000UL",
"DEBUG",
"AVR_ATmega328P"
],
"compilerPath": "/usr/bin/avr-gcc",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "linux-gcc-x64"
}
]
}
Release profile:
{
"configurations": [
{
"name": "STM32 Release",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/Drivers/CMSIS/Include"
],
"defines": [
"NDEBUG",
"USE_HAL_DRIVER",
"STM32F103xx"
],
"compilerPath": "/opt/st/STM32CubeIDE_1.15.0/STM32CubeIDE/plugins/ctools/arm-none-eabi-gcc/bin/arm-none-eabi-gcc",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "linux-gcc-arm"
}
]
}
Sources
- Official VS Code Documentation - Workspaces and Folders
- C/C++ Extension Configuration Guide
- PlatformIO IDE Documentation
- STM32 for VS Code - Official Extension
- Makefile Configuration in VS Code
Conclusion
- Create a hierarchical settings structure with global and project-specific configurations
- Use workspace files to manage multiple projects simultaneously
- Configure specialized extensions for AVR and STM32 development
- Implement automation for building and flashing microcontrollers
- Use a settings inheritance system for reusing common parameters
- Create development profiles for different scenarios (debug, release, testing)
- Integrate version control with proper ignoring of generated files
This configuration will allow you to work effectively with AVR and STM32 projects while maintaining flexibility and reusability of common settings.