Yocto Programming with VSCode: Difference between revisions

From Variscite Wiki
No edit summary
No edit summary
Line 283: Line 283:
  ./hello.bin
  ./hello.bin


A new debugging session can be started by selecting '''Run->Start Debugging''' or by pressing 'F5' on the keyboard.
A new debugging session can be started by selecting '''Run->Start Debugging''' or by pressing 'F5' on the keyboard. VSCode will switch to the debug perspective and launch a gnome-terminal running gdbserver on the target device:
 
[[File:Vscode_debug.png]]


= Example Project Source Code =
= Example Project Source Code =

Revision as of 15:43, 27 July 2021

DART-MX8M-MINI - Yocto Programming with Visual Studio Code

Visual Studio Code (VSCode) is a powerful, modern code editor that can be used to develop and debug C/C++ applications on Variscite System on Modules.

This guide demonstrates how to create and debug a C++ application using VSCode on the DART-MX8M-MINI.


Setup Host Computer Environment

Please follow the steps below to prepare a fresh Ubuntu 20.04 installation for VSCode debugging:

Install Dependencies

$ sudo apt-get -y update
$ sudo apt-get -y install build-essential gdb gdb-multiarch git

Install VSCode

$ sudo snap install --classic code

Install VSCode Extensions

VSCode has a graphical interface for installing and managing extensions. To learn more, please see Using extensions in Visual Studio Code

For this guide, we will install the required extensions using the command line:

$ code --install-extension ms-vscode.cpptools

Install Yocto Toolchain

A toolchain is necessary for cross compiling applications. To install the toolchain, follow Variscite's Yocto Toolchain installation guide.

Create, cross compile, and run a new "Hello, World!" project

First, open a new terminal and configure the environment with the toolchain setup script:

$ source /opt/fslc-xwayland/3.1/environment-setup-aarch64-fslc-linux 

From the same terminal, create an empty project directory and open VSCode:

$ mkdir ~/var-hello-world
$ cd ~/var-hello-world
$ code .

This will launch VSCode with ~/var-hello-world as working directory (which is currently empty):

Vscode start.png

Next, we will create the following files:

main.cpp Source code for hello.bin
Makefile Makefile to cross compile main.cpp
.vscode/tasks.json VSCode file to override or add new tasks. Runs Makefile when VSCode build command is executed.
.vscode/c_cpp_properties.json VSCode file to configure include path for IntelliSense.


To create a new file or folder in VSCode, right click in the VSCode explorer view and select New File or New Folder:

Vscode start newfile.png

Create a new file called main.cpp:

main.cpp:

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Hello, World!\n");
    return 0;
}

Create a new Makefile to build hello.bin:

Makefile:

all: main.cpp
	$(CXX) $(CXXFLAGS) -Og main.cpp -g -o hello.bin
clean:
	rm -f hello.bin

Create a new folder named .vscode. Then, create a new file .vscode/tasks.json

.vscode/tasks.json:

{
    "version": "2.0.0",
    "tasks": [{
        "label": "build",
        "type": "shell",
        "command": "make clean; make -j$(nproc)",
        "problemMatcher": [],
    }]
}

Configure the include path for IntelliSense by creating vscode/c_cpp_properties.json.

.vscode/c_cpp_properties.json:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "${SDKTARGETSYSROOT}/usr/include/"
            ]
        }
    ],
    "version": 4
}


Your workspace should look similar to this:

Vscode-gdb-build.png

Compile the project by selecting Terminal->Run Build Task... or entering Ctrl+Shift+B and selecting Build:

Vscode run build task.png

