This is the third and last part of the tutorial on setting up a free and fully functional GCC + Eclipse + OpenOCD (ST-LINK V/2) environment for use with the STM32F0Discovery board. In this entry, I will show you how to debug an eclipse project using the OpenOCD GDB server. In order to be able to follow this blog entry you must already have the gcc-arm toolchain and eclipse setup and configured as described in the previous two entries:
When we talk about debugging it's important to understand that the actual "debugger" or emulation hardware is "on chip" and is called the "on chip debug" (OCD) hardware. Typically a device such as ST-LINK V/2 or the JLINK is required to provide an interface between the on chip debugger, and your PC or IDE debug software. Furthermore when using a GCC based debug interface within your IDE, your debug software consists of a GDB server and a GDB client. This is known as "Client-Server" architecture.
So the STLINK V/2 device that exists on board of the STM32F0Discovery board, provides an interface between the "on chip debug" circuitry on the MCU side and the GDB server on the development PC. The GDB server provides any compatible GDB client with access to the on-chip debug capabilities on the STM32F0 chip. Typically the IDE is able to integrate the GDB client into it. When its time to debug, the GDB client connects with the GDB server which in turn enables the chip to be debugged.
In this tutorial we will be using the GDB server from OpenOCD verson 0.6.x. Future versions should also work adequately but older versions will not include support for the STM32F0Discovery board. OpenOCD is a free and open source GDB Server software that is compatible with many hardware debug tools including ST-LinkV/2, J-Link, R-link, Olimex-JTAG e.t.c.
On the OpenOCD website, links to only the source files are available. While its possible to build OpenOCD from source in a MS Windows environment using Cygwin as described here, we will take the easy path and simply used MS Windows binaries that were built by Freddie Chopin and are readily available on hissite.
We will also be using the GDB client that comes with the gcc-arm toolchain; "arm-none-eabi-gdb". While we can use the GDB client from the command line, we will opt for integrating the GDB client into the developed Eclipse setup covered in the previous entry and performing the debug via the eclipse IDE.
- So the first step will be to download OpenOCD0.6.x Binaries. We will also need to download the "zadig" tool if you wish to install a custom USB Driver. This may not be necessary however if you've already installed the ST LINK Utility.
- Once you download the "openocd-0.6.x.zip" file, extract its contents into the "C:Development" directory such that you end up with a directory "C:Developmentopenocd-0.6.x". Inside this directory you will find a "bin" and "bin-x64" folders. The former contains the openOCD executable for 32-bit systems while the later contains the executable for 64-bit systems. Since I am running a 64-bit version of the MS Windows 7 OS, I will be utilizing the 64-bit version of OpenOCD which means that I will use the "openocd-x64-0.6.x" binary found in the bin-x64 directory in the openocd folder. If you have a 32-bit MS Windows OS, you'll have to use the "openocd-0.6.x" binary found in the bin directory in the openocd folder.
Adding OpenOCD's binary folder to the Path Environment Variable
- The next step will be to add the path of the openOCD executable to the "Path" variable in the MS windows operating system. This will allow us to execute OpenOCD from any directory in the commandline environment and not just from the folder/directory containing the openOCD binary. To do this click on the "Start menu", right click on "Computer" and select "Properties"
- This will open the "System Window shown in Figure 2. Click on "Advanced System Settings"
- This will open a "System Properties" window as shown in Figure 3. Click on the "Environment Variables" button in the bottom right of the window.
- This will open an "Environment Variables" window. Under "System Variables" select the "Path" system variable and click on the bottom "Edit" button. This will open an "Edit System Variable" window. In the "Variable value" field go to the very far right and add "C:\Development\openocd-0.6.x\bin-x64" if you're running a 64-bit OS or "C:\Development\openocd-0.6.x\bin" if you're running a 32-bit OS. Make sure that there's a ";" between the directory path that you just entered and others already included in the "Path" variable. Click on OK in the "Edit System Variable" window, OK in the "Environment variables" Window and OK in the "System Properties" Window.
- Now open a new window command line window (if you have an old one open this won't work) and type in either "openocd-x64-0.6.x -v" if you're using a 64-bit OS or "openocd-0.6.x -v" if you're using a 32-bit OS and you should see an output that looks like that shown in Figure 5.
Installing ST LINK Drivers (Optional if you have ST LINK UTILITY Drivers already installed)
- The next step will be to install the necessary drivers to get the ST-LINK V/2 debug hardware to work with OpenOCD. If you completed part one of this tutorial chances are that you've already installed the official ST driver that comes with the ST-LINK Utility. This driver works well with the ST-LINK utility and the ATollic GDB Server and seems to work well with the OpenOCD GDB server as well. If you wish to continue using it, skip to the next section of this tutorial (Starting the OpenOCD GDB Server). If you are however interested in installing the STLINK drivers the "openOCD" way then continue with this section.
- OK back to business. We will first need to connect the STM32F0Discovery board (ST Link) to the computer via USB.
- Then We need to extract the "zadig.exe" executable from the compressed zadig_v18.104.22.168.7z that we should've downloaded from here. Run the Executable. Go to the "Options" Menu and click on "List All Devices".
- Select the "STM32 STLink" from the drop down menu and make sure that WinUSB is selected in the adjacent window as shown in Figure 6. Then press the "Upgrade Drivers" button.
- After about 30sec - 2min you should get a message saying that the installation is successful. It might also ask you to restart your computer. If it asks you to do this then please comply before moving forwards.
Starting the OpenOCD GDB Server
- At this point the driver is successfully installed and ready to run OpenOCD.
- In the File explorer/ manager go to the "C:\Development\openocd-0.6.x\scripts\board" directory and copy the "stm32f0discovery.cfg" script into your "iotgglem0" project directory ("C:\Development\Workspace\iotogglem0"). Now open a new command line window and type "cd C:\Development\Workspace\iotogglem0" to get to your project directory in the command line, followed by "openocd-x64-0.6.x -f stm32f0discovery.cfg" (Note that if you are using a 32-bit Windows OS you should type "openocd-0.6.0 -f stm32f0discovery.cfg"). This should activate the openOCD GDB server and you should get the output shown in in Figure 7.
- You can ignore the any warning as long as openOCD blocks the command line and gives you the message "Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints". This is important because it means that when running code from flash you only have 4 hardware breakpoints to work with.
- Now leave the current command line window open and open another command line window.
Erasing and Flashing your Microcontroller using OpenOCD
- Without having to worry about being in a particular directory location, type "telnet localhost 4444" in the new command line window. This will allow you to access the GDB server by telneting into it.
- Now to erase the chip type: "reset halt", "sleep 100", "stm32f1x mass_erase 0" and "sleep 100" (See Figure 9). You can then type "exit" to close your telnet session.
- To program the chip telnet into the OpenOCD GDB Server again and type: "reset halt", "sleep 100", "wait_halt 2", "flash write_image erase iotogglem0_rom.elf" (or "flash write_image erase iotogglem0_rom.hex") and "sleep 100".
- To verify type: "verify_image iotogglem0_rom.elf" (or "verify_image iotogglem0_rom.hex") and "sleep run".
- To have the debugger put the micro in run mode type: "reset run"
- If OpenOCD hangs, try either pressing the "RESET" button on the STM32F0Discovery board and/or remove the JP2 jumper and put it back on again to cycle power to the board.
- You could probably omit the "wait_halt 2" command mentioned for programming.
- Also verifying flash might not be necessary for most cases. If you look at Figure 10 you will see that the number of bytes wrote in the program step is larger than the the number of bytes verified. This maybe due to the debug information being embedded in the .elf (& the .hex ) file that does not need to be verified. But I'm really not sure. Either way the new program should run on the chip with no problems.
- I got the above commands from a script posted on github by Mike Szczys. I had to modify it a bit to make it work.
- Finally note how we didn't have to specify the directory that the .elf/.hex file to be programmed was in. This is because we started the GDB server in the project directory. When using OpenOCD it is very important to START THE OPENOCD SERVER IN THE PROJECT DIRECTORY!!!!
Debugging in Eclipse Using OpenOCD
- So now comes the highlight of this tutorial where we get to debug using the OpenOCD server from Eclipse! So let's open Eclipse and load our iotogglem0 project. If you haven't worked your way through the first two parts of the tutorial, you need to do this before you can proceed.
- Make sure that you are able to build the "iotogglem0" project successfully in Eclipse, that the STM32F0Discovery board is connected to the PC via USB, and that the OpenOCD GDB server is running.
- Click on the "Debug Configurations" option under the Run Menu. This will open up a "Debug Configurations" window as shown in Figure 11. Double click on "GDB hardware Debugging" on the left.
- This will create a new Debug configuration called "iotogglem0 Default". I opted to change its name via the "Name:" field in the "Main" tab to "iotogglem0 OpenOCD Debug". Make sure that the "iotogglem0_rom.elf" is selected in the "C/C++ Application" Field. This can be done either by clicking on the adjacent "Search Project" button and selecting the ".elf" file directly or by clicking on the Browse button and browse for the ".elf" through the file system. The former approach is quicker. Also make sure that "iotogglem0" is in the "Project:" field as shown in Figure 11. Then click on the "Debugger" tab.
- In the Debugger tab enter the name of the gdb client program "arm-none-eabi-gdb" in the GDB command field. Also make sure you specify the port number to which you want the GDB client to connect to. This is the same port number that the GDB server is listening to, which is 3333. Then click on the Startup Tab. At this point its important to note that to telnet into the OpenOCD GDB Server we use port 4444 but to connect a GDB Client to the OpenOCD server, we must use port 3333. Then click on the Startup Tab.
- In the Startup tab we will type in the "initialization commands" box : "*monitor reset halt*". We will leave everything else as is (see Figure 13). Note that both the "Load image" and "Load symbols" check boxes are checked. Both the image and symbols are derived from the iotogglem0.elf output file. This is fine since, the .elf contains both and is adequate for the job. The image mentioned here is the executable program to be downloaded into flash. Whereas the symbols are the debug symbols required for debugging. If you want to only download the program but not debug it, you could check only the "Load Image" box. This will in effect program the chip but not put it in a debug ready state; allowing you to program the chip from Eclipse!. In fact you could create another "iotogglem0 OpenOCD Flash" configuration that does just that!. Both the image and the debug symbols need to be loaded to properly debug the chip. Then click on the common Tab.
In the common tab make sure that the "Debug" check box is checked. This will allow us to select this our "iotogglemo Debug" debug configuration via the "debug" icon in the toolbar as well will see shortly.
- The OpenOCD Server does not seem to like the GDB(DSF) Hardware Debugging Launcher Very much so we need to change this. To do this we need to click on the "select other" link in bottom of the Debug Configurations window (adjacent to "Using GDB (DSF) Hardware Debugging Launcher").
This will open a "Select Preferred Launcher" window. Click on the "Change Workspace Settings" link. This will open a third window named "Preferences (Filtered) - Default Launchers". Under "Launch Type/Mode:", select " [Debug] found under "GDB Hardware Debugging". Then under "Preferred Launcher" check the box adjacent to "Standard GDB Hardware Debugging Launcher".
- Click the "Apply" Button followed by the "OK" button in the "Preferences (Filtered) - Default Launchers". Then click OK in the "Select Preferred Launcher Window" and then the "close" button in the Debug Configurations button. We are now ready to debug.
- Now you should be back in the Eclipse IDE. Right Click on the small "debug" (see Figure 17) icon in the Eclipse IDE toolbar, select the "iotogglem0 OpenOCD Debug" configuration and click it. You will get a confirmation Perspective switch window. Choose yes and you'll find that Eclipse has switched from the C/C++ perspective to the debug perspective.
- You will now be in the Debug Perspective. In the top right you'll find several tabbed windows showing you the local variables, current breakpoints, CPU registers and modules. You can also add disassembly or memory windows by clicking on the "show view" option under the "Window" menu and then selecting an item to view. There is also a Debug tab that contains useful icons. The icons are numbered in figure 18.
- This is the continue or Resume icon and will cause code to be run.
- This icon halts execution and is selectable only while the program is running
- The red square button terminates debug mode.
- This icon disconnects the GDB client from the GDB Server.
- This is the "step into" icon allowing you to step into functions or to the next instruction
- This is the "step over" icon allowing you to step over functions or to the next instruction
- This is the "step out of" icon allowing you to step out of a function or the current scope.
- To add a breakpoint just right click in the grey margin if the source code window in the bottom left and choose the "toggle breakpoint" option. Repeat the process to remove break points. Remember that you only have 4 breakpoints! So let's add a break point at main function (line 55) and two more break points at the "delay(1000000);" function calls on lines 84 and 87. Now click continue.
- After hitting the continue icon once, code execution will halt at the beginning of the main function. hitting the continue icon again repeatedly will cause code to halt right before executing the two delay function calls allowing you to see the LEDS toggle. Congratulations! you just debugged your first STM32F0Discovery project!
- Once you are done debugging, you can always stop debugging by pressing on the red square termination icon (icon 3) or icon 4 and switching the perspective back to C/C++.
- Note that you must have the OpenOCD GDB Server application running and listening (as well as the STLINK V/2 on the STM32F0Discovery board connected to the PC via USB cable) before you can debug a project from Eclipse. If the GDBServer isn't running, the GDB client on the Eclipse side has no way of connecting to the on chip debug hardware by itself. You can turn on the GDB Server from Eclipse by setting up external tools via the run menu. But I prefer simply making sure that the GDB Server is activated from the command line before I start debugging in Eclipse.