NeuroAgent

Setting up VS Code workspace for AVR and STM32

Complete guide to creating a VS Code workspace with global settings for AVR and STM32 microcontrollers and project-specific configurations.

Question

How to create a workspace in VS Code with global settings for AVR and STM32 microcontrollers and project-specific settings within each?

NeuroAgent

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

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:

  1. Global settings (settings.json) - applied to all projects
  2. Workspace settings (workspace.json) - applied to all projects in the current folder
  3. 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:

json
{
  "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:

json
{
  "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:

json
{
  "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:

json
{
  "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:

  1. C/C++ (Microsoft) - extension for C/C++ development
  2. PlatformIO IDE - for managing microcontroller projects
  3. STM32 for VS Code - specialized extension for STM32
  4. Arduino - for Arduino-compatible projects
  5. Makefile Tools - for working with Makefile
  6. CMake Tools - for managing CMake projects

Extension Configuration

Create a file ~/.vscode/extensions.json to manage extensions:

json
{
  "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:

json
{
  "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:

json
{
  "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

json
{
  "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:

json
{
  "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:

  1. Global settings (~/.vscode/settings.json) - basic parameters
  2. Workspace settings - common parameters for all projects in the folder
  3. 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:

bash
#!/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:

bash
#!/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:

json
{
  "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:

json
{
  "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

  1. Official VS Code Documentation - Workspaces and Folders
  2. C/C++ Extension Configuration Guide
  3. PlatformIO IDE Documentation
  4. STM32 for VS Code - Official Extension
  5. 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.