<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Cyril Marpaud</title>
    <description>The latest articles on Forem by Cyril Marpaud (@cyrilmarpaud).</description>
    <link>https://forem.com/cyrilmarpaud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1028836%2F84d1bba8-00f8-457c-942b-360fa3b8c05b.jpeg</url>
      <title>Forem: Cyril Marpaud</title>
      <link>https://forem.com/cyrilmarpaud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/cyrilmarpaud"/>
    <language>en</language>
    <item>
      <title>Impl Snake For Micro:bit - Embedded async Rust on BBC Micro:bit with Embassy</title>
      <dc:creator>Cyril Marpaud</dc:creator>
      <pubDate>Mon, 28 Oct 2024 13:00:00 +0000</pubDate>
      <link>https://forem.com/cyrilmarpaud/impl-snake-for-microbit-embedded-async-rust-on-bbc-microbit-with-embassy-ohn</link>
      <guid>https://forem.com/cyrilmarpaud/impl-snake-for-microbit-embedded-async-rust-on-bbc-microbit-with-embassy-ohn</guid>
      <description>&lt;p&gt;In this article, I will guide you through creating a &lt;a href="https://en.wikipedia.org/wiki/Snake_(video_game_genre)" rel="noopener noreferrer"&gt;Snake&lt;/a&gt; game in embedded Rust on the &lt;a href="https://microbit.org/" rel="noopener noreferrer"&gt;BBC Micro:bit&lt;/a&gt; using the asynchronous framework &lt;a href="https://embassy.dev" rel="noopener noreferrer"&gt;Embassy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://microbit.org/" rel="noopener noreferrer"&gt;BBC Micro:bit&lt;/a&gt; is a small educational board. It is equipped with an ARM Cortex-M4F nRF52833 microcontroller, a 5⨉5 LED matrix, 3 buttons (one of which is touch-sensitive), a microphone, a speaker, Bluetooth capabilities, and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/cyril-marpaud/impl_snake_for_microbit" rel="noopener noreferrer"&gt;The complete source code of the project&lt;/a&gt; is available on GitLab.&lt;/p&gt;

&lt;p&gt;Although I tried to make this article accessible to as many people as possible, some prior knowledge of Rust is recommended to understand the technical details.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;Here’s an overview of the software stack we will be using:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvrlz19hlhi7k496w0f0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvrlz19hlhi7k496w0f0.png" alt="stack diagram" width="378" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will briefly explain the function of each layer in the sections below. Note that for our implementation, we only need to focus on the application layer, as the others are provided by the Rust ecosystem thanks to the incredible efforts of the community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Support
&lt;/h3&gt;

&lt;p&gt;The lowest layer (i.e., the closest to the hardware) concerns architecture support. Our microcontroller is an ARM Cortex-M4F, so we will use the &lt;a href="https://crates.io/crates/cortex-m" rel="noopener noreferrer"&gt;&lt;code&gt;cortex-m&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://crates.io/crates/cortex-m-rt" rel="noopener noreferrer"&gt;&lt;code&gt;cortex-m-rt&lt;/code&gt;&lt;/a&gt; crates, but there are others, such as &lt;a href="https://crates.io/crates/riscv" rel="noopener noreferrer"&gt;&lt;code&gt;riscv&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://crates.io/crates/x86_64" rel="noopener noreferrer"&gt;&lt;code&gt;x86_64&lt;/code&gt;&lt;/a&gt;. In general, these crates provide the code necessary to boot a microcontroller and interact with it (interrupts, specific instructions, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  Peripheral Access Crate
&lt;/h3&gt;

&lt;p&gt;The next layer is called the PAC. These are crates that provide structures and functions for reading/writing to the registers of a microcontroller in a standardized way, enabling the configuration and access to all peripherals (GPIO, SPI, I²C, etc.) without risking memory corruption or hardware errors.&lt;/p&gt;

&lt;p&gt;PACs are generated using the &lt;a href="https://crates.io/crates/svd2rust" rel="noopener noreferrer"&gt;&lt;code&gt;svd2rust&lt;/code&gt;&lt;/a&gt; tool, which converts an &lt;a href="https://arm-software.github.io/CMSIS_5/SVD/html/index.html" rel="noopener noreferrer"&gt;SVD file&lt;/a&gt; describing a microcontroller's hardware into a comprehensive API.&lt;/p&gt;

&lt;p&gt;This layer is inherently unsafe (as it reads/writes values to arbitrary addresses), but it serves the purpose of providing a safe API for embedded developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware Abstraction Layer
&lt;/h3&gt;

&lt;p&gt;In the embedded ecosystem, the &lt;a href="https://crates.io/crates/embedded-hal" rel="noopener noreferrer"&gt;&lt;code&gt;embedded-hal&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://crates.io/crates/embedded-hal-async" rel="noopener noreferrer"&gt;&lt;code&gt;embedded-hal-async&lt;/code&gt;&lt;/a&gt; crates play a central role. They define traits that allow for interacting with peripherals in a generic way, which facilitates code reuse and portability across different targets.&lt;/p&gt;

&lt;p&gt;Microcontroller manufacturers often provide specific HALs, but these are typically tailored to individual hardware and lack cross-platform compatibility. The &lt;code&gt;embedded-hal&lt;/code&gt; and &lt;code&gt;embedded-hal-async&lt;/code&gt; crates address this issue by offering a common high-level interface, allowing for the development of reusable, generic drivers across multiple targets.&lt;/p&gt;

&lt;p&gt;The HAL we will use is an implementation of those traits called &lt;a href="https://crates.io/crates/embassy-nrf" rel="noopener noreferrer"&gt;&lt;code&gt;embassy-nrf&lt;/code&gt;&lt;/a&gt;, which provides drivers for the peripherals of the nRF52833 microcontroller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operating System: Embassy
&lt;/h3&gt;

&lt;p&gt;Although an operating system is not strictly necessary, it is often much more convenient to delegate task and interrupt management to a third-party library. This is the role of &lt;a href="https://github.com/embassy-rs/embassy" rel="noopener noreferrer"&gt;Embassy&lt;/a&gt;, which provides an asynchronous runtime for microcontrollers.&lt;/p&gt;

&lt;p&gt;It allows multiple tasks to run concurrently (either in parallel or not) in a non-blocking, asynchronous manner. This enables quick responses to events while improving performance compared to a traditional preemptive kernel and keeping the code clean and organized, without the complexity of interrupt-based programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Application
&lt;/h3&gt;

&lt;p&gt;Our application sits atop all these software layers. Thanks to them, we have all the tools needed to schedule tasks and access the microcontroller’s peripherals through high-level abstractions. This allows us to focus on developing our Snake game without worrying about the technical details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flashing with &lt;a href="https://probe.rs/" rel="noopener noreferrer"&gt;Probe-rs&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;To flash our application onto the board, we will use probe-rs, a powerful and flexible open-source debugging and flashing tool for embedded systems. It allows developers to program and debug a wide variety of microcontroller targets, such as ARM Cortex-M, RISC-V, and STM32 families, among many others. Probe-rs abstracts away the intricacies of different debug probes and programming interfaces, making it easier to work with a wide range of hardware.&lt;/p&gt;

&lt;p&gt;The tool supports a &lt;a href="https://probe.rs/targets/" rel="noopener noreferrer"&gt;wide range of targets&lt;/a&gt;, including &lt;a href="https://probe.rs/targets/master/nRF52833_xxAA" rel="noopener noreferrer"&gt;our nRF52833_xxAA&lt;/a&gt;, which we'll be using for this project. Installation instructions are available on &lt;a href="https://probe.rs/docs/getting-started/installation/#using-install-scripts" rel="noopener noreferrer"&gt;the tool's documentation page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can verify the installation with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;probe-rs &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run software on a target, you can use the command &lt;code&gt;probe-rs run&lt;/code&gt;, specifying the target chip with the &lt;code&gt;--chip&lt;/code&gt; argument. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;probe-rs run &lt;span class="nt"&gt;--chip&lt;/span&gt; nRF52833_xxAA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command automatically flashes and starts the program on the specified microcontroller.&lt;/p&gt;

&lt;h1&gt;
  
  
  Software
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using cargo-embassy
&lt;/h3&gt;

&lt;p&gt;It is possible to create a project manually by following &lt;a href="https://embassy.dev/book/#_starting_a_project_from_scratch" rel="noopener noreferrer"&gt;the instructions in Embassy's documentation&lt;/a&gt;. However, it is much easier and quicker to use a template that will take care of creating all the necessary configuration for us.&lt;/p&gt;

&lt;p&gt;This is exactly what &lt;a href="https://crates.io/crates/cargo-embassy" rel="noopener noreferrer"&gt;cargo-embassy&lt;/a&gt; was created for. Let's start by installing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;cargo-embassy
cargo embassy &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's generate a preconfigured project in the &lt;code&gt;snake&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo embassy init &lt;span class="nt"&gt;--chip&lt;/span&gt; nrf52833_xxAA snake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;Here's a screenshot of the filetree structure of the project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj4uqz5iifajf4u7gzl6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj4uqz5iifajf4u7gzl6v.png" alt="filetree" width="154" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;.cargo/config.toml&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;It contains the configuration for the runner, which allows probe-rs to flash the target automatically when we use the &lt;code&gt;cargo run&lt;/code&gt; command, and the compilation target that has been set to &lt;code&gt;thumbv7em-none-eabihf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[target.thumbv7em-none-eabihf]&lt;/span&gt;
&lt;span class="py"&gt;runner&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'probe-rs run --chip nRF52833_xxAA'&lt;/span&gt;

