====== Visual Studio Code ====== Visual Studio Code (VS Code) is a free, open source development environment developed by Microsoft and optimized for many programming languages such as C, %%C++%%, C# and Python. One of the most important features of VS Code is its support for IntelliSense, a code completion and debugging technology. In the context of building C programs and including them in the Yocto build system, VS Code offers a number of extensions and tools that help developers perform their work more efficiently and accurately. Below we will describe the steps to build C programs with VS Code and how to integrate them into the Yocto build system. === Knowledge Requirements === This tutorial requires basic knowledge of the programming languages %%C/C++%% and Make. === Tested Software/Hardware === This tutorial is tested on **Ubuntu 22.04** as host system with the **TQMa8MPxL** as target module. \\ However, the procedure is the same for other modules. ===== Install VS Code ===== Visual Studio is available for many different platforms such as Linux, Windows and MacOS. In this tutorial we will use the tool on Linux (Ubuntu), but the procedures will be similar for all platforms. \\ It is available for download from the official website: \\ [[https://code.visualstudio.com/|https://code.visualstudio.com/]] \\ ==== Install VS Code C/C++ extension ==== The %%C/C++%% extension in Visual Studio Code allows developers to write, edit, and debug %%C/C++%% code directly in VSCode. It provides features such as IntelliSense (code completion), code formatting, syntax checking, support for multiple compilers, and the ability to create and manage %%C++%% projects. In addition, it also allows controlling build and debug processes through the integrated terminal. The installation is done via the built-in extension management of VS Code:\\ 1. Open the extensions menu or use the keyboard shortcut **Ctrl+Shift+x** to open it \\ 2. Search for the extension %%C/C++%% from Microsoft \\ 3. Klick **Install** \\ {{:en:general_information:vscode_extention_c.png?nolink&600|}} Alternatively it can be installed via the Linux CLI: code --install-extension ms-vscode.cpptools ==== Linux host dependencies ==== Some Dependencies are required on the Linux host. \\ Under Ubuntu these can be installed as follows: sudo apt install build-essential gdb gdb-multiarch ===== Setup for ARM ===== The source code can be compiled for different platforms. It is important that the correct cross compiler is used. \\ Below we explain how to install and use the ARM compilers for our embedded modules. ==== SDK Installation ==== For the next steps the appropriate ARM compilers are needed. These can be found in the Yocto-SDK of the corresponding module. If you have already built the BSP, the SDK can be built with the following command: bitbake -c populate_sdk ++++ example | bitbake -c populate_sdk tq-image-weston-debug ++++ After building the toolchain, a script file is generated, which must be executed on the host system to install the toolchain. More information about building the SDK can be found in the **HowTo > Development Host** section of the corresponding module. ==== Create and build Project ==== Our project files are all created in a project folder. The first thing we need to do is create this folder in your workspace: mkdir hello_world After creating the folder we can open it in VSCode under **File > Open Folder...**. \\ Next we create the main sourcefile main.cpp under **File > new File...** or by pressing **Alt + Ctrl + N** Next, we create the main source file main.cpp and fill it with the following sample source code: #include int main(int argc, char *argv[]) { printf("Hello, World!\n"); return 0; } Immediately after inserting the code, VSCode should show an error on the first __#include__ because it does not know where the include files are located. \\ To make the error disappear, we have to tell VSCode where the include files are located. For this we create the folder .vscode in the root directory of the folder and in it the file c_cpp_properties.json with the following content: { "configurations": [ { "name": "Linux", "compilerPath": "", "intelliSenseMode": "linux-gcc-arm64", "includePath": [ "${workspaceFolder}/**", "${SDKTARGETSYSROOT}/usr/include/**" ] } ], "version": 4 } Note that for 32bit-Plattforms, **linux-gcc-arm64** would be **linux-gcc-arm** In the next file we set the IP of our target device. To find out the IP, run ''ifconfig'' command on target. Create a settings.json file in the .vscode folder, fill it with the following and modify the IP: { "TARGET": { "IP": "192.168.1.100" }, "C_Cpp.errorSquiggles": "disabled" } In order for VSCode to know what to run when the Run button is clicked, we need to configure the task. This is done in the new file tasks.json in the .vscode folder. Note that before building, the correct environment variables from the cross compiler need to be sourced. That can be performed directly in "command": { "version": "2.0.0", "tasks": [ { "label": "build all", "type": "shell", "command": "source /opt/dumpling-wayland-nxp/3.3.6/environment-setup-cortexa53-crypto-tq-linux; make clean; make -j$(nproc)", "problemMatcher": [], "group": { "kind": "build", "isDefault": true } }, ] } To compile the program, we have to tell the compiler what to do. This is done via a **Makefile** which is created in the root folder (not .vscode): #build all all: main.cpp $(CXX) $(CXXFLAGS) -Og main.cpp -g -o helloworld.bin #clean build result clean: rm -f helloworld.bin The project is now set up and ready to be built. The build process can be started via the entry **Terminal > Run Build Task** or by pressing **Ctrl+Shift+b**. ===== Deploy and debug on Target ===== Deploying the program to the target works via scp and for debugging the own application via the GDB debugger. Make sure SSH is set up and accessible on the target! See the HowTo page of the corresponding module for more information. ==== Deploy over terminal ==== VSCode offers the option to start a terminal session directly in the program. This function makes it unnecessary to switch between different terminal windows and offers the possibility to copy the previously built binary directly from the terminal to the target with scp. To open a new terminal, goto **Terminal > New Terminal**. the new terminal opens directly in the project folder and allows you to deploy the software to the target using the following command: scp helloworld.bin root@:/root/ The built executable is sent to the /root/ directory of the running target over scp. It can then be executed from the console of the target. ./helloworld.bin === Tip === In VS Code, several terminals can be started simultaneously. One of them can be used for SSH connection to the target. Thus, the program on the target can also be executed immediately via the build host via the SSH connection. ==== Deploy and Debug over VSCode ==== For debugging your own program, it is a good idea to automate the deploy process. In the following we do this via a bash script, which does the task automatically. We create a script file named deploy.sh in the project folder with the following content: #!/bin/bash TARGET_IP="$1" # stop gdbserver and delete old binary on target echo "Deploy program on target" ssh root@${TARGET_IP} "sh -c '/usr/bin/killall -q gdbserver; rm -rf /root/helloworld.bin exit 0'" # deploy program to the target scp helloworld.bin root@${TARGET_IP}:/root/ # start gdbserver on target echo "Run progran with gdb on target" ssh -t root@${TARGET_IP} "sh -c 'cd /root/; gdbserver localhost:3000 helloworld.bin'" === important === The output of the "echo" commands is relevant for the following process. When adjusting the "echo" output, the "tasks.json" file must also be adjusted. In order for VSCode to know what to do when debugging the application, we need to create the **launch.json** file in the **.vscode** folder and configure it accordingly: { "version": "0.2.0", "configurations": [{ "name": "Debug", "type": "cppdbg", "request": "launch", "program": "helloworld.bin", "stopAtEntry": true, "cwd": "${workspaceFolder}", "MIMode": "gdb", "targetArchitecture": "arm64", "preLaunchTask": "deploy", "miDebuggerPath": "/usr/bin/gdb-multiarch", "miDebuggerServerAddress": "${config:TARGET.IP}:3000", }] } Note that for 32bit-Plattforms, **targetArchitecture** should be set to **arm** Finally, we need to add our deploy script and debugging process to tasks.json. The completed tasks.json looks like this: { "version": "2.0.0", "tasks": [ { "label": "build all", "type": "shell", "command": "source /opt/dumpling-wayland-nxp/3.3.6/environment-setup-cortexa53-crypto-tq-linux; make clean; make -j$(nproc)", "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true } }, { "label": "deploy", "isBackground": true, "problemMatcher":{ "base": "$gcc", "background": { "activeOnStart": true, "beginsPattern": "Deploy program on target", "endsPattern": "Run progran with gdb on target" } }, "type": "shell", "command": "sh", "args": [ "deploy.sh", "${config:TARGET.IP}" ], "dependsOn": ["build all"], } ] } The project folder should contain the following files:\\ {{:en:general_information:vscode_files.png?nolink&300|}} \\ Now debugging the application is fully prepared. \\ === Start debugging === The debugging of the application can be started via **Run > Start Debugging** or via the **F5** key. \\ {{:en:general_information:vscode_debugging.jpg?nolink|}}