My solution
What solution did you come up with?
Here's mine. It's probably one of the simplest (but of course not most beautiful) ways to generate the required matrix:
#![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use microbit::{board::Board, display::blocking::Display, hal::Timer}; use panic_rtt_target as _; use rtt_target::rtt_init_print; #[rustfmt::skip] const PIXELS: [(usize, usize); 16] = [ (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4), (4, 3), (4, 2), (4, 1), (4, 0), (3, 0), (2, 0), (1, 0), ]; #[entry] fn main() -> ! { rtt_init_print!(); let board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0); let mut display = Display::new(board.display_pins); #[rustfmt::skip] let mut leds = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ]; let mut last_led = (0, 0); loop { for current_led in PIXELS.iter() { leds[last_led.0][last_led.1] = 0; leds[current_led.0][current_led.1] = 1; display.show(&mut timer, leds, 30); last_led = *current_led; } } }
One more thing! Check that your solution also works when compiled in "release" mode:
$ cargo embed --release
If you want to debug your "release" mode binary you'll have to use a different GDB command:
$ gdb ../../../target/thumbv7em-none-eabihf/release/led-roulette
The Rust compiler modifies the machine instructions generated in a release build (sometimes by a lot) in order to try to make the code faster or smaller. Unfortunately, GDB has a hard time figuring out what is going on after this. As a result, debugging release builds with GDB can be difficult.
Binary size is something we should always keep an eye on! How big is your solution? You can check
that using the size
command on the release binary:
$ cargo size --release -- -A
Finished release [optimized + debuginfo] target(s) in 0.02s
led-roulette :
section size addr
.vector_table 256 0x0
.text 6332 0x100
.rodata 648 0x19bc
.data 0 0x20000000
.bss 1076 0x20000000
.uninit 0 0x20000434
.debug_loc 9036 0x0
.debug_abbrev 2754 0x0
.debug_info 96460 0x0
.debug_aranges 1120 0x0
.debug_ranges 11520 0x0
.debug_str 71325 0x0
.debug_pubnames 32316 0x0
.debug_pubtypes 29294 0x0
.ARM.attributes 58 0x0
.debug_frame 2108 0x0
.debug_line 19303 0x0
.comment 109 0x0
Total 283715
Your numbers may differ somewhat depending on how your code is built: this is OK.
Know how to read this output? The text
section contains the program instructions. The rodata
section contains read-only data stored with the program instructions. The data
and bss
sections
contain variables statically allocated in RAM (static
variables). If you remember the
specification of the microcontroller on your micro:bit, you should notice that its flash memory is
less than double the size of this extremely simple binary: can this be right? As we can see from
the size statistics most of the binary is actually made up of debugging related sections. However,
those are not flashed to the microcontroller at any time — after all they aren't relevant for the
execution.