The Raspberry Pi Pico, powered by the RP2040 microcontroller, has gained significant popularity among embedded systems enthusiasts and hobbyists. While it’s often programmed in C/C++, Rust has also emerged as a compelling option for developing firmware for this chip. In this article, I’ll guide you through the process of writing and compiling Rust code for the RP2040 chip using the rp-hal
and rp-pico
crates. We’ll illustrate the process with a simple LED blink example.
Prerequisites
Before we dive into writing and compiling Rust code, make sure you have the following prerequisites in place:
- Rust Environment: You need Rust installed on your development machine. You can install Rust by following the instructions at rustup.rs.
- Cargo and Rustc: Ensure that you have Cargo (the Rust package manager) and Rustc (the Rust compiler) properly set up.
- RP2040 Toolchain: You’ll need the RP2040 toolchain. You can obtain it by running the following commands:
rustup target install thumbv6m-none-eabi <br></br>cargo install flip-link <br></br>cargo install elf2uf2-rs --locked
- Raspberry Pi Pico: Have a Raspberry Pi Pico board on hand for testing your code.
Setting Up Your Project
Let’s create a new Rust project and configure it for the RP2040 chip.
- Create a new Rust project using Cargo:bash
cargo new pico-blink --bin cd pico-blink
Edit your Cargo.toml
file to add dependencies:
toml
[dependencies] rp-hal = "0.5" rp-pico = "0.5"
Next, create a new main.rs
file in the src
directory of your project.
In main.rs
, import the necessary crates and set up the main
function:
// Import the necessary crates
use rp_hal::prelude::*;
use rp_pico::hal::pac as rp2040;
fn main() { // Your code will go here }
Writing the LED Blink Code
Now, let’s write a simple LED blink code for the RP2040 chip. We will blink the built-in LED (pin 25) on the Raspberry Pi Pico.
use rp_hal::prelude::*;
use rp_pico::hal::pac as rp2040;
fn main() {
// Initialise the RP2040 peripherals
let mut pac = rp2040::Peripherals::take().unwrap();
let mut watchdog = rp2040::WATCHDOG::take().unwrap();
// Configure GPIO pin 25 as an output
let mut gpio = rp2040::GPIO::take().unwrap();
gpio.gpio25_ctrl.write(|w| w.funcsel().bits(1)); // 1 corresponds to GPIO function
gpio.gpio25_oe.modify(|_, w| w.bits(1)); // Set pin 25 as an output
// Main loop loop
{
// Turn the LED on
gpio.gpio25_set.write(|w| w.bits(1));
// Delay for a while
for _ in 0..1_000_000 { cortex_m::asm::nop(); }
// Turn the LED off
gpio.gpio25_clr.write(|w| w.bits(1));
// Delay for a while
for _ in 0..1_000_000 { cortex_m::asm::nop(); }
}
}
This code initialises the RP2040 peripherals, configures pin 25 as an output, and enters a loop to toggle the LED state, creating a blinking effect.
Compiling and Flashing
To compile your Rust code and flash it onto the Raspberry Pi Pico, follow these steps:
- Build the code:bash
cargo build --release
Convert the resulting binary into a UF2 format file compatible with the Pico:
bash
cargo objcopy --release -- -O binary target/thumbv6m-none-eabi/release/pico-blink.bin
- Flash the UF2 file onto the Raspberry Pi Pico:
- Connect your Pico to your computer via USB.
- While holding down the “BOOTSEL” button on the Pico, plug it in.
- The Pico will appear as a USB drive. Copy the
pico-blink.bin
file to this drive. - The Pico will reset, and your Rust program will start running.
Conclusion
With the rp-hal
and rp-pico
crates, writing and compiling Rust code for the RP2040 chip on the Raspberry Pi Pico becomes accessible and straightforward. You can now expand upon this example to create more complex projects and explore the capabilities of Rust in embedded systems development with the RP2040 microcontroller.