This tutorial will show you how to debug an Arduino sketch using the Portenta H7, Portenta Breakout board and the Segger J-link device. Using the Arduino IDE we will build a version of the sketch so that it can be used in Segger's Ozone debugger.
First, if you haven't already, install the Arduino IDE and connect your Portenta H7. When uploading a sketch to your Arduino board with the Arduino IDE, it will build an .ELF file of the sketch. We will need this file to debug in Ozone in the next step. To easily find the file path to the .ELF file, we can enable the show verbose output option in the Arduino IDE. To do this, open up the preferences under File > Preferences in the Arduino IDE.
When you have the preferences window open, look for the Show verbose output during: compilation option and make sure that the checkbox is ticked.
Now we are ready to upload the script that we want to debug. If you don't have a sketch to test, you can use the example sketch found in the Conclusion section of this tutorial.
When we upload the sketch with the Arduino IDE, we need to know where the .ELF file will be saved. Build your project in the Arduino IDE, and highlight the output directory, it could look for example like
C:\Users\profile\AppData\Local\Temp\arduino_build_815037
. Note down the path for easier access in the next step.
First, connect the Portenta H7 to the Breakout. To begin using the J-link device with the Portenta H7 and Breakout, you will need a J-link adapter, sold separately. The cable for the adapter needs to be connected as indicated in the illustration below, with the cable going inwards towards the H7 and center of the Breakout. On the J-link side, connect the cable going away form the J-link device on the adapter. Now you just need to connect the USB cable from the J-link to your computer and the USB cable from the Portenta H7 that is on the Breakout to your computer.
Download and install Segger's Ozone debugger. If you are on windows, make sure to also download the J-Link Software and Documentation Pack for Windows.
When starting Ozone, make sure to enter the correct CPU into the settings box. The Portenta H7 uses the STM32H747XI, you can then chose between the M4 and M7 core on the Portenta.
Continue to the next step. Here we need to change the Target Interface to SWD. The Portenta H7 does not support JTAG. Then select your J-link device in the list of emulators and head to the next page.
Now you get to the window that asks you to select the program to be debugged, this is where you load the project's .ELF file. With the temporary output path that we noted before. Navigate to the correct directory, and select the .ELF file.
In the 'optional settings' dialog, set both options 'Initial PC' and 'Initial Stack Pointer' to 'Do not set' as it would skip the Arduino bootloader otherwise which may prevent the sketch from running correctly.
When the setup is finished Ozone will open the file containing the main function. You will note that this is not the .ino sketch you wrote since this is an abstraction layer generated by the IDE. To open our .ino sketch we need to go to Find > Find source file in the top toolbar.
In the little window that appears, type ".ino". You should now be able to see the file, select the file and it will open it in Ozone.
Now you are ready to start debugging. Simply go to Debug > Download & Reset Program to start debugging your sketch, you can add breakpoints , inspect variables, halt the execution and more.
For more information about the features present in the Ozone debugger, please go here.
In this tutorial, you learned how to connect your Portenta H7 and Breakout board to a J-link device and use it with the Ozone debugger. We also went through how to create a file with Arduino IDE that can be debugged in Ozone. And finally how to use the Ozone debugger to debug an Arduino sketch.
1int counter1 = {0};2int counter2 = {0};3
4unsigned long timer1 = {0};5unsigned long timer2 = {0};6int period1 = 1000;7int period2 = 500;8
9void setup()10{11
12 // Set the LED pins up as OUTPUT13 pinMode(LEDR, OUTPUT);14 pinMode(LEDG, OUTPUT);15 pinMode(LEDB, OUTPUT);16
17 digitalWrite(LEDR, HIGH);18 digitalWrite(LEDG, HIGH);19 digitalWrite(LEDB, HIGH);20}21
22void loop()23{24
25 if (millis() >= timer1 + period1)26 {27 timer1 = millis();28 counter1++;29 digitalWrite(LEDB, !digitalRead(LEDB));30 }31
32 if (millis() >= timer2 + period2)33 {34 timer2 = millis();35 counter2++;36 digitalWrite(LEDR, !digitalRead(LEDR));37 } 38}