2 stable releases
| 2.0.1 | Dec 23, 2025 |
|---|---|
| 2.0.0 | Dec 4, 2025 |
#119 in Hardware support
185KB
3.5K
SLoC
BNO08x IMU Driver
Rust userspace driver for the BNO08x family of 9-axis Inertial Measurement Units (IMUs) with sensor fusion.
Overview
The BNO08x is a System-in-Package (SiP) that integrates a triaxial 14-bit accelerometer, a triaxial 16-bit gyroscope, a triaxial geomagnetic sensor, and a 32-bit microcontroller running SHTP (Sensor Hub Transport Protocol) firmware for sensor fusion. This library provides a safe Rust interface for communicating with the sensor over SPI and GPIO.
Features
- SPI communication with GPIO interrupt and reset control
- Sensor fusion quaternion output (rotation vectors: absolute, game, geomagnetic)
- Raw sensor data access (accelerometer, gyroscope, magnetometer)
- Linear acceleration and gravity vectors
- Configurable report rates (1 Hz to 1 kHz)
- Flash Record System (FRS) for sensor orientation configuration
- Callback-based sensor event handling
- Portable GPIO configuration via device tree symbolic names
Requirements
- Rust 1.90 or later
- Linux with SPI (
spidev) and GPIO (gpiod) support - BNO08x sensor connected via SPI with GPIO for interrupt (HINTN) and reset (RSTN)
Hardware Setup
The driver requires three connections to the BNO08x:
| Signal | Type | Description |
|---|---|---|
| SPI | Bus | Data communication (MOSI, MISO, SCLK, CS) |
| HINTN | GPIO Input | Hardware interrupt - sensor signals data ready |
| RSTN | GPIO Output | Reset control - toggle low to reset sensor |
Installation
Add to your Cargo.toml:
[dependencies]
bno08x-rs = "2.0"
Or clone and build from source:
git clone https://github.com/EdgeFirstAI/bno08x-rs.git
cd bno08x-rs
cargo build --release
Quick Start
On Maivin Hardware
The Maivin platform has pre-configured device tree settings for the IMU:
# Run the demo example
cargo run --example demo --release
# Or use as a library in your application
Library Usage
use bno08x_rs::{BNO08x, SENSOR_REPORTID_ROTATION_VECTOR, SENSOR_REPORTID_ACCELEROMETER};
use bno08x_rs::interface::delay::delay_ms;
fn main() -> std::io::Result<()> {
// Create driver using GPIO symbolic names (recommended)
let mut imu = BNO08x::new_spi_from_symbol(
"/dev/spidev1.0", // SPI device
"IMU_INT", // Interrupt GPIO name
"IMU_RST", // Reset GPIO name
)?;
// Initialize the sensor
imu.init().expect("Failed to initialize IMU");
// Enable sensor reports with update intervals (milliseconds)
imu.enable_report(SENSOR_REPORTID_ROTATION_VECTOR, 100)?; // 10 Hz
imu.enable_report(SENSOR_REPORTID_ACCELEROMETER, 50)?; // 20 Hz
// Main loop
loop {
// Process incoming sensor messages
imu.handle_messages(10, 20); // 10ms timeout, max 20 messages
// Read sensor data
let [qi, qj, qk, qr] = imu.rotation_quaternion()?;
let [ax, ay, az] = imu.accelerometer()?;
println!("Quaternion: [{:.3}, {:.3}, {:.3}, {:.3}]", qi, qj, qk, qr);
println!("Accel: [{:.3}, {:.3}, {:.3}] m/s²", ax, ay, az);
delay_ms(50);
}
}
Using Callbacks
use bno08x_rs::{BNO08x, SENSOR_REPORTID_ROTATION_VECTOR};
let mut imu = BNO08x::new_spi_from_symbol("/dev/spidev1.0", "IMU_INT", "IMU_RST")?;
imu.init()?;
imu.enable_report(SENSOR_REPORTID_ROTATION_VECTOR, 100)?;
// Register callback for rotation vector updates
imu.add_sensor_report_callback(
SENSOR_REPORTID_ROTATION_VECTOR,
"my_handler".to_string(),
|imu| {
let quat = imu.rotation_quaternion().unwrap();
println!("Quaternion: {:?}", quat);
},
);
loop {
imu.handle_messages(10, 20); // Callbacks invoked automatically
}
Alternative: Explicit GPIO Pins
If your platform doesn't have named GPIO lines, specify chip and pin numbers directly:
let mut imu = BNO08x::new_spi(
"/dev/spidev1.0",
"/dev/gpiochip4", 31, // HINTN: chip 4, pin 31
"/dev/gpiochip5", 1, // RSTN: chip 5, pin 1
)?;
Testing
Unit Tests
Run the unit tests (no hardware required):
cargo test
Hardware Integration Tests
Integration tests require a physical BNO08x sensor and are marked with #[ignore]. Run them on target hardware:
# Run all hardware tests (single-threaded to avoid SPI conflicts)
RUST_LOG=debug cargo test -- --ignored --test-threads=1
# Run a specific test
RUST_LOG=debug cargo test test_accelerometer -- --ignored
Testing on Maivin
The Maivin platform comes pre-configured with the correct device tree settings. Simply run:
cargo test -- --ignored --test-threads=1
The tests use these default settings:
- SPI device:
/dev/spidev1.0 - Interrupt GPIO:
IMU_INT - Reset GPIO:
IMU_RST
Testing on Custom Hardware
For custom hardware platforms, you need to:
-
Connect the BNO08x sensor via SPI with HINTN and RSTN GPIO lines
-
Configure the Linux device tree with
gpio-line-namesfor your GPIO controllers -
Verify GPIO names are accessible:
gpioinfo | grep -E "IMU_INT|IMU_RST" -
Update test constants in
tests/hardware_integration.rsif using different names:const TEST_SPI_DEVICE: &str = "/dev/spidev1.0"; const TEST_INT_GPIO: &str = "IMU_INT"; const TEST_RST_GPIO: &str = "IMU_RST";
See ARCHITECTURE.md for detailed GPIO configuration guidance.
Running the Demo
The included example demonstrates all sensor features:
cargo run --example demo --release
Output:
Report 5 is enabled
Report 1 is enabled
Report 2 is enabled
Report 3 is enabled
loop_interval: 50
Attitude [degrees]: yaw=45.123, pitch=2.456, roll=-0.789, accuracy=0.052
Accelerometer [m/s^2]: ax=0.123, ay=-0.456, az=9.789
Gyroscope [rad/s]: gx=0.001, gy=-0.002, gz=0.000
Magnetometer [uTesla]: mx=25.123, my=-12.456, mz=42.789
timestamp [ns]: 1234567890123456789
Documentation
API documentation is available on docs.rs.
To build documentation locally:
cargo doc --open
Contributing
See CONTRIBUTING.md for guidelines on contributing to this project.
Architecture
See ARCHITECTURE.md for detailed information about:
- Driver architecture and design decisions
- Protocol stack (SH-2 and SHTP)
- GPIO pin mapping and device tree configuration
- Module structure and dependencies
License
Copyright 2025 Au-Zone Technologies Inc.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Security
For security vulnerabilities, see SECURITY.md.
Related Projects
- Maivin Platform - EdgeFirst AI edge computing platform
- Maivin Overlays - Device tree overlays for Maivin hardware
- EdgeFirst Fusion - Multi-modal sensor fusion
- EdgeFirst Samples - Example applications
Dependencies
~2MB
~43K SLoC