Raspberry Pi IoT In C - VS Code Remote C
Written by Harry Fairhead   
Monday, 05 October 2020
Article Index
Raspberry Pi IoT In C - VS Code Remote C
Arm Headers

A remote development environment is the ideal way of working with the Pi, or any Linux, IoT-based machine. VS Code doesn't do remote development to the Pi out of the box, but it is easy to add some tasks to automate things. This is an extract from the newly-published Raspberry Pi IoT in C, Second Edition.

Raspberry Pi And The IoT In C Second Edition

By Harry Fairhead


Buy from Amazon.


  1. Why Pi For IoT?
  2. Getting Started
  3. Getting Started With The GPIO
  4. Simple Output
  5. Some Electronics
  6. Simple Input
  7. GPIO The Linux Way
       Extract 1:The Linux GPIO Driver 
  8. Advanced Input – Events, Threads, Interrupts
       Extract 1: Events & Interrupts 
  9. Pulse Width Modulation - Servos And More
       Extract 1:Basic Pulse Width Modulation 
  10. Using The I2C Bus
  11. The DHT22 Sensor Implementing A Custom Protocol
  12. Exploring - 1‑Wire Bus Basics ***NEW!
  13. Using iButtons
  14. DS18B20 Temperature Sensor
      Extract 1: The DS18B20 Temperature Sensor 
  15. The Multidrop 1‑Wire Bus
  16. The Serial Port
      Extract 1: 1-wire Via Serial 
  17. Getting Started With The SPI Bus
  18. A to D With The SPI Bus
  19. Connecting With The Web - Sockets
  20. Memory-Mapped GPIO
  21. Almost Real-Time Linux
  22. Appendix I GPIO Sysfs Interface



Visual Studio Code, or VS Code, is a very popular code editor and, with just a little effort, it can be made to work very well with a Raspberry Pi for remote development. VS Code can be installed on a PC, a Mac or a Linux machine, including the Pi, and you can simply use it for local code development. That is, you create the source code and run the program on the same machine that VS Code is running on. As explained in Chapter 2, this works well on a Pi 4, but it can be slow on a Pi Zero. There is also the matter of having to copy source code onto another machine if you want to try it out on a different device.

A simpler alternative is to use remote development, where VS Code is installed on a desktop or portable computer and used to write the source code which is stored on the same computer. When the time comes to run the source code, it is uploaded to the remote machine and compiled and run there. You can even run a debug session with the code running on a remote machine and the debugger console running on the local machine. This is very convenient because you have a central copy of the program and switching to another Raspberry Pi is very easy.

VS Code has a remote development option for C/C++, but it currently doesn’t work on ARM machines like the Pi and it is unlikely to ever work on the Pi Zero because of the demands it makes. A simple solution is to use a custom launch file to implement remote running and remote debugging.
The files presented here have been tested on Windows, but they should work on Mac OS and Linux with changes to the folders used.

It is assumed that you have VS Code installed and working and the Microsoft C/C++ extension installed. You also need  to install mingw-w64 from SourceForge:


Run the installer and accept all the defaults.

Next add the location of the directory:

C:\Program Files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin

to the path and restart VS Code. When VS Code restarts it automatically finds MinGW and hence the GCC compiler and the GDB debugger and automatically configures itself to use them to run and debug C/C++ programs. You can now select the Run option in the side panel and you will be asked to select the run configuration to use and gcc is the correct option.

After this a .vscode folder will be created and the details of the configuration will be stored in launch.json for reuse the next time you run the program. Now you can set a break point and debug a hello world program o the local machine.

Make sure you know how breakpoints work and where to see the output of the program – in the Terminal window with details of the debugging in the Debug window.

Remote Development

To develop C/C++ on a remote machine you first need to have SSH setup and be able to log in without supplying a password. If you can’t do this then the remote development tasks will fail unless you switch to the Terminal window and enter the password each time you are asked for it.

Next you need to create some files in the .vscode folder. All of the files listed below are available from this book’s page on the I/O Press website, and you can simply download .vscode and copy the whole folder to the local machine.

The first is settings.json:

    "sshUser": "pi",
    "sshEndpoint": "",
    "remoteDirectory": "/home/pi/Documents/
    "std": "c99",

Of course, you need to change the data to correspond to the remote machine you are actually using – the IP address, user name and so on. The remoteDirectory variable specifies the directory on the remote machine that you want to store all of the project folders in. In this example it is /home/pi/Documents/CProjects and as this has to exist there is an automatic task that will create it for you. The std variable specifies the version of C you want to use with the compiler, libs specifies any library files you want the compiler to use and header specifies a single custom header file on the remote machine. As we are developing IoT programs this is just the bcm2835 header.

Next you need launch.json:

  "configurations": [     
      "name": "Remote C Debug",
      "type": "cppdbg",
      "request": "launch",
      "program": "${config:remoteDirectory}/
${fileBasenameNoExtension}.exe", "args": [], "stopAtEntry": false, "cwd": "${config:remoteDirectory}/
${relativeFileDirname}", "environment": [], "externalConsole": false, "pipeTransport": { "debuggerPath": "/usr/bin/gdb", "pipeProgram": "C:/Windows/System32/OpenSSH/ssh", "pipeArgs": [ "${config:sshUser}@${config:sshEndpoint}" ], "pipeCwd": "${workspaceFolder}" }, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "sourceFileMap": { "${config:remoteDirectory}/ ${relativeFileDirname}": "${fileDirname}" }, "preLaunchTask": "CopyBuildRemote", } ] }

This specifies the location of all the files on the local and remote machine and how to connect to the remote machine. The preLaunchTask runs a task called CopyBuildRemote. As its name suggests, this copies the files in the current folder and uses GCC to build an .exe with debug information.

Last Updated ( Monday, 05 October 2020 )