Skip to content

Commit c4db305

Browse files
authored
Merge pull request #2 from rust-embedded/faq
add FAQ; enable table of contents
2 parents 6584edc + c725677 commit c4db305

File tree

3 files changed

+274
-0
lines changed

3 files changed

+274
-0
lines changed

ci/script.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ main() {
3030

3131
# build index page
3232
rustdoc --markdown-css rust.css --markdown-no-toc index.md
33+
rustdoc --markdown-css rust.css faq.md
3334

3435
# build books
3536
local books=(

faq.md

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# Frequently Asked Questions
2+
3+
# Does Rust support my device?
4+
5+
## Short answer
6+
7+
As of 2018-09-18 the Rust compiler supports cross compiling to these embedded
8+
architectures (see `rustup target list`):
9+
10+
- ARM Cortex-M (since 1.27)
11+
- `thumbv6m-none-eabi`, Cortex-M0
12+
- `thumbv7m-none-eabi`, Cortex-M3
13+
- `thumbv7em-none-eabi`, Cortex-M4 and Cortex-M7
14+
- `thumbv7em-none-eabihf`, Cortex-M4F and Cortex-M7F
15+
- ARM Cortex-R (1.30-beta)
16+
- `armebv7r-none-eabi`, big endian Cortex-R4 and Cortex-R5
17+
- `armebv7r-none-eabihf`, big endian Cortex-R4F and Cortex-R5F
18+
- `armv7r-none-eabi`, little endian Cortex-R4 and Cortex-R5
19+
- `armv7r-none-eabihf`, little endian Cortex-R4F and Cortex-R5F
20+
- ARM Linux
21+
- ARMv5TE (e.g. ARM926EJ-S),
22+
- ARMv6 (e.g. ARM11 as found in the Raspberry Pi 1 / Zero),
23+
- ARMv7-A (e.g. Cortex-A8 as found in the Beaglebones),
24+
- and ARMv8 (e.g. Cortex-A53 as found in the ODROID-C2) ...
25+
- ... in GNU and MUSL flavors and in soft float and hard float variants;
26+
- notably, support for ARMv4T (e.g. ARM7) and older versions is missing.
27+
- RISCV (1.30-beta)
28+
- `riscv32imac-unknown-none-elf`, RV32I base instruction set with M, A and C
29+
extensions
30+
- `riscv32imc-unknown-none-elf`, RV32I base instruction set with M, and C
31+
extensions
32+
33+
`rustc` also supports code generation for the MSP430 architecture (see `rustc
34+
--print target-list`).
35+
36+
In general, ARM Cortex-M and ARM Linux have the most mature ecosystems whereas
37+
the ARM Cortex-R, MSP430 and RISCV ecosystems are in early stages or not as
38+
mature.
39+
40+
For specific device support check [awesome-embedded-rust].
41+
42+
[awesome-embedded-rust]: https://github.com/rust-embedded/awesome-embedded-rust
43+
44+
## Long answer
45+
46+
We can talk about support at different levels: does the compiler support my
47+
device? does the crate ecosystem support my device?
48+
49+
Let's start with compiler support. The compiler supports architectures or ISA
50+
(Instruction Set Architectures) rather than specific devices. Compiler support
51+
can be further divided in two levels: compilation target support and
52+
architecture support.
53+
54+
### Compilation target support
55+
56+
By compilation target support we mean that you can readily cross compile a crate
57+
for a certain *compilation target* using Cargo. To keep the default installation
58+
slim only the native compilation target is installed and other targets have to
59+
be installed using the `rustup target` subcommand. If `rustup target list` lists
60+
a compilation target that matches your device then Cargo supports cross
61+
compiling to your device.
62+
63+
For example, let's say we want to know if `rustc` supports cross compiling to
64+
32-bit RISCV. We check `rustup target list`
65+
66+
``` console
67+
$ rustup default 1.29.0
68+
$ rustup target list | grep -i riscv || echo not supported
69+
not supported
70+
71+
$ rustup default nightly-2018-09-18 # this date is just an example
72+
$ rustc -V
73+
rustc 1.30.0-nightly (2224a42c3 2018-09-17)
74+
$ rustup target list | grep -i riscv || echo not supported
75+
riscv32imac-unknown-none-elf
76+
riscv32imc-unknown-none-elf
77+
```
78+
79+
This indicates that 1.29 doesn't support 32-bit RISCV but that 1.30 will.
80+
81+
Once you have installed a compilation target using `rustup target add $T` you'll
82+
be able to cross compile crates to it using `cargo build --target $T`.
83+
84+
``` console
85+
$ rustup target add riscv32imac-unknown-none-elf
86+
$ cargo build --target riscv32imac-unknown-none-elf
87+
```
88+
89+
### Architecture support
90+
91+
If your device doesn't appear in `rustup target list` that doesn't mean that
92+
`rustc` doesn't support your device at all. It could still support code
93+
generation for your device *architecture*. `rustc` uses LLVM to generate machine
94+
code; if the LLVM backend for your device architecture is enabled in `rustc`
95+
then `rustc` can produce assembly and/or object files for that architecture.
96+
97+
The easiest way to list the architectures that LLVM supports is to run
98+
`cargo objdump -- -version` where `cargo-objdump` is one of [`cargo-binutils`]
99+
subcommands.
100+
101+
[`cargo-binutils`]: https://github.com/rust-embedded/cargo-binutils
102+
103+
``` console
104+
$ rustup default nightly-2018-09-18 # this date is just an example
105+
$ rustup component add llvm-tools-preview
106+
$ cargo install cargo-binutils
107+
108+
$ cargo objdump -- -version
109+
LLVM (http://llvm.org/):
110+
LLVM version 8.0.0svn
111+
Optimized build.
112+
Default target: x86_64-unknown-linux-gnu
113+
Host CPU: skylake
114+
115+
Registered Targets:
116+
aarch64 - AArch64 (little endian)
117+
aarch64_be - AArch64 (big endian)
118+
arm - ARM
119+
arm64 - ARM64 (little endian)
120+
armeb - ARM (big endian)
121+
hexagon - Hexagon
122+
mips - Mips
123+
mips64 - Mips64 [experimental]
124+
mips64el - Mips64el [experimental]
125+
mipsel - Mipsel
126+
msp430 - MSP430 [experimental]
127+
nvptx - NVIDIA PTX 32-bit
128+
nvptx64 - NVIDIA PTX 64-bit
129+
ppc32 - PowerPC 32
130+
ppc64 - PowerPC 64
131+
ppc64le - PowerPC 64 LE
132+
riscv32 - 32-bit RISC-V
133+
riscv64 - 64-bit RISC-V
134+
sparc - Sparc
135+
sparcel - Sparc LE
136+
sparcv9 - Sparc V9
137+
systemz - SystemZ
138+
thumb - Thumb
139+
thumbeb - Thumb (big endian)
140+
wasm32 - WebAssembly 32-bit
141+
wasm64 - WebAssembly 64-bit
142+
x86 - 32-bit X86: Pentium-Pro and above
143+
x86-64 - 64-bit X86: EM64T and AMD64
144+
```
145+
146+
If your device architecture is not there that means `rustc` doesn't support your
147+
device. It could be that LLVM doesn't support the architecture (e.g. Xtensa,
148+
ESP8266's architecture) or that LLVM's support for the architecture is not
149+
considered stable enough and has not been enabled in `rustc` (e.g. AVR, the
150+
architecture most commonly found in Arduino microcontrollers).
151+
152+
If your device architecture is there then that means that, in principle, `rustc`
153+
supports your device. However, an architecture like ARM can be very broad
154+
covering several ISAs and extensions. Instead, you'll want to work with a
155+
compilation target tailored to your device. Custom compilation targets are out
156+
of scope for this document; you should refer to the [embedonomicon] for more
157+
information.
158+
159+
[embedonomicon]: https://rust-embedded.github.io/embedonomicon/compiler-support.html
160+
161+
### Crate ecosystem support
162+
163+
Crate ecosystem support can range from generic support for the architecture to
164+
device-specific support. We recommend that you search on crates.io for the
165+
architecture (e.g. ARM or Cortex-M), for the microcontroller vendor (e.g.
166+
STM32), for the target device (e.g. STM32F103) and the target development board
167+
(e.g. STM32F3DISCOVERY). We also suggest that you check the
168+
[awesome-embedded-rust] list and [the crates maintained by the embedded Working
169+
Group][wg-crates].
170+
171+
[wg-crates]: https://github.com/rust-embedded/wg#organization
172+
173+
# (When) will Rust support the AVR architecture?
174+
175+
As of 2018-09-19 the official Rust compiler, `rustc`, relies on LLVM for
176+
generating machine code. It's a requirement that LLVM supports an architecture
177+
for `rustc` to support it.
178+
179+
LLVM does support the AVR architecture but the AVR backend has bugs that prevent
180+
it from being enabled in `rustc`. In particular, the AVR backend should be able
181+
to compile the `core` crate without hitting any LLVM assertion before it's
182+
enabled in `rustc`. A likely outdated list of LLVM bugs that need to be fixed
183+
can be found in [the issue tracker of the the rust-avr fork of rustc][rust-avr].
184+
185+
[rust-var]: https://github.com/avr-rust/rust/issues
186+
187+
TL;DR `rustc` will support the AVR architecture when the LLVM backend is
188+
relatively bug free. As LLVM is a project independent of the Rust project we
189+
can't give you any estimate on when that might happen.
190+
191+
# (When) will Rust support the Xtensa architecture?
192+
193+
As of 2018-09-19 the official Rust compiler, `rustc`, relies on LLVM for
194+
generating machine code. It's a requirement that LLVM supports an architecture
195+
for `rustc` to support it.
196+
197+
There is no support for the Xtensa architecture in LLVM proper. You may be able
198+
to find several forks of LLVM with varying levels of support for the Xtensa
199+
architecture but `rustc` will not be able to use any of those forks due to the
200+
maintenance and infrastructure costs of developing `rustc` against different
201+
versions of LLVM.
202+
203+
TL;DR `rustc` will support the Xtensa architecture when the official LLVM gains
204+
support for the Xtensa architecture. As LLVM is a project independent of the
205+
Rust project we can't give you any estimate on when that might happen.
206+
207+
# My embedded Rust program is too big!
208+
209+
We sometimes get questions like this one: "My Rust program is 500 KB but my
210+
microcontroller only has 16 KB of Flash; how can I make it fit?".
211+
212+
The first thing to confirm is that correctly measuring the size of your program.
213+
`rustc` produces ELF files for most embedded targets. ELF files have metadata
214+
and contain debug information so measuring their size on disk with e.g. `ls -l`
215+
will give you the wrong number.
216+
217+
``` console
218+
$ # 500 KB?
219+
$ ls -hl target/thumbv7m-none-eabi/debug/app
220+
-rwxr-xr-x 2 japaric japaric 554K Sep 19 13:37 target/thumbv7m-none-eabi/debug/app
221+
```
222+
223+
The correct way to measure the size of an embedded program is to use the `size`
224+
program or the [`cargo size`] subcommand.
225+
226+
[`cargo size`]: https://github.com/rust-embedded/cargo-binutils
227+
228+
``` console
229+
$ # ~ 2 KB of Flash
230+
$ cargo size --bin app -- -A
231+
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
232+
app :
233+
section size addr
234+
.vector_table 1024 0x8000000
235+
.text 776 0x8000400
236+
.rodata 208 0x8000708
237+
.data 0 0x20000000
238+
.bss 0 0x20000000
239+
.debug_str 145354 0x0
240+
.debug_abbrev 11264 0x0
241+
.debug_info 139259 0x0
242+
.debug_macinfo 33 0x0
243+
.debug_pubnames 40901 0x0
244+
.debug_pubtypes 14326 0x0
245+
.ARM.attributes 50 0x0
246+
.debug_frame 21224 0x0
247+
.debug_line 117666 0x0
248+
.debug_ranges 63800 0x0
249+
.comment 75 0x0
250+
Total 555960
251+
```
252+
253+
Of the standard sections, `.text`, `.rodata` and `.data` will occupy Flash /
254+
ROM; `.bss` and `.data` will occupy RAM; `.debug_*`, `.ARM.attributes` and
255+
`.comments` can be ignored as they won't be loaded into the target device
256+
memory. For the other sections you'll have to check your dependencies' docs.
257+
258+
In this examples the program will occupy `2008` bytes of Flash.
259+
260+
Note that most (all?) runtime crates, like `cortex-m-rt`, will check at link
261+
time that the program fits in the target device memory. If it doesn't fit you'll
262+
get a linker error and no output binary. So, provided that you correctly entered
263+
the size of the memory regions of your device then if it links it should fit in
264+
the target device!
265+
266+
If you are measuring size using the right method and your program is still too
267+
big then check out our section on optimizations.
268+
269+
> **TODO**(resources team) add link to the optimizations section

index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ programs easier.
5151

5252
[Awesome embedded Rust]: https://github.com/rust-embedded/awesome-embedded-rust
5353

54+
## Frequently Asked Questions
55+
56+
You can find our FAQ [here](faq.html).
57+
5458
# Master embedded Rust
5559

5660
Once you're quite familiar with embedded Rust development, you may find these

0 commit comments

Comments
 (0)