# 25\_rust\_on\_embedded\_systems

## 🦀 30 Days of Rust: Day 25 - Rust on Embedded Systems 🛠️

[![LinkedIn](https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn\&logo=linkedin\&style=social) ](https://www.linkedin.com/in/het-patel-8b110525a/?utm_source=share\&utm_campaign=share_via\&utm_content=profile\&utm_medium=android_app)[![Follow me on GitHub](https://img.shields.io/badge/Follow%20me%20on-GitHub-blue?style=flat-square\&logo=github)](https://github.com/Hunterdii)

***Author:*** [***Het Patel***](https://www.linkedin.com/in/het-patel-8b110525a/?utm_source=share\&utm_campaign=share_via\&utm_content=profile\&utm_medium=android_app)

October, 2024

[<< Day 24](https://hunterdii.gitbook.io/30-days-of-rust/24_integrating_with_c_c++/24_integrating_with_c_c++) | [Day 26 >>](https://hunterdii.gitbook.io/30-days-of-rust/26_rust-and-webassembly/26_rust_and_webassembly)

![30DaysOfRust](https://github.com/user-attachments/assets/a1083fb3-3eec-4d1e-b93a-fa4d7a99f180)

* [📘 Day 25 - Rust on Embedded Systems 🛠️](#-day-25---rust-on-embedded-systems-)
  * [👋 Welcome](#-welcome)
  * [🔍 What Are Embedded Systems?](#-what-are-embedded-systems)
  * [🤔 Why Rust for Embedded Systems?](#-why-rust-for-embedded-systems)
  * [🛠 Setting Up Your Environment](#-setting-up-your-environment)
    * [💻 Installing Rust](#-installing-rust)
    * [⚙️ Installing Cargo Tools](#-installing-cargo-tools)
    * [🛡️ Installing a Cross-Compiler](#-installing-a-cross-compiler)
    * [🔗 Setting Up OpenOCD (Optional)](#-setting-up-openocd-optional)
    * [🧰 Hardware Requirements](#-hardware-requirements)
  * [⚡ Writing Your First Embedded Program](#-writing-your-first-embedded-program)
    * [1. Blink an LED on a Microcontroller](#1-blink-an-led-on-a-microcontroller)
    * [2. Key Concepts](#2-key-concepts)
  * [🧰 Tools and Frameworks for Embedded Rust](#-tools-and-frameworks-for-embedded-rust)
  * [📊 Understanding Memory Management in Embedded Systems](#-understanding-memory-management-in-embedded-systems)
  * [🔗 Key Concepts in Embedded Rust](#-key-concepts-in-embedded-rust)
    * [🚀 `no_std` and `no_main`](#-no_std-and-no_main)
    * [📟 Hardware Peripherals](#-hardware-peripherals)
    * [⚡ Interrupts](#-interrupts)
  * [📦 Starting an Embedded Rust Project](#-starting-an-embedded-rust-project)
    * [🛠️ Create a New Project](#️-create-a-new-project)
    * [🛡️ Configure Your Target](#️-configure-your-target)
    * [🖋️ Write Your Firmware](#️-write-your-firmware)
    * [📤 Build and Flash](#-build-and-flash)
  * [🔄 Essential Tools and Crates](#-essential-tools-and-crates)
  * [💻 Example Project: Blinking an LED](#-example-project-blinking-an-led)
    * [🖊️ Writing the Firmware](#️-writing-the-firmware)
    * [🚀 Flashing the Firmware](#-flashing-the-firmware)
  * [🛡️ Debugging Tips](#-debugging-tips)
  * [🎯 Hands-On Challenge](#-hands-on-challenge)
  * [💻 Exercises - Day 25](#-exercises---day-25)
    * [✅ Exercise: Level 1](#-exercise-level-1)
    * [🚀 Exercise: Level 2](#-exercise-level-2)
    * [🏆 Exercise: Level 3 (Advanced)](#-exercise-level-3-advanced)
  * [🎥 Helpful Video References](#-helpful-video-references)
  * [📚 Further Reading](#-further-reading)
  * [📝 Day 25 Summary](#-day-25-summary)

***

## 📘 Day 25 - Rust on Embedded Systems 🛠

Welcome to **Day 25** of the **30 Days of Rust Challenge**! 🎉

Today, we step into the realm where software meets hardware: **embedded systems**. Whether it's blinking LEDs, managing sensors, or building IoT devices, Rust’s features make it a standout choice for embedded programming. With its focus on **safety**, **performance**, and **control**, Rust is redefining how we write firmware.

Let’s dive into the intricate and exciting world of **Rust for Embedded Systems**! 🚀

### 👋 Welcome

Welcome to **Day 25** of the **30 Days of Rust Challenge**! 🎉

Today, we’re diving into **Embedded Systems Development with Rust**, where Rust shines with its focus on:

* Safety in systems programming.
* Memory efficiency.
* Low-level control and concurrency.
* How to configure Rust for embedded development.
* Key concepts like `no_std`, interrupts, and peripherals.
* Building, flashing, and debugging firmware.

By the end of this lesson, you will:

* Set up a Rust environment for embedded systems development.
* Write a basic Rust program for a microcontroller.
* Learn tools and frameworks to streamline embedded development.

### 🔍 What Are Embedded Systems?

Embedded systems are computers designed for specific tasks, often integrated into larger systems. Unlike general-purpose computers, they operate under strict constraints: limited memory, real-time requirements, and low power consumption.

**Examples of Embedded Systems:**

* Home automation (e.g., smart thermostats 🌡️, light controls 💡).
* Automotive systems (e.g., ABS 🚗, engine control units).
* Consumer electronics (e.g., washing machines 🧺, smart TVs 📺).
* Robotics 🤖 and drones 🚁.

#### Common Characteristics of Embedded Systems

* **Real-Time Performance**: Must meet strict timing deadlines.
* **Resource Constraints**: Limited CPU, memory, and storage.
* **Direct Hardware Access**: Close interaction with peripherals like GPIO, ADC, and UART.

### 🤔 Why Rust for Embedded Systems?

Rust addresses many challenges in embedded development by offering:

| **Feature**                | **Rust**                                   | **C/C++**                    |
| -------------------------- | ------------------------------------------ | ---------------------------- |
| **Safety**                 | Memory safety by default, no null pointers | Manual memory management     |
| **Concurrency**            | Fearless concurrency with borrow checker   | Prone to data races          |
| **Zero-Cost Abstractions** | High-level features with no runtime cost   | Requires manual optimization |
| **Tooling**                | Cargo, Clippy, Rustfmt                     | Less standardized            |

Rust’s **ownership model** prevents common bugs like null pointer dereferences and data races, making it an excellent choice for writing secure firmware.

Embedded systems often have strict constraints on:

* **Memory usage**
* **Power consumption**
* **Real-time performance**

Rust is ideal for embedded systems because:

1. **Zero-cost abstractions** ensure minimal overhead.
2. **Safety features** like memory and concurrency safety help prevent bugs.
3. **No runtime** means Rust can run on bare metal.
4. **Modern tooling** enhances productivity.

### 🛠 Setting Up Your Environment

#### 💻 Installing Rust

Install Rust with the nightly toolchain, which is required for embedded development:

```bash
rustup install nightly
rustup default nightly
rustup target add thumbv7em-none-eabihf
```

### ⚙ Installing Cargo Tools

Install these essential tools for embedded Rust:

```bash
cargo install cargo-generate cargo-embed
```

### 🛡 Installing a Cross-Compiler

Install the `arm-none-eabi-gcc` cross-compiler:

* **Ubuntu**:

  ```bash
  sudo apt install gcc-arm-none-eabi
  ```
* **macOS**:

  ```bash
  brew install arm-none-eabi-gcc
  ```

#### 🔗 Setting Up OpenOCD (Optional)

Install OpenOCD for advanced debugging:

* **Ubuntu**:

  ```bash
  sudo apt install openocd
  ```
* **macOS**:

  ```bash
  brew install openocd
  ```

#### 🧰 Hardware Requirements

You’ll need:

* A **development board** (e.g., STM32, ESP32, Raspberry Pi Pico).
* A USB-to-serial programmer or built-in debugger.

### ⚡ Writing Your First Embedded Program

#### 1. **Blink an LED on a Microcontroller**

**Hardware Setup**

* Use an ARM Cortex-M-based microcontroller (e.g., STM32).
* Connect an LED to a GPIO pin.

**Rust Code**

Create a new project with the `--bin` flag:

```bash
cargo new led_blink --bin
cd led_blink
```

Modify `Cargo.toml`:

```toml
[dependencies]
cortex-m-rt = "0.7.3"
stm32f3xx-hal = "0.7.0"
panic-halt = "0.2.0"

[build-dependencies]
cc = "1.0"
```

Write the LED blinking program (`src/main.rs`):

```rust
#![no_std]
#![no_main]

use panic_halt as _; // Halt the program on panic
use cortex_m_rt::entry;
use stm32f3xx_hal::{
    prelude::*,
    pac,
};

#[entry]
fn main() -> ! {
    // Access the peripherals of the microcontroller
    let dp = pac::Peripherals::take().unwrap();
    
    let mut rcc = dp.RCC.constrain();
    let mut gpioc = dp.GPIOC.split(&mut rcc.ahb);
    
    let mut led = gpioc.pc13.into_push_pull_output();
    
    loop {
        led.set_high().unwrap();
        cortex_m::asm::delay(8_000_000); // Delay
        led.set_low().unwrap();
        cortex_m::asm::delay(8_000_000); // Delay
    }
}
```

#### 2. **Key Concepts**

1. **`no_std` and `no_main`**
   * `no_std`: Excludes Rust's standard library, as it requires an OS.
   * `no_main`: Provides custom entry points for bare-metal programs.
2. **Hardware Abstraction Layer (HAL)**
   * HAL crates like `stm32f3xx-hal` provide high-level abstractions for peripherals.
3. **Delay and GPIO Control**
   * Use `asm::delay` for precise timing.
   * Configure GPIO pins for output and control their states (`high` or `low`).
4. **Panic Handling**
   * Use `panic-halt` to halt execution on panic.

### 🧰 Tools and Frameworks for Embedded Rust

* **`cargo-embed`**: Tool for flashing and debugging embedded Rust programs.

  ```bash
  cargo install cargo-embed
  ```
* **`probe-rs`**: Multi-architecture debugging tool.
* **Real-Time Operating Systems (RTOS)**:
  * Integrate real-time kernels like `RTIC` or `FreeRTOS` with Rust for multitasking.
* **`rtt-target`**: Debug output over the SWD interface.

### 📊 Understanding Memory Management in Embedded Systems

Embedded systems often deal with limited memory:

1. **Static Memory Allocation**
   * Use global or stack-based variables.
2. **Heap Allocation**
   * Avoid unless necessary. Embedded environments have constrained dynamic memory.
3. **Interrupt Handlers**
   * Use interrupt handlers sparingly to avoid stack overflow.
4. **Memory Protection**
   * Rust’s borrow checker ensures no dangling pointers or data races.

### 🔗 Key Concepts in Embedded Rust

#### 🚀 `no_std` and `no_main`

Embedded Rust often operates without an OS, so it excludes the standard library using the **`no_std`** attribute.

**Example: Minimal `no_std` Application**

```rust
#![no_std]
#![no_main]

use panic_halt as _;

#[cortex_m_rt::entry]
fn main() -> ! {
    loop {
        // Your embedded logic
    }
}
```

#### 📟 Hardware Peripherals

Accessing peripherals like GPIO, UART, and I2C is fundamental in embedded systems. Rust uses **Hardware Abstraction Layer (HAL)** crates for this.

**Example: Controlling GPIO**

```rust
use stm32f4xx_hal::{pac, prelude::*};

#[cortex_m_rt::entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let gpioa = dp.GPIOA.split();
    let mut led = gpioa.pa5.into_push_pull_output();

    loop {
        led.set_high();
        cortex_m::asm::delay(1_000_000);
        led.set_low();
        cortex_m::asm::delay(1_000_000);
    }
}
```

#### ⚡ Interrupts

Interrupts handle hardware events asynchronously.

**Example: Handling an Interrupt**

```rust
#[interrupt]
fn TIM2() {
    // Handle Timer 2 interrupt
}
```

### 📦 Starting an Embedded Rust Project

#### 🛠️ Create a New Project

Use `cargo-generate` to scaffold a project:

```bash
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
```

#### 🛡️ Configure Your Target

Edit `.cargo/config.toml` to specify your target:

```toml
[build]
target = "thumbv7em-none-eabihf"
```

#### 🖋️ Write Your Firmware

Edit `src/main.rs` to add your embedded logic.

#### 📤 Build and Flash

Build and flash your firmware:

```bash
cargo build --release
cargo embed
```

### 🔄 Essential Tools and Crates

| **Tool/Crate**     | **Purpose**                                 |
| ------------------ | ------------------------------------------- |
| **`cortex-m`**     | Core support for Cortex-M processors.       |
| **`cortex-m-rt`**  | Runtime for ARM Cortex-M chips.             |
| **`embedded-hal`** | Abstractions for hardware peripherals.      |
| **`panic-halt`**   | Minimal panic handler for embedded systems. |
| **`probe-rs`**     | On-chip debugging and flashing.             |
| **`defmt`**        | Lightweight logging for embedded systems.   |

Here are some tools and crates that simplify embedded development with Rust:

* **`embedded-hal`**: A set of hardware abstraction interfaces for common peripherals like GPIO, UART, and I2C.
  * 🔗 [Documentation](https://docs.rs/embedded-hal)
* **`cortex-m-rtic`**: Enables real-time interrupt handling for ARM Cortex-M microcontrollers.
  * 🔗 [Documentation](https://docs.rs/cortex-m-rtic)
* **`probe-rs`**: A tool for flashing and debugging embedded systems.
  * 🔗 [Documentation](https://docs.rs/probe-rs)
* **`cortex-m`**: Provides low-level access to ARM Cortex-M microcontrollers.
  * 🔗 [Documentation](https://docs.rs/cortex-m)

### 💻 Example Project: Blinking an LED

Let’s implement a simple project to blink an LED on your microcontroller.

#### 🖊️ Writing the Firmware

Here’s the Rust code for blinking an LED:

```rust
#![no_std]
#![no_main]

use panic_halt as _; 
use cortex_m_rt::entry;
use stm32f4xx_hal::{pac, prelude::*};

#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let gpioc =

 dp.GPIOC.split();
    let mut led = gpioc.pc13.into_push_pull_output();

    loop {
        led.set_high();
        cortex_m::asm::delay(8_000_000);
        led.set_low();
        cortex_m::asm::delay(8_000_000);
    }
}
```

#### 🚀 Flashing the Firmware

```bash
cargo embed
```

To deploy the firmware to your device:

```bash
cargo run --release
```

Ensure the debugger or flashing tool is connected to the microcontroller.

### 🛡 Debugging Tips

Use **`probe-rs`** or **OpenOCD** for debugging.\
Debugging embedded systems can be challenging. Here are some tips:

* **Use Serial Output**: Print debug messages to the serial monitor for runtime inspection.
* **Check Connections**: Ensure your GPIO and power connections are secure.
* **Debugging Tools**: Use tools like `probe-rs` for flashing and debugging:

  ```bash
  probe-rs debug
  ```

### 🎯 Hands-On Challenge

#### Objective:

This hands-on challenge will guide you through using Rust for embedded systems development, specifically targeting microcontrollers. The focus will be on learning the basic steps to set up a Rust project for embedded systems, writing simple embedded code, and using debugging tools to test your code.

#### **Challenge 1: Setting Up Your Embedded Rust Project**

To get started, you'll first need to set up a basic Rust project that targets an embedded system. This will involve:

**Step 1: Install Rust and Required Toolchains**

1. **Install Rust**: Ensure you have Rust installed by running:

   ```bash
   rustup --version
   ```

   If it's not installed, download it from the [official website](https://www.rust-lang.org/tools/install).
2. **Install the `nightly` version of Rust** (required for embedded development):

   ```bash
   rustup install nightly
   rustup default nightly
   ```
3. **Install the target architecture for the embedded system**. If you're working with a common microcontroller like ARM Cortex-M, add the following target:

   ```bash
   rustup target add thumbv7em-none-eabihf
   ```

**Step 2: Create a New Project**

Now, create a new project using `cargo`:

```bash
cargo new --bin embedded_rust_project
cd embedded_rust_project
```

**Step 3: Update `Cargo.toml`**

In the `Cargo.toml` file, add the dependencies for embedded systems. For example, if you’re using the `cortex-m` and `cortex-m-rt` crates for ARM Cortex-M:

```toml
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
```

#### **Challenge 2: Writing Simple Embedded Code**

Now that your project is set up, let’s write a simple embedded program that toggles an LED (assuming your hardware supports it).

**Step 1: Write the Main Code**

Open the `src/main.rs` file, and add the code for blinking an LED. For this example, you can use the `cortex-m` crate to interact with GPIO pins.

Here’s an example of basic code that runs on a microcontroller and toggles an LED:

```rust
#![no_std]
#![no_main]

use cortex_m::prelude::*;
use cortex_m_rt::entry;
use stm32f4xx_hal as hal; // Example for STM32F4 series

#[entry]
fn main() -> ! {
    let dp = hal::pac::Peripherals::take().unwrap(); // Get the peripherals
    let rcc = dp.RCC.constrain(); // Clock control
    let gpioa = dp.GPIOA.split(); // GPIO port A

    let mut led = gpioa.pa5.into_push_pull_output(); // Set pin A5 as output (LED pin)

    loop {
        led.set_high().unwrap(); // Turn LED on
        cortex_m::asm::delay(8_000_000); // Delay for a while
        led.set_low().unwrap(); // Turn LED off
        cortex_m::asm::delay(8_000_000); // Delay for a while
    }
}
```

This code assumes you're working with an STM32F4 microcontroller, but the logic is similar across most microcontrollers: configure the GPIO, and toggle the LED on and off.

**Step 2: Build and Flash the Code**

1. **Build your code for the embedded target**:

   ```bash
   cargo build --release --target thumbv7em-none-eabihf
   ```
2. **Flash the firmware to your microcontroller** (depending on your setup, you may use tools like OpenOCD, STM32CubeProgrammer, etc.).

#### **Challenge 3: Debugging the Embedded System**

Debugging embedded systems can be challenging, especially without the right tools. Here’s how to approach debugging:

**Step 1: Use Debugging Tools**

1. **Use GDB for Debugging**:
   * Ensure you have GDB installed (you may need a version of GDB that supports your embedded system).
   * Use the following command to start GDB:

     ```bash
     gdb target/thumbv7em-none-eabihf/debug/embedded_rust_project
     ```
2. **Monitor Logs and Debug Output**:
   * You can use `probe-rs` (a Rust crate) for debugging and flashing embedded systems.
   * Run the following to install `probe-rs`:

     ```bash
     cargo install probe-rs-cli
     ```
   * Flash and debug the system:

     ```bash
     probe-rs flash --chip <your-chip> --verbose
     ```

#### **Challenge 4: Exploring Interrupts (Advanced)**

In this challenge, you’ll work with interrupts to handle events like external button presses.

1. **Set Up the Interrupt**: Configure the GPIO pin for an external button press (interrupt).
2. **Implement the Interrupt Handler**: Write the code to trigger an event (e.g., toggle the LED) when the button is pressed.

Here’s a simplified example of handling an interrupt:

```rust
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use stm32f4xx_hal::gpio::{Edge, Input, PullUp};
use stm32f4xx_hal::prelude::*;

#[entry]
fn main() -> ! {
    let dp = stm32f4xx_hal::pac::Peripherals::take().unwrap();
    let gpioa = dp.GPIOA.split();

    // Set PA0 as input for the button with pull-up resistor
    let mut button = gpioa.pa0.into_pull_up_input();

    // Enable interrupt on rising edge (button press)
    button.make_interrupt_source(&dp.SYSCFG);
    button.enable_interrupt(&dp.EXTI);
    NVIC::unmask(stm32f4xx_hal::pac::Interrupt::EXTI0);

    loop {
        // Wait for interrupt to trigger
        cortex_m::asm::wfi();
    }
}

#[interrupt]
fn EXTI0() {
    // Interrupt handler for button press
    // Toggle the LED or perform other actions
}
```

#### **Challenge 5: Further Exploration and Optimization**

After completing the basic setup and challenges, dive deeper by optimizing the system, exploring real-time operating systems (RTOS), or adding communication protocols like SPI or I2C.

### 💻 **Exercises - Day 25**

#### ✅ **Exercise: Level 1**

1. **Blink an LED**: Use `embedded-hal` to toggle GPIO pins on and off.
2. **Read Sensor Data**: Connect an I2C temperature sensor, such as the **DS3231**, and read temperature values.
3. **Use a Timer**: Implement a delay function using a microcontroller timer.

#### 🚀 **Exercise: Level 2**

1. **Interrupt Handling**:
   * Configure an interrupt for a button press using the `cortex-m-rtic` crate.
2. **Serial Communication**:
   * Transmit and receive data over UART and display debug information.
3. **PWM Control**:
   * Control the brightness of an LED using Pulse Width Modulation (PWM).

#### 🏆 **Exercise: Level 3 (Advanced)**

1. **Build a Sensor Network**:
   * Use SPI or I2C to communicate with multiple sensors and display data on an OLED screen.
2. **Real-Time Operating System (RTOS)**:
   * Use the `RTIC` framework to create a task scheduler for handling multiple concurrent tasks.
3. **Device Drivers**:
   * Write a Rust driver for a specific sensor or actuator, such as a DHT22 temperature and humidity sensor.

### 🎥 **Helpful Video References**

1. [Getting Started with Embedded Rust](https://youtube.com/playlist?list=PLL2SCPK5xSRWBPj-nKOVYIhxRw7C4kYeI\&si=pcHStvCh9y8OcNhE)
2. [Rust for Embedded Developers](https://www.youtube.com/watch?v=TOAynddiu5M)

### 📚 **Further Reading**

| **Topic**                    | **Resource**                                                                            |
| ---------------------------- | --------------------------------------------------------------------------------------- |
| **Embedded Rust Guide**      | [Embedded Rust Book](https://docs.rust-embedded.org/discovery/)                         |
| **Peripheral Access Crates** | [Awesome Embedded Rust](https://github.com/rust-embedded/awesome-embedded-rust)         |
| **Using `no_std`**           | [Rust no\_std Guide](https://docs.rust-lang.org/stable/embedded-book/intro/no-std.html) |
| **Hardware Abstraction**     | [embedded-hal Documentation](https://docs.rs/embedded-hal/latest/embedded_hal/)         |
| **Flashing and Debugging**   | [probe-rs Guide](https://probe.rs/)                                                     |

### 📝 **Day 25 Summary**

Today, we explored the exciting world of **Embedded Systems with Rust**. Here's what we covered:

* **Key Concepts**: `no_std`, `no_main`, GPIO, and interrupt handling.
* **Real Hardware Interfacing**: Blinking LEDs, reading sensors, and using timers.
* **Advanced Topics**: PWM control, RTOS basics, and creating device drivers.
* **Challenges**: Building real-world applications using embedded-hal and RTIC.

Embedded Rust is a game-changer for building safe, efficient, and low-level systems. Practice the hands-on challenges to solidify your understanding.

You’ve unlocked a powerful domain with Rust! Continue experimenting and building!

Today, we learned how to develop embedded systems using Rust. We set up our development environment, explored key libraries like `embedded-hal` and `cortex-m`, and wrote our first embedded application to blink an LED. Rust is a powerful tool for embedded programming, offering memory safety and performance while allowing low-level control over hardware.

#### Why Rust for Embedded Systems?

Rust's **memory safety**, **zero-cost abstractions**, and **powerful concurrency features** make it a perfect fit for embedded development. With today's exercises, you're now equipped to start building reliable and high-performance firmware for microcontrollers.

As always, keep exploring and **happy coding!** 🚀

Stay tuned for **Day 26**, where we will explore **Rust and WebAssembly** in Rust! 🚀

🌟 *Great job on completing Day 25! Keep practicing, and get ready for Day 26!*

Thank you for joining **Day 25** of the 30 Days of Rust challenge! If you found this helpful, don’t forget to ![Star GIF](https://github.com/user-attachments/assets/35f6838c-52f5-4e48-8a98-c5203f8c57e3) star this repository, share it with your friends, and stay tuned for more exciting lessons ahead!

**Stay Connected**\
📧 **Email**: [Hunterdii](mailto:hunterdii9879@gmail.com)\
🐦 **Twitter**: [@HetPate94938685](https://twitter.com/HetPate94938685)\
🌐 **Website**: [Working On It(Temporary)](https://hunterdii.github.io/Portfolio-Temporary/)

[<< Day 24](https://hunterdii.gitbook.io/30-days-of-rust/24_integrating_with_c_c++/24_integrating_with_c_c++) | [Day 26 >>](https://hunterdii.gitbook.io/30-days-of-rust/26_rust-and-webassembly/26_rust_and_webassembly)

***
