You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/DEBUGGING.md
+72-10Lines changed: 72 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,15 +4,23 @@ The uVisor is distributed as a pre-linked binary blob. Blobs for different mbed
4
4
5
5
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.
6
6
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:
8
8
* A GDB-enabled board (and the related tools).
9
9
* yotta.
10
10
11
-
## Debug your application
11
+
## Debug capabilities
12
12
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:
14
14
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:
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:
25
34
26
35
```bash
27
36
$ yotta build -d
28
37
```
29
38
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.
31
40
32
41
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:
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).
39
48
40
49
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.
41
50
@@ -64,8 +73,6 @@ The following is the minimum set of commands you need to send to the device to f
64
73
65
74
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.
66
75
67
-
## Debugging messages
68
-
69
76
You can observe the debug messages using `netcat` or any other equivalent program:
70
77
71
78
```bash
@@ -93,9 +100,64 @@ Currently the following messages are printed:
93
100
94
101
* 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.
95
102
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
+
typedefstruct 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.
0 commit comments