Skip to content

mtassone1/bbb-linux-platform-driver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🦴 BeagleBone Black β€” MPU6050 I2C Linux Driver & Filtered Data Server

A full-stack embedded Linux project: custom I2C kernel driver for the MPU6050 IMU, a multithreaded C server with a FIR low-pass filter, and a Python client β€” all running on the BeagleBone Black.

Language: C Python Platform Kernel Sensor IPC


πŸ“– Table of Contents


About

This project implements a complete embedded Linux data acquisition pipeline on the BeagleBone Black (BBB):

  1. A custom Linux I2C kernel driver (td3_i2c_dev) reads raw motion data from an MPU6050 6-axis IMU (gyroscope + accelerometer) over the I2C bus.
  2. A multithreaded C server (server_thread_2) reads from the driver, applies a FIR low-pass filter to clean the sensor signal, and exposes the data over a Unix socket.
  3. A Python client (cliente_2.py) connects to the socket and consumes the processed IMU data.

This project demonstrates skills across the full embedded Linux stack: kernel module development, device tree configuration, digital signal processing, multithreaded systems programming, and IPC.


Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     User Space                       β”‚
β”‚                                                      β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      Unix Socket               β”‚
β”‚   β”‚  cliente_2.py   │◀────────────────────────┐      β”‚
β”‚   β”‚  (Python client)β”‚                         β”‚      β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                         β”‚      β”‚
β”‚                                               β”‚      β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”   β”‚
β”‚   β”‚          server_thread_2  (C server)         β”‚   β”‚
β”‚   β”‚                                              β”‚   β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚
β”‚   β”‚   β”‚  I2C read    │───▢│  FIR Low-Pass     β”‚  β”‚   β”‚
β”‚   β”‚   β”‚  thread      β”‚    β”‚  Filter           β”‚  β”‚   β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚              β”‚  /dev/td3_i2c_dev    β”‚                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚              β”‚    Kernel Space      β”‚                 β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚   β”‚       td3_i2c_dev.ko  (I2C kernel driver)  β”‚      β”‚
β”‚   β”‚       Linux I2C subsystem                  β”‚      β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                          β”‚ I2C Bus (i2c-1)             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ ─
β”‚                Hardware  β”‚                             β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚              β”‚  MPU6050 IMU         β”‚                  β”‚
β”‚              β”‚  Gyro + Accelerometerβ”‚                  β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

beaglebone/
β”œβ”€β”€ client/
β”‚   └── cliente_2.py              # Python Unix socket client
β”‚
β”œβ”€β”€ deviceTree/
β”‚   β”œβ”€β”€ am335x-temp.dts           # Device Tree Source overlay
β”‚   β”œβ”€β”€ am335x-boneblack-td3.dtb  # Compiled DT blob (td3 variant)
β”‚   └── am335x-boneblack.dtb      # Compiled DT blob (base)
β”‚
β”œβ”€β”€ platformDriver/
β”‚   β”œβ”€β”€ Makefile                  # Kernel build system integration
β”‚   β”œβ”€β”€ inc/
β”‚   β”‚   β”œβ”€β”€ BBB_I2C_REG.h         # BeagleBone Black I2C register map
β”‚   β”‚   └── MPU6050_REG.h         # MPU6050 register definitions
β”‚   └── src/
β”‚       β”œβ”€β”€ td3_i2c_dev.c         # Kernel module β€” main driver source
β”‚       β”œβ”€β”€ td3_i2c_dev.h         # Driver header
β”‚       └── td3_i2c_dev.ko        # Compiled kernel object (built output)
β”‚
└── server/
    β”œβ”€β”€ Makefile                  # Server build file
    β”œβ”€β”€ config.ini                # Runtime configuration
    β”œβ”€β”€ FIR_LPF.csv               # FIR low-pass filter coefficients
    β”œβ”€β”€ inc/
    β”‚   β”œβ”€β”€ servidor.h            # Server header
    β”‚   └── FIR_filter.h          # FIR filter header
    └── src/
        β”œβ”€β”€ server_thread_2.c     # Multithreaded server β€” main source
        └── FIR_filter.c          # FIR filter implementation

Technologies Used

Technology Role
C Kernel module, multithreaded server, FIR filter
Python 3 Unix socket client
Linux I2C Subsystem Kernel-level sensor communication
MPU6050 IMU 6-axis gyroscope + accelerometer sensor
Device Tree Source (.dts) Hardware description for I2C bus and MPU6050 node
FIR Low-Pass Filter Digital signal processing on raw IMU data
Unix Domain Sockets IPC between C server and Python client
POSIX Threads (pthreads) Multithreaded server architecture
Makefile Build automation for kernel module and server
BeagleBone Black Target hardware β€” ARM Cortex-A8, AM335x SoC

