Skip to content

Commit 11339d9

Browse files
committed
Add debugging tutorial
1 parent 0f5b20e commit 11339d9

9 files changed

Lines changed: 166 additions & 1 deletion

File tree

_data/docs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
- title: General
22
docs:
33
- home
4+
- hardware_support
45

56
# placeholder for tutorials...
67
- title: Tutorials
78
docs:
89
- tutorials
10+
- tutorials/debugging-gdb-openocd
911

1012
- title: Concepts
1113
docs:

_docs/hardware_support.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: Supported Hardware
3+
---
4+
5+
This page lists the hardware that microROS currently supports, and also accessories that we frequently refer to, such as add-on boards, and JTAG probes.
6+
7+
## Evaluation Boards
8+
9+
### Olimex STM32-E407
10+
11+
This is a fairly bare-bones evaluation board with an STM32F407ZGT6 microcontroller.
12+
13+
## Development Tools
14+
15+
### Olimex ARM-USB-OCD-H JTAG probe
16+
17+
This is a JTAG probe with a USB and RS232 port that can also power the board. It looks as follows:
18+
![image of ARM-USB-OCD-H](https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/images/thumbs/310x230/ARM-USB-OCD-H-2.png)
19+
20+
See the [Olimex product page for ARM-USB-OCD-H](https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/) for details.

_docs/tutorials.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@ title: Tutorials
33
permalink: /docs/tutorials/
44
---
55

6-
content to be added by all
6+
content to be added by all
7+
8+
9+
## Basic Tutorials
10+
11+
* [Debugging NuttX with gdb and OpenOCD](/docs/tutorials/debugging-gdb-openocd)

