Be you a hacker, a student, or building Industrial IoT solutions on devices like the Revolution Pi then C and C++ development continues to be an important part of the mix when building solutions targeting Raspberry Pi based devices.
Developer with Visual Studio Code | Hack on Raspberry Pi | Build Industrial IoT |
---|---|---|
![]() |
![]() |
![]() |
Revolution Pi image included here with permission from KUNBUS GmbH
Visual Studio Code is a free, extensible code editor and is one of the most popular Open Source projects on GitHub. It runs on Linux, macOS, and Windows.
This tutorial targets modern Raspberry Pis, version 2 or better, including Industrial IoT devices like the Revolution Pi built on the Raspberry Pi Compute module.
There are two approaches to developing C/C++ applications for the Raspberry Pi. You can either cross-compile to the ARM processor architecture from your desktop computer, or you can build, compile, and debug on the Raspberry Pi itself.
Visual Studio 2019 (inc free of charge Community Edition) includes tools to develop, cross-compile, copy the app to the Raspberry Pi and remotely attach the GDB debugger. It's a great option but it is Windows only.
This tutorial explores using Visual Studio Code from Linux, macOS, or Windows to build C/C++ applications on the Raspberry Pi itself.
The following is a guide to C/C++ development on a Raspberry Pi with Visual Studio Code. At the time of writing the Microsoft C/C++ Visual Studio Code extension does not support ARM based systems.
The Raspberry Pi is a great learning platform for C and C++ development. Interesting enough, C and C++ are one of the fastest growing languages still. This article 5 REASONS WHY YOU SHOULD KEEP LEARNING C/C++ covers the great reasons why you should be learning C and C++.
- Set up your Raspberry Pi
- Ensure Operating System updated
- Raspberry Pi set up tips and tricks
Install the following libraries on the Raspberry Pi from the command line.
sudo apt install cmake clang clang-format cppcheck global build-essential gdb git wiringpi
- Visual Studio Code Remote - SSH
- C/C++ Clang Command Adapter
- CMake Tools
- Native Debug
- C/C++ Snippets
- C/C++ Advanced Lint
- C Snippets
- Clang-Format
Clone this project to your computer as you will need to run a script to set up SSH authentication between your computer and your Raspberry Pi.
git clone --depth=1 https://github.com/gloveboxes/Raspberry-Pi-with-Visual-Studio-Code-Remote-SSH-and-C-or-C-Development.git
Setting up a public/private key pair for SSH authentication is a secure and fast way to authenticate from your computer to the Raspberry Pi. This is recommended for this hands-on lab.
The SSH utility guides you through the process of setting up a secure SSH channel for Visual Studio Code and the Raspberry Pi.
You will be prompted for:
- The Raspberry Pi Network IP Address,
- The Raspberry Pi login name and password. The Raspberry Pi default login name is pi, and the default password is raspberry.
- From Windows File Explorer, open the directory you cloned this tutorial into.
- Open the scripts folder
- Double click the windows-setup-ssh.cmd
The SSH utility guides you through the process of setting up a secure SSH channel for Visual Studio Code and the Raspberry Pi.
You will be prompted for:
- The Raspberry Pi Network IP Address,
- The Raspberry Pi login name and password
- Open a Terminal window
- Navigate to the directory you cloned this tutorial into.
- Open the scripts folder.
- Grant execute privileges to ssh-setup.sh.
sudo chmod +x ssh-setup.sh
- run the ssh-setup script
./ssh-setup.sh
-
Start Visual Studio Code
-
Press F1 to open the Command Palette, type ssh connect and select Remote-SSH: Connect to Host
-
Select the pylab-pi configuration
-
Check the Remote SSH has connected.
It will take a moment to connect, then the SSH Status in the bottom lefthand corner of Visual Studio Code will change to >< SSH:pylab-pi.
-
First, create a folder for your project
-
From the Visual Studio Code menu select Terminal -> New Terminal.
-
From the Raspberry Pi Bash command prompt, create a directory structure for your project. I like to keep projects in a directory named github. But this is just my preference as most projects I work on are either cloned from GitHub or are published on GitHub.
mkdir -p ~/github
Then create your C/C++ project directory.
mkdir -p ~/github/your-project-name
This tutorial includes a several samples that you can clone to your Raspberry Pi.
From the Visual Studio Terminal window you just opened, run the following command to copy the samples to your Raspberry Pi
git clone --depth=1 https://github.com/gloveboxes/Raspberry-Pi-with-Visual-Studio-Code-Remote-SSH-and-C-or-C-Development.git
-
From Visual Studio Code main menu, select File -> pen Folder.
-
Navigate to the github folder.
-
Navigate to the project directory you created.
-
Click OK
Tip: Click the double dots if you need to navigate back up the directory structure.
-
Press F1 to open the Visual Studio Code command prompt.
-
Select CMake: Quick Start
-
Select GCC for c99 unless you have some specific requirements.
-
Name your project
-
Select Executable (or Library, if you know what you are doing).
-
The CMake project will be created and the CMake cache generated.
If you are planning on writing C++ then you are set. The project generated a main.cpp file for you.
If you are planning on writing a C application, then right mouse click the main.cpp file and rename main to main.c then open the main.c and replace the content with the following C code.
#include <stdio.h>
int main(int argc, char *argv[])
{
for (int i = 0; i < 100; i++)
{
printf("%d\n", i);
}
}
In this tutorial, we are going to create a C application, so I have renamed the main.cpp file to main.c. You can rename main.cpp file from the Visual Studio Code Explorer by right mouse clicking the file and selecting rename.
As a convenience, the build and debug process uses the name of the project directory. We need to update the CMake file, and create a Launcher and Build Task.
-
Open the CMakeList.txt file
-
Replace the existing contents with the following text. This CMake code sets the project name to the name of the project directory.
cmake_minimum_required(VERSION 3.13.0) get_filename_component(ProjectId ${CMAKE_CURRENT_LIST_DIR} NAME) string(REPLACE " " "_" ProjectId ${ProjectId}) project(${ProjectId} VERSION 0.1.0) include(CTest) enable_testing() add_executable(${PROJECT_NAME} main.c) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack)
-
From the Visual Studio Code main menu, select Terminal -> Configure Default Build Task.
-
Select Create tasks.json file from template -> Others.
-
Replace the contents of the task.json file with the following. This creates a build task called cmake.
{ // See https://go.microsoft.com/fwlink/?LinkId=733558&WT.mc_id=iot-0000-dglover // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "cmake", "type": "shell", "options": { "cwd": "${workspaceRoot}/build" }, "command": "cmake", "args": [ "--build", "${workspaceRoot}/build", "--config", "Debug", "--target", "all", "--", "-j", "6" ] } ] }
-
From the Visual Studio Code main menu, select Run -> Add Configuration.
-
Select GDB
-
The launch.json file will open.
We are going to make the following two changes:
- Call the preLaunchTask named cmake.
- Change the target property so that it launches the CMake generated application. Remember, the application name matches the project directory name. The ${workspaceFolderBasename} is a Visual Studio Code variable that contains the project directory name.
Change the target property to read:
"target": "./build/${workspaceFolderBasename}"
Add the preLaunchTask property to read:
"preLaunchTask": "cmake"
The launch.json file should look like the following after you have updated it.
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387&WT.mc_id=iot-0000-dglover "version": "0.2.0", "configurations": [ { "name": "Debug", "preLaunchTask": "cmake", "type": "gdb", "request": "launch", "target": "./build/${workspaceFolderBasename}", "cwd": "${workspaceRoot}", "valuesFormatting": "parseText" } ] }
-
Save the launch.json file
-
Open main.c
-
Put a breakpoint at line 5. With the mouse, click in the margin just to the left of line 5.
-
Press F5 to start the build process, to launch the application, and to attach the debugger. The code will halt execution at line 5.
-
Using the Visual Studio Debug Toolbar, step through the code. You can either step through the code using the toolbar, or the shortcut keys. F10 to step over a line, F11 to step into a function.
-
Remove the debug breakpoint by clicking on the red dot next to line 5.
-
Press F5 to continue the execution of the application.
-
Switch to the Debug Console to see the output from the printf statement in the application.
Be sure to check out the CMake options on the Visual Studio Code Status Bar.
You can change the build from Debug to Release, rebuild the project and run the application without attaching the debugger.
In the top right hand corner of Visual Studio Code there is a Compile Active File button.
As tempting as it may be, don't put all your code into main.c. A well factored application should be split up by function.
Here are the steps to add a new file to the project to have it compiled and included in your main.c file.
- Create your .c and corresponding .h files. In my case, I've created a isoTime.c and an isoTime.h. Open the CMakeList.txt file and add the isoTime.c file to the add_executable(${PROJECT_NAME} main.c isoTime.c) line.
- Save the the CMakeList.txt file. The CMake cache will be updated with the new build configuration.
See the sample-c-app project included with this tutorial.
MQTT install/make requires the openssl library header.
sudo apt-get install libssl-dev
git clone https://github.com/eclipse/paho.mqtt.c.git
cd paho.mqtt.c
sudo make install