Using embOS with Visual Studio Code and CMake

From SEGGER Knowledge Base
Jump to navigation Jump to search

This guide shows how to create a Visual Studio Code project for embOS BSPs using CMake, Ninja, and the Arm GNU toolchain. CMake will be configured to generate the Ninja build files for a debug and a release configuration. Ninja is a small and fast cross-platform build system designed to be used with build file generators like CMake. Therefore, the Visual Studio Code project can be used with Windows, Linux, and macOS. CMake will be executed indirectly through the Visual Studio Code project to generate the Ninja build files and to build the executables. Furthermore, the executables can be loaded and debugged on the target using gdb and J-Link.

An example project for the SEGGER emPower board, Visual Studio Code and CMake can be downloaded here: File:embOS Classic CortexM GCC Obj SFL V5.20.0.0 VSCode CMake.zip

Requirements

Following tools are required:

Furthermore, this guide expects the CMake, Ninja, Arm GNU toolchain, and J-Link Software and Documentation Pack executables to be accessible via the system's path environment variable. Should this not be possible, absolute paths need be used instead.

Project overview

The Visual Studio Code project consists of the following files:

  • CMakeLists.txt
  • CMakePresets.json
  • optional Visual Studio Code workspace file (*.code-workspace)
  • .vscode/launch.json
  • .vscode/tasks.json

The CMakeLists.txt, CMakePresets.json, the optional worskpace file, and the .vscode directory need to be placed in the root directory of the embOS BSP whereas the tasks.json and launch.json files need to be placed in the .vscode diectory. This guide uses the BSP for the SEGGER emPower board taken from the embOS-Classic Cortex-M GCC port. The project structure of the embOS shipment is also kept as it is. Therefore, the files and the directory are placed at .../Start/BoardSupport/Segger/K66FN2M0_emPower/.

The CMakeLists.txt defines everything required by CMake to generate the Ninja build files. This includes the target platform, the toolchain, source files, include paths, macro definitions, compiler options and linker options. And the CMakePresets.json file is used to facilitate the usage of CMake as it contains all information that needs to be passed to CMake to generate or build the available configurations of the project.

The Visual Studio Code workspace file is optional but it can be used to easily open Visual Studio Code and display additional directories and files in the explorer view.

The tasks.json file provides tasks that can be executed to generate the build files with CMake and to build applications. The launch.json enables Visual Studio Code to start a debug session for the Debug and the Release configurations. It also specifies the respective prelaunch tasks so that the application is re-built when the debug session is started.

Visual Studio Code workspace

If you want to use a Visual Studio Code workspace, you can create a *.code-workspace file in the root directory of the BSP with the following content. This will give the BSP directory the specified name and also add the Inc and Lib directory to the explorer view. It can also be used to store project specific settings that shall be used by everyone that is using this workspace.

{
  "folders": [
    {
      "path": ".",
      "name": "Start K66FN2M0"
    },
    {
      "path": "./../../../Inc"
    },
    {
      "path": "./../../../Lib"
    }
  ],
  "settings": {}
}

CMake files

For creating the CMakeLists.txt and CMakePresets.json files, please refer to Using embOS with CMake. These files can be used as they are for the Visual Studio Code project.

tasks.json

The following tasks.json creates tasks for generating the build files and building the application for the Debug and Release configurations by invoking CMake with the desired preset.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Build Debug",
      "type": "shell",
      "command": "cmake",
      "args": [
        "--build",
        "--preset", "Debug"
      ],
      "group": "build",
      "problemMatcher": [],
      "detail": "Builds the K66FN2M0 debug configuration.",
      "dependsOn": "Configure Debug"
    },
    {
      "label": "Configure Debug",
      "type": "shell",
      "command": "cmake",
      "args": [
        "--preset Debug"
      ],
      "group": "build",
      "problemMatcher": [],
      "detail": "Generates the build files for the K66FN2M0 debug configuration."
    },
    {
      "label": "Build Release",
      "type": "shell",
      "command": "cmake",
      "args": [
        "--build",
        "--preset", "Release"
      ],
      "group": "build",
      "problemMatcher": [],
      "detail": "Builds the K66FN2M0 release configuration.",
      "dependsOn": "Configure Release"
    },
    {
      "label": "Configure Release",
      "type": "shell",
      "command": "cmake",
      "args": [
        "--preset Release"
      ],
      "group": "build",
      "problemMatcher": [],
      "detail": "Generates the build files for the K66FN2M0 release configuration."
    }
  ]
}

launch.json

The launch.json file shown below contains two launch configurations, one for starting a debug and the other for starting a release debug session. Starting a debug session will also invoke its prelaunch task that generates the build files and builds the application if necessary. For further information on creating a launch.json file for debugging embedded devices with Visual Studio Code and J-Link, please refer to J-Link Visual Studio Code.

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug",
      "cwd": "${workspaceFolder}",
      "executable": "${workspaceFolder}/Output/Debug/Start_K66FN2M0.elf",
      "request": "launch",
      "type": "cortex-debug",
      "runToEntryPoint": "main",
      "servertype": "jlink",
      "device": "MK66FX1M0xxx18",
      "interface": "jtag",
      "svdFile": "${workspaceFolder}/Setup/MK66F18.svd",
      "preLaunchTask": "Build Debug"
    },
    {
      "name": "Release",
      "cwd": "${workspaceFolder}",
      "executable": "${workspaceFolder}/Output/Release/Start_K66FN2M0.elf",
      "request": "launch",
      "type": "cortex-debug",
      "runToEntryPoint": "main",
      "servertype": "jlink",
      "device": "MK66FX1M0xxx18",
      "interface": "jtag",
      "svdFile": "${workspaceFolder}/Setup/MK66F18.svd",
      "preLaunchTask": "Build Release"
    }
  ]
}

Using the Visual Studio Code project

After creating all files the BSP directory should look similar to this:

K66FN2M0_emPower/
├─ .vscode/
│  ├─ launch.json
│  └─ tasks.json
├─ Application/
│  └─ ...
├─ CoreSupport/
│  └─ ...
├─ DeviceSupport/
│  └─ ...
├─ SEGGER/
│  └─ ...
├─ Setup/
│  └─ ...
├─ Start_K66FN2M0.code-workspace
├─ CMakePresets.json
├─ CMakeLists.txt
└─ ReadMe.txt

Now, open the workspace or the BSP directory with Visual Studio Code. Open the "Run and Debug" view on the left and open the drop down list with the launch configurations. You should see a Debug and a Release configuration.

embOS VSCode RunAndDebug.png


Select one of the configurations and pree F5 or click on the play button to start the debug session. Before starting the debug session, Visual Studio Code will invoke the prelaunch task that generates the Ninja build files and also builds the application. As soon as the application was built successfully, the debug session is started.

embOS VSCode DebugSession.png