Skip to content

Embedded Protocols

Overview

Low-level hardware communication protocols for embedded systems and SoC peripherals. All modules use Linux device interfaces (/dev/tty*, /dev/spidev*, /dev/i2c-*, SocketCAN, /dev/gpiochip*) with zero dynamic allocation and deterministic timing.

┌─────────────────────────────────────────────────────────────────────┐
│                         Application                                  │
├──────────┬──────────┬──────────┬──────────┬──────────────────────────┤
│   UART   │   SPI    │   I2C    │   CAN    │         GPIO            │
│ (termios)│ (spidev) │(i2c-dev) │(SocketCAN)│      (chardev)         │
├──────────┼──────────┼──────────┼──────────┼──────────────────────────┤
│/dev/ttyS*│/dev/spi* │/dev/i2c-*│  vcan0   │    /dev/gpiochip0       │
├──────────┴──────────┴──────────┴──────────┴──────────────────────────┤
│                    Linux Kernel Subsystems                            │
├─────────────────────────────────────────────────────────────────────┤
│                      Hardware / SoC                                   │
└─────────────────────────────────────────────────────────────────────┘

Modules

Module Status Interface Max Speed Topology
UART ✅ Implemented termios 4 Mbaud Point-to-point
SPI ✅ Implemented spidev ioctl 50+ MHz Master + N slaves
I2C ✅ Implemented i2c-dev ioctl 3.4 MHz Multi-master bus
CAN ✅ Implemented SocketCAN 8 Mbps (FD) Multi-master bus
GPIO ✅ Implemented chardev ioctl N/A Per-pin digital I/O

Comparison

Feature UART SPI I2C CAN
Wires 2 (TX/RX) 4 (SCLK/MOSI/MISO/CS) 2 (SDA/SCL) 2 (CANH/CANL)
Duplex Full Full Half Half
Clock Async (baud) Master-driven Master-driven Async (bit-timing)
Addressing None CS per slave 7/10-bit address 11/29-bit CAN ID
Error detection Parity None (app-level) ACK/NACK CRC + error frames
Bus length ~15m (RS-232) < 1m < 1m (std) ~40m (1 Mbps)
Multi-master No No Yes Yes

Design Principles

  1. Header-only implementation Single .h file with static inline functions for zero-cost abstraction
  2. No dynamic allocation All state in caller-provided structs
  3. Raw device access Direct ioctl() calls, no middleware layers
  4. Testable without hardware Virtual devices (socat, vcan, spi-pipe) for CI/CD
  5. poll()-compatible All FDs integrate with the epoll reactor

Quick Start

# Build all embedded modules
for dir in uart spi i2c can gpio; do
    make -C src/embedded/$dir
done

# Create virtual test interfaces
socat -d -d pty,raw,echo=0 pty,raw,echo=0 &   # UART loopback
sudo ip link add dev vcan0 type vcan            # Virtual CAN
sudo ip link set up vcan0

Hardware Setup Notes

# Enable SPI
sudo raspi-config nonint do_spi 0
# Enable I2C
sudo raspi-config nonint do_i2c 0
# UART is on /dev/ttyAMA0 or /dev/serial0
# Load SPI overlay
echo BB-SPIDEV0 > /sys/devices/platform/bone_capemgr/slots
# CAN on DCAN1
sudo ip link set can1 type can bitrate 500000
sudo ip link set up can1
# Virtual UART pair
socat -d -d pty,raw,echo=0 pty,raw,echo=0
# Virtual CAN
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0