GDB, the GNU Project Debugger is a debugging tool provided with the GNU Compiler Collection (GCC). GDB allows you to stop and start a running program, examine its functioning, and make changes.
The Eclipse IDE is a multi-language integrated development environment which can be used to develop, install, and debug embedded applications.
This guide will walk you through installing Eclipse and configuring it for embedded development, installing a GCC toolchain to compile programs for ARM processors, and finally compiling and debugging a simple program in GDB. These instructions were written for Ubuntu 12.04 LTS and the Texas Instruments BeagleBone Black.
The BeagleBone Black comes pre-loaded with Angstrom Linux, but this guide will walk you through compiling, loading, and debugging a “bare metal” program. Users wishing to develop programs that run within the BeagleBone’s operating system may not find much help here, but plenty of useful guides are available elsewhere. (The BeagleBone’s Linux install includes tutorial information to help you get started. To access it, just connect the BeagleBone to a USB port on your PC and go to http://192.168.7.2 in Firefox or Chrome.)
- 1 Install the ARM EABI Toolchain
- 2 Install and Configure Eclipse
- 3 Create a Simple Eclipse Project
- 4 Load and Debug the Program with GDB
- 5 Using GDB in Eclipse
Install the ARM EABI Toolchain
To compile programs for ARM processors you will need a cross-compiler and toolchain. This guide will compile and install the ARM EABI toolchain via a script created by James Snyder.
Step 1: Download the Script via Git.
Git is version-control software used for managing code and assets during software development. Here we use it to download Snyder’s script. In a terminal window, type:
sudo apt-get install git
When the install finishes, type:
cd ~ git clone https://github.com/jsnyder/arm-eabi-toolchain.git
This will create a folder called arm-eabi-toolchain in your Home directory, containing the makefile script we need.
Step 2: Install Dependencies.
The makefile requires several utilities and libraries to compile and install correctly. In a terminal window type (all on one line):
sudo apt-get install curl flex bison libgmp3-dev libmpfr-dev texinfo libelf-dev autoconf build-essential libncurses5-dev libmpc-dev
WARNING: Don’t try to copy and paste the text above into your terminal window! If you want to copy and paste so you don’t miss anything, use the line below:
sudo apt-get install curl flex bison libgmp3-dev libmpfr-dev texinfo libelf-dev autoconf build-essential libncurses5-dev libmpc-dev
Select the text in your browser, press Ctrl+C, then right-click on the terminal window and select Paste. Press Enter to install.
You can find this list of dependencies in Snyder’s readme file, installed at /home/USERNAME/arm-eabi-toolchain/readme.md.
Step 3: Install libexpat.
Before we compile the toolchain we need to install one more library. In the terminal window, type:
sudo apt-get install libexpat-dev
Without this library, the toolchain will compile successfully but the debugger won’t be configured to load software to the correct place in the board’s memory. You may see an error stating that libexpat-dev has an unmet dependency: the wrong version of another library libexpat1. In that case, use this instead to install with the correct version of libexpat1:
sudo apt-get install libexpat1=2.0.1-7.2ubuntu1 libexpat-dev
Step 4: Execute the Makefile.
Navigate to /home/USERNAME/arm-eabi-toolchain and execute the makefile with sudo make install-cross:
cd ~/arm-eabi-toolchain sudo make install-cross
The script downloads the source code for the toolchain, compiles them, and installs.
Step 5: Wait.
The makefile will take a long time to run – possibly upwards of an hour. When it finishes, check back over the last several lines in the terminal window to make sure there were no errors. If everything went correctly, you should now have a folder in your Home directory called arm-cs-tools.
Step 6: Add the Cross-Compiler Tools to PATH.
In a terminal window, navigate to /etc and open the file called environment in a text editor. We’ll use gedit, the text editor installed by default on Ubuntu.
cd /etc sudo gedit environment
The first line of environment is a list of directories Ubuntu uses to search for executables. Add the following text to the beginning of the list, right after the open-quote:
Save the file and exit. Now back in the terminal window, update your PATH by typing:
The directories containing the cross-compiler executables should now be in your PATH. You can verify by typing:
To make sure Ubuntu can find the cross-compiler, type:
You should see a printout with version information.
Remember this Later…
You may get a “Command not found” error when trying to run part of the toolchain. When you restart your computer, your path may change. You can fix this by resetting PATH from the file you edited earlier:
Also, the sudo command changes your PATH. It won’t matter for the rest of this guide, but if you ever need to access part of the toolchain with sudo you can do so like this:
sudo env PATH=$PATH command_here
Install and Configure Eclipse
Step 1: Install Java.
Eclipse can be used to develop programs for multiple languages, but the Eclipse software itself runs in Java. If you’re not sure whether you have Java installed already, open a terminal window and type:
If you have a Java Runtime Environment (JRE) installed, you will see the name of the distribution and a version number. Note for users unfamiliar with Java development: The Java Runtime Environment (JRE) and the Java plugin that runs applets in your web browser are two different things. What we need is the JRE.
To install the JRE, type in a terminal window:
sudo apt-get install openjdk-7-jre
Press ‘Enter’ on your keyboard, then ‘y’ when prompted.
Once installation completes you can verify that everything installed correctly by typing java –version again.
Step 2: Download Eclipse.
Go to http://www.eclipse.org/downloads in your browser. Download the Eclipse IDE for C/C++ Developers. There are different versions for 32- and 64-bit Linux; download the one appropriate to your computer’s operating system.
Open the archive and extract it to your Home folder.
Doubleclick the eclipse executable to start the IDE. You should see this loading screen:
Next Eclipse will prompt you to select a workspace:
This will create a new directory to store your Eclipse projects. This guide will assume you use the default /home/USERNAME/workspace. Click OK.
Step 3: Install the Eclipse CDT Plugin.
You should now be at the Eclipse welcome screen.
At the top of the window, go to Help > Install New Software… to bring up the Install window. In the text bar at the top of the window, enter the following URL:
You should see two options: CDT Main Features and CDT Optional Features. Click the checkboxes next to each and click Next to go to a list of features to be installed:
Click Next again to install.
Step 4: Install Cross Development Tools.
In the Eclipse window, go again to Help > Install New Software… This time in the text bar at the top of the window, enter:
Check the box net to CDT GNU Cross Development Tools, hit Next, and then Next again to install.
Create a Simple Eclipse Project
The bbone_ledblink program will repeatedly blink the outermost blue LED on the BeagleBone Black. Download it here:
Open the archive and extract the contents to your Home folder.
Step 2: Create a New Eclipse Project.
In Eclipse, look at the menu at the top of the screen. Select New > Makefile Project with Existing Code. The New Project window should appear. Configure your new project as follows:
- Give the project a name.
- In Existing Code Location, browse to /home/USERNAME/bbone_ledblink and click OK.
- Check C and uncheck C++ under Languages.
- Under Toolchain for Indexer Settings, select Cross GCC.
Click Finish to create your project. You can now view your project heirarchy in the Eclipse Project Explorer window (on the left in the picture below).
Step 3: Set your Project’s PATH Variable.
Earlier, we set the PATH variable so your operating system could find the ARM EABI toolchain executables. When Eclipse creates a new project it imports your PATH and uses it by default. Just one problem: Eclipse can’t parse the $HOME variable in your PATH, so you’ll have to edit your project settings.
In the Project Explorer window, left-click on the top level of your project to select it. Then in the menu at the top, go to Project > Properties. Expand C/C++ Build and select Environment.
Select PATH and click Edit to bring up the Edit Variable window. Add the following text to the beginning of the text box:
…but replace USERNAME with your Linux username. Don’t use $HOME or the tilde (~) symbol in place of /home/USERNAME.
Click OK. Then back in the Properties window, click Apply then OK.
Step 4: Build your Project.
In the top menu, go to Project > Build All. If the project compiles successfully you should see new object files appear in the Project Explorer.
Step 5: Set your Project’s Debug Configuration.
Back on the Eclipse main screen, click on the top level of your project again to select it. Then in the top menu go to Run > Debug Configurations. A new window should appear. In the menu on the left, double-click GDB Hardware Debugging and select bbone_ledblink Default (or whatever you named your project).
To the right, look under Project: The text field should show the name of your project. If it doesn’t, click Browse… and select your project. Then under C/C++ Application, make sure it lists the name of your executable, code.elf. If it doesn’t, click Search Project… and select code.elf.
Next, click on the Debugger tab.
- Change GDB Command to arm-none-eabi-gdb. (It should say gdb by default.)
- Change Port number to 3333.
Now go to the Startup tab.
- Uncheck Reset and Delay.
- Uncheck Halt.
- In the textbox beneath Reset and Delay and Halt, type the following:
monitor sleep 1000 monitor am335x.cpu cortex_a dbginit monitor reset monitor sleep 500 monitor halt monitor sleep 500
- Make sure the settings under Load Image and Symbols look like the image below. (You shouldn’t need to change anything.)
Click the Apply button, then click Close.
Load and Debug the Program with GDB
For this step, you will need a Flyswatter2, OpenOCD and a configuration file for the BeagleBone Black. If you haven’t already installed OpenOCD and downloaded ti_beaglebone_with_fs2.cfg, go to the Flyswatter2 BeagleBone Black How To and follow the instructions there.
Step 1: Start OpenOCD.
Connect your Flyswatter2 and BeagleBone Black. Open a terminal window and run OpenOCD as described in the Flyswatter2 BeagleBone Black How To.
cd ~/openocd-bin sudo ./openocd -f interface/flyswatter2.cfg -f target/ti_beaglebone_with_fs2.cfg -c init -c "reset init"
Step 2: Start GDB and Load the Program.
Back in Eclipse, select the top level of your project. In the top menu go to Run > Debug Configurations. Expand the GDB Hardware Debugging Tab and select bbone_ledblink Default. You should now be back where you were when you set your debug settings earlier.
This time, click Debug. You will be prompted to switch to a Debug perspective. Click Yes.
This will change Eclipse’s layout to show debugging information. (Later you can get back to the old perspective from the top menu: Window > Open Perspective > C/C++.) The Debug perspective looks something like this:
You may see an error like the one above – No source available for “0x2086c”. If you do, don’t worry. It should go away when we resume the program in the next step.
Step 3: Resume the Program.
The LEDblink program should now be in your board’s flash memory. However, nothing should be happening yet. In the Eclipse top menu, go to Run > Resume. You should see the rightmost blue LED on the Beaglebone flash one long pulse, then one short pulse, repeating about once per second. If you saw the No source available… error before, it should now be replaced with a view of your code:
If you see the No source available… error again, end your session (top menu bar, Run > Disconnect) and try again. If you still see No source available…, end your session again, but this time exit OpenOCD and unplug the BeagleBone and the Flyswatter2. Plug them back in, and repeat Steps 1-3 above.
Using GDB in Eclipse
Eclipse provides a GUI wrapper around the most common GDB commands. Normally you would run GDB commands from a terminal window, but you can perform several GDB actions through Eclipse.
Suspend and Resume the Program
To pause the program, use the top menu, Run > Suspend. Try this and you should see the LEDs on the BeagleBone stop flashing. To resume, use Run > Resume or press F8 on your keyboard.
Insert a Breakpoint
A breakpoint suspends the program each time it reaches a particular line of code. Breakpoints allow you to read the contents of memory before the program can change it, or find errors by verifying that the program runs correctly up to a particular point.
First suspend the program as above (Run > Suspend). In the code view for code.c at the center left of the Eclipse screen, click to place your mouse cursor in line 99. Line 99 should read:
In the top menu, select Run > Toggle Breakpoint. Alternatively you can press Shift+Ctrl+B on your keyboard. A blue dot should appear to the left of Line 99.
Resume the program (Run > Resume or F8). The program will run until it reaches the breakpoint and then suspend automatically. You should see the LED on the BeagleBone flash on and stay on. Because this breakpoint is in a function that is called repeatedly from a loop that never terminates, you can keep repeating this indefinitely. Each time you resume the program, the light should turn off, then quickly turn on and off again, then come on and stay on.
To remove the breakpoint, select Run > Toggle Breakpoint or press F8 again. Do that now.
Check the Value of a Variable
While the program is suspended, Eclipse shows you the current value of variables. Insert a new breakpoint at Line 52. Just as before, suspend the program (Run > Suspend), place your cursor in Line 52 and select Run > Toggle Breakpoint or press F8. Line 52 is a for loop that forces LEDblink to delay between flashes:
for (; counter < nr_of_nops; ++counter)
After you insert the breakpoint at line 52, resume the program with Run > Resume or F8. The program will now break each time the dummy_wait() function is called. In the upper right, you can see the values of two variables:
- nr_of_ops, which controls how many passes through the loop to wait. You can see that the program calls dummy_wait() with different values for long or short flashes and long or short pauses.
- counter, which should always be zero. We’re just starting the for loop, so it hasn’t yet incremented.
Check the Value of a Memory Address
Unfortunately we can’t use the Eclipse GUI to read the values that turn the LEDs on and off. However, we can get those values from memory directly using GDB text commands. Remove the breakpoint at Line 52 and put a new one back at Line 99 where we had it earlier (dummy_wait(0x007ABE5); in the heartbeat_forever() function). Resume the program so that it runs to the breakpoint.
Move your mouse over 0x4804c000 in the line just above the breakpoint. This value is a memory address, and you should see a small window pop up showing you the value stored at that address.
To check the current value of 0x4804c000, click on the Console window at the bottom of the screen. Your mouse cursor should appear. Move the mouse cursor to the last line and type:
The Console window should print out:
Run Other Text Commands
You can run other GDB text commands from the Console window. You can find a full list of GDB commands at http://web.cecs.pdx.edu/~jrb/cs201/lectures/handouts/gdbcomm.txt .
End your Debugging Session
To stop debugging, go to Run > Disconnect in the top menu. You can leave Debug perspective and return to the C/C++ perspective (the window layout you saw when you first loaded your project) with Window > Open Perspective > C/C++.