TQMa8MPxL - YOCTO Linux BSP documentation
Setting up VS Code for TQMa8MPxL
The guide shows how to set up the Linux development host for using VS Code for building, deploying and debugging C/C++ programs on STKa8MPxL.
Prerequisites
- BSP built according to quickstart guide
- Yocto SDK built based on the current RootFS configuration, installed on the development host. See Build Yocto SDK how to build it.
- Configured SSH login on target.
- Configured network connection between target and development host
Setup Workspace
Create a new workspace for the project:
mkdir vscode_debug
cd vscode_debug
Install and Setup VS Code
If not already installed, install VS Code:
snap install code
Before starting VS Code, source the prebuilt Yocto SDK:
source /opt/dumpling-wayland/6.0/environment-setup-armv8a-tq-linux
Note: Versions may differ!
Start VS Code:
code .
If not already installed, add the C/C++ extension in VS Code.
Project Setup
Create a C/C++ program to demonstrate debugging applications on the board. For now, a simple hello world programm is enough to illustrate the workflow. The setup process is based on NXP's VS Code setup guide. For more detailed information about the setup and used variables, see VS Code setup guide for i.MX8M.
First, create a main.c:
#include <stdio.h>
int main (){
printf("Hello World! \n");
return 0;
}
Further, create a Makefile:
CC ?= gcc CFLAGS ?= -Wall -Wextra DEBUGFLAGS = -Og -g TARGET = main SOURCE = main OBJECTS = $(TARGET).o .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJECTS) $(CC) $(CFLAGS) $(DEBUGFLAGS) -o $@ $^ $(OBJECTS): $(SOURCE).c $(CC) $(CFLAGS) $(DEBUGFLAGS) -c -o $@ $^
Project Configuration
Create a .vscode folder to store the project configuration files:
mkdir .vscode
Create a settings.jsonfile that defines the workspace variables used across other configuration files:
{
/* Target Device Settings */
"TARGET_IP":"10.250.250.12",
/* Project Settings */
"PROGRAM":"main",
/* SDK Configuration */
"ARCH":"aarch64-tq-linux",
"OECORE_NATIVE_SYSROOT":"/opt/dumpling-wayland/6.0/sysroots/x86_64-tqsdk-linux",
"SDKTARGETSYSROOT": "/opt/dumpling-wayland/6.0/sysroots/armv8a-tq-linux",
"CC_PREFIX": "${config:OECORE_NATIVE_SYSROOT}/usr/bin/${config:ARCH}/${config:ARCH}-",
"CXX": "${config:CC_PREFIX}g++ -march=armv8-a+crc+crypto -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=${config:SDKTARGETSYSROOT}",
"CC": "${config:CC_PREFIX}gcc -march=armv8-a+crc+crypto -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=${config:SDKTARGETSYSROOT}",
"CPP": "${config:CC_PREFIX}gcc -E -march=armv8-a+crc+crypto -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=${config:SDKTARGETSYSROOT}",
}
Configure Target_IP to match your target board's IP and set the sysroot paths accordingly.
Next, create a c_cpp_properties.json, where the settings for the C/C++ extension will be configured:
{
"configurations": [
{
"name": "Yocto-SDK",
"includePath": [
"${workspaceFolder}/**",
"${config:SDKTARGETSYSROOT}/usr/include/**"
],
"compilerPath": "${config:CC_PREFIX}gcc",
"intelliSenseMode": "linux-gcc-arm64",
"browse": {
"path": [
"${workspaceFolder}/**",
"${config:SDKTARGETSYSROOT}/usr/include/**"
],
"limitSymbolsToIncludedHeaders": true
}
}
],
"version": 4
}
Create a tasks.json, which is used to define automated tasks:
{
"version": "2.0.0",
"options": {
"env": {
"CXX": "${config:CXX}",
"CC": "${config:CC}",
"CPP": "${config:CPP}"
}
},
/* Configure integrated VS Code Terminal */
"presentation": {
"echo": false,
"reveal": "always",
"focus": true,
"panel": "dedicated",
"showReuseMessage": true,
},
"tasks": [
{
"label": "imx-deploy-gdb",
"isBackground": true,
"problemMatcher":{
"base": "$gcc",
"background": {
"activeOnStart": true,
"beginsPattern": "Deploying to target",
"endsPattern": "Starting GDB Server on Target"
}
},
"type": "shell",
"command": "sh",
"args": [
"imx-deploy-gdb.sh",
"${config:TARGET_IP}",
"${config:PROGRAM}"
],
"dependsOn": ["build"],
},
/* Configure Build Task */
{
"label": "build",
"type": "shell",
"command": "make clean; make -j$(nproc)",
"problemMatcher": ["$gcc"]
},
]
}
Create a launch.json, that is used to configure debug settings:
{
"version": "0.2.0",
"configurations": [{
"name": "GDB debug",
"type": "cppdbg",
"request": "launch",
"program": "${config:PROGRAM}",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"MIMode": "gdb",
"targetArchitecture": "arm64",
"preLaunchTask": "imx-deploy-gdb",
"setupCommands": [{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}],
"miDebuggerPath": "/opt/dumpling-wayland/6.0/sysroots/x86_64-tqsdk-linux/usr/bin/aarch64-tq-linux/aarch64-tq-linux-gdb",
"miDebuggerServerAddress": "${config:TARGET_IP}:3000",
}]
}
Finally, create a imx-deploy-gdb.sh script in the project's root directory:
#!/bin/bash
readonly TARGET_IP="$1"
readonly PROGRAM="$2"
readonly TARGET_DIR="/root"
# Must match startsPattern in tasks.json
echo "Deploying to target"
# kill gdbserver on target and delete old binary
ssh root@${TARGET_IP} "sh -c '/usr/bin/killall -q gdbserver; rm -rf ${TARGET_DIR}/${PROGRAM} exit 0'"
# send the program to the target
scp ${PROGRAM} root@${TARGET_IP}:${TARGET_DIR}
# Must match endsPattern in tasks.json
echo "Starting GDB Server on Target"
# start gdbserver on target
ssh -t root@${TARGET_IP} "sh -c 'cd ${TARGET_DIR}; gdbserver localhost:3000 ${PROGRAM}'"
Debugging the program
- Set a breakpoint in the main.c file
- In the top bar, press Run → Start Debugging
- The program will be compiled, sent to the board and a debugging session will be launched.