Skip to content

Commit 804d6ce

Browse files
authored
Merge pull request #9 from microROS/feature/debug-tutorial
Add debugging tutorial
2 parents 8829199 + b6c8190 commit 804d6ce

13 files changed

Lines changed: 270 additions & 1 deletion

_data/docs.yml

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

56
# placeholder for tutorials...
67
- title: Tutorials
78
docs:
9+
- tutorials
810
- tutorials/getting_started
911
- tutorials/getting_started_embedded
1012
- tutorials/getting_started_simulator
1113
- tutorials/advanced
1214
- tutorials/advanced/nuttx_getting_started
15+
- tutorials/advanced/debugging-gdb-openocd
16+
- tutorials/advanced/debugging-vscode
1317

1418
- title: Concepts
1519
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: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,12 @@ 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+
## Intermediate Tutorials
12+
13+
* [Debugging NuttX with gdb and OpenOCD](/docs/tutorials/debugging-gdb-openocd)
14+
* [Debugging using Visual Studio Code](/docs/tutorials/debugging-vscode)
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
title: Debugging a NuttX target with GDB and OpenOCD
3+
author: Ingo Lütkebohle
4+
permalink: /docs/tutorials/advanced/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+
**NOTE** The Sony OpenOCD branch has some compile issues on Ubuntu 18.04 right now, because it uses a newer compiler. The easiest "solution" is to remove the `-Werror` from your compile. We'll submit a patch soon.
79+
80+
To compile and install OpenOCD, after you made your changes, run
81+
```bash
82+
./bootstrap
83+
./configure
84+
make
85+
sudo make install
86+
```
87+
88+
### Test OpenOCD
89+
90+
To test OpenOCD, try the following command line:
91+
```bash
92+
/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"
93+
```
94+
95+
The output should look as in the following image:
96+
![OpenOCD test output](/img/tutorials/openocd-test.png)
97+
98+
OpenOCD will then block, waiting for a debugger to attach, so lets do that in the next section.
99+
100+
## Running GDB with OpenOCD
101+
102+
Run gdb in your NuttX directory as follows:
103+
```bash
104+
arm-none-eabi-gdb nuttx
105+
(gdb) target extended-remote :3333
106+
(gdb) cont
107+
```
108+
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.
109+
110+
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.
111+
112+
### Inspect the program
113+
114+
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:
115+
![](/img/tutorials/gdb-info-threads.png)
116+
So we see four threads, two of which are the OS work queues, one is the init thread, and one is the idle thread.
117+
118+
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:
119+
120+
```gdb
121+
thread 2
122+
info locals
123+
print rtcb
124+
print *rtcb
125+
```
126+
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:
127+
![](/img/tutorials/gdb-print-rtcb.png)
128+
In my case, this is the NSH thread which is waiting for some input.
129+
130+
131+
## Conclusion
132+
133+
This concludes this basic tutorial on getting gdb to run with OpenOCD and NuttX support.
134+
135+
Using gdb on the command line is considered a bit cumbersome by many. So if you know your way
136+
around an IDE with gdb support, integrating it should be easy. We leave that as an exercise
137+
for the reader ;-)
138+
139+
There are also IDEs with microcontroller support -- stay tuned for another tutorial with more
140+
details on that.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
title: Debugging with Visual Studio Code
3+
permalink: /docs/tutorials/advanced/debugging-vscode/
4+
author: Ingo Lütkebohle
5+
---
6+
7+
This is a follow-up to [Debugging with gdb and openocd](/docs/tutorials/debugging-gdb-openocd/), because the set up done in that tutorial is a pre-requisite to debugging with Visual Studio Code.
8+
9+
## Motivation
10+
11+
Visual Studio Code is a modern IDE that is very easy to extend and popular with both the Web/Cloud and IoT communities. It is also one of the easiest IDEs to get working with embedded systems. That said, it is *not* the most powerful or featureful IDEs for this purpose, but it is easy and will do.
12+
13+
## Prerequisites
14+
15+
* All the prerequisites of [Debugging with gdb and openocd](/docs/tutorials/debugging-gdb-openocd/)
16+
* Cortex-M hardware (all of our standard boards are ARM based)
17+
* [Visual Studio Code](https://code.visualstudio.com/)
18+
19+
20+
## Installing Cortex-Debug
21+
22+
In the extensions marketplace, enter "cortex", then install "Cortex-Debug". Depending on your version of Visual Studio Code, you may need to restart after installing the extension.
23+
24+
## Set up your project for debugging
25+
26+
Open your project folder in Visual Studio Code -- this is usually the `NuttX` folder, or a subdirectory of `apps`.
27+
28+
### Create a Visual Studio Code launch configuration for NuttX
29+
30+
From the `Debug` menu, select `Open Configurations`. This will open a `launch.json' file. See [Cortex-Debug Launch configurations](https://marcelball.ca/projects/cortex-debug/cortex-debug-launch-configurations/) for documentation.
31+
32+
To get started, I have prepared a working launch configuration for using our STM32-E407 board with the ARM-USB-OCD-H jtag probe. If you use a different board or probe, you only need to replace the `configFiles` section. Each entry in the section is an argument that you would normally pass as a `-f` option to OpenOCD.
33+
```json
34+
{
35+
"version": "0.2.0",
36+
"configurations": [
37+
{
38+
"name": "Debug (OpenOCD/NuttX)",
39+
"cwd": "${workspaceRoot}",
40+
"executable": "nuttx",
41+
"request": "launch",
42+
"type": "cortex-debug",
43+
"servertype": "openocd",
44+
"device": "stm32f4x",
45+
"configFiles": [
46+
"interface/ftdi/olimex-arm-usb-ocd-h.cfg",
47+
"target/stm32f4x.cfg"
48+
]
49+
}
50+
]
51+
}
52+
```
53+
The `name` is what will appear in the status bar for running it.
54+
55+
### Running the debugger
56+
57+
Either press `F5` or select `Debug/Start Debugging` from the menu to get started. This will take a moment, and then you should get a red status bar and the debug window, like in the following image:
58+
![debug window](/img/tutorials/debug-vscode.png)
59+
60+
As in the gdb tutorial, initially you won't see much because the program is stopped during OS initialization. Press `F5` again or click the "play" button from the debug menu at the top of the window, wait a few seconds, then press `F6` or click the pause button. The window should change to give you thread, variable, and register information, like in the following. Note that "Call Stack" window displays multiple threads.
61+
62+
![debug window with running code](/img/tutorials/debug-vscode-phyread.png)
63+
64+
### Adding an SVD File
65+
66+
You may have noticed that on the left-hand side, there is a sub-window called "Cortex Peripherals" which simply states "No SVD File loaded". SVD means "System View Description" and is a standard format which microcontroller vendors use to describe the available features of their MCUs.
67+
68+
For example, in the case of our STM32-E407 board, which features an STM32F407ZGT6 MCU, we can download the SVD description from [STM's web-page for the STM32F407ZG series](https://www.st.com/en/microcontrollers-microprocessors/stm32f407zg.html). In the "HW Model, CAD Libraries & SVD", you will find a link to the [STM32F4 series SVD](https://www.st.com/resource/en/svd/stm32f4_svd.zip).
69+
70+
Extract the SVD and then add an `svdFile` attribute to the launch configuration. The full configuration will look like this:
71+
72+
```json
73+
{
74+
"version": "0.2.0",
75+
"configurations": [
76+
{
77+
"name": "Debug (OpenOCD/SVD)",
78+
"cwd": "${workspaceRoot}",
79+
"executable": "nuttx",
80+
"request": "launch",
81+
"type": "cortex-debug",
82+
"servertype": "openocd",
83+
"device": "stm32f4x",
84+
"svdFile": "STM32F407.svd",
85+
"configFiles": [
86+
"interface/ftdi/olimex-arm-usb-ocd-h.cfg",
87+
"target/stm32f4x.cfg"
88+
]
89+
}
90+
]
91+
}
92+
```
93+
94+
Run the debugger again, and your window should look as follows:
95+
![](/img/tutorials/debug-vscode-svd.png)
96+
97+
Voilà! The `Cortex Peripherals` is populated with everything that the STM32F407 MCU has to offer. Please note that not all of these peripherals might actually be connected on the board. However, those that are, and that are used in your application, can easily be investigated like this.
257 KB
Loading

img/tutorials/debug-vscode-svd.png

248 KB
Loading

img/tutorials/debug-vscode.png

227 KB
Loading

img/tutorials/gdb-info-threads.png

37.1 KB
Loading

img/tutorials/gdb-print-offset.png

68.3 KB
Loading

0 commit comments

Comments
 (0)