Skip to content

Commit 04b67a2

Browse files
Start review of exceptions
1 parent 60e2ec3 commit 04b67a2

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

src/exceptions.md

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
11
# Exception handling
22

3-
During the "Memory layout" section we decided to start out simple and leave out handling of
4-
exceptions. In this section we'll add support for handling exceptions; this serves as an example of
3+
During the "Memory layout" section, we decided to start out simple and leave out handling of
4+
exceptions. In this section, we'll add support for handling them; this serves as an example of
55
how to achieve compile time overridable behavior in stable Rust (i.e. without relying on the
66
unstable `#[linkage = "weak"]` attribute, which makes a symbol weak).
77

88
## Background information
99

1010
In a nutshell, *exceptions* are a mechanism the Cortex-M and other architectures provide to let
11-
applications respond to asynchronous, usually external, events. The exception mechanism works like
12-
this: when the processor receives a signal or event associated to a type of exception it suspends
11+
applications respond to asynchronous, usually external, events. The most prominent type of exception,
12+
that most people will know, is the classical (hardware) interrupt.
13+
14+
The Cortex-M exception mechanism works like this:
15+
When the processor receives a signal or event associated to a type of exception, it suspends
1316
the execution of the current subroutine (by stashing the state in the call stack) and then proceeds
1417
to execute the corresponding exception handler, another subroutine, in a new stack frame. After
15-
finishing the execution of the exception handler (i.e. returning from it) the processor resumes the
18+
finishing the execution of the exception handler (i.e. returning from it), the processor resumes the
1619
execution of the suspended subroutine.
1720

1821
The processor uses the vector table to decide what handler to execute. Each entry in the table
1922
contains a pointer to a handler, and each entry corresponds to a different exception type. For
2023
example, the second entry is the reset handler, the third entry is the NMI (Non Maskable Interrupt)
2124
handler, and so on.
2225

23-
As mentioned before the processor expects the vector table to be at some specific location and each
24-
entry in it can potentially be used by the processor at runtime so they must always contain valid
25-
values. Furthermore, we want the `rt` crate to be flexible so the end user can customize the
26+
As mentioned before, the processor expects the vector table to be at some specific location in memory,
27+
and each entry in it can potentially be used by the processor at runtime. Hence, the entries must always
28+
contain valid values. Furthermore, we want the `rt` crate to be flexible so the end user can customize the
2629
behavior of each exception handler. Finally, the vector table is read only memory, or rather in not
2730
easily modified memory, so the user has to register the handler statically, rather than at runtime.
2831

29-
To satisfy all these constraints we'll assign a *default* value to all the entries of the vector
30-
table in the `rt` crate but make these values kind of *weak* to let the end user override them
32+
To satisfy all these constraints, we'll assign a *default* value to all the entries of the vector
33+
table in the `rt` crate, but make these values kind of *weak* to let the end user override them
3134
at compile time.
3235

3336
## Rust side
@@ -36,8 +39,8 @@ Let's see how all this can be implemented. For simplicity, we'll only work with
3639
of the vector table; these entries are not device specific so they have the same function on any
3740
kind of Cortex-M microcontroller.
3841

39-
The first thing we'll do is create an array of vectors (pointers to exception handlers) in the Rust
40-
code:
42+
The first thing we'll do is create an array of vectors (pointers to exception handlers) in the
43+
`rt` crate's code:
4144

4245
``` rust
4346
pub union Vector {
@@ -63,9 +66,7 @@ pub static EXCEPTIONS: [Vector; 14] = [
6366
Vector { handler: HardFault },
6467
Vector { handler: MemManage },
6568
Vector { handler: BusFault },
66-
Vector {
67-
handler: UsageFault,
68-
},
69+
Vector { handler: UsageFault },
6970
Vector { reserved: 0 },
7071
Vector { reserved: 0 },
7172
Vector { reserved: 0 },
@@ -83,7 +84,7 @@ should be assigned the value `0` so we use a union to do exactly that. The entri
8384
to a handler make use of *external* functions; this is important because it lets the end user
8485
*provide* the actual function definition.
8586

86-
Next we define a default exception handler in the Rust code. Exceptions that have not been assigned
87+
Next, we define a default exception handler in the Rust code. Exceptions that have not been assigned
8788
a handler by the end user will make use of this default handler.
8889

8990
``` rust
@@ -130,8 +131,8 @@ PROVIDE(PendSV = DefaultExceptionHandler);
130131
PROVIDE(SysTick = DefaultExceptionHandler);
131132
```
132133

133-
`PROVIDE` only takes effect when symbol on the RHS is still undefined after inspecting all the input
134-
object files. This is the scenario where the user didn't assign a handler to the exception.
134+
`PROVIDE` only takes effect when a symbol on the RHS is still undefined after inspecting all the input
135+
object files. This is the scenario where the user didn't implement the handler for the respective exception.
135136

136137
## Testing it
137138

@@ -216,7 +217,7 @@ Contents of section .vector_table:
216217

217218
## Overriding a handler
218219

219-
To override an exception handler the user has to provide a function whose symbol name exactly
220+
To override an exception handler, the user has to provide a function whose symbol name exactly
220221
matches the name we used in `EXCEPTIONS`.
221222

222223
``` rust
@@ -262,9 +263,9 @@ Process 1 stopped
262263
The program now executes the user defined `HardFault` function instead of the
263264
`DefaultExceptionHandler` in the `rt` crate.
264265

265-
Like our first attempt at a `main` interface this first implementation has the problem of having no
266+
Like our first attempt at a `main` interface, this first implementation has the problem of having no
266267
type safety. It's also easy to mistype the name of the exception, but that doesn't produce an error
267-
or warning instead the user defined handler is simply ignored. Those problems can be fixed using a
268+
or warning. Instead the user defined handler is simply ignored. Those problems can be fixed using a
268269
macro like the [`exception!`] macro defined in `cortex-m-rt`.
269270

270271
[`exception!`]: https://github.com/japaric/cortex-m-rt/blob/v0.5.1/src/lib.rs#L79

0 commit comments

Comments
 (0)