beginner: less tooling invocations; add cargo-bloat

This commit is contained in:
Jorge Aparicio 2020-07-10 18:34:55 +02:00
parent b7a922746b
commit ae3fb7a288
3 changed files with 34 additions and 28 deletions

View file

@ -291,7 +291,7 @@ Mass erase completed, chip unlocked
### Cargo subcommands
Install version v0.8.0 of the `cargo-flash` and `cargo-embed` subcommands, as well as the `cargo-binutils` subcommand, using the following commands:
Install version v0.8.0 of the `cargo-flash` and `cargo-embed` subcommands, as well as the `cargo-binutils` set of subcommands and the `cargo-bloat` subcommand using the following Cargo commands:
``` console
$ cargo install cargo-flash --version 0.8.0 -f
@ -305,6 +305,10 @@ Installed package `cargo-embed v0.8.0` (..)
$ cargo install cargo-binutils
(..)
Installed package `cargo-binutils v0.3.0` (..)
$ cargo install cargo-bloat
(..)
Installed package `cargo-bloat v0.9.3` (..)
```
## License

View file

@ -1,49 +1,33 @@
# Building an Embedded Program
The following command cross compiles the program to the ARM Cortex-M4 architecture. The `--target` arguments instructs Cargo to cross compile the program.
``` console
$ cargo build --target thumbv7em-none-eabi --bin hello
```
The default in a new Cargo project is to compile for the host (native compilation). Within the `beginner/apps` folder you can however omit the `--target ` flag and Cargo will still cross compile for the ARM Cortex-M4 architecture.
The following command cross compiles the program to the ARM Cortex-M4 architecture.
``` console
$ cargo build --bin hello
```
The reason for this is that the default compilation target has been set to ARM Cortex-M4 in the Cargo configuration file (`.cargo/config`):
The default in a Cargo project is to compile for the host (native compilation) but the `beginner/apps` project has been configured for cross compilation. This configuration can be see in the Cargo configuration file (`.cargo/config`):
``` text
# .cargo/config
[build]
target = "thumbv7em-none-eabi"
target = "thumbv7em-none-eabi" # = ARM Cortex-M4
```
The output of the compilation process will be an ELF (Executable and Linkable Format) file. The file will be placed in the `beginner/apps/target` directory. To display the amount of Flash the program will occupy on the target device use the `rust-size` tool (part of the `cargo-binutils` package):
The output of the compilation process will be an ELF (Executable and Linkable Format) file. The file will be placed in the `target/thumbv7em-none-eabi` directory.
``` console
$ rust-size target/thumbv7em-none-eabi/debug/hello
text data bss dec hex filename
14564 8 2124 16696 4138 target/thumbv7em-none-eabi/debug/hello
$ file target/thumbv7em-none-eabi/debug/hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
```
`14460` bytes is the amount of Flash memory the program will occupy.
## Binary size
Alternatively, you can run the `cargo-size` subcommand, which will build the program before displaying the size of the binary.
ELF files contain metadata like debug information and their size on disk is not a good indication of the amount of Flash the program will use once it's loaded on the target device's memory.
To display the amount of Flash the program will occupy on the target device use the `cargo-size` tool (part of the `cargo-binutils` package):
``` console
$ cargo size --bin hello
text data bss dec hex filename
14564 8 2124 16696 4138 hello
```
Passing the `-A` flag to `rust-size` or `cargo-size` will give a more detailed breakdown of the static memory usage:
``` console
$ # omit the `--` flag if using `rust-size`
$ cargo size --bin hello -- -A
hello :
section size addr
@ -55,6 +39,24 @@ section size addr
.uninit 0 0x20000854
```
This gives you a breakdown of the program's static memory usage per *linker section*.
The `.vector_table` section contains the *vector table*, a data structure required by the Cortex-M ISA. The `.text` section contains the instructions the program will execute. The `.rodata` section contains constants like strings literals. These three sections are contiguously located in Flash memory -- Flash memory spans from address `0x0000_0000` to `0x0010_0000` (1 MB).
The next three sections, `.data`, `.bss` and `.uninit`, are located in RAM -- RAM memory spans the address range `0x2000_0000` - `0x2004_0000` (256 KB). These sections contain statically allocated variables (`static` variables).
Another other useful tool to analyze the binary size of a program is `cargo-bloat`:
``` console
$ cargo bloat --bin hello
File .text Size Crate Name
0.7% 13.5% 1.3KiB std <char as core::fmt::Debug>::fmt
0.5% 9.6% 928B hello hello::__cortex_m_rt_main
0.4% 8.4% 804B std core::str::slice_error_fail
0.4% 8.0% 768B std core::fmt::Formatter::pad
0.3% 6.4% 614B std core::fmt::num::<impl core::fmt::Debug for usize>::fmt
(..)
5.1% 100.0% 9.4KiB .text section size, the file size is 184.5KiB
```
This breakdowns the size of the `.text` section by function. This breakdown can be used to identify the largest functions in the program; those could then be modified to make them smaller.

View file

@ -5,4 +5,4 @@ rustflags = [
]
[build]
target = "thumbv7em-none-eabi"
target = "thumbv7em-none-eabi" # = ARM Cortex-M4