_docs/tutorials/debugging/index.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
title: Debugging a NuttX target with GDB and OpenOCD
3+
author: Ingo Lütkebohle
4+
permalink: /docs/tutorials/debugging-gdb-openocd/
5+
---
6+
7+
Rare is the program that works on the first try -- so you will usually need a debugger. This is even more true on an embedded device, where "printf"-style debugging is very cumbersome.
8+
9+
There are many tools for embedded debugging. This tutorial will show you how to debug on the command line, using the [GNU Debugger gdb](https://www.gnu.org/software/gdb/) and the [Open On-Chip Debugger, OpenOCD](http://openocd.org/). These two open source tools are readily available on Linux, and they form the basis for many more advanced tools, including graphical debuggers.
10+
11+
NuttX integration for OpenOCD is relatively new as of the time of writing (early 2019), so this tutorial also includes instructions on how to get and configure it.
12+
13+
## Pre-Requisites
14+
15+
### Hardware
16+
17+
* a [supported embedded board](/docs/hardware_support#evaluation-boards)
18+
* a [support debugger probe](/docs/hardware_support#development-tools)
19+
20+
### Software
21+
22+
* a NuttX development setup, including gdb
23+
* OpenOCD-Nuttx (but we will show to install that)
24+
25+
26+
## Install OpenOCD-Nuttx
27+
28+
Sony has added NuttX support to OpenOCD, and most importantly, this includes thread info. Since NuttX is a real RTOS with support multiple tasks/threads, you need thread support to look at anything other than the currently active task.
29+
30+
### Get the code
31+
32+
The repository is on Github at [https://github.com/sony/openocd-nuttx](https://github.com/sony/openocd-nuttx). Check it out like this:
33+
```
34+
git clone --depth 1 https://github.com/sony/openocd-nuttx
35+
```
36+
(the '--depth 1' is not required, but it saves you from downloading unnecessary data)
37+
38+
Do *not* compile openocd just yet!
39+
40+
### Determine your NuttX configuration
41+
42+
NuttX sometimes switches around the memory location of the necessary information, so we need to configure OpenOCD for the currently used NuttX version.
43+
44+
Put the following into your `.gdbinit`:
45+
```
46+
define print-offset
47+
printf "#define PID %p\n",&((struct tcb_s *)(0))->pid
48+
printf "#define XCPREG %p\n",&((struct tcb_s *)(0))->xcp.regs
49+
printf "#define STATE %p\n",&((struct tcb_s *)(0))->task_state
50+
printf "#define NAME %p\n",&((struct tcb_s *)(0))->name
51+
printf "#define NAME_SIZE %d\n",sizeof(((struct tcb_s *)(0))->name)
52+
end
53+
```
54+
55+
Then run gdb on your nuttx binary and run this function:
56+
```
57+
arm-none-eabi-gdb nuttx
58+
(gdb) print-offset
59+
```
60+
On Nuttx 7.27, the result should look something like this:
61+
![gdb print offset output](/img/tutorials/gdb-print-offset.png)
62+
The interesting bits are the `#define` statements at the end,
63+
64+
Now open `openocd-nuttx/src/nuttx_header.h` in your favor editor, locate the existing `#define` lines
65+
and replace them with what you got. The result should be like this:
66+
![](/img/tutorials/nuttx_header_h.png)
67+
68+
### Configure OpenOCD for NuttX support
69+
70+
OpenOCD has a set of target configurations for the various boards. Since the boards could run one of many RTOS's, the default configuration doesn't specify any particular one -- so we have to add it.
71+
72+
When using the Olimex STM32-E407 board, one of our standard boards, the target configuration file is `stm32f4x.cfg` and it is normally located in `tcl/target/`. For your hardware, it might be a different file, so be sure to use the right one.
73+
74+
Open the target configuration and locate a line starting with `$_TARGETNAME configure`. Then add `-rtos nuttx` to this line.
75+
76+
### Compile OpenOCD
77+
78+
To compile and install OpenOCD, after you made your changes, run
79+
```bash
80+
./bootstrap
81+
./configure
82+
make
83+
sudo make install
84+
```
85+
86+
### Test OpenOCD
87+
88+
To test OpenOCD, try the following command line:
89+
```bash
90+
/usr/local/bin/openocd -f /usr/share/openocd/scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg -f stm32f4x.cfg -c init -c "reset halt"
91+
```
92+
93+
The output should look as in the following image:
94+
![OpenOCD test output](/img/tutorials/openocd-test.png)
95+
96+
OpenOCD will then block, waiting for a debugger to attach, so lets do that in the next section.
97+
98+
## Running GDB with OpenOCD
99+
100+
Run gdb in your NuttX directory as follows:
101+
```bash
102+
arm-none-eabi-gdb nuttx
103+
(gdb) target extended-remote :3333
104+
(gdb) cont
105+
```
106+
This connected to the gdb server running on port 3333 (OpenOCD default) of the same machine. It will sit on the NuttX `_start` function, which isn't very interesting, so we let it continue.
107+
108+
At this moment we have not defined any breakpoints, yet, so you can just press `Ctrl-C` to interrupt the running program again. This will interrupt it after NuttX had a chance to do initialization, so we will actually get to see some data.
109+
110+
### Inspect the program
111+
112+
Now, if everything worked correctly, we should get some information from the RTOS, such as thread info. To test, type `info threads` at the gdb prompt to get a thread info table. Your output will very depending on the NuttX configuration. On my bare-bones NSH-only configuration, it looks as follows:
113+
![](/img/tutorials/gdb-info-threads.png)
114+
So we see four threads, two of which are the OS work queues, one is the init thread, and one is the idle thread.
115+
116+
Most likely, NuttX has stopped in the idle thread, which isn't very interesting. To inspect the others, we can use the `thread` command to switch a thread and then maybe display a backtrace and some variables. Try the following:
117+
118+
```gdb
119+
thread 2
120+
info locals
121+
print rtcb
122+
print *rtcb
123+
```
124+
This switches to thread 2 and then inspects the local variables, of which there are two, one being called `rtcb`. We print it, see its a pointer to a structure, so we dereference and print again to display all the structure fields. This should look something like the following:
125+
![](/img/tutorials/gdb-print-rtcb.png)
126+
In my case, this is the NSH thread which is waiting for some input.
127+
128+
129+
## Conclusion
130+
131+
This concludes this basic tutorial on getting gdb to run with OpenOCD and NuttX support.
132+
133+
Using gdb on the command line is considered a bit cumbersome by many. So if you know your way
134+
around an IDE with gdb support, integrating it should be easy. We leave that as an exercise
135+
for the reader ;-)
136+
137+
There are also IDEs with microcontroller support -- stay tuned for another tutorial with more
138+
details on that.

img/tutorials/gdb-info-threads.png

37.1 KB
Loading

img/tutorials/gdb-print-offset.png

68.3 KB
Loading

img/tutorials/gdb-print-rtcb.png

73.7 KB
Loading

img/tutorials/nuttx_header_h.png

77.7 KB
Loading

img/tutorials/openocd-test.png

78.8 KB
Loading

0 commit comments

Comments
 (0)