Skip to content

Commit 54fe069

Browse files
committed
Add documentation about the debug box
1 parent f344277 commit 54fe069

File tree

1 file changed

+72
-10
lines changed

1 file changed

+72
-10
lines changed

docs/DEBUGGING.md

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@ The uVisor is distributed as a pre-linked binary blob. Blobs for different mbed
44

55
If you only want to use the uVisor debug features on an already supported platform, you do not need to clone it and build it locally. If you instead want to make modifications to uVisor (or port it to your platform) and test the modifications locally with your app, please follow the [Developing with uVisor locally](DEVELOPING_LOCALLY.md) guide first.
66

7-
In this quick guide we will show you how to enable debug on uVisor. You will need the following:
7+
In this quick guide we will show you how to enable the default debug features on uVisor, and how to instrument it to get even more debug information. You will need the following:
88
* A GDB-enabled board (and the related tools).
99
* yotta.
1010

11-
## Debug your application
11+
## Debug capabilities
1212

13-
Debug messages are delivered through [semihosting](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471l/pge1358787045051.html), which requires a debugger to be connected to the device.
13+
The uVisor provides two main sources of debug information:
1414

15-
We will assume from now on that you have a debugger connected to your board. We will use our Hello World application for this example, but of course any other can be used, provided that it is correctly setup to use uVisor. See [Developing with uVisor locally](DEVELOPING_LOCALLY.md) for more details.
15+
1. Runtime messages. These are delivered through [semihosting](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0471l/pge1358787045051.html), which requires a debugger to be connected to the device. Currently debug messages are used to instrument some of the security-critical features of uVisor, like boot and start-up configuration, interrupts management, and context switching. A post-mortem screen is also output when the system is halted due to a fault.
16+
17+
2. Debug box drivers. We call a *debug box* a secure box that registers with uVisor to handle debug events and messages. The uVisor provides a predefined function table that describes the driver and its capabilities. Different debug boxes can implement these handlers differently, independently from uVisor. All handlers are executed in unprivileged mode.
18+
19+
Runtime messages and debug box handlers are independent from each other. Even if an application does not include a debug box, the uVisor is still able to deliver basic runtime messages. Conversely, an application that includes a debug box will handle debug events even if the release build of uVisor is used and possibly even without a debugger connected.
20+
21+
## Enabling runtime messages
22+
23+
If you want to observe the uVisor runtime messages you need to have a debugger connected to your board. We will use our Hello World application for this guide, built for the NXP FRDM-K64F target:
1624

1725
```bash
1826
$ cd ~/code
@@ -21,21 +29,22 @@ $ yotta install uvisor-helloworld
2129
$ cd uvisor-helloworld
2230
```
2331

24-
Build your application:
32+
Of course any other application can be used, provided that it is correctly set up to use uVisor. See [Developing with uVisor locally](DEVELOPING_LOCALLY.md) for more details.
33+
Runtime messages are silenced by default. In order to enable them, you need to build your application linking to the debug version of uVisor. Starting with v2.0.0, `uvisor-lib` comes with both the release and debug builds of uVisor, so you only need to run the following command:
2534

2635
```bash
2736
$ yotta build -d
2837
```
2938

30-
The `-d` option ensures that yotta enables debug symbols and disables optimizations. In addition, it ensures that the `uvisor-lib` modules selects the debug build of uVisor, which enables the uVisor debug features.
39+
The `-d` option ensures that yotta enables debug symbols and disables optimizations. In addition, it ensures that the `uvisor-lib` modules selects the debug build of uVisor, which enables the uVisor runtime messages.
3140

3241
Now start the GDB server. This step changes depending on which debugger you are using. In case you are using a J-Link debugger, run:
3342

3443
```bash
3544
$ JLinkGDBServer -device ${device_name} -if ${interface}
3645
```
3746

