1
1
# A ` main ` interface
2
2
3
- We have a minimal working program but we need to package it in such a way that end user can build
4
- safe programs on top of it. In this section we'll implement a ` main ` interface like the one standard
3
+ We have a minimal working program now, but we need to package it in a way that the end user can build
4
+ safe programs on top of it. In this section, we'll implement a ` main ` interface like the one standard
5
5
Rust programs use.
6
6
7
7
First, we'll convert our binary crate into a library crate:
@@ -10,7 +10,7 @@ First, we'll convert our binary crate into a library crate:
10
10
$ mv src/main.rs src/lib.rs
11
11
```
12
12
13
- And rename it to ` rt ` which stands for "runtime".
13
+ And then rename it to ` rt ` which stands for "runtime".
14
14
15
15
``` console
16
16
$ sed -i s/app/rt/ Cargo.toml
@@ -37,11 +37,11 @@ pub unsafe extern "C" fn Reset() -> ! {
37
37
38
38
We also drop the ` #![no_main] ` attribute has it has no effect on library crates.
39
39
40
- > There's an orthogonal question that arises at this stage: should the ` rt ` library provide a
40
+ > There's an orthogonal question that arises at this stage: Should the ` rt ` library provide a
41
41
> standard panicking behavior, or should it * not* provide a ` #[panic_implementation] ` function and
42
42
> leave the end user choose the panicking behavior? This document won't delve into that question and
43
- > for simplicity will leave the dummy ` #[panic_implementation] ` function in the ` rt ` crate, but we
44
- > wanted to inform the reader that there are other options.
43
+ > for simplicity will leave the dummy ` #[panic_implementation] ` function in the ` rt ` crate.
44
+ > However, we wanted to inform the reader that there are other options.
45
45
46
46
The second change involves providing the linker script we wrote before to the application crate. You
47
47
see the linker will search for linker scripts in the library search path (` -L ` ) and in the directory
@@ -134,12 +134,12 @@ Reset:
134
134
135
135
## Making it type safe
136
136
137
- The ` main ` interface works but it's easy to get it wrong: for example, the user could write ` main `
137
+ The ` main ` interface works, but it's easy to get it wrong: For example, the user could write ` main `
138
138
as a non-divergent function, and they would get no compile time error and undefined behavior (the
139
139
compiler will misoptimize the program).
140
140
141
141
We can add type safety by exposing a macro to the user instead of the symbol interface. In the
142
- ` rt ` crate we can write this macro:
142
+ ` rt ` crate, we can write this macro:
143
143
144
144
``` rust
145
145
#[macro_export]
@@ -231,9 +231,9 @@ fn main() -> ! {
231
231
}
232
232
```
233
233
234
- However if you run this program on real hardware and debug it you'll observe that the ` static `
235
- variables ` BSS ` and ` DATA ` don't have the values ` 0 ` and ` 1 ` by the time ` main ` have been reached.
236
- Instead these variables will have junk values; the problem is that the contents of RAM are
234
+ However if you run this program on real hardware and debug it, you'll observe that the ` static `
235
+ variables ` BSS ` and ` DATA ` don't have the values ` 0 ` and ` 1 ` by the time ` main ` has been reached.
236
+ Instead, these variables will have junk values. The problem is that the contents of RAM are
237
237
random after powering up the device. You won't be able to observe this effect if you run the
238
238
program in QEMU.
239
239
@@ -283,7 +283,7 @@ later use from Rust code.
283
283
```
284
284
285
285
We set the Load Memory Address (LMA) of the ` .data ` section to the end of the ` .rodata `
286
- section. The ` .data ` contains ` static ` variable with a non-zero initial value; the Virtual Memory
286
+ section. The ` .data ` contains ` static ` variables with a non-zero initial value; the Virtual Memory
287
287
Address (VMA) of the ` .data ` section is somewhere in RAM -- this is where the ` static ` variables are
288
288
located. The initial values of those ` static ` variables, however, must be allocated in non volatile
289
289
memory (Flash); the LMA is where in Flash those initial values are stored.
@@ -295,7 +295,7 @@ memory (Flash); the LMA is where in Flash those initial values are stored.
295
295
Finally, we associate a symbol to the LMA of ` .data ` .
296
296
297
297
On the Rust side, we zero the ` .bss ` section and initialize the ` .data ` section. We can reference
298
- the symbols we created in the linker script from the Rust code. The * addresses* of these symbols are
298
+ the symbols we created in the linker script from the Rust code. The * addresses* [ ^ 1 ] of these symbols are
299
299
the boundaries of the ` .bss ` and ` .data ` sections.
300
300
301
301
The updated reset handler is shown below:
@@ -339,3 +339,6 @@ undefined behavior!
339
339
> are interested in learning how this can be achieved check the [ ` cortex-m-rt ` ] crate.
340
340
341
341
[ `cortex-m-rt` ] : https://github.com/japaric/cortex-m-rt/tree/v0.5.1
342
+
343
+ [ ^ 1 ] : The fact that the addresses of the linker script symbols must be used here can be confusing and
344
+ unintuitive. An elaborate explanation for this oddity can be found [ here] ( https://stackoverflow.com/a/40392131 ) .
0 commit comments