&lt;span class="nn"&gt;[build]&lt;/span&gt;
&lt;span class="py"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"thumbv7em-none-eabihf"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;Cargo.toml&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;It declares all our project's dependencies, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cortex-m&lt;/code&gt; and &lt;code&gt;cortex-m-rt&lt;/code&gt; for supporting the microcontroller's architecture&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defmt&lt;/code&gt; and &lt;code&gt;defmt-rtt&lt;/code&gt; for execution logs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;embassy-*&lt;/code&gt; for our application's functionality&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;panic-halt&lt;/code&gt; and &lt;code&gt;panic-probe&lt;/code&gt; for panic handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The &lt;code&gt;src&lt;/code&gt; folder
&lt;/h4&gt;

&lt;p&gt;It contains both &lt;code&gt;main.rs&lt;/code&gt;, which I will describe in the next section, and &lt;code&gt;fmt.rs&lt;/code&gt;, which provides the components necessary for displaying execution or crash logs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assertions (&lt;code&gt;assert&lt;/code&gt;, &lt;code&gt;assert_eq&lt;/code&gt;, &lt;code&gt;assert_ne&lt;/code&gt;, and &lt;code&gt;debug&lt;/code&gt; versions)&lt;/li&gt;
&lt;li&gt;panic (&lt;code&gt;panic&lt;/code&gt;, &lt;code&gt;unwrap&lt;/code&gt;, &lt;code&gt;unreachable&lt;/code&gt;, &lt;code&gt;todo&lt;/code&gt;...)&lt;/li&gt;
&lt;li&gt;logs (&lt;code&gt;trace&lt;/code&gt;, &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;memory.x&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;It is &lt;a href="https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#requirements" rel="noopener noreferrer"&gt;a prerequisite for using the cortex-m-rt crate&lt;/a&gt;. It describes the memory layout of the microcontroller.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;build.rs&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;The build script is preconfigured to ensure that &lt;code&gt;memory.x&lt;/code&gt; is available in the appropriate folder during compilation. We also need two specific linker scripts: &lt;code&gt;link.x&lt;/code&gt; (provided by the &lt;a href="https://crates.io/crates/cortex-m-rt" rel="noopener noreferrer"&gt;cortex-m-rt crate&lt;/a&gt;) and &lt;a href="https://defmt.ferrous-systems.com/setup.html#linker-script" rel="noopener noreferrer"&gt;&lt;code&gt;defmt.x&lt;/code&gt;&lt;/a&gt; (for logs), which &lt;code&gt;build.rs&lt;/code&gt; also takes care of.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;Embed.toml&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;It specifies the target for the &lt;a href="https://probe.rs/docs/tools/cargo-embed/" rel="noopener noreferrer"&gt;&lt;code&gt;cargo embed&lt;/code&gt;&lt;/a&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing the Project
&lt;/h3&gt;

&lt;p&gt;Let's start with the &lt;code&gt;main.rs&lt;/code&gt; file, which for now consists of the minimal code to blink an LED.&lt;/p&gt;

&lt;p&gt;We are in &lt;code&gt;no_std&lt;/code&gt; mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main function is asynchronous, and the entry point is declared via the &lt;a href="https://docs.rs/embassy-executor/latest/embassy_executor/attr.main.html" rel="noopener noreferrer"&gt;embassy_executor::main&lt;/a&gt; macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[embassy_executor::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_spawner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Spawner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will later see how to use this &lt;a href="https://docs.rs/embassy-executor/latest/embassy_executor/struct.Spawner.html" rel="noopener noreferrer"&gt;Spawner&lt;/a&gt; to start tasks.&lt;/p&gt;

&lt;p&gt;We begin by initializing the board and retrieving the peripheral we are interested in (here, a simple output pin):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;embassy_nrf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputDrive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we loop, toggling its state on and off:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pin used by the template (&lt;code&gt;P0_13&lt;/code&gt;) does not correspond to an LED on our board. By examining &lt;a href="https://github.com/microbit-foundation/microbit-v2-hardware/blob/main/V2.21/MicroBit_V2.2.1_nRF52820%20schematic.PDF" rel="noopener noreferrer"&gt;the schematic of the board&lt;/a&gt;, we can see that each LED is at the intersection of a row and a column of the matrix. To turn one on, we need to manipulate two LEDs (&lt;code&gt;ROW1&lt;/code&gt; and &lt;code&gt;COL1&lt;/code&gt;, for example).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tech.microbit.org/hardware/schematic/#v2-pinmap" rel="noopener noreferrer"&gt;The pin mapping&lt;/a&gt; gives the correspondence between the name and number of a pin. &lt;code&gt;ROW1&lt;/code&gt; corresponds to &lt;code&gt;P0_21&lt;/code&gt;, while &lt;code&gt;P0_28&lt;/code&gt; corresponds to &lt;code&gt;COL1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;According to the schematic, for the LED to light up, its row must be high and its column must be low. We will initialize these two pins to low, then toggle one regularly to see it blink:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;row1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputDrive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;col1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputDrive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;row1&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;row1&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the LED blinks, congratulations, your project is now set up! We can move on to more advanced tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;We will create three tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first will control the display through the LED matrix rows and columns.&lt;/li&gt;
&lt;li&gt;The second will manage the controller through the button pins.&lt;/li&gt;
&lt;li&gt;The last will handle the game logic (using the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/rng/struct.Rng.html" rel="noopener noreferrer"&gt;RNG&lt;/a&gt; to generate the snake's food).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw42ia2r64go2u7d7gh4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw42ia2r64go2u7d7gh4f.png" alt="arch diagram" width="658" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A task is nothing more than a simple function that runs continuously. It can communicate with other tasks via primitives like &lt;a href="https://docs.embassy.dev/embassy-sync/git/default/channel/struct.Channel.html" rel="noopener noreferrer"&gt;Channel&lt;/a&gt; or &lt;a href="https://docs.embassy.dev/embassy-sync/git/default/signal/struct.Signal.html" rel="noopener noreferrer"&gt;Signal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We annotate the function with &lt;a href="https://docs.rs/embassy-executor/latest/embassy_executor/attr.task.html" rel="noopener noreferrer"&gt;the task macro&lt;/a&gt; and start the task with &lt;a href="https://docs.rs/embassy-executor/latest/embassy_executor/struct.Spawner.html#method.spawn" rel="noopener noreferrer"&gt;Spawner::spawn&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[embassy_executor::task]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;mytask&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;spawner&lt;/span&gt;&lt;span class="nf"&gt;.spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mytask&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This task now runs concurrently with other tasks and uses asynchronous programming to yield control whenever it encounters an &lt;a href="https://doc.rust-lang.org/std/keyword.await.html" rel="noopener noreferrer"&gt;await&lt;/a&gt; point. This is the principle of a &lt;a href="https://en.wikipedia.org/wiki/Cooperative_multitasking" rel="noopener noreferrer"&gt;&lt;strong&gt;cooperative&lt;/strong&gt;&lt;/a&gt; system, as opposed to &lt;a href="https://en.wikipedia.org/wiki/Preemption_(computing)" rel="noopener noreferrer"&gt;&lt;strong&gt;preemptive&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Screen
&lt;/h2&gt;

&lt;p&gt;Our first task involves display, so let's start by creating a structure representing the screen and a mechanism to receive the images to display:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ROWS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;COLS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;COLS&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;ROWS&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IMG_SIG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CriticalSectionRawMutex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;a href="https://docs.rs/embassy-sync/latest/embassy_sync/signal/struct.Signal.html" rel="noopener noreferrer"&gt;Signal&lt;/a&gt; is a synchronization primitive that allows tasks to send data to each other. It is declared static to be shared and is protected from concurrent access by a &lt;a href="https://docs.embassy.dev/embassy-sync/git/default/critical_section/struct.CriticalSectionRawMutex.html" rel="noopener noreferrer"&gt;CriticalSectionRawMutex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, let's pass the pins corresponding to the LED matrix rows and columns to our task via two arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;embassy_nrf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_21&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_22&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_15&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_24&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_19&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_28&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_11&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_31&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P1_05&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_30&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since each pin has a different type, we need to convert them to a unique type to insert them into an array. The &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/gpio/trait.Pin.html#method.degrade" rel="noopener noreferrer"&gt;degrade()&lt;/a&gt; method of the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/gpio/trait.Pin.html" rel="noopener noreferrer"&gt;Pin trait&lt;/a&gt; allows us to do this by transforming them into &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/gpio/struct.AnyPin.html" rel="noopener noreferrer"&gt;AnyPin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can now modify the task prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[embassy_executor::task]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;display_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r_pins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AnyPin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nn"&gt;image&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ROWS&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;c_pins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AnyPin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nn"&gt;image&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;COLS&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's move on to implementing the task itself: we'll start by initializing the pins in output mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;r_pins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r_pins&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputDrive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;c_pins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c_pins&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;High&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputDrive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we need to wait for the first image to be signaled for display:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;image&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IMG_SIG&lt;/span&gt;&lt;span class="nf"&gt;.wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.rs/embassy-sync/latest/embassy_sync/signal/struct.Signal.html#method.wait" rel="noopener noreferrer"&gt;wait&lt;/a&gt; function returns a &lt;a href="https://doc.rust-lang.org/std/future/trait.Future.html" rel="noopener noreferrer"&gt;Future&lt;/a&gt; that will resolve when the signal is emitted (i.e., when the main task sends its first image). We can thus await it.&lt;/p&gt;

&lt;p&gt;Considering the electrical schematic, it's not possible to manage the image all at once because lighting two diagonal LEDs also lights the other two LEDs on the same row and column. We will therefore display the image line by line very quickly, relying on persistence of vision.&lt;/p&gt;

&lt;p&gt;To do this, we need a &lt;a href="https://docs.rs/embassy-time/latest/embassy_time/struct.Ticker.html" rel="noopener noreferrer"&gt;Ticker&lt;/a&gt; with the appropriate frequency. 60Hz is enough for the human eye not to notice. Knowing that we have 5 lines, we can initialize it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Ticker&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_hz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, we can start the display loop, which will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Display a row of the image&lt;/li&gt;
&lt;li&gt;Wait for a tick&lt;/li&gt;
&lt;li&gt;Turn off the row&lt;/li&gt;
&lt;li&gt;If a new image is signaled, update it
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r_pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r_img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r_pins&lt;/span&gt;&lt;span class="nf"&gt;.iter_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c_pins&lt;/span&gt;
      &lt;span class="nf"&gt;.iter_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nf"&gt;.zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r_img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c_img&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;c_img&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;.for_each&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;r_pin&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="nf"&gt;.next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;r_pin&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;c_pins&lt;/span&gt;&lt;span class="nf"&gt;.iter_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.for_each&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IMG_SIG&lt;/span&gt;&lt;span class="nf"&gt;.try_take&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_img&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can test this mechanism by sending it a fixed image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;HAPPY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nn"&gt;image&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IMG_SIG&lt;/span&gt;&lt;span class="nf"&gt;.signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HAPPY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have a functional screen; all that remains is to send actual images to display.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Controller
&lt;/h2&gt;

&lt;p&gt;The control task is a bit simpler: the touch button will be used to start a game, and buttons A and B will direct the snake. We will pass them separately to the main task via a &lt;a href="https://docs.rs/embassy-sync/latest/embassy_sync/channel/struct.Channel.html" rel="noopener noreferrer"&gt;Channel&lt;/a&gt; and a &lt;a href="https://docs.rs/embassy-sync/latest/embassy_sync/signal/struct.Signal.html" rel="noopener noreferrer"&gt;Signal&lt;/a&gt;, respectively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;BTN_CHAN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CriticalSectionRawMutex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;TOUCH_SIG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CriticalSectionRawMutex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type transmitted by the signal is &lt;code&gt;()&lt;/code&gt;, meaning it transmits no data, only the "start signal" matters.&lt;/p&gt;

&lt;p&gt;As with the screen, pass the pins corresponding to the buttons to the task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;btn_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;btn_b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_14&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P0_23&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.P1_04&lt;/span&gt;&lt;span class="nf"&gt;.degrade&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;spawner&lt;/span&gt;&lt;span class="nf"&gt;.spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;control_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;btn_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;btn_b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the task prototype accordingly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[embassy_executor::task]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;control_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;btn_a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AnyPin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;btn_b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AnyPin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AnyPin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert these pins to &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/gpio/struct.Input.html" rel="noopener noreferrer"&gt;Input&lt;/a&gt;s, allowing us to retrieve their respective states. We can see from &lt;a href="https://github.com/microbit-foundation/microbit-v2-hardware/blob/main/V2.21/MicroBit_V2.2.1_nRF52820%20schematic.PDF" rel="noopener noreferrer"&gt;the electrical schematic&lt;/a&gt; that A and B have pull-up resistors, while the touch button does not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;btn_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;btn_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;btn_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;btn_b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Electrically, a button is a switch that closes when pressed. We will wait for a button state change from high to low, then transmit it to the main task using the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/gpio/struct.Input.html#method.wait_for_falling_edge" rel="noopener noreferrer"&gt;Input::wait_for_falling_edge&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;This function is asynchronous and returns a future. We have three events to monitor, and we can use the &lt;a href="https://docs.rs/embassy-futures/latest/embassy_futures/select/fn.select3.html" rel="noopener noreferrer"&gt;&lt;code&gt;select3&lt;/code&gt;&lt;/a&gt; macro from the &lt;a href="https://docs.rs/embassy-futures/latest/embassy_futures/index.html" rel="noopener noreferrer"&gt;embassy-futures crate&lt;/a&gt; to handle this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;select3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;btn_a&lt;/span&gt;&lt;span class="nf"&gt;.wait_for_falling_edge&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;btn_b&lt;/span&gt;&lt;span class="nf"&gt;.wait_for_falling_edge&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="nf"&gt;.wait_for_falling_edge&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a button is pressed, one of the match arms is executed, allowing us to determine which button it is via &lt;a href="https://docs.rs/embassy-futures/latest/embassy_futures/select/enum.Either3.html" rel="noopener noreferrer"&gt;&lt;code&gt;Either3&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nn"&gt;Either3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;First&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BTN_CHAN&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nn"&gt;Either3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BTN_CHAN&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nn"&gt;Either3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Third&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TOUCH_SIG&lt;/span&gt;&lt;span class="nf"&gt;.signal&lt;/span&gt;&lt;span class="p"&gt;(()),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since switches are mechanical components, they can be subject to bouncing. To prevent triggering the same event multiple times, we can add a debounce delay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, place this match in an infinite loop to continuously listen for commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;select3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;btn_a&lt;/span&gt;&lt;span class="nf"&gt;.wait_for_falling_edge&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;btn_b&lt;/span&gt;&lt;span class="nf"&gt;.wait_for_falling_edge&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="nf"&gt;.wait_for_falling_edge&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;.await&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;Either3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;First&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BTN_CHAN&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;Either3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BTN_CHAN&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;Either3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Third&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TOUCH_SIG&lt;/span&gt;&lt;span class="nf"&gt;.signal&lt;/span&gt;&lt;span class="p"&gt;(()),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;after_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our controller is ready; we will retrieve commands in the main task when appropriate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling the Game
&lt;/h2&gt;

&lt;p&gt;This section is not intended to describe the operation of the Snake game in detail, but to focus on the interesting aspects related to embedded systems. For reference, &lt;a href="https://gitlab.com/cyril-marpaud/impl_snake_for_microbit" rel="noopener noreferrer"&gt;the complete source code of the project&lt;/a&gt; is available on GitLab.&lt;/p&gt;

&lt;p&gt;Broadly speaking, the main task will loop over the play function, which itself consists of the game’s three stages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Game&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;snake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Snake&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Food&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[embassy_executor::task]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RNG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="nf"&gt;.play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.waiting_state&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.ongoing_state&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.over_state&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating the Food: Random Numbers
&lt;/h3&gt;

&lt;p&gt;Start this task by passing it the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/peripherals/struct.RNG.html" rel="noopener noreferrer"&gt;RNG&lt;/a&gt; (&lt;strong&gt;R&lt;/strong&gt;andom &lt;strong&gt;N&lt;/strong&gt;umber &lt;strong&gt;G&lt;/strong&gt;enerator):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="py"&gt;.RNG&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;spawner&lt;/span&gt;&lt;span class="nf"&gt;.spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the name suggests, it allows us to generate random numbers, which is useful for placing the snake's food randomly on the screen.&lt;/p&gt;

&lt;p&gt;As with the LEDs and buttons, the first step is to transform this peripheral into a usable programmatic object. This is what the &lt;code&gt;new&lt;/code&gt; method does when initializing the game's state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RNG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Game&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Game&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;snake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Food&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Rng&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Irqs&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/rng/struct.Rng.html" rel="noopener noreferrer"&gt;&lt;code&gt;Rng&lt;/code&gt;&lt;/a&gt; object returned by the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/rng/struct.Rng.html#method.new" rel="noopener noreferrer"&gt;&lt;code&gt;Rng::new&lt;/code&gt;&lt;/a&gt; method implements the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/rng/struct.Rng.html#impl-RngCore-for-Rng%3C'd,+T%3E" rel="noopener noreferrer"&gt;&lt;code&gt;RngCore&lt;/code&gt; trait&lt;/a&gt;. This is very interesting because the &lt;a href="https://docs.rs/rand/latest/rand/trait.Rng.html" rel="noopener noreferrer"&gt;rand crate&lt;/a&gt; defines the &lt;a href="https://docs.rs/rand/latest/rand/trait.Rng.html" rel="noopener noreferrer"&gt;&lt;code&gt;Rng&lt;/code&gt; trait&lt;/a&gt; as a subtrait of &lt;code&gt;RngCore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This means that we can use the &lt;code&gt;Rng&lt;/code&gt; trait with our peripheral to generate random numbers more sophisticatedly than using the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/rng/struct.Rng.html#implementations" rel="noopener noreferrer"&gt;low-level API of the embassy_nrf crate&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, to generate a random number between 0 and 25:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import the trait into the local scope&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rng&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Rng&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Irqs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="nf"&gt;.gen_range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Binding Interrupts
&lt;/h3&gt;

&lt;p&gt;The more curious among you might be wondering what the &lt;code&gt;Irqs&lt;/code&gt; structure passed to &lt;code&gt;Rng::new&lt;/code&gt; is and what it is for. It is a structure generated by the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/macro.bind_interrupts.html" rel="noopener noreferrer"&gt;&lt;code&gt;bind_interrupts&lt;/code&gt; macro&lt;/a&gt;, which ensures at compile-time that the RNG interrupts are bound to ISRs (&lt;a href="https://en.wikipedia.org/wiki/Interrupt_handler" rel="noopener noreferrer"&gt;&lt;strong&gt;I&lt;/strong&gt;nterrupt &lt;strong&gt;S&lt;/strong&gt;ervice &lt;strong&gt;R&lt;/strong&gt;outines&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Indeed, most peripherals in a microcontroller can generate interrupts to inform the core of an event. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An I²C or SPI peripheral generates an interrupt to signal that a message is available on the bus.&lt;/li&gt;
&lt;li&gt;An RNG generates an interrupt to indicate that it has finished generating a random number.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/macro.bind_interrupts.html?search=InterruptHandler" rel="noopener noreferrer"&gt;etc.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When one of these interrupts occurs, the core is interrupted and executes the corresponding ISR, which is a specific function that handles the interrupt. It is important to bind the interrupts we are interested in to ISRs to ensure they are executed when the events of interest occur.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;main.rs&lt;/code&gt;, we just need to bind the RNG interrupt to its ISR for everything to work correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;bind_interrupts!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Irqs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;RNG&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;embassy_nrf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InterruptHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RNG&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Storing Data on no_std
&lt;/h3&gt;

&lt;p&gt;Finally, I want to mention the &lt;a href="https://crates.io/crates/heapless" rel="noopener noreferrer"&gt;heapless crate&lt;/a&gt;, which allows us to define static data structures. This means that the size of these structures is known at compile-time, and they do not require dynamic allocation. This is very useful for embedded systems where memory is limited and dynamic allocation is undesirable.&lt;/p&gt;

&lt;p&gt;The Snake structure in my source code is a &lt;a href="https://docs.rs/heapless/latest/heapless/struct.Vec.html" rel="noopener noreferrer"&gt;Vec&lt;/a&gt; with a capacity of 25 elements, the size of the screen. This means that the snake can never exceed this size, and the memory needed to store it is allocated at compile-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;heapless&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Coords&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Snake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Coords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ROWS&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;COLS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other structures like &lt;a href="https://docs.rs/heapless/latest/heapless/struct.Deque.html" rel="noopener noreferrer"&gt;Deque&lt;/a&gt;, &lt;a href="https://docs.rs/heapless/latest/heapless/struct.IndexMap.html" rel="noopener noreferrer"&gt;IndexMap&lt;/a&gt;, or &lt;a href="https://docs.rs/heapless/latest/heapless/struct.String.html" rel="noopener noreferrer"&gt;String&lt;/a&gt; are also available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Adding Sound
&lt;/h2&gt;

&lt;p&gt;The example project contains an additional task that uses the board's speaker to play simple sounds. To do this, it uses the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/pwm/struct.Pwm.html" rel="noopener noreferrer"&gt;PWM&lt;/a&gt; (&lt;a href="https://en.wikipedia.org/wiki/Pulse-width_modulation" rel="noopener noreferrer"&gt;&lt;strong&gt;P&lt;/strong&gt;ulse &lt;strong&gt;W&lt;/strong&gt;idth &lt;strong&gt;M&lt;/strong&gt;odulation&lt;/a&gt;) peripheral, which generates signals of variable frequency.&lt;/p&gt;

&lt;p&gt;We can see from &lt;a href="https://tech.microbit.org/hardware/schematic/#v2-pinmap" rel="noopener noreferrer"&gt;the pin mapping&lt;/a&gt; that the speaker is assigned to pin &lt;code&gt;P0_00&lt;/code&gt;. We need to send the PWM signal to this pin. A simple technique is to use the &lt;a href="https://docs.embassy.dev/embassy-nrf/git/nrf52832/pwm/struct.SimplePwm.html" rel="noopener noreferrer"&gt;SimplePwm driver&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the rest, feel free to explore this path ;)&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This project demonstrates Rust’s strengths for embedded development, especially with async programming. Rust’s memory safety and zero-cost abstractions translate directly into reliability and performance, making it well-suited for production-ready embedded and IoT.&lt;/p&gt;

&lt;p&gt;The async model in Embassy introduces a concurrency approach where tasks are efficiently woken by wakers, similar to the way microcontrollers respond to hardware interrupts. This approach allows tasks to react quickly to events while maintaining a clean and organized code structure, without the complexity of traditional interrupt-driven programming. The PAC+HAL stack further showcases Rust's flexibility, combining low-level control with high-level abstractions to balance precision and ease of use.&lt;/p&gt;

&lt;p&gt;Rust’s rich ecosystem, including tools like probe-rs and built-in cross-compiling support, streamlines the development process compared to more traditional languages. Setting up projects, flashing, debugging, and leveraging crates like heapless for memory-efficient data handling become more intuitive, enabling scalable and reliable embedded solutions.&lt;/p&gt;

&lt;p&gt;As embedded systems demand modern practices, Rust’s approach to safety, async programming, and hardware flexibility, empowered by a rich ecosystem, establishes it as a mature, production-ready option for modern embedded and IoT projects.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=8_Pj6q_mVQw" rel="noopener noreferrer"&gt;Rust Lyon Meetup #8: impl Snake for Micro:bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tweedegolf.nl/en/blog/65/async-rust-vs-rtos-showdown" rel="noopener noreferrer"&gt;Async Rust vs RTOS showdown!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://notgull.net/why-not-threads/" rel="noopener noreferrer"&gt;Why choose async/await over threads?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://interrupt.memfault.com/blog/embedded-async-rust" rel="noopener noreferrer"&gt;Asynchronous Rust on Cortex-M Microcontrollers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Snake_(video_game_genre)" rel="noopener noreferrer"&gt;Snake (video game genre) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Pulse-width_modulation" rel="noopener noreferrer"&gt;Pulse Width Modulation - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Cooperative_multitasking" rel="noopener noreferrer"&gt;Cooperative Multitasking - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Preemption_(computing)" rel="noopener noreferrer"&gt;Preemption (Computing) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Interrupt_handler" rel="noopener noreferrer"&gt;Interrupt Handler - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  BBC Micro:bit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://microbit.org/" rel="noopener noreferrer"&gt;BBC Micro:bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tech.microbit.org/hardware/" rel="noopener noreferrer"&gt;Micro:bit Hardware Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tech.microbit.org/hardware/schematic/#v2-pinmap" rel="noopener noreferrer"&gt;Micro:bit V2 Pin Mapping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microbit-foundation/microbit-v2-hardware/blob/main/V2.21/MicroBit_V2.2.1_nRF52820%20schematic.PDF" rel="noopener noreferrer"&gt;Micro:bit V2.2.1 Schematic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Rust Language
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust Programming Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/std/keyword.await.html" rel="noopener noreferrer"&gt;Rust Async Await Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/std/future/trait.Future.html" rel="noopener noreferrer"&gt;Rust Futures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Embassy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://embassy.dev" rel="noopener noreferrer"&gt;Embassy - Async Rust for Embedded Systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/adinack/cargo-embassy" rel="noopener noreferrer"&gt;Cargo Embassy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Probe-rs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://probe.rs/" rel="noopener noreferrer"&gt;Probe-rs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://probe.rs/docs/getting-started/installation/#using-install-scripts" rel="noopener noreferrer"&gt;Probe-rs Installation Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://probe.rs/targets/" rel="noopener noreferrer"&gt;Supported Targets for Probe-rs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://probe.rs/targets/master/nRF52833_xxAA" rel="noopener noreferrer"&gt;nRF52833_xxAA Target - Probe-rs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dependencies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.rs/heapless/" rel="noopener noreferrer"&gt;Heapless Crate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#requirements" rel="noopener noreferrer"&gt;Cortex-M-RT Crate Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://defmt.ferrous-systems.com/setup.html#linker-script" rel="noopener noreferrer"&gt;Defmt Setup for Logs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Whoami
&lt;/h1&gt;

&lt;p&gt;My name is &lt;a href="https://cyril-marpaud.gitlab.io/en/" rel="noopener noreferrer"&gt;Cyril Marpaud&lt;/a&gt;, I'm an embedded systems freelance engineer and a Rust enthusiast 🦀 I have 10 years experience and am currently living in Lyon (France).&lt;/p&gt;

&lt;p&gt;[![LinkedIn][linkedin-shield]][linkedin-url]&lt;/p&gt;

</description>
      <category>rust</category>
      <category>embeddedsystems</category>
      <category>embassy</category>
      <category>microbit</category>
    </item>
    <item>
      <title>Embedded Rust on BBC Micro Bit: unlocking Vec and HashMap</title>
      <dc:creator>Cyril Marpaud</dc:creator>
      <pubDate>Fri, 24 Mar 2023 09:41:55 +0000</pubDate>
      <link>https://forem.com/cyrilmarpaud/embedded-rust-on-bbc-micro-bit-unlocking-vec-and-hashmap-2nm0</link>
      <guid>https://forem.com/cyrilmarpaud/embedded-rust-on-bbc-micro-bit-unlocking-vec-and-hashmap-2nm0</guid>
      <description>&lt;p&gt;As an engineer having spent most of 2022 learning &lt;a href="https://www.rust-lang.org/"&gt;the Rust language&lt;/a&gt;, I was a little worried about the &lt;a href="https://docs.rust-embedded.org/book/intro/no-std.html"&gt;&lt;code&gt;no_std&lt;/code&gt;&lt;/a&gt; side of embedded systems programming.&lt;/p&gt;

&lt;p&gt;Embedded systems, like the &lt;a href="https://en.wikipedia.org/wiki/Micro_Bit"&gt;BBC Micro Bit&lt;/a&gt; (a small &lt;a href="https://en.wikipedia.org/wiki/ARM_Cortex-M#Cortex-M4"&gt;ARM Cortex-M4F&lt;/a&gt;-based computer designed for educational purposes featuring a 5×5 LED matrix, multiple sensors, Bluetooth Low Energy capabilities and a lot more), are usually programmed as &lt;strong&gt;bare_metal&lt;/strong&gt; devices in a &lt;code&gt;no_std&lt;/code&gt; environment, meaning we can't use the &lt;a href="https://doc.rust-lang.org/std/index.html"&gt;&lt;code&gt;std&lt;/code&gt;&lt;/a&gt; crate where &lt;code&gt;Vec&lt;/code&gt; and &lt;code&gt;HashMap&lt;/code&gt;, among others, reside.&lt;/p&gt;

&lt;p&gt;While very understandable when considering older devices, the growing specs and capabilities of modern devices make it increasingly tempting to use higher-level abstractions. The purpose of this tutorial is thus to demonstrate how to enable the use of &lt;a href="https://doc.rust-lang.org/std/vec/struct.Vec.html"&gt;&lt;code&gt;Vec&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/std/collections/struct.HashMap.html"&gt;&lt;code&gt;HashMap&lt;/code&gt;&lt;/a&gt; on a BBC Micro Bit.&lt;/p&gt;

&lt;p&gt;The original article and associated examples are available in my &lt;a href="https://gitlab.com/cyril-marpaud/microbit_vec_hashmap"&gt;Micro Bit Vec and HashMap&lt;/a&gt; GitLab repository. Let us now initiate this endeavor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;This tutorial does not require much:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A computer with internet access&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://microbit.org"&gt;BBC Micro Bit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A USB cable&lt;/li&gt;
&lt;li&gt;Less than an hour of your time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the OS
&lt;/h2&gt;

&lt;p&gt;It is assumed that you have a fully functional 22.10 Ubuntu Linux distribution up and running. If you don't, &lt;a href="https://gitlab.com/cyril-marpaud/rust_esp_quickstart/-/blob/main/README.md#the-os"&gt;detailed instructions to set one up can be found in my previous tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the development environment
&lt;/h2&gt;

&lt;p&gt;First of all, we are going to install a few required dependencies. Open a terminal (the default shortcut is &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;Alt&lt;/code&gt;+&lt;code&gt;T&lt;/code&gt;) and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; curl gcc libudev-dev&lt;span class="o"&gt;=&lt;/span&gt;251.4-1ubuntu7 pkg-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(installing version &lt;code&gt;251.4-1ubuntu7.1&lt;/code&gt; of &lt;code&gt;libudev-dev&lt;/code&gt; induces a crash on my machine so I'm using version &lt;code&gt;251.4-1ubuntu7&lt;/code&gt; instead)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We also need to install &lt;a href="https://www.rust-lang.org"&gt;Rust&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/stable/cargo/"&gt;Cargo&lt;/a&gt;. &lt;a href="https://rustup.rs/"&gt;Rustup&lt;/a&gt; can take care of that for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;--fail&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt; https://sh.rustup.rs | sh &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.cargo/env"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we will be compiling for an ARM Cortex-M4F microcontroller, we have to install &lt;a href="https://doc.rust-lang.org/beta/rustc/platform-support.html"&gt;the adequate target&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup target add thumbv7em-none-eabihf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After compilation comes flashing. &lt;a href="https://probe.rs/docs/tools/cargo-embed/"&gt;&lt;code&gt;cargo embed&lt;/code&gt;&lt;/a&gt; is the solution we will be using for that purpose. Install it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;cargo-embed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, a &lt;strong&gt;udev rule&lt;/strong&gt; will take care of granting USB access to the Micro Bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SUBSYSTEMS==&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;usb&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, ATTRS{idVendor}==&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0d28&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, ATTRS{idProduct}==&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0204&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, MODE=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0660&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, GROUP=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;plugdev&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/udev/rules.d/99-microbit.rules &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;sudo &lt;/span&gt;udevadm control &lt;span class="nt"&gt;--reload-rules&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;udevadm trigger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up the project
&lt;/h2&gt;

&lt;p&gt;Cargo makes it easy to create a Rust project and add the adequate dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo init microbit
&lt;span class="nb"&gt;cd &lt;/span&gt;microbit
cargo add cortex-m-rt microbit-v2 panic_halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;cargo embed&lt;/code&gt; needs to know which device it has to flash. Create a file named &lt;code&gt;Embed.toml&lt;/code&gt; at the root of the project with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[default.general]&lt;/span&gt;
&lt;span class="py"&gt;chip&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"nrf52833_xxAA"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can either specify a &lt;code&gt;--target&lt;/code&gt; flag each time we compile our software or set that up once and for all in a configuration file. Moreover, our device's memory layout needs to be provided to the linker. Create the following &lt;code&gt;.cargo/config&lt;/code&gt; file which will do just that for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; .cargo
&lt;span class="nb"&gt;touch&lt;/span&gt; .cargo/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;[target.'cfg(all(target_arch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"arm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;target_os&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"none"&lt;/span&gt;&lt;span class="err"&gt;))&lt;/span&gt;&lt;span class="s"&gt;']&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;rustflags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"-C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"link-arg&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;-Tlink.x&lt;/span&gt;&lt;span class="s"&gt;",&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[build]&lt;/span&gt;
&lt;span class="py"&gt;target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"thumbv7em-none-eabihf"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, open &lt;code&gt;src/main.rs&lt;/code&gt; and copy/paste this LED-blink minimal example inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;cortex_m_rt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;microbit&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;board&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;panic_halt&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[entry]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;board&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;take&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to take board"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;board&lt;/span&gt;&lt;span class="py"&gt;.TIMER0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;board&lt;/span&gt;&lt;span class="py"&gt;.display_pins.row1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150u16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;board&lt;/span&gt;&lt;span class="py"&gt;.display_pins.col1&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set col1 low"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set row1 high"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="nf"&gt;.delay_ms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set row1 low"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="nf"&gt;.delay_ms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Blinking an LED
&lt;/h2&gt;

&lt;p&gt;Plug the board to your computer then compile the program and flash it single-handedly with this simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo embed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the process ends, you should see the upper-left LED blink. Congratulations!&lt;/p&gt;

&lt;h2&gt;
  
  
  Unlocking Vec
&lt;/h2&gt;

&lt;p&gt;I have to admit that I shamefully lied when I told you &lt;a href="https://doc.rust-lang.org/std/index.html?search=vec"&gt;&lt;code&gt;Vec&lt;/code&gt; resides in the &lt;code&gt;std&lt;/code&gt; crate&lt;/a&gt; as &lt;a href="https://doc.rust-lang.org/alloc/vec/struct.Vec.html"&gt;it is actually available in the &lt;code&gt;alloc&lt;/code&gt; crate&lt;/a&gt;. As the name suggests, using it requires an allocator.&lt;/p&gt;

&lt;p&gt;Luckily, the &lt;code&gt;embedded-alloc&lt;/code&gt; crate provides us with one (there is &lt;a href="https://github.com/rust-embedded/embedded-alloc"&gt;a complete example in the associated Github repository&lt;/a&gt;). We also need the &lt;code&gt;cortex-m&lt;/code&gt; crate to handle critical sections. Add them to the project's dependencies like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo add embedded-alloc
cargo add cortex-m &lt;span class="nt"&gt;--features&lt;/span&gt; critical-section-single-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in &lt;code&gt;src/main.rs&lt;/code&gt;, we need to customize a few things. Import &lt;code&gt;Vec&lt;/code&gt; and declare a global allocator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;embedded_alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Heap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[global_allocator]&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;HEAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Heap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Heap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the beginning of the &lt;code&gt;main&lt;/code&gt; function, initialize the allocator and a size for our heap (the Micro Bit has 128KiB of RAM):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;HEAP_SIZE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 8KiB&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;HEAP_MEM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;HEAP_SIZE&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;MaybeUninit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uninit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;HEAP_SIZE&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;HEAP&lt;/span&gt;&lt;span class="nf"&gt;.init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_MEM&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HEAP_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the main loop, using &lt;code&gt;Vec&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.cycle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.for_each&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set row high"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set row low"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="nf"&gt;.delay_ms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, compile and flash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo embed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LED should now be blinking in a heartbeat pattern. You are using Rust's &lt;code&gt;Vec&lt;/code&gt; on a Micro Bit, congratulations!&lt;/p&gt;

&lt;h2&gt;
  
  
  Unlocking HashMap
&lt;/h2&gt;

&lt;p&gt;Unlike &lt;code&gt;Vec&lt;/code&gt;, &lt;a href="https://doc.rust-lang.org/std/index.html?search=HashMap"&gt;the &lt;code&gt;alloc&lt;/code&gt; crate does not suffice for &lt;code&gt;HashMap&lt;/code&gt;&lt;/a&gt;, full &lt;code&gt;std&lt;/code&gt; is required (which in turn requires a &lt;code&gt;nightly&lt;/code&gt; toolchain because &lt;code&gt;std&lt;/code&gt; is not supported for our platform). To avoid having to type &lt;code&gt;+nightly&lt;/code&gt; each time we invoke &lt;code&gt;cargo&lt;/code&gt; or &lt;code&gt;rustup&lt;/code&gt;, create a file named &lt;code&gt;rust-toolchain.toml&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[toolchain]&lt;/span&gt;
&lt;span class="py"&gt;channel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"nightly"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As building the &lt;code&gt;std&lt;/code&gt; crate requires its source code, use rustup to fetch that component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup component add rust-src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;.cargo/config&lt;/code&gt;, add the following lines (&lt;code&gt;panic_abort&lt;/code&gt; is needed here because of &lt;a href="https://github.com/rust-lang/rust/issues/83805#issuecomment-812874115"&gt;a currently unresolved issue&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[unstable]&lt;/span&gt;
&lt;span class="py"&gt;build-std&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"panic_abort"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;std&lt;/code&gt; crate provides an allocator, we can therefore remove those lines from &lt;code&gt;src/main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;std&lt;/code&gt; also provides a panic handler, the import and &lt;code&gt;panic-halt&lt;/code&gt; dependency can therefore be removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;panic_halt&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo remove panic-halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we are rid of those useless parts, there are a few things we need to add. As we're building &lt;code&gt;std&lt;/code&gt; for an unsupported (thus flagged &lt;em&gt;unstable&lt;/em&gt;) platform, we need the &lt;code&gt;restricted_std&lt;/code&gt; feature. Add it to &lt;code&gt;src/main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![feature(restricted_std)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import &lt;code&gt;HashMap&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;hash_map&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DefaultHasher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nn"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BuildHasherDefault&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And use it instead of &lt;code&gt;Vec&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;hm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_hasher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;BuildHasherDefault&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DefaultHasher&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;hm&lt;/span&gt;&lt;span class="nf"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.cycle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.for_each&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set row high"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set row low"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="nf"&gt;.delay_ms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason we are providing our own hasher is that the default one relies on the &lt;code&gt;sys&lt;/code&gt; crate which is platform dependent. Our platform being unsupported, &lt;a href="https://github.com/rust-lang/rust/tree/master/library/std/src/sys/unsupported"&gt;the associated implementation&lt;/a&gt; either does nothing or &lt;a href="https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unsupported/common.rs#L15"&gt;fails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, keep in mind that using anything from said &lt;code&gt;sys&lt;/code&gt; crate will either fail or hang (in particular: threads). &lt;code&gt;HashMap&lt;/code&gt; is fine though, and the above snippet should make the LED blink in an inverted heartbeat pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo embed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust's &lt;code&gt;HashMap&lt;/code&gt; on a Micro Bit, Hooray !&lt;/p&gt;

&lt;h2&gt;
  
  
  Actually using HashMap
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://gitlab.com/cyril-marpaud/microbit_vec_hashmap/-/tree/main/alphabet"&gt;alphabet folder&lt;/a&gt; of my Gitlab repository demonstrates how to display caracters on the LED matrix using a &lt;code&gt;HashMap&lt;/code&gt;. You can flash it by running the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;  &lt;span class="c"&gt;# We need to move out of the "microbit" folder we created earlier&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; git
git clone https://gitlab.com/cyril-marpaud/microbit_vec_hashmap.git
&lt;span class="nb"&gt;cd &lt;/span&gt;microbit_vec_hashmap/alphabet
cargo embed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The ability to use Rust collections on a device as humble as the BBC micro:bit represents a remarkable achievement in embedded programming. Thanks to recent hardware advances, even modest embedded devices can now support high-level abstractions that were once the exclusive domain of larger and more expensive systems.&lt;/p&gt;

&lt;p&gt;Rust's efficiency and modern design make it an ideal language for taking advantage of these new capabilities and pushing the limits of what is possible on a microcontroller: developers can create complex and sophisticated projects that once seemed impossible on such small devices, from data-driven sensors to interactive games and applications.&lt;/p&gt;

&lt;p&gt;Whether you are a seasoned expert or just getting started, the future of embedded programming is brighter than ever, and Rust is leading the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  See also (aka useful links)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rust-lang.org"&gt;The Rust Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Micro_Bit"&gt;BBC Micro Bit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Crates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.rs/microbit-v2/0.13.0/microbit/"&gt;microbit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/lsm303agr/latest/lsm303agr/index.html"&gt;LMS303AGR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/tiny-led-matrix/latest/tiny_led_matrix/"&gt;tiny_led_matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/cortex-m/0.7.7/cortex_m/"&gt;cortex_m&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/cortex-m-log/latest/cortex_m_log/"&gt;cortex_m_log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://crates.io/crates/minimult_cortex-m"&gt;minimult_cortex-m&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/embedded-alloc/0.5.0/embedded_alloc/"&gt;embedded_alloc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tutorials
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.rust-embedded.org/discovery/microbit/index.html"&gt;Discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.timhutt.co.uk/std-embedded-rust/index.html"&gt;&lt;code&gt;std&lt;/code&gt; on Micro Bit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Whoami
&lt;/h2&gt;

&lt;p&gt;My name is &lt;a href="https://www.linkedin.com/in/cyrilmarpaud/"&gt;Cyril Marpaud, I'm an embedded systems freelance engineer and a Rust enthusiast 🦀&lt;/a&gt; I have nearly 10 years experience and am currently living in Lyon (France).&lt;/p&gt;

</description>
      <category>rust</category>
      <category>embedded</category>
      <category>microbit</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to set up a Zola website with HayFlow theme in under 15 minutes</title>
      <dc:creator>Cyril Marpaud</dc:creator>
      <pubDate>Fri, 10 Mar 2023 21:15:36 +0000</pubDate>
      <link>https://forem.com/cyrilmarpaud/how-to-set-up-a-zola-website-with-hayflow-theme-in-under-15-minutes-4kbj</link>
      <guid>https://forem.com/cyrilmarpaud/how-to-set-up-a-zola-website-with-hayflow-theme-in-under-15-minutes-4kbj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This article was written by &lt;a href="https://fr.wikipedia.org/wiki/ChatGPT"&gt;ChatGPT&lt;/a&gt; based on &lt;a href="https://gitlab.com/cyril-marpaud/hayflow/-/blob/main/README.md"&gt;HayFlow’s readme&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're looking for a clean, modern-looking website theme that's easy to set up, HayFlow is a great option. This theme is designed to work with Zola, a static site generator written in Rust, and it features a dark theme with a particles background, vertical arrows for navigation, and a few card types to choose from. Best of all, it requires only Markdown editing, so you don't need to know HTML or CSS to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, you'll need to make sure you have &lt;a href="https://www.getzola.org/documentation/getting-started/installation/"&gt;Zola&lt;/a&gt; installed on your system. You'll also need to have &lt;a href="https://git-scm.com/downloads"&gt;Git&lt;/a&gt; installed to be able to clone the HayFlow theme repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live demo
&lt;/h2&gt;

&lt;p&gt;See &lt;a href="https://cyril-marpaud.gitlab.io/"&gt;my personal website&lt;/a&gt; to get a sense of what can be accomplished in a few minutes with this theme. Its source code is also available as an example in my &lt;a href="https://gitlab.com/cyril-marpaud/cyril-marpaud.gitlab.io"&gt;Gitlab website repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Initialize a new Zola website
&lt;/h2&gt;

&lt;p&gt;The first step is to initialize a new Zola website. Open your terminal and navigate to the directory where you want to create your new website. Then, enter the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zola init mywebsite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new directory called &lt;code&gt;mywebsite&lt;/code&gt; with the basic files and folders needed to run a Zola website.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Download and install the HayFlow theme
&lt;/h2&gt;

&lt;p&gt;Next, you need to download and install the HayFlow theme. To do this, navigate to the &lt;code&gt;mywebsite&lt;/code&gt; directory in your terminal and clone the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;mywebsite
git clone git@gitlab.com:cyril-marpaud/hayflow.git themes/hayflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will download the HayFlow theme from the GitLab repository and place it in a new directory called &lt;code&gt;themes/hayflow&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Configure your website to use the HayFlow theme
&lt;/h2&gt;

&lt;p&gt;Now that you have the HayFlow theme installed, you need to tell Zola to use it for your website. Open the &lt;code&gt;config.toml&lt;/code&gt; file in your text editor and add the following line at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hayflow"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Zola to use the HayFlow theme for your website. Save the file and close it.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Run your website
&lt;/h2&gt;

&lt;p&gt;With your website set up and customized, you're ready to run it. Open your terminal, navigate to the &lt;code&gt;mywebsite&lt;/code&gt; directory, and enter the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zola serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start a local web server and open your website in your default web browser. You should see your landing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Customize your landing page
&lt;/h2&gt;

&lt;p&gt;With the HayFlow theme installed and configured, you're ready to customize your landing page. Open the &lt;code&gt;config.toml&lt;/code&gt; file again and scroll down to the &lt;code&gt;[extra]&lt;/code&gt; section. This is where you can add variables to customize your landing page.&lt;/p&gt;

&lt;p&gt;There are three variables you can use to customize your landing page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: This is your name.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;roles&lt;/code&gt;: This is an array of strings that represent your roles or areas of expertise.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;links&lt;/code&gt;: This is an array of objects that represent links to your social media profiles or other pages. You can use any free icon from &lt;a href="https://fontawesome.com/search?o=r&amp;amp;m=free"&gt;Font Awesome&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To add your own information, simply replace the default values with your own. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[extra]&lt;/span&gt;
&lt;span class="nn"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;first&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;last&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Doe"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="py"&gt;roles&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Web Developer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Graphic Designer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Social Media Manager"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="py"&gt;links&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="py"&gt;icon&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fa-brands fa-twitter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://twitter.com/johndoe"&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="py"&gt;icon&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fa-brands fa-linkedin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://www.linkedin.com/in/johndoe"&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="py"&gt;icon&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fa-solid fa-envelope"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mailto:johndoe@example.com"&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've made your changes, save the &lt;code&gt;config.toml&lt;/code&gt; file and close it.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Add additional sections to your landing page
&lt;/h2&gt;

&lt;p&gt;One of the great features of the HayFlow theme is its support for multiple sections on your landing page. You can create new sections by adding new folders inside the &lt;code&gt;content&lt;/code&gt; directory and adding Markdown files to those folders.&lt;/p&gt;

&lt;p&gt;For example, to create a new section called "Pizza", create a new folder inside the &lt;code&gt;content&lt;/code&gt; directory with the name of your section (e.g. pizza) and add an &lt;code&gt;_index.md&lt;/code&gt; file inside it with the following front matter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pizza"&lt;/span&gt;
&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new section on your landing page with the title "Pizza". You can add your own content to the section by editing the &lt;code&gt;_index.md&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Customize section cards
&lt;/h2&gt;

&lt;p&gt;HayFlow offers three types of cards for your sections: &lt;code&gt;simple&lt;/code&gt;, &lt;code&gt;columns&lt;/code&gt;, and &lt;code&gt;list&lt;/code&gt;. By default, sections use the simple card type, but you can customize this by adding a &lt;code&gt;card_type&lt;/code&gt; variable to the front matter of your &lt;code&gt;_index.md&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;For example, to create a section with a columns card type, create a new folder inside the content directory with the name of your section (e.g. ingredients) and add an &lt;code&gt;_index.md&lt;/code&gt; file with the following front matter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ingredients"&lt;/span&gt;
&lt;span class="nn"&gt;[extra]&lt;/span&gt;
&lt;span class="py"&gt;card_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"columns"&lt;/span&gt;
&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create three additional Markdown files inside the ingredients folder with names like &lt;code&gt;one.md&lt;/code&gt;, &lt;code&gt;two.md&lt;/code&gt;, and &lt;code&gt;three.md&lt;/code&gt;. These files will contain the content for your columns. Here's an example front matter for the &lt;code&gt;one.md&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="err"&gt;+++&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Tomatoes"&lt;/span&gt;
&lt;span class="nn"&gt;[extra]&lt;/span&gt;
&lt;span class="py"&gt;icons&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"fa-solid fa-tomato"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;+++&lt;/span&gt;

&lt;span class="err"&gt;Tomatoes&lt;/span&gt; &lt;span class="err"&gt;are&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;delicious&lt;/span&gt; &lt;span class="err"&gt;ingredient&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;many&lt;/span&gt; &lt;span class="err"&gt;pizza&lt;/span&gt; &lt;span class="err"&gt;recipes.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a column card with a tomato icon and the title "Tomatoes".&lt;/p&gt;

&lt;p&gt;If you want to create a section with a &lt;code&gt;list&lt;/code&gt; card type, the process is similar. Just set the &lt;code&gt;card_type&lt;/code&gt; variable to &lt;code&gt;list&lt;/code&gt; in your &lt;code&gt;_index.md&lt;/code&gt; file and create Markdown files for each item in your list. You can optionally set a &lt;code&gt;link&lt;/code&gt; variable detailing the corresponding URL if applicable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With HayFlow, you can have a beautiful and functional landing page up and running in just a few minutes. The modular design and support for multiple sections make it easy to customize your page to fit your needs, and the use of Markdown makes it easy for anyone to create and maintain their own landing page.&lt;/p&gt;

&lt;p&gt;Whether you're a freelancer, a small business owner, or just looking to create a personal website, HayFlow is a great choice for your landing page. So why not give it a try and see what you can create?&lt;/p&gt;

&lt;h2&gt;
  
  
  Whoami
&lt;/h2&gt;

&lt;p&gt;My name is Cyril Marpaud, I’m an &lt;a href="https://www.linkedin.com/in/cyrilmarpaud/"&gt;embedded systems freelance engineer&lt;/a&gt; and a Rust enthusiast 🦀 I have nearly 10 years experience and am currently living in Lyon (France).&lt;/p&gt;

</description>
      <category>zola</category>
      <category>hayflow</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Embedded Rust on ESP32C3 Board, a Hands-on Quickstart Guide</title>
      <dc:creator>Cyril Marpaud</dc:creator>
      <pubDate>Wed, 22 Feb 2023 19:01:33 +0000</pubDate>
      <link>https://forem.com/cyrilmarpaud/embedded-rust-on-esp32c3-board-a-hands-on-quickstart-guide-28mf</link>
      <guid>https://forem.com/cyrilmarpaud/embedded-rust-on-esp32c3-board-a-hands-on-quickstart-guide-28mf</guid>
      <description>&lt;p&gt;Today, I'll be showing you how to use the &lt;a href="https://www.rust-lang.org" rel="noopener noreferrer"&gt;Rust programming language&lt;/a&gt; on a &lt;a href="https://github.com/esp-rs/esp-rust-board" rel="noopener noreferrer"&gt;Rust ESP board&lt;/a&gt;, a recent embedded platform packed with Wi-Fi and Bluetooth capabilities.&lt;/p&gt;

&lt;p&gt;We won't go through the details of &lt;a href="https://esp-rs.github.io/book/overview/index.html" rel="noopener noreferrer"&gt;&lt;code&gt;no_std&lt;/code&gt; vs &lt;code&gt;std&lt;/code&gt;&lt;/a&gt; development, just know that the latter allows us to use full Wi-Fi and Bluetooth capabilities along with the actual entire &lt;a href="https://doc.rust-lang.org/std/index.html" rel="noopener noreferrer"&gt;Rust Standard Library&lt;/a&gt; with ease which is usually &lt;strong&gt;NOT&lt;/strong&gt; straightforward but hey, this is 2023, enjoy!&lt;/p&gt;

&lt;p&gt;The original article and associated examples are available in my &lt;a href="https://gitlab.com/cyril-marpaud/rust_esp_quickstart" rel="noopener noreferrer"&gt;Rust ESP Quickstart&lt;/a&gt; GitLab repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If you are already running Linux and just want to flash your ESP board with a fully configured Rust "Hello, World!" project, see the &lt;a href="https://gitlab.com/cyril.marpaud/rust_esp_quickstart/-/blob/main/script/setup.sh" rel="noopener noreferrer"&gt;&lt;code&gt;script/setup.sh&lt;/code&gt; script&lt;/a&gt;, it should help you get started in no time. Be aware, though, that it has been made for a freshly installed 22.10 Ubuntu distribution and is untested on any other platform yet (i.e. use it at your own risks). On the other hand, please read on if you intend to walk the learning path instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Here's everything we are going to need during our little adventure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A computer with internet access&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/esp-rs/esp-rust-board" rel="noopener noreferrer"&gt;Rust ESP Board&lt;/a&gt; (this is open hardware so you can either buy one or build one yourself!)&lt;/li&gt;
&lt;li&gt;A USB cable&lt;/li&gt;
&lt;li&gt;An empty USB stick that we are going to erase completely so don't forget to &lt;strong&gt;BACKUP YOUR DATA FIRST&lt;/strong&gt; (A 16GiB one is fine)&lt;/li&gt;
&lt;li&gt;Less than an hour of your time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The OS
&lt;/h2&gt;

&lt;p&gt;We'll be using a live 22.10 Ubuntu distribution so that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;anyone with a decent computer can follow this guide&lt;/li&gt;
&lt;li&gt;our setups are the exact same, thus greatly reducing the rate of environment-related errors&lt;/li&gt;
&lt;li&gt;everything is instantly reversible, meaning that your computer will be left completely &lt;strong&gt;untouched&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;we won't need to go through an actual Linux installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One drawback of this solution is that each reboot will wipe the environment but feel free to actually install linux if persistence across said reboots is required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making a bootable USB stick
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Download the 22.10 "Kinetic Kudu" Ubuntu ISO image &lt;a href="https://ubuntu.com/download/desktop/thank-you?version=22.10&amp;amp;architecture=amd64" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Flash the USB stick using either &lt;a href="https://manpages.ubuntu.com/manpages/trusty/man8/usb-creator-gtk.8.html" rel="noopener noreferrer"&gt;&lt;code&gt;usb-creator-gtk&lt;/code&gt;&lt;/a&gt; if running Linux or &lt;a href="https://win32diskimager.download/" rel="noopener noreferrer"&gt;&lt;code&gt;Win32DiskImager&lt;/code&gt;&lt;/a&gt; if running Windows&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Installing &lt;code&gt;usb-creator-gtk&lt;/code&gt; on Linux
&lt;/h4&gt;

&lt;p&gt;Open a terminal (the default shortcut is &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;Alt&lt;/code&gt;+&lt;code&gt;T&lt;/code&gt; on Ubuntu) and run those commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; usb-creator-gtk


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Installing &lt;code&gt;Win32DiskImager&lt;/code&gt; on Windows
&lt;/h4&gt;

&lt;p&gt;Download the installer from &lt;a href="https://sourceforge.net/projects/win32diskimager/" rel="noopener noreferrer"&gt;the project's page&lt;/a&gt; and run it.&lt;/p&gt;
&lt;h4&gt;
  
  
  Flashing the USB stick
&lt;/h4&gt;

&lt;p&gt;In both cases, we will need to select the ISO image we want to flash and the device we want to use then click the &lt;strong&gt;Write&lt;/strong&gt; or &lt;strong&gt;Make startup disk&lt;/strong&gt; button. The process should complete within a few minutes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Booting Ubuntu
&lt;/h3&gt;

&lt;p&gt;Let's ask &lt;a href="https://chat.openai.com" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; how to do that:&lt;/p&gt;



![Booting from a USB stick](https://gitlab.com/cyril.marpaud/rust_esp_quickstart/-/raw/main/images/chatgpt_boot_from_usb.png "Booting from a USB stick")



&lt;p&gt;Thank you ChatGPT ! Finally, hit that &lt;strong&gt;Try Ubuntu&lt;/strong&gt; button to be greeted with a GNOME desktop.&lt;/p&gt;

&lt;p&gt;The next steps require internet access so connect to a Wi-Fi (see the top-right corner menu) or wired network if you want to go old-school.&lt;/p&gt;
&lt;h2&gt;
  
  
  The tools
&lt;/h2&gt;

&lt;p&gt;Here, we are going to make &lt;strong&gt;heavy&lt;/strong&gt; use of a terminal. On Ubuntu, you can open one by pressing &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;Alt&lt;/code&gt;+&lt;code&gt;T&lt;/code&gt;. You might want to copy/paste the following commands to avoid typos but suit yourself!&lt;/p&gt;
&lt;h3&gt;
  
  
  Build dependencies
&lt;/h3&gt;

&lt;p&gt;We need a few more packages than Ubuntu provides by default. Please bear with the trauma of installing them:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository &lt;span class="nt"&gt;--yes&lt;/span&gt; universe
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; clang curl git libudev-dev libssl-dev pkg-config python3-pip


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Rust and Cargo components
&lt;/h3&gt;

&lt;p&gt;We'll now use &lt;a href="https://rustup.rs" rel="noopener noreferrer"&gt;Rustup&lt;/a&gt; to install both &lt;a href="https://github.com/rust-lang/rust" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; and &lt;a href="https://github.com/rust-lang/cargo" rel="noopener noreferrer"&gt;Cargo&lt;/a&gt; (Rust's package manager):&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;--fail&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt; https://sh.rustup.rs | sh &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.cargo/env"&lt;/span&gt;
rustup toolchain &lt;span class="nb"&gt;install &lt;/span&gt;nightly &lt;span class="nt"&gt;--component&lt;/span&gt; rust-src


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Moreover, we need a few additional Cargo modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;espflash&lt;/code&gt; to flash the device (see &lt;a href="https://github.com/esp-rs/espflash" rel="noopener noreferrer"&gt;espflash&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ldproxy&lt;/code&gt; to forward linker arguments (see &lt;a href="https://github.com/esp-rs/embuild/tree/f2cbbf9795676af52d2ffb53f102d70cac25116a/ldproxy" rel="noopener noreferrer"&gt;ldproxy&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo-generate&lt;/code&gt; to generate projects according to a template (see &lt;a href="https://github.com/cargo-generate/cargo-generate" rel="noopener noreferrer"&gt;cargo-generate&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

cargo &lt;span class="nb"&gt;install &lt;/span&gt;espflash ldproxy cargo-generate


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Generating a project
&lt;/h2&gt;

&lt;p&gt;The awesome &lt;a href="https://github.com/esp-rs/esp-idf-template" rel="noopener noreferrer"&gt;ESP IDF Template&lt;/a&gt; will save us the pain of configuring a fully functional project ourselves, use it like so:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

cargo generate &lt;span class="nt"&gt;--git&lt;/span&gt; https://github.com/esp-rs/esp-idf-template cargo


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;During the process, you will be asked a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;Project Name&lt;/strong&gt;. Go wild and use &lt;strong&gt;test-project&lt;/strong&gt;, for instance&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;ESP-IDF native build version&lt;/strong&gt;. Go with the &lt;strong&gt;stable&lt;/strong&gt; one (it is &lt;strong&gt;v4.4&lt;/strong&gt; at the moment)&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;MCU&lt;/strong&gt;. Our board is equipped with an &lt;strong&gt;ESP32C3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;support for &lt;strong&gt;dev containers&lt;/strong&gt;. We don't need that for now so that's a &lt;strong&gt;false&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;STD support. We're building an std app so that's a &lt;strong&gt;true&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitlab.com%2Fcyril.marpaud%2Frust_esp_quickstart%2F-%2Fraw%2Fmain%2Fimages%2Fcargo_generate_answers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitlab.com%2Fcyril.marpaud%2Frust_esp_quickstart%2F-%2Fraw%2Fmain%2Fimages%2Fcargo_generate_answers.png" title="For those who feel like cheating" alt="Cargo generate answers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello, World!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Getting access to the USB peripheral
&lt;/h3&gt;

&lt;p&gt;You might like "Permission Denied" errors. If not, those commands will create a udev rule to avoid that when accessing our board through USB:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SUBSYSTEMS==&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;usb&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, ATTRS{idVendor}==&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;303a&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, ATTRS{idProduct}==&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;1001&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, MODE=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;0660&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, GROUP=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;plugdev&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/udev/rules.d/99-esp-rust-board.rules &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;sudo &lt;/span&gt;udevadm control &lt;span class="nt"&gt;--reload-rules&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;udevadm trigger


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Flash, run &amp;amp; monitor
&lt;/h3&gt;

&lt;p&gt;Now make use of that USB cable and connect the board to your computer, then run this simple yet elegant command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

cargo run


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If everything goes smoothly, Cargo should build the project, flash it on the MCU and finally run it, meaning that a line reading "Hello, World!" should be displayed in the terminal. Hit &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;R&lt;/code&gt; to restart the program (not very useful at that point but it might be later) or &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;C&lt;/code&gt; to quit monitoring it.&lt;/p&gt;

&lt;p&gt;Congratulations, you are officially programming Rust on your ESP board !&lt;/p&gt;

&lt;h2&gt;
  
  
  The IDE
&lt;/h2&gt;

&lt;p&gt;We could configure Vim, Emacs or any other terminal-based IDE, but the low-friction solution is to use Visual Studio Code with the appropriate extensions. This way, we are only a few clicks away from syntax highlighting, code completion and much more.&lt;/p&gt;

&lt;h3&gt;
  
  
  VSCodium
&lt;/h3&gt;

&lt;p&gt;It is the exact same as VSCode but without telemetry/tracking stuff, plus it uses MIT license (see &lt;a href="https://vscodium.com" rel="noopener noreferrer"&gt;the official website&lt;/a&gt;). Install and run it like so:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

snap &lt;span class="nb"&gt;install &lt;/span&gt;codium &lt;span class="nt"&gt;--classic&lt;/span&gt;
codium


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;An &lt;strong&gt;Open Folder&lt;/strong&gt; button should be visible in the explorer tab on the left. Click it to add our project to the workspace. We are now able to edit source code way more handily than in a terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extensions
&lt;/h3&gt;

&lt;p&gt;Go to the extensions tab and type "rust analyzer" in the search bar, then click the &lt;strong&gt;install&lt;/strong&gt; button ("Rust language support for Visual Studio Code"). That's it! You can find more information about it on the &lt;a href="https://rust-analyzer.github.io" rel="noopener noreferrer"&gt;official website&lt;/a&gt;. The &lt;a href="https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml" rel="noopener noreferrer"&gt;Even Better TOML&lt;/a&gt; and &lt;a href="https://marketplace.visualstudio.com/items?itemName=serayuzgur.crates" rel="noopener noreferrer"&gt;crates&lt;/a&gt; extensions might also be of interest to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://gitlab.com/cyril.marpaud/rust_esp_quickstart/-/tree/main/examples" rel="noopener noreferrer"&gt;examples folder&lt;/a&gt; of this repository contains three projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;blink&lt;/strong&gt;: makes the LED connected to GPIO7 blink&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;i2c-sensors&lt;/strong&gt;: read and display data from the embedded SHTC3 &amp;amp; ICM42670 I2C sensors (temperature, humidity, accelerometer &amp;amp; gyroscope)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wi-Fi&lt;/strong&gt;: very basic Wi-Fi connection + ping example, just uncomment and fill &lt;code&gt;WIFI_SSID&lt;/code&gt; and &lt;code&gt;WIFI_PWD&lt;/code&gt; environment variables at the bottom of &lt;code&gt;.cargo/config.toml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As a kid, I used to boot my sister's laptop from a live 8.04 "Hardy Heron" Ubuntu CD (you could order one for free back then!) to bypass her password protection. This way, no one ever knew what I was doing (meerely looking for cheat codes for the games I used to play at the time 😉️). Today, I still believe this technique is of great value to anyone wishing to try something out without breaking anything.&lt;/p&gt;

&lt;p&gt;Growing up, I then had the pleasure to learn how embedded development can sometimes be a pain: messy setup, weird and abstruse error messages... But hopefully, it has been less than an hour since you began reading this article and you are now able to use a modern language with &lt;code&gt;std&lt;/code&gt; support on a recent Wi-Fi-enabled microcontroller. Ain't that marvelous ?&lt;/p&gt;

&lt;p&gt;I hope you enjoyed it as much as I do, especially when considering the tremendous amount of work that was needed to make this so easy for us.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

&lt;h2&gt;
  
  
  See also (aka useful links)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rust-lang.org" rel="noopener noreferrer"&gt;The Rust Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/esp-rs/esp-rust-board" rel="noopener noreferrer"&gt;The Rust ESP Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/esp-rs" rel="noopener noreferrer"&gt;Espressif's Rust-related repos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Crates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/esp-rs/esp-rust-board-bsp" rel="noopener noreferrer"&gt;Board Support Package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/esp32c3-hal/latest/esp32c3_hal/" rel="noopener noreferrer"&gt;ESP32C3 &lt;code&gt;no_std&lt;/code&gt; Hardware Abstraction Layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://esp-rs.github.io/esp-idf-hal/esp_idf_hal/" rel="noopener noreferrer"&gt;ESP32C3 &lt;code&gt;std&lt;/code&gt; Hardware Abstraction Layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/esp-rs/esp-template" rel="noopener noreferrer"&gt;&lt;code&gt;esp-template&lt;/code&gt;: &lt;code&gt;no_std&lt;/code&gt; project template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/esp-rs/esp-idf-template" rel="noopener noreferrer"&gt;&lt;code&gt;esp-idf-template&lt;/code&gt;: &lt;code&gt;std&lt;/code&gt;-enabled project template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/embedded-svc/latest/embedded_svc/" rel="noopener noreferrer"&gt;&lt;code&gt;embedded-svc&lt;/code&gt;: service-related traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://esp-rs.github.io/esp-idf-svc/esp_idf_svc/" rel="noopener noreferrer"&gt;&lt;code&gt;esp-idf-svc&lt;/code&gt;: &lt;code&gt;embedded-svc&lt;/code&gt; implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/shared-bus/latest/shared_bus/" rel="noopener noreferrer"&gt;&lt;code&gt;shared-bus&lt;/code&gt;: share I2C/SPI/ADC buses between peripherals (namely: sensors)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/shtcx/latest/shtcx/" rel="noopener noreferrer"&gt;&lt;code&gt;shtcx&lt;/code&gt;: access the SHTC3 embedded temperature+humidity I2C sensor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/icm42670/latest/icm42670/" rel="noopener noreferrer"&gt;&lt;code&gt;icm42670&lt;/code&gt;: access the ICM42670 embedded temperature+accelerometer+gyroscope I2C sensor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ivmarkov/rust-esp32-std-demo" rel="noopener noreferrer"&gt;A complete STD demo on ESP32C3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wokwi.com/projects/357177745915181057" rel="noopener noreferrer"&gt;A Rust ESP Board simulator (simple &lt;code&gt;no_std&lt;/code&gt; blink project)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tutorials
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://esp-rs.github.io/book/" rel="noopener noreferrer"&gt;Rust on ESP book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://espressif-trainings.ferrous-systems.com" rel="noopener noreferrer"&gt;Embedded Rust on Espressif (Ferrous Systems training)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://betterprogramming.pub/rust-for-iot-is-it-time-67b14ab34b8" rel="noopener noreferrer"&gt;Another quickstart guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Whoami
&lt;/h2&gt;

&lt;p&gt;My name is &lt;a href="https://www.linkedin.com/in/cyrilmarpaud/" rel="noopener noreferrer"&gt;Cyril Marpaud, I'm an embedded systems freelance engineer and a Rust enthusiast 🦀&lt;/a&gt; I have nearly 10 years experience and am currently living in Lyon (France).&lt;/p&gt;

</description>
      <category>embedded</category>
      <category>rust</category>
      <category>esp32</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
