Yocto Programming with VSCode: Difference between revisions
Line 137: | Line 137: | ||
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 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", | "version": "0.2.0", | ||
Line 171: | Line 171: | ||
|<code>program</code> || Must match the name of the binary generated by the the Makefile | |<code>program</code> || Must match the name of the binary generated by the the Makefile | ||
|- | |- | ||
|<code>preLaunchTask</code> || Must match the name of the task in <code>. | |<code>preLaunchTask</code> || Must match the name of the task in <code>.vscode/tasks.json</code> in the following step | ||
|} | |} | ||
== Create tasks.json == | |||
In <code>launch.json</code>, we created a <code>preLaunchTask</code> to run a task named <code>var-build-and-debug</code> at the beginning of each debugging session. This task is configured by adding a '''.vscode/tasks.json''' file: | |||
'''.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.136", | |||
"hello.bin" | |||
], | |||
}] | |||
} | |||
The following table summarizes variables in tasks.json: | |||
{| class="wikitable" | |||
|- | |||
|<code>label</code> || Must match preLaunchTask in '''launch.json''' | |||
|- | |||
|<code>type</code> || This task will launch a shell | |||
|- | |||
|<code>command</code> || Launch sh, with arguments <code>var-build-and-debug.sh "192.168.0.136" "hello.bin"</code> | |||
|} | |||
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 | |||
./.vscode/launch.json | |||
./.vscode/tasks.json | |||
./Makefile | |||
./var-build-and-debug.sh | |||
./main.cpp | |||
./hello.bin | |||
A new debugging session can be started by typing 'f5' on the keyboard. Please refer to the image below for a real time demonstration of this process: | |||
[[File:Vscode-gdb.gif|1280px]] | |||
= Example Project Source Code = | = Example Project Source Code = |
Revision as of 16:59, 14 July 2021
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 VAR-SOM-MX8M-NANO.
Setup Host Computer Environment
This guide is tested using a fresh Ubuntu 20.04 installation.
Install Dependencies
$ sudo apt-get -y update $ sudo apt-get -y install build-essential gdb gdb-multiarch cmake
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/fsl-imx-xwayland/5.4-zeus/environment-setup-aarch64-poky-linux
From the same terminal, create an empty project directory and open VSCode:
$ mkdir ~/var-hello-world $ cd ~/var-hello-world $ code .
Create a new file called main.cpp. This demo uses freopen to redirect stdout to /dev/console on the target device. This way we can see the output even when debugging remotely using GDB:
#include <iostream> int main(int argc, char *argv[]) { FILE *fp; fp = freopen("/dev/console","w",stdout); printf("Hello, World!\n"); fclose(fp); return 0; }
Create a new Makefile to build hello.bin
all: main.cpp $(CXX) $(CXXFLAGS) main.cpp -g -o hello.bin clean: rm -f hello.bin
Open a new terminal in VSCode by typing ctrl+shift+`
. Your workspace should look similar to this:
Run make
in the new terminal
$ make
Send the file to the target device using SCP:
$ scp hello.bin root@<ip addr>:/home/root/
Run 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:
~/var-hello-world$ find . ./Makefile ./main.cpp
We will add three 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 | VSCode file to override or add new tasks. Calls 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:
TARGETIP
: The IP Address of the target deviceEXE
: The name of the 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 TARGETIP="$1" readonly EXE="$2" readonly EXE_TARGET_DIR="/home/root" # rebuild project make clean; make -j8 # kill gdbserver on target ssh root@$TARGETIP "sh -c '/usr/bin/killall -q gdbserver; exit 0'" # send exe to target scp $EXE root@$TARGETIP:${EXE_PATH} # start gdbserver on target ssh -n -f root@$TARGETIP "sh -c 'cd ${EXE_DIR}; nohup gdbserver localhost:3000 ${EXE}'"
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": [], "externalConsole": true, "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.136: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 .vscode/tasks.json file:
.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.136", "hello.bin" ], }] }
The following table summarizes variables 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 ./.vscode/launch.json ./.vscode/tasks.json ./Makefile ./var-build-and-debug.sh ./main.cpp ./hello.bin
A new debugging session can be started by typing 'f5' on the keyboard. Please refer to the image below for a real time demonstration of this process: