This tutorial shows how to develop and debug Arduino projects for the ESP32-based boards using Visual Studio and the Advanced Arduino Project Subsystem of VisualGDB. We will create a basic “Blinking LED” project for the SparkFun ESP32 Thing board and will show how to navigate the code and debug the project.
Before you begin, install VisualGDB 5.4 Preview 4 or later.
- Start Visual Studio and open the VisualGDB Arduino Project Wizard:
- Proceed with the default “Blinking LED” project:
- On the next page select your ESP32 board. If you don’t see your board in the list, select any other ESP32-based board and click “Install” to automatically get the ESP32 Arduino core along with an up-to-date board list:
- Once you selected your board, connect it to the USB port and pick the COM corresponding to it below:
- Debugging ESP32 boards requires a JTAG debugger (e.g. Olimex ARM-USB-OCD-H or Segger J-Link). You can find detailed board-specific wiring instructions in our ESP32 tutorials (see this tutorial for SparkFun ESP32 Thing instructions). Connect your debugger to the board and plug it into the USB port. Select it in the “USB Devices” view to automatically configure it for debugging:
- Press “Finish” to generate the project. VisualGDB will generate an Advanced Arduino Project including both a basic sketch and the ESP32 Arduino core. Build it via Ctrl-Shift-B:Note that the build is done using the Arduino builder tool, so the result will be the same as when using the Arduino IDE. VisualGDB also queries the detailed code model from the Arduino builder that allows displaying the precise list of source files used by the project and various libraries, and also configures IntelliSense to see the code exactly as the compiler does.
- Once the project is built, press F5 to start debugging it:VisualGDB will automatically program the FLASH memory and begin running the project. The on-board LED will start blinking as expected.
- Set a breakpoint inside the loop() function and wait for it to trigger:Once the breakpoint triggers, you will be able to debug the code as any other Visual Studio project.
- VisualGDB will automatically disable optimization when compiling the sketch (but not the platform or the libraries) when building the debug configuration, to ensure the best debugging experience. You can alter this behavior via the first page of VisualGDB Project Properties:
- As VisualGDB indexes all the source files used by the project, you can use commands like Go To Definition, Peek Definition, Code Map, etc. to easily explore the code of your sketches, the Arduino core and the related libraries:
- Now we will show how to use the Arduino API for the serial port. Include the <HardwareSerial.h> file from your sketch:Note how VisualGDB shows the header files of available libraries with a special package icon. Including those header files will automatically reference the corresponding libraries once you save the sketch file.
- Replace the contents of your sketch file with the following code:2468101214161820{Serial.begin(115200);{delay(1000);delay(1000);chartmp[32];Serial.write(tmp);
Then build your project by pressing Ctrl-Shift-B:
- Open VisualGDB Project Properties and go to the Arduino Serial Terminal page. Enable the serial terminal and ensure that the baud rate matches the one configured in the sketch file:
- Press F5 to begin debugging. Now you will see the output from the Serial API in the terminal pane inside Visual Studio:
- You can set breakpoints and step through your code as usual. Since the debugging is done via the JTAG interface, it will not interfere with the serial port output:
- You can also program the FLASH memory without debugging and open the serial terminal via the context menu in Solution Explorer:
- If you encounter problems programming the FLASH memory using OpenOCD, select “Program FLASH using Arduino tools” on the Debug Settings page of VisualGDB Project Properties. This will configure VisualGDB to program the FLASH memory using esptool.py and the ESP32 bootloader instead of the OpenOCD FLASH programming logic:
- Run the View->Embedded Memory Explorer command to see an overview of memory utilization for your ESP32 board:
- Click “explore details” to view the detailed information about each function, method and global variable and also highlight their sizes and the memory type where they are placed directly in the code:
About this document
This document describes how to build the required images for .NET nanoFramework for ESP32 targets.The build is based on CMake tool to ease the development in all major platforms.
Programming Esp32 With Visual Studio
#ESP32 #ESPIDF This is the third video in the series of learning ESP32 using ESP-IDF framework, In this video we saw how to program ESP32 in visual studio c. VS Code ESP32 Debug (Preview) This is a VS Code extension for debugging ESP32 chip. This project is still alpha version under development. Please use it at your own risk. Currently only basic debugging features, such as stepIn, stepOut, Next, etc., are supported. More features are under planning. Supported Feautures: Pause/Continue; StepIn. Download and install Visual Studio Code (VS Code) from the link provided on the PlatformIO.org website; Open VS Code, and open the extensions menu, the button is highlighted in the picture above. I found I could just disconnect the ESP32 and the ESP-Prog, upload the code to the ESP32 and then reconnect them and it would work fine. How to Build, Flash and Debug the ESP32 nanoCLR on Windows using Visual Code About this document. This document describes how to build the required images for.NET nanoFramework for ESP32 targets. The build is based on CMake tool to ease the development in all major platforms.
Using Dev Container
If you want a simple, efficient way, we can recommend you to use Dev Container to build your image. This has few requirements as well like Docker Desktop and Remote Container extension in VS Code but it is already all setup and ready to run!
If you prefer to install all the tools needed on your Windows machine, you should continue this tutorial.
Prerequisites
You'll need:
- Visual Studio Code. Additional extensions and setup steps follow below. Set up Visual Code
- Python 3.6.5 Required for uploading the nanoCLR to the ESP32.
- Ensure the Windows default app to open
.py
files is Python.
- Ensure the Windows default app to open
- CMake (Minimum required version is 3.15)
- A build system for CMake to generate the build files to. We recommend Ninja.
- OpenOCD For on chip debugging of the nanoCLR.
- Driver for the USB to UART Bridge. This depends on the ESP32 hardware. After installing it, use Windows Device Manager to determine the COM port as this is needed to complete the setup. Follows the most common drivers:
- CP210x USB to UART Bridge VCP Drivers used in the standard ESP32 DevKitC.
- FTDI Virtual COM Port Drivers.
All the above can be installed using the Power Shell script .install-nf-tools.ps1 -TargetSeries ESP32
from the install-scripts
folder within the nanoFramework/nf-interpreter project (cloned or downloaded). If you prefer you can do it manually (NOT RECOMMENDED for obvious reasons).
Overview
To simplify: this guide we will put all our tools and source in easily accessible folders and not at the default install paths (you do not have to do the same).
Create a directory structure such as the following:
C:nftools
C:nanoFramework
Download and install Visual Studio Code.
Clone
nf-interpreter
repository intoC:nanoFrameworknf-interpreter
. See next section for more info.Run the PowerShell script that's on the
install-scripts
folder that will download and install all the required tools..install-nf-tools.ps1 -TargetSeries ESP32 -Path 'C:nftools'
For best results, run in an elevated command prompt, otherwise setting system environnement variables will fail.Review and adjust several JSON files to match your environment (as documented below)
Restart Visual Studio Code (due to json changes)
The setup is a lot easier than it seems. The setup scripts do almost everything.
.NET nanoFramework GitHub repo
If you intend to change the nanoCLR and create Pull Requests then you will need to fork the nanoFramework/nf-interpreter to your own GitHub repo and clone the forked GitHub repo to your Windows system using an Git client such as Fork or the GitHub Desktop application.
The develop branch is the default working branch. When working on a fix or experimenting a new feature you should do it on another branch. See the Contributing guide for specific instructions on the suggested contributing workflow.
If you don't intend to make changes to the nanoBooter and nanoCLR, you can clone nanoFramework/nf-interpreter directly from here.
Make sure to put this folder high enough on your drive, that you won't trigger long filename issues. CMake does not support filenames in excess of 250 characters.
Setting up the build environment
After cloning the repo, you need to setup the build environment. You can use the power shell script or follow the step-by-step instructions.
Automated Install of the build environment
Run Power Shell as an Administrator and run set-executionpolicy RemoteSigned
to enable execution of the signed script.
On Windows, one may use the .install-nf-tools.ps1
Power Shell script located in the repository install-scripts
folder to download/install CMake, the ESP32 IDF Source, toolchain, prebuilt libraries, OpenOCD (for JTAG debugging) and Ninja. You may need to use Run as Administrator for power shell to permit installing modules to unzip the downloaded archives.The script will download the zips and installers into the repository zips
folder and extract them into sub-folders of the nanoFramework tools folder C:nftools
or install the tool manually.
Open Power Shell in the
install-scripts
folder of the repository.Example Power Shell command line:
You can force the environment variables to be updated by adding
-Force
to the command line.The script will create the following sub-folders (see manual install below):
C:nftools
C:nftoolsesp-idf-v3.3.1
C:nftoolslibs-v3.3.1
C:nftoolsninja
C:nftoolsopenocd-esp32
The following Environment Variables will be created for the current Windows User.
NF_TOOLS_PATH = C:nftools
ESP32_TOOLCHAIN_PATH = C:nftoolsxtensa-esp32-elf
ESP32_LIBS_PATH = C:nftoolslibs-v3.3.1
IDF_PATH = C:nftoolsesp-idf-v3.3.1
NINJA_PATH = C:nftoolsninja
Manual Install of the build environment
These steps are not required if you've used the automated install script as described above.
To save time on building the nanoCLR and to avoid having to create a CMakeLists.txt project for the ESP32 IDF files, the ESP32 IDF libraries are prebuilt using the Esp32 Msys32 environment then used for linking in the CMake build of nanoCLR.This has already been done and the libraries can be just be downloaded.
Create a directory such as the following:
C:nftools
C:nftoolslibs-v3.3.1
Download the pre-built libs zip from here and extract it into
C:nftoolslibs-v3.3.1
.Download the v3.3.1 IDF source zip file from here and extract it into
C:nftools
so you getC:nftoolsesp-idf-v3.3components
etc.Download the Esp32 toolchain from here and extract it into
C:nftools
so you getC:nftoolsxtensa-esp32-elf
.For on chip debugging of the nanoCLR, download OpenOCD from here and extract OpenOCD into
C:nftools
so you getC:nftoolsopenocd-esp32
.Download the light weight build system Ninja for CMake to generate the build files from here. This is lightweight build system, designed for speed and it works on Windows and Linux machines. See here how to setup Ninja to build .NET nanoFramework.
Define the environment variables to match the install locations. Default locations are:
ESP32_TOOLS_PATH = C:nftools
ESP32_TOOLCHAIN_PATH = C:nftoolsxtensa-esp32-elf
ESP32_LIBS_PATH = C:nftoolslibs-v3.3.1
IDF_PATH = C:nftoolsesp-idf-v3.3.1
NINJA_PATH = C:nftoolsninja
Add Ninja to the PATH (i.e.
C:nftoolsninja
)Download the latest stable version from here and install it.
Install Python 3.6.5 and then install the serial driver for python from the command line:
Note that
.install-esp32-tools.ps1
will installpyserial
for you if you installed Python prior to running the script. (It is Ok to runpython -m pip install pyserial
multiple times.)
Set up Visual Studio Code
Install the extensions:
Run the PowerShell script
Initialize-VSCode.ps1
that's on theinstall-scripts
folder. This will adjust the required settings, build launch configuration for debugging and setup the tasks to ease your developer work.- You can force the environment variables to be updated by adding
-Force
to the command line. - The PowerShell relies on the environment variables described above to properly setup the various VS Code working files. In case you have not used the automated install and the variable are not available you'll have to manually edit
tasks.json
,launch.json
,cmake-variants.json
andsettings.json
to replace the relevant paths. !!mind to always use forward slashes in the paths!! - More info available on the Tweaking cmake-variants.TEMPLATE.json documentation page.
- You can force the environment variables to be updated by adding
Save any open files and RESTART VS Code. Have you RESTARTED VS Code? You really have to do it otherwise this won't work.
Build nanoCLR
Launch Visual Studio from the repository folder, or load it from the File menu, select Open Folder and browse to the repo folder. VS Code could prompt you asking 'Would you like to configure this project?'. Ignore the prompt as you need to select the build variant first.Next time VS Code open it should load the workspace automatically.
In the status bar at the bottom left, click on the
No Kit Selected
and select[Unspecified]
.In the status bar at the bottom left, click on the
CMake:Debug ESP32_WROOM_32: Ready
and selectDebug
. Wait for it to finish Configuring the project (progress bar shown in right bottom corner). This can take a while the first time.In the status bar click
Build
or hit F7.Wait for the build to finish with
Build finished with exit code 0
output message.In the
build
folder you'll find several files:nanoCLR.bin
nanoCLR.elf
partitions_4mb.elf
Note: If there are errors during the build process it is possible to end up with a partial build in the build
folder, and the CMake/Ninja
build process declaring a successful build despite the .bin
targets not being created, and a CMake clean
not helping.In this case deleting the contents of the build
folder should allow the build to complete once you resolve the issues that cause the original failure.
Common Build Issues
The above may have some errors if:
- CMake is not installed properly, not in the PATH or cannot be found for some reason.
- Ninja is not recognized: check settings.json or your PATH environment variable and restart Visual Studio Code.
- COMPILATION object file not found: check that your paths don't exceed 140 chars. Put the solution folder high enough on drive.
- Make sure to 'Build all' first time.
- Reopen VS Code if you have changed anything on the
cmake-variants.json
. - Clean the build folder by deleting it's contents and restart VS Code.
Flash nanoCLR into ESP32
The third file that gets flashed into the ESP32 is the
bootloader.bin
which will be located hereC:/nftools/libs-v3.3.1/bootloader.bin
if the automated install script is used.Connect your development board.
Some ESP32 boards require to be put into 'download mode'. Most don't even need this. Check the documentation for your variant. One of the most common options are: hold down the GPIO0 pin to GND or holding down the respective button during power up.
Download the image to device.
In Visual Studio Code go to menu 'Terminal' -> 'Run Task' and select 'Flash nanoCLR to ESP32 from the list.
As an alternative enter the command in command palette:
and if you flash the board for the first time
and then
It will ask you for the COM port where it's connected.
An other alternative is using nanoff tool:
An other alternative would be to use Espressif's own esptool.py tool:
Start with a 'Hello World' C# application
Watch the video tutorial here and follow the step that should be done in Visual Studio 2017 Community Edition. Skip the steps that describing uploading the nanoCLR into the STM32 Nucleo board.
Debugging nanoCLR
If you want to debug the nanoCLR code on the ESP32 chip you'll need an JTAG debugging adapter. ESP32 WROVER KIT already includes one. For other boards you can use the Olimex ARM-USB-OCD-H JTAG debugging adapter or a Segger JLink. There are preset configurations for these adapters.
You can now debug nanoCLR on the ESP32 by pressing F5 in Visual Studio Code.
Notes on JTAG debugging on ESP32
The JTAG connections on ESP32 DEVKITC are:
- TDI -> GPIO12
- TCK -> GPIO13
- TMS -> GPIO14
- TDO -> GPIO15
- TRST -> EN / RST (Reset)
- GND -> GND
See Gojimmypi for description of JTAG connections here.
If flashing nanoCLR via a COM port (default), then be aware that you need to disconnect the JTAG to avoid it preventing the bootloader from running, and therefore being unable to reprogram the ESP23. e.g. if you see the following pattern repeating, unplug the USB-OCD-H, and then the programming will proceed.
The Esp32 only has 2 hardware breakpoints.
Esp32 Visual Studio Codes
As code is dynamically loaded unless the method has an IRAM_ATTR
attribute any breakpoints set up at the start will cause an error when you try to debug (Unable to set breakpoint). When launched the debugger will normally stop at the main task. Its not possible to set a break point on code that is not yet loaded so either step down to a point that it is loaded or temporarily set the method with the IRAM_ATTR attribute.
For more information on JTAG debugging see Espressif documentation.
Debugging nanoCLR without special hardware
If you do not have access to any special hardware required for debug methods mentioned above you still may use some old-school technique: just place some temporary code at interesting places to get the required information. Using steps below you will get that information in Visual Studio's standard debug output window.Certainly Visual Studio must be debugging something to have that window in working state. So this hack will work only in cases whenyou want to debug a nanoCLR code which can be executed via managed code.
Esp32 Visual Studio Code 2020
- Step 1: Write some managed code which results in a nanoCLR call executing the code you are interested in.
- Step 2: Choose one or more places in nanoCLR code where you want to know something.e.g.: What is the value of a variable? Which part of an if-else statement gets executed?
- Step 3: Put the following temporary code there:
Or simply:
- Step 4: The boring part: rebuild and re-flash firmware and your program.
- Step 5: Start debugging in Visual Studio and keep eye on it's debug output window.You will get your messages there when the related temporary code gets executed!
- Step 6: Iterate steps 2-5 till you find out what you were interested in.
- Step 7: Do not forget to remove all those temporary code blocks before you accidentally commit it!