Install Rust-embedded on Micro:bit, run on Linux Mint 21.1.

Install Rust-embedded on Micro:bit, run on Linux Mint 21.1 (over Windows 11/VirtualBox).

This post shows how I start in rust-embedded on my micro:bit.

Basically, this post follow the on-line book Discovery (micro:bit version) to introduce you to micro:bit and Rust-embedded.

Setting up a development environment:-

Install rustc & Cargo:
Install rustup by following the instructions at https://rustup.rs
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Install cargo-binutils:
$ rustup component add llvm-tools-preview
$ cargo install cargo-binutils --vers 0.3.3
$ cargo size --version

Install prerequisites for cargo-embed:
$ sudo apt install -y pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev

Install cargo-embed:
$ cargo install cargo-embed --vers 0.11.0

but fail:
failed to select a version for requirement 'cargo_toml = "^0.9.0"'...


Then I install the latest 0.18.0 instead of 0.11.0. The error fixed.
$ cargo install cargo-embed --vers 0.18.0

Download the repository rust-embedded/discovery, it's the examples in Discovery.
https://github.com/rust-embedded/discovery/

Install gdb-multiarch and minicom:
$ sudo apt-get install gdb-multiarch minicom

Add udev rules for micro:bit:-

Create file /etc/udev/rules.d/99-microbit.rules, with content:
# CMSIS-DAP for microbit
SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", ATTR{idProduct}=="0204", MODE:="666"


Then reload the udev rules with:
$ sudo udevadm control --reload-rules

Verify cargo-embed with 03-setup example in downloaded repository rust-embedded/discovery:

Edit Embed.toml in the src/03-setup, uncomment the line:
chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2

Open Terminal in src/03-setup folder, enter:
$ rustup target add thumbv7em-none-eabihf
$ cargo embed --target thumbv7em-none-eabihf

If everything works correctly cargo-embed should first compile the small example program in this directory, then flash it and finally open a nice text based user interface that prints Hello World.


Setup debugging


Continue LED roulette.

Switch to src/05-led-roulette directory in the downloaded repository. Edit Embed.toml to uncomment the line for micro:bit V2:
chip = "nrf52833_xxAA" /# uncomment this line for micro:bit V2

Download pre-compiled standard library for your micro:bit V2 (You only need to do this step once):
$ rustup target add thumbv7em-none-eabihf

Cross compile the program:
$ cargo build --features v2 --target thumbv7em-none-eabihf

Verify that the produced executable is actually an ARM binary:
$ cargo readobj --features v2 --target thumbv7em-none-eabihf --bin led-roulette -- --file-headers

Flash it:
$ cargo embed --features v2 --target thumbv7em-none-eabihf

cargo-embed blocks after flashed, and GDB stub will listen at 127.0.0.1:1337.

Open a new shell to run gdb:
$ gdb target/thumbv7em-none-eabihf/debug/led-roulette

Note: Depending on which GDB you installed  you will have to use a different command to launch it.
Actually gdb is not work for me! It will fail later.

In (gdb), connect to the GDB stub:
target remote :1337

Failed on GDB stuff!
During the execution of GDB an error was encountered:
failed to fill whole buffer

Flash again to run GDB stub again:
$ cargo embed --features v2 --target thumbv7em-none-eabihf

Launch gdb again with gdb-multiarch:
$ gdb-multiarch target/thumbv7em-none-eabihf/debug/led-roulette

Again, connect to the GDB stub in (gdb):
target remote :1337

It will connect to GDB stub.

Some useful GDB commands HERE.


Blinking LED

Follow Discovery > 5.LED roulette > 5.5. It blinks

Switch to 05-led-roulette directory.
Edit Cargo.toml, uncomment the two RTT lines and comment the panic-halt one out.

#panic-halt = "0.2.0"
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] }

Copy the code of Blinking into src/main.rs.

Repeats steps above in debugging.

Build and flash:-

$ cargo build --features v2 --target thumbv7em-none-eabihf
$ cargo embed --features v2 --target thumbv7em-none-eabihf

GDB stub listening at 127.0.0.1:1337

launch gdb-multiarch:
gdb-multiarch target/thumbv7em-none-eabihf/debug/led-roulette

After, you can disable GDB stub, such that the program will start running after flashed.

to disable gdb:
Edit Embed.toml
[default.gdb]
enabled = false

Build and flash again:
$ cargo build --features v2 --target thumbv7em-none-eabihf
$ cargo embed --features v2 --target thumbv7em-none-eabihf




Walking LED

Visit https://docs.rust-embedded.org/discovery/microbit/05-led-roulette/my-solution.html, it's a solution to display walking LED on micro:bit. Listed here:
#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use rtt_target::rtt_init_print;
use panic_rtt_target as _;
use microbit::{
    board::Board,
    display::blocking::Display,
    hal::Timer,
};

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);
    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;
        }
    }
}
Compiled in "release" mode:

cargo embed --features v2 --target thumbv7em-none-eabihf --release




Related:
~ Install Embedded Rust for ESP32 on Linux Mint 21.3 over VirtualBox/Windows 11 (tested with ESP32-C3-DevKitM-1)


Comments

Popular posts from this blog

MicroPython/ESP32-C3 + 1.8" 128x160 TFT ST7735 SPI, using boochow/MicroPython-ST7735 library.

CameraWebServe: ESP32-S3 (arduino-esp32) + OV5640 camera module