38-
where `${device_name}` and `${interface}` are J-Link-specific. Please check out the [J-Link documentation](https://www.segger.com/admin/uploads/productDocs/UM08001_JLink.pdf) and the list of [supported devices](https://www.segger.com/jlink_supported_devices.html).
47+
In the command above `${device_name}` and `${interface}` are J-Link-specific. Please check out the [J-Link documentation](https://www.segger.com/admin/uploads/productDocs/UM08001_JLink.pdf) and the list of [supported devices](https://www.segger.com/jlink_supported_devices.html).
3948

4049
Time to flash the device! We will use GDB for that, even if your device allows drag & drop flashing. This allows us to potentially group several commands together into a start-up GDB script.
4150

@@ -64,8 +73,6 @@ The following is the minimum set of commands you need to send to the device to f
6473

6574
From here on if you send the `c` command the program will run indefinitely. Of course you can configure other addresses/ports for the target. Please refer to the [GDB documentation](http://www.gnu.org/software/gdb/documentation/) for details on the GDB commands.
6675

67-
## Debugging messages
68-
6976
You can observe the debug messages using `netcat` or any other equivalent program:
7077

7178
```bash
@@ -93,9 +100,64 @@ Currently the following messages are printed:
93100

94101
* Debug messages might interfere with timing constraints, as they are shown while running in the highest priority level. Applications that have very strict timing requirements might show some unexpected behaviour.
95102

103+
## The debug box
104+
105+
> Warning: The debug box feature is an early prototype. The APIs and procedures described here might change several times in non-backwards-compatible ways.
106+
107+
The uVisor code is instrumented to output debug information when it is relevant. In order to keep the uVisor as simple and hardware-independent as possible, some of this information is not handled and interpreted directly by uVisor.
108+
109+
Instead, debug events and messages are forwarded to a special unprivileged box, called a *debug box*. A debug box is configured just like any other secure box, but it registers with uVisor to handle debug callbacks. These callbacks must adhere to a format that is provided by uVisor, in the form of a debug box driver.
110+
111+
The debug box driver is encoded in a standard table (a C `struct`) that must be populated by a debug box at initialization time. A debug box can decide to implement only some of the available handlers, although they must all exist at least as empty functions, otherwise the program behaviour might be unpredictable.
112+
113+
Currently, only one debug handler is provided. A debug box driver will always expect a `get_version()` handler in position 0 of the function table:
114+
115+
```C
116+
typedef struct TUvisorDebugDriver {
117+
uint32_t (*get_version)(void); /* 0. Return the implemented driver version. */
118+
void (*halt_error)(int); /* 1. Halt on error. Reboot upon return. */
119+
}
120+
```
121+
122+
The following is an example of how to implement and configure a debug box.
123+
124+
```C
125+
#include "mbed-drivers/mbed.h"
126+
#include "uvisor-lib/uvisor-lib.h"
127+
128+
/* Configure the debug box. */
129+
UVISOR_BOX_NAMESPACE(NULL);
130+
UVISOR_BOX_CONFIG(box_debug, UVISOR_BOX_STACK_SIZE);
131+
132+
static uint32_t get_version(void) {
133+
return 0;
134+
}
135+
136+
static void halt_error(int reason) {
137+
printf("We halted with reason %i\r\n", reason);
138+
/* We will now reboot. */
139+
}
140+
141+
UVISOR_EXTERN void __box_debug_init(void) {
142+
/* Debug box driver -- Version 0 */
143+
static const TUvisorDebugDriver driver = {
144+
get_version,
145+
halt_error
146+
};
147+
148+
/* Register the debug box with uVisor. */
149+
uvisor_debug_init(&driver);
150+
}
151+
152+
void box_debug::init(void) {
153+
/* The debug box is initialized from the context of box_debug. */
154+
secure_gateway(box_debug, __box_debug_init);
155+
}
156+
```
157+
96158
## Platform-specific details
97159
98-
Currently the following platforms are supported by uVisor:
160+
Currently the following platforms are officially supported by uVisor:
99161
100162
* [NXP FRDM-K64F](http://developer.mbed.org/platforms/FRDM-K64F/).
101163
* [STMicorelectronics STM32F429I-DISCO](http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090).

0 commit comments

Comments
 (0)