From ae3fb7a288d0dc8ad1aa9eb123c2054cc22b915d Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 10 Jul 2020 18:34:55 +0200 Subject: [PATCH] beginner: less tooling invocations; add cargo-bloat --- README.md | 6 ++- beginner-workshop/src/building-program.md | 54 ++++++++++++----------- beginner/apps/.cargo/config | 2 +- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index a27a16d..bdb384a 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/beginner-workshop/src/building-program.md b/beginner-workshop/src/building-program.md index d12be9a..d3ab443 100644 --- a/beginner-workshop/src/building-program.md +++ b/beginner-workshop/src/building-program.md @@ -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 ::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::::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. diff --git a/beginner/apps/.cargo/config b/beginner/apps/.cargo/config index 5859d1d..4e40aab 100644 --- a/beginner/apps/.cargo/config +++ b/beginner/apps/.cargo/config @@ -5,4 +5,4 @@ rustflags = [ ] [build] -target = "thumbv7em-none-eabi" \ No newline at end of file +target = "thumbv7em-none-eabi" # = ARM Cortex-M4 \ No newline at end of file