Rust programming for rp2040¶
Widely inspired from https://tutoduino.fr/en/tutorials/programing-in-rust-the-xiao-rp2040-board/ (with some modification about install and build)
Install¶
Rust¶
- install Rust :
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh
- add to PATH :
source $HOME/.cargo/env
- check it works :
rustc --version
- Hello world :
rustc hw.rs; ./hw
Rust for embedded Rust¶
- install
build-essential
andlibudev-dev
(if not already) :sudo apt update && sudo apt upgrade; sudo apt install build-essential libudev-dev;
- Prepare your Rust environment setup :
rustup target add thumbv6m-none-eabi
cargo install cargo-binutils
rustup component add llvm-tools-preview
- install elf to UF2 converter :
cargo install elf2uf2-rs
Hello World!¶
git clone https://github.com/rp-rs/rp-hal
cd rp-hal
cargo build --features="critical-section-impl" --example blinky
- Put your RP2040 in boot mode (keep boot button pressed while pushing and releasing reset button)
- Once mounted, run :
cargo run --features="critical-section-impl" --example blinky
Write your own code examples¶
Blink¶
cargo new 01-blink
- Edit Cargo.toml :
[package] name = "xiao_rp2040_rs" version = "0.1.0" edition = "2021" description = "XIAO RP2040 RGB LED Blinking" authors = [ "Stephane POTIER <tutoduino@gmx.fr>", "Thomas POTIER <d34db4b3@protonmail.com>", ] homepage = "https://tutoduino.fr/en/tutorials/programing-in-rust-the-xiao-rp2040-board/" license = "MIT OR Apache-2.0" repository = "https://github.com/rp-rs/rp-hal.git" [dependencies] cortex-m = "0.7.6" seeeduino-xiao-rp2040 = "0.2.0" panic-halt = "0.2.0" embedded-hal = "0.2.7" cortex-m-rt = "0.7" rp2040-boot2 = "0.2.0" ws2812-pio = "0.4.0" smart-leds = "0.3.0"
- create
memory.x
in same folder :MEMORY { BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 RAM : ORIGIN = 0x20000000, LENGTH = 256K } EXTERN(BOOT2_FIRMWARE) SECTIONS { /* ### Boot loader */ .boot2 ORIGIN(BOOT2) : { KEEP(*(.boot2)); } > BOOT2 } INSERT BEFORE .text;
- Create new directory
.cargo
with newconfig.toml
in it :# set default build target for rp2040 [build] target = "thumbv6m-none-eabi" # upload binary to rp2040 instead of running on host [target.thumbv6m-none-eabi] runner = "elf2uf2-rs -d" # use appropriate memory layout rustflags = ["-C", "link-arg=-Tlink.x"]
- in main directory, create your main file
main.rs
://! XIAO RP2040 Blinking LED Example //! //! https://tutoduino.fr/ //! //! Blinks the LED on a Seeed Studio XIAO RP2040 board. //! #![no_std] #![no_main] use embedded_hal::digital::v2::OutputPin; use panic_halt as _; use seeeduino_xiao_rp2040::entry; use seeeduino_xiao_rp2040::hal; use seeeduino_xiao_rp2040::hal::pac; use seeeduino_xiao_rp2040::hal::prelude::*; /// Entry point to our bare-metal application. /// /// The `#[entry]` macro ensures the Cortex-M start-up code calls this function /// as soon as all global variables are initialised. /// /// The function configures the RP2040 peripherals, then blinks the LED in an /// infinite loop. #[entry] fn main() -> ! { // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); let core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); // Configure the clocks // // The default is to generate a 125 MHz system clock let clocks = hal::clocks::init_clocks_and_plls( seeeduino_xiao_rp2040::XOSC_CRYSTAL_FREQ, pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut watchdog, ) .ok() .unwrap(); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); // Set the pins up according to their function on this particular board let pins = seeeduino_xiao_rp2040::Pins::new( pac.IO_BANK0, pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS, ); // The delay object lets us wait for specified amounts of time (in // milliseconds) let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); // Configure the pins to operate as a push-pull output let mut led_blue_pin = pins.led_blue.into_push_pull_output(); let mut led_green_pin = pins.led_green.into_push_pull_output(); let mut led_red_pin = pins.led_red.into_push_pull_output(); // Set green and red led OFF led_green_pin.set_high().unwrap(); led_red_pin.set_high().unwrap(); loop { // Turn on blue LED for 1s led_blue_pin.set_low().unwrap(); delay.delay_ms(1000); // Turn off blue LED for 500ms led_blue_pin.set_high().unwrap(); delay.delay_ms(500); } }
- Set your board in boot mode and launch
cargo run --release
- The blue LED of the XIAO should now blink
Neopixel blink¶
- see https://github.com/tutoduino/xiao_rp2040_rs/tree/main