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.
- About
- Architecture Overview
- Project Structure
- Technologies Used
- Prerequisites
- Installation
- Usage
- Device Tree Configuration
- Platform Driver Details
- Signal Processing β FIR Low-Pass Filter
- Client-Server Communication
This project implements a complete embedded Linux data acquisition pipeline on the BeagleBone Black (BBB):
- 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. - 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. - 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.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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β β
β ββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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
| 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 |
- 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)
git clone https://github.com/mtassone1/beaglebone.git
cd beagleboneThe 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.dtbReboot for the device tree to take effect:
sudo rebootcd platformDriver
make
sudo insmod src/td3_i2c_dev.koVerify the driver loaded and the MPU6050 was detected:
dmesg | tail -20
ls /dev/td3*cd server
make
./bin/server_thread_2The server reads raw I2C data from the driver, applies the FIR low-pass filter, and listens on a Unix socket for client connections.
With the driver loaded and the server running, launch the Python client:
python3 client/cliente_2.pyThe 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 removalThe 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.dtstd3_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 usingcompatible = "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 |
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
The server and client communicate over a Unix domain socket for low-latency, zero-overhead local IPC on the BeagleBone:
server_thread_2creates the socket, accepts connections, and streams filtered IMU structscliente_2.pyconnects and deserializes the binary data (via Python'sstruct.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)