Prerequisites

  • BeagleBone Black running Debian Linux (kernel 4.14+)
  • Linux kernel headers matching the target kernel:
    sudo apt install linux-headers-$(uname -r)
  • Cross-compilation toolchain (for building off-board):
    sudo apt install gcc-arm-linux-gnueabihf
  • Device Tree Compiler:
    sudo apt install device-tree-compiler
  • Python 3 on the BeagleBone:
    sudo apt install python3
  • MPU6050 wired to the BBB I2C-1 bus (pins P9_19 / P9_20)

Installation

1. Clone the repository

git clone https://github.com/mtassone1/beaglebone.git
cd beaglebone

2. Apply the Device Tree Overlay

The custom .dtb configures the I2C bus and registers the MPU6050 device node. Copy it to the boot partition:

sudo cp deviceTree/am335x-boneblack-td3.dtb /boot/dtbs/$(uname -r)/

Update /boot/uEnv.txt to load the overlay:

dtb=am335x-boneblack-td3.dtb

Reboot for the device tree to take effect:

sudo reboot

3. Build and Insert the Kernel Module

cd platformDriver
make
sudo insmod src/td3_i2c_dev.ko

Verify the driver loaded and the MPU6050 was detected:

dmesg | tail -20
ls /dev/td3*

4. Build and Start the Server

cd server
make
./bin/server_thread_2

The server reads raw I2C data from the driver, applies the FIR low-pass filter, and listens on a Unix socket for client connections.


Usage

With the driver loaded and the server running, launch the Python client:

python3 client/cliente_2.py

The client connects to the Unix socket and streams filtered IMU data (accelerometer X/Y/Z + gyroscope X/Y/Z) in real time.

To unload the kernel module when done:

sudo rmmod td3_i2c_dev
dmesg | tail -5   # Confirm clean removal

Device Tree Configuration

The deviceTree/am335x-temp.dts overlay registers the MPU6050 as an I2C client device on the BeagleBone Black's I2C-1 bus. The key device node:

&i2c1 {
    status = "okay";
    mpu6050@68 {
        compatible = "td3,mpu6050";
        reg = <0x68>;   /* MPU6050 default I2C address */
    };
};

The compiled .dtb files are included in the repo and ready to use. To recompile from the .dts source:

cd deviceTree
dtc -O dtb -o am335x-boneblack-td3.dtb -b 0 -@ am335x-temp.dts

Platform Driver Details

td3_i2c_dev is a Linux kernel module that integrates with the I2C subsystem to drive the MPU6050:

  • Registers via i2c_add_driver() and matches devices using compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx", "td3_i2c_dev";
  • On probe: wakes the MPU6050 from sleep, configures the sample rate and built-in digital low-pass filter
  • Creates a character device at /dev/td3_i2c_dev
  • Implements read() to deliver raw accelerometer and gyroscope register bytes to user space

Key header files:

File Contents
inc/MPU6050_REG.h Register map: PWR_MGMT_1, SMPLRT_DIV, ACCEL_XOUT_H, GYRO_XOUT_H, etc.
inc/BBB_I2C_REG.h BeagleBone Black I2C controller base addresses and configuration

Signal Processing β€” FIR Low-Pass Filter

Raw MPU6050 readings contain high-frequency noise. The server applies a FIR (Finite Impulse Response) low-pass filter to each axis before forwarding data to the client.

  • Filter coefficients are loaded at runtime from server/FIR_LPF.csv β€” the cutoff frequency can be retuned by replacing this file without recompiling
  • Implementation lives in server/src/FIR_filter.c / server/inc/FIR_filter.h

The per-axis pipeline:

Raw ADC sample β†’ FIR convolution (FIR_LPF.csv coefficients) β†’ Filtered sample β†’ Unix socket

Client-Server Communication

The server and client communicate over a Unix domain socket for low-latency, zero-overhead local IPC on the BeagleBone:

  • server_thread_2 creates the socket, accepts connections, and streams filtered IMU structs
  • cliente_2.py connects and deserializes the binary data (via Python's struct.unpack)

Full data path:

MPU6050 ──I2C──▢ td3_i2c_dev.ko ──/dev/──▢ server_thread_2 ──FIR──▢ Unix socket ──▢ cliente_2.py
  (HW)           (kernel driver)           (C, threaded)    (DSP)      (IPC)         (Python)

About

Custom Linux platform driver + device tree overlay + client-server interface for the BeagleBone Black.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors