---
title: Rust Code
description: A reference page in my new Starlight docs site.
hero:
  title: "Seeed XIAO nRF52840 with Rust"
  tagline: Blazingly fast on-device inference.
  image:
    alt: A glittering, brightly colored logo
    file: ../../../assets/ferris_embedded.webp
---

import { Steps, Tabs, TabItem } from "@astrojs/starlight/components";

The analysis of the acceleration and rotation data on-device requires us to run a TinyML model on the microcontroller in an efficient manner.
TinyGo unfortunately does not have any support for running TinyML models at the moment
and we had to switch to Rust.

## Why Rust?

The decision to adopt Rust was driven by several key factors,
particularly its suitability for resource-constrained embedded environments.

- **[MicroFlow](https://github.com/matteocarnelos/microflow-rs) integration**: Developed by Matteo Carnelos, MicroFlow excels in deploying machine learning models on embedded systems. Its compiler-based architecture, consisting of the microflow-macros and microflow crates, allows for efficient model parsing, preprocessing, and runtime execution.
- **[Embassy](https://embassy.dev) for Asynchronous Programming**: Rust's embassy framework provided us with a robust and user-friendly solution for asynchronous programming. This was essential for managing concurrent tasks and optimizing performance on the microcontroller. Embassy greatly simplifies the development of responsive and efficient embedded applications.
- **Performance and Memory Efficiency**: Rust's focus on performance and memory safety aligns perfectly with the requirements of TinyML. Its zero-cost abstractions and control over memory management enable us to optimize our model execution for minimal resource consumption.
- **Memory Safety**: In embedded systems, memory errors can lead to unpredictable behavior and system crashes. Rust's strong memory safety guarantees, enforced at compile time, prevent common errors like buffer overflows, dangling pointers, and data races. This is crucial for ensuring the reliability and stability of our on-device TinyML implementation.

## Rust Support for the Xiao Seeed BLE

There was no full implementation for the Xiao Seeed BLE microcontroller available anywhere online in Rust. The embassy library has support for the `nrf52840` SoC, but we
had to write custom drivers to access the acceleration and rotation data from the `lsm6ds3tr` IMU.

These driver are available [here](https://avoid.sh/PetActivityMonitor/lsm6ds3tr).

## Usage

<Steps>

1. Get the Rust project files:

   ```bash
   git clone https://avoid.sh/PetActivityMonitor/xiao_pet_tracker_rust.git
   ```

   The project contains multiple Rust projects separated into folders.

1. The project contains a `build_and_flash.sh` script to easily build the project and flash it to the microcontroller. Put the microcontroller into DFU mode and run the script with the folder name of the project as secondary parameter.

   ```bash
   # flash the lsm6ds3tr demo
   ./build_and_flash.sh lsm6ds3tr_demo
   # flash the tflite demo
   ./build_and_flash.sh tflite_demo
   ```

   Make sure to edit the `COM_PORT` variable accordingly to your connected controller. You can use `tinygo ports` from the commandline to check the ports.

</Steps>

## Issues

After flashing the microcontroller with the Rust project, the DFU mode can only be entered manually by clicking the reset button twice in a short time. It is currently not possible to send a signal to the device to enter the DFU mode.
