From 10dd7977cb36c78dc4d2d07568984e21b12425d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Schulz-Andres?= Date: Tue, 9 Sep 2025 21:27:52 +0200 Subject: [PATCH 1/2] Add first chapter --- src/SUMMARY.md | 25 ++++---- src/chapter_1.md | 1 - src/exercise1.md | 1 - src/exercise2.md | 1 - ...hing_rust_is_easier_than_brewing_coffee.md | 3 + src/flashing/install_tools_for_flashing.md | 32 ++++++++++ src/flashing/rp2350_mcu_flashing_methods.md | 60 +++++++++++++++++++ ...setting-up-your-rust-embedded-toolchain.md | 19 ++++++ ...ng_a_new_project_blinky_rp2350_template.md | 3 + src/index.md | 2 + src/introduction.md | 1 - src/introduction/how_to_use_this_guide.md | 9 +++ src/introduction/introduction.md | 7 +++ src/introduction/setup.md | 1 - .../what_youll_need_prerequisites.md | 5 ++ src/introduction/who_should_use_this_guide.md | 7 +++ src/setup.md | 1 - src/wrapup.md | 1 - 18 files changed, 157 insertions(+), 22 deletions(-) delete mode 100644 src/chapter_1.md delete mode 100644 src/exercise1.md delete mode 100644 src/exercise2.md create mode 100644 src/flashing/flashing_rust_is_easier_than_brewing_coffee.md create mode 100644 src/flashing/install_tools_for_flashing.md create mode 100644 src/flashing/rp2350_mcu_flashing_methods.md create mode 100644 src/flashing/setting-up-your-rust-embedded-toolchain.md create mode 100644 src/flashing/starting_a_new_project_blinky_rp2350_template.md delete mode 100644 src/introduction.md create mode 100644 src/introduction/how_to_use_this_guide.md create mode 100644 src/introduction/introduction.md delete mode 100644 src/introduction/setup.md create mode 100644 src/introduction/what_youll_need_prerequisites.md create mode 100644 src/introduction/who_should_use_this_guide.md delete mode 100644 src/setup.md delete mode 100644 src/wrapup.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9911c64..1b6a1fe 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -1,19 +1,14 @@ # Summary -- [Getting Started With Embedded Rust 📟🦀](./index.md) -- [Introduction](./introduction.md) - - [Setup](./setup.md) - +[Getting Started With Embedded Rust 🦀](./index.md) +- [Introduction](./introduction/introduction.md) + - [Who should use this Guide?](./introduction/who_should_use_this_guide.md) + - [What you'll need (Prerequisites)](./introduction/what_youll_need_prerequisites.md) + - [How to Use This Guide](./introduction/how_to_use_this_guide.md) +- [Flashing Rust is Easier Than Brewing Coffee. ☕](./flashing/flashing_rust_is_easier_than_brewing_coffee.md) + - [Setting Up Your Rust Embedded Toolchain](./flashing/setting-up-your-rust-embedded-toolchain.md) + - [RP2350 MCU Flashing Methods](./flashing/rp2350_mcu_flashing_methods.md) + - [Install tools for flashing](./flashing/install_tools_for_flashing.md) + - [Starting a New Project – Blinky (RP2350 Template)](./flashing/starting_a_new_project_blinky_rp2350_template.md) --- -# Exercises - -- [First Exercise](./exercise1.md) -- [Second Exercise](./exercise2.md) - ---- - -# Final Words - -- [Wrap-up](./wrapup.md) - diff --git a/src/chapter_1.md b/src/chapter_1.md deleted file mode 100644 index b743fda..0000000 --- a/src/chapter_1.md +++ /dev/null @@ -1 +0,0 @@ -# Chapter 1 diff --git a/src/exercise1.md b/src/exercise1.md deleted file mode 100644 index ed1372c..0000000 --- a/src/exercise1.md +++ /dev/null @@ -1 +0,0 @@ -# First Exercise diff --git a/src/exercise2.md b/src/exercise2.md deleted file mode 100644 index 9d7cf69..0000000 --- a/src/exercise2.md +++ /dev/null @@ -1 +0,0 @@ -# Second Exercise diff --git a/src/flashing/flashing_rust_is_easier_than_brewing_coffee.md b/src/flashing/flashing_rust_is_easier_than_brewing_coffee.md new file mode 100644 index 0000000..a7a205e --- /dev/null +++ b/src/flashing/flashing_rust_is_easier_than_brewing_coffee.md @@ -0,0 +1,3 @@ +# Flashing Rust is Easier Than Brewing Coffee. ☕ + +Our first goal is to show that getting Rust code running on a real microcontroller is **surprisingly simple** – often just a few commands. We’ll set up the toolchain for the RP2350, compile a “blinky” program, and flash it to the board. By the end of this chapter, you’ll have an LED blinking on actual hardware, and you’ll see that putting Rust on a microchip is _literally easier than making a cup of coffee._ \ No newline at end of file diff --git a/src/flashing/install_tools_for_flashing.md b/src/flashing/install_tools_for_flashing.md new file mode 100644 index 0000000..bd3490d --- /dev/null +++ b/src/flashing/install_tools_for_flashing.md @@ -0,0 +1,32 @@ +# Install tools for flashing + +## Method 1: RP2350-built-in bootloader via drag & drop + +As described in the previous chapter, you don't need to install any tools to flash the RP2350 using the RP2350-built-in bootloader if you use our online conversion method at [elf2uf2.yrust.de](https://elf2uf2.yrust.de/). If you prefer to convert it locally though, you will need to install `picotool`, as described in the next paragraph. + +## Method 2: RP2350-built-in bootloader with picotool + +The RP2040 and RP2350 have a built-in bootloader that presents the device as a USB drive when you plug it in with the BOOTSEL button pressed. You can copy a `.uf2` file to that drive to flash new firmware . For this, it’s helpful to install [picotool](https://github.com/raspberrypi/picotool/), a utility from Raspberry Pi that can convert binaries to UF2 and upload them. You can download a pre-built picotool binary from the [releases page](https://github.com/raspberrypi/picotool/releases) for your OS or build it from source. +Their docs state that _You cannot just copy the binary into your PATH, else the Pico SDK will not be able to locate it._, however, if you only want to use the RP2350 with Rust code and don't plan on using the SDK, you absolutely can just copy the picotool binary to your PATH. + +With picotool installed, you can now flash the RP2350 (given that the bootsel button is pressed when plugging it in) using: +```bash +picotool load -u -v -x -t elf your_file.elf +``` +you can also convert `.elf` files to `.uf2` files using: +```bash +picotool uf2 convert your_file.elf your_file.uf2 +``` + +## Method 3: Probe-based flashing (SWD) +Using an external debug probe or a second Pico as a probe, you can flash and debug the chip directly via the SWD interface. For this, we use **probe-rs**, a Rust project that replaces OpenOCD/GDB. We recommend installing using the [recommended install scripts](https://probe.rs/docs/getting-started/installation/), which provides the probe-rs CLI and associated tools: +```bash +curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.sh | sh +``` +This gives you commands like probe-rs flash and also includes probe-run (for running programs with semi-hosted debugging). _(If you’re curious: probe-rs is a pure-Rust implementation of the ARM debugging protocol and works with CMSIS-DAP, J-Link, etc. It makes flashing and even debuggingfirmware straightforward.)_ + +## (optional) Install cargo-generate +We will use cargo-generate to quickly bootstrap projects from templates. Install it with: +```bash +cargo install cargo-generate +``` \ No newline at end of file diff --git a/src/flashing/rp2350_mcu_flashing_methods.md b/src/flashing/rp2350_mcu_flashing_methods.md new file mode 100644 index 0000000..75ea2a4 --- /dev/null +++ b/src/flashing/rp2350_mcu_flashing_methods.md @@ -0,0 +1,60 @@ +# RP2350 MCU Flashing Methods + +There are three main ways to flash firmware onto an RP2350 microcontroller, each with different prerequisites and use cases. +You can either flash it using the RP2350-built-in bootloader by dragging & dropping the `.uf2` file to the mounted drive, by using the [picotool](https://github.com/raspberrypi/picotool/) tool to talk to the bootloader directly, or by using a hardware debugger or second Pico for programming and debugging over an Serial-Wire-Debug (SWD) connection. The methods are detailed below. + +Depending on your preference, you will then learn how to install the tools for these methods in the next chapter. We recommend trying Method 1 first, as it is the easiest to use and doesn't require any installation and setup the other methods later if you need to. + +## Method 1: Online Conversion + +This method requires no software installation and works entirely through a web browser and your system's file manager. + +**Prerequisites:** None + +**Steps:** +1. Take your `.elf` file +2. Go to [elf2uf2.yrust.de](https://elf2uf2.yrust.de/)[^1] +3. Upload and convert to `.uf2` +4. Put RP2350 into boot mode: + - Hold **BOOTSEL** button + - Power on + - Release **BOOTSEL** +5. Drag & drop the `.uf2` file to the mounted drive +6. Device will automatically reset and run + +## Method 2: Bootloader and picotool + +This method uses the official Raspberry Pi tool for direct flashing. + +**Prerequisites:** [picotool](https://github.com/raspberrypi/picotool/) installed + +**Steps:** +1. Put RP2350 into boot mode: + - Hold **BOOTSEL** button + - Power on + - Release **BOOTSEL** +2. Flash directly with picotool: + ```bash + picotool load -u -v -x -t elf your_file.elf + ``` +3. Device will automatically reset and run + +## Method 3: Debug Probe + +This method uses a hardware debugger or second Pico for programming and debugging. + +**Prerequisites:** Debugger or second Pico + [probe-rs](https://probe.rs/) installed + +**Steps:** +1. Connect debugger or second Pico to target RP2350 +2. Flash and run with probe-rs: + ```bash + probe-rs run --chip RP235x --protocol swd your_file.elf + ``` +3. Device will be programmed and start running automatically + +## Additional Notes + +To erase the flash, you can use `picotool erase` or drag & drop the flash nuke utility: [flash_nuke.uf2](https://datasheets.raspberrypi.com/soft/flash_nuke.uf2) (direct download, 96 kB) + +[^1]: Our online tool [elf2uf2.yrust.de](https://elf2uf2.yrust.de/) simply executes `picotool uf2 convert your_file.elf your_file.uf2` - it's equivalent to having picotool installed locally but runs in the browser. \ No newline at end of file diff --git a/src/flashing/setting-up-your-rust-embedded-toolchain.md b/src/flashing/setting-up-your-rust-embedded-toolchain.md new file mode 100644 index 0000000..ce62272 --- /dev/null +++ b/src/flashing/setting-up-your-rust-embedded-toolchain.md @@ -0,0 +1,19 @@ +# Setting Up Your Rust Embedded Toolchain + +Before writing any code, we need to configure our development environment for cross-compiling to the RP2350 microcontroller. The RP2350 is a **dual-core ARM Cortex-M33** microcontroller (with some special features we’ll discuss later). Rust, via `rustup`, can target this architecture easily. + +1. **Install Rust (stable)** if you haven’t already, via [rustup](https://rustup.rs/). Ensure you also have Cargo, which comes with Rust. +2. **Update Rust** to the latest stable version and self-update rustup (to avoid any surprises): + ```bash + rustup self update + rustup update stable + ``` +3. **Add the target for RP2350:** The Cortex-M33 core uses the ARMv8-M architecture with hardware floating-point. The correct Rust target triple is `thumbv8m.main-none-eabihf`. We’ll add that, and for completeness also add the ARMv6-M target used by older Pico (RP2040) and the RISC-V target (the RP2350 has a RISC-V mode, as we’ll mention). Run: + ```bash + rustup target add thumbv6m-none-eabi # (for RP2040, if needed) + rustup target add thumbv8m.main-none-eabihf # RP2350 Arm Cortex-M33 + rustup target add riscv32imac-unknown-none-elf # (RP2350 RISC-V mode) + ``` + > **Note:** The RP2350 is unique in that each core can actually run as either an ARM Cortex-M33 or a RISC-V core (Hazard3) – a novel feature where the core type can be swapped at runtime . In this guide we’ll focus on the standard Cortex-M (ARM) mode. The RISC-V target is added just in case and for future exploration. + +With these tools you will already be able to turn valid Rust code into a `.elf` file, which you can then flash onto the RP2350 using the methods described in the next chapter. \ No newline at end of file diff --git a/src/flashing/starting_a_new_project_blinky_rp2350_template.md b/src/flashing/starting_a_new_project_blinky_rp2350_template.md new file mode 100644 index 0000000..d4ee619 --- /dev/null +++ b/src/flashing/starting_a_new_project_blinky_rp2350_template.md @@ -0,0 +1,3 @@ +# Starting a New Project – Blinky (RP2350 Template) + +Next, we’ll start a new Rust project for the Raspberry Pi Pico 2 board. The community provides ready-to-go templates for Rust on these boards, which set up all the necessary bits (memory layout, linker script, HAL dependencies, and so on). We will use the official **rp-rs project template** for RP2350. \ No newline at end of file diff --git a/src/index.md b/src/index.md index 9aeb5a6..afe897d 100644 --- a/src/index.md +++ b/src/index.md @@ -1 +1,3 @@ # Getting Started With Embedded Rust 📟🦀 + +This is a free book about Embedded Rust on the Raspberry Pi Pico 2 (with the RP2350 microcontroller). We primarily use this internally at Systemscape, but we hope it can be useful to others as well and invite you to use it as well and contribute to it. \ No newline at end of file diff --git a/src/introduction.md b/src/introduction.md deleted file mode 100644 index e10b99d..0000000 --- a/src/introduction.md +++ /dev/null @@ -1 +0,0 @@ -# Introduction diff --git a/src/introduction/how_to_use_this_guide.md b/src/introduction/how_to_use_this_guide.md new file mode 100644 index 0000000..54351f3 --- /dev/null +++ b/src/introduction/how_to_use_this_guide.md @@ -0,0 +1,9 @@ +# How to Use This Guide + +This guide is organized as a progression of chapters that build on each other. It is recommended to go in order, since later chapters assume knowledge and setup from earlier ones. Each chapter includes explanations, code examples, and often an **exercise** or challenge for you to try. These exercises are typically short (a few minutes each) and give you hands-on practice – **don’t skip them!** You’ll learn more by doing. By the end of the guide, you’ll have two versions of a small project (one using a traditional HAL, one using async Embassy) that blink an LED and communicate over serial, plus familiarity with how to extend these to real-world tasks (like reading sensors or handling multiple tasks concurrently). + +Throughout the text, we include citations to external sources and documentation for deeper reference.[^mdBook] If you’re reading this in a medium that supports it, you can click those to see the source. We also include occasional images or diagrams to illustrate points (with captions and attribution). + +Alright, let’s dive in! + +[^mdBook]: https://rust-lang.github.io/mdBook/format/markdown.html \ No newline at end of file diff --git a/src/introduction/introduction.md b/src/introduction/introduction.md new file mode 100644 index 0000000..e7c472a --- /dev/null +++ b/src/introduction/introduction.md @@ -0,0 +1,7 @@ +# Introduction +## Embedded Rust on the Raspberry Pi Pico 2 (RP2350) – Workshop Guide +Welcome to this workshop guide on Embedded Rust using the Raspberry Pi Pico 2 (with the RP2350 microcontroller). This guide is structured as an mdBook (a collection of chapters), meant to provide a comprehensive, hands-on learning experience. We will start from the basics – getting Rust set up and blinking an LED – and work up to more advanced topics like using hardware abstraction layers (HALs), interacting with sensors, and even writing asynchronous embedded code with the Embassy framework. +Along the way, we’ll emphasize three key messages (our learning outcomes): +- “Flashing Rust is easier than brewing coffee. ☕” – _Getting Rust onto a chip is dead simple._ +- “Embedded Rust feels like Rust — not like C. 🤮” – _Embedded Rust lets you use familiar Rust concepts and patterns._ +- “Scale without pain: async & tooling to keep you sane. 📈” – _Modern Rust tooling (async runtimes, debuggers, CI) helps your projects grow without becoming a nightmare._ \ No newline at end of file diff --git a/src/introduction/setup.md b/src/introduction/setup.md deleted file mode 100644 index feae8cb..0000000 --- a/src/introduction/setup.md +++ /dev/null @@ -1 +0,0 @@ -# Setup diff --git a/src/introduction/what_youll_need_prerequisites.md b/src/introduction/what_youll_need_prerequisites.md new file mode 100644 index 0000000..efe8612 --- /dev/null +++ b/src/introduction/what_youll_need_prerequisites.md @@ -0,0 +1,5 @@ +# What you'll need (Prerequisites) + +- **Hardware:** For hands-on exercises, you will need a Raspberry Pi **Pico 2** board (featuring the RP2350 microcontroller). This board was chosen for its modern capabilities and ease of use. You’ll also need some basic accessories: a USB cable to connect the Pico to your computer, and optionally a **sensor or display module** for later chapters (more on this below). A suggested sensor is the **MCP9808** I²C temperature sensor (a cheap, widely available sensor) or a small I²C OLED display like the **SSD1306** – we’ll use these to demonstrate hardware interactions. If you have a different I²C sensor or display, that’s fine too – the concepts will generalize. +- **Software:** You should have a recent stable version of Rust installed (with **rustup**). We will install a few additional Rust targets and tools for cross-compiling to the ARM Cortex-M33 processor in the RP2350 and for flashing the device. All needed software is free and open-source. +- **Time & Effort:** Working through the **entire** guide (including examples and exercises) will take around **3-4 hours**. The guide is designed so you can follow at your own pace, and you can break it into multiple sessions. The first section (up to getting an LED blinking) can be done in about **30 minutes** (this mimics the short in-person workshop version). Subsequent sections diving into HAL usage, sensors, and async will add a few more hours of exploration. \ No newline at end of file diff --git a/src/introduction/who_should_use_this_guide.md b/src/introduction/who_should_use_this_guide.md new file mode 100644 index 0000000..7e9d595 --- /dev/null +++ b/src/introduction/who_should_use_this_guide.md @@ -0,0 +1,7 @@ +# Who should use this guide? + +This book is for anyone interested in embedded programming with Rust, from Rust developers who have never touched a microcontroller to embedded veterans curious about Rust. In particular, it’s written with two audiences in mind: +- **Experienced Rust developers (e.g. web/backend developers)** who have little or no embedded systems experience. If you know Rust’s basics and have written and debugged Rust code on desktop, this guide will show you that you can quickly apply Rust to microcontrollers without “unlearning” anything. +- **Embedded systems developers who may be new to Rust.** If you have familiarity with concepts like cross-compilation, microcontroller peripherals (GPIO, I2C, etc.), and tools like debuggers, this guide will demonstrate how Rust’s abstractions and tooling can make embedded development more robust and productive. + +No prior embedded knowledge is strictly required – we will introduce concepts as needed – but basic Rust language knowledge (ownership, traits, async, etc.) will help you get the most out of it. \ No newline at end of file diff --git a/src/setup.md b/src/setup.md deleted file mode 100644 index feae8cb..0000000 --- a/src/setup.md +++ /dev/null @@ -1 +0,0 @@ -# Setup diff --git a/src/wrapup.md b/src/wrapup.md deleted file mode 100644 index b0c0e12..0000000 --- a/src/wrapup.md +++ /dev/null @@ -1 +0,0 @@ -# Wrap-up From cdd3511e553b039cc968dfd27912d1177220be83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Schulz-Andres?= Date: Wed, 24 Sep 2025 16:50:38 +0200 Subject: [PATCH 2/2] Update src/flashing/install_tools_for_flashing.md Co-authored-by: Julian <20155974+JuliDi@users.noreply.github.com> --- src/flashing/install_tools_for_flashing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flashing/install_tools_for_flashing.md b/src/flashing/install_tools_for_flashing.md index bd3490d..1e4bd89 100644 --- a/src/flashing/install_tools_for_flashing.md +++ b/src/flashing/install_tools_for_flashing.md @@ -2,7 +2,7 @@ ## Method 1: RP2350-built-in bootloader via drag & drop -As described in the previous chapter, you don't need to install any tools to flash the RP2350 using the RP2350-built-in bootloader if you use our online conversion method at [elf2uf2.yrust.de](https://elf2uf2.yrust.de/). If you prefer to convert it locally though, you will need to install `picotool`, as described in the next paragraph. +As described in the previous chapter, you don't need to install any tools to flash the RP2350 using the RP2350-built-in bootloader if you use our online conversion method at elf2uf2.yrust.de. If you prefer to convert it locally though, you will need to install `picotool`, as described in the next paragraph. ## Method 2: RP2350-built-in bootloader with picotool