Open a new VSCode terminal by selecting Terminal->New Terminal or entering Ctrl+Shift+`.

Send hello.bin to the target device using SCP:

$ scp hello.bin root@<ip addr>:/home/root/

Vscode new terminal.png

Launch hello.bin on the target device:

# ./hello.bin 
Hello, World!

Remote Debugging with VSCode

After verifying hello.bin runs on the target device, we can now setup VSCode for remote debugging.

The working directory should currently have these files:

variscite@ubuntu:~/var-hello-world$ find 
./.vscode/tasks.json
./Makefile
./main.cpp
./hello.bin

To enable debugging, ww will edit .vscode/tasks.json and add two additional files to the project:

var-build-and-debug.sh Generic script to build, deploy, and launch gdbserver
.vscode/launch.json VSCode file to configure debug settings. Runs var-build-and-debug in tasks.json
.vscode/tasks.json Edit to call var-debug-and-debug.sh prior to debugging.


Create var-build-and-debug.sh

First, add a generic script to build, deploy, and launch gdbserver. The script requires two arguments:

  1. TARGET_IP: The IP Address of the target device
  2. PROGRAM: The name of the binary executable, hello.bin in this example

In the end, tasks.json will run this script at the beginning of each debug session.

var-build-and-debug.sh:

#!/bin/bash
readonly TARGET_IP="$1"
readonly PROGRAM="$2"
readonly TARGET_DIR="/home/root"

# rebuild project
make clean; make -j$(nproc)

# kill gdbserver on target
ssh root@${TARGET_IP} "sh -c '/usr/bin/killall -q gdbserver; exit 0'"

# send the program to the target
scp ${PROGRAM} root@${TARGET_IP}:${TARGET_DIR}

# start gdbserver on target
REMOTE_GDB_CMD="ssh -t root@${TARGET_IP} \"sh -c 'cd ${TARGET_DIR}; gdbserver localhost:3000 ${PROGRAM}'\""
gnome-terminal -x bash -c "${REMOTE_GDB_CMD}"

Create launch.json

VSCode has a powerful built in debugger capable of debugging many programming languages. In this step, we will add a configuration for debugging CPP:

.vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [{
        "name": "GDB debug",
        "type": "cppdbg",
        "request": "launch",
        "program": "hello.bin",
        "args": [],
        "stopAtEntry": true,
        "cwd": "${workspaceFolder}",
        "environment": [],
        "console": "integratedTerminal",
        "MIMode": "gdb",
        "targetArchitecture": "arm64",
        "preLaunchTask": "var-build-and-debug",
        "setupCommands": [{
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
        }],
        "miDebuggerPath": "/usr/bin/gdb-multiarch",
        "miDebuggerServerAddress": "192.168.0.118:3000",
    }]
}

See the table below for important details regarding launch.json variables:

miDebuggerServerAddress Must match the IP Address of the target device
program Must match the name of the binary generated by the the Makefile
preLaunchTask Must match the name of the task in .vscode/tasks.json in the following step


Create tasks.json

In launch.json, we created a preLaunchTask to run a task named var-build-and-debug at the beginning of each debugging session. This task is configured by adding a new task to .vscode/tasks.json:

.vscode/tasks.json:

{
    "version": "2.0.0",
    "tasks": [{
        "label": "var-build-and-debug",
        "type": "shell",
        "command": "sh",
        "args": [
            "var-build-and-debug.sh",
            "192.168.0.118",
            "hello.bin"
        ],
    },{
        "label": "build",
        "type": "shell",
        "command": "make clean; make -j$(nproc)",
        "problemMatcher": [],
    }]
}

The following table summarizes the var-build-and-debug configuration in tasks.json:

label Must match preLaunchTask in launch.json
type This task will launch a shell
command Launch sh, with arguments var-build-and-debug.sh 192.168.0.136 hello.bin

Note: The IP Address must match the IP address of the target device, as defined in .vscode/launch.json

Launch a Debugging Session

After following the steps above, the working directory should now have these files:

~/var-hello-world$ find
./.vscode/launch.json
./.vscode/tasks.json
./Makefile
./var-build-and-debug.sh
./main.cpp
./hello.bin

A new debugging session can be started by selecting Run->Start Debugging or by pressing 'F5' on the keyboard. VSCode will switch to the debug perspective and launch a gnome-terminal running gdbserver on the target device:

Vscode debug.png

Example Project Source Code

The source code for this example is available from Variscite's Github repository:

$ git clone https://github.com/nsdrude-varigit/var-demos
$ cd var-demos/hello-world

Setup the toolchain environment:

$ source /opt/fslc-xwayland/3.1/environment-setup-aarch64-fslc-linux

Launch VSCode:

$ code .

Configure the target device IP Address in .vscode/tasks.json and .vscode/launch.json

Finally, start a debugging session by selecting Run->Start Debugging or pressing 'F5' on the keyboard.