Inspiration:

In modern embedded systems and robotics, microcontrollers frequently need to synchronize state variables across distributed chips—such as an ESP32 handling telemetry and an STM32 managing real-time motor kinematics.

Traditional approaches force developers into bad trade-offs:

String-based serialization (JSON, XML, ASCII AT commands): Inflicts heavy CPU parsing overhead, bloats payload sizes, and relies on dynamic heap allocation (malloc/free), leading to inevitable heap fragmentation and random system crashes.

Complex industrial fieldbuses (Modbus RTU, CANopen): Introduce rigid frame constraints, high transmission overhead, and heavyweight software stacks that are overkill for lightweight, multi-MCU inter-chip communication.

We asked a fundamental question: Why translate raw binary memory into human-readable text strings just to send it over a serial wire?

We set out to build the BAVA Protocol (Bidirectional Asynchronous Versatile Architecture)—an $O(1)$ memory-deterministic, zero-allocation framing and storage engine that enables direct "variable teleportation" across microcontrollers with zero runtime heap allocation.

What it does

The BAVA Protocol is a lightweight, universal, transport-agnostic embedded communication and memory-routing layer. Rather than parsing text, BAVA establishes an Object Dictionary mapping logical hexadecimal keys directly to application memory pointers.

Key Capabilities:

Direct Variable Teleportation: Synchronizes raw variables directly into target memory locations via pointer dereferencing in $O(1)$ constant time.

Zero-Allocation Memory Model: Completely eliminates dynamic allocation. All buffers are statically bounded at compile time, guaranteeing $0$ bytes of heap fragmentation.

Universal Transport Agnostic: BAVA is purely a logical framing engine. Any byte stream entering via UART, SPI, $I^2C$, or WiFi can be fed into the protocol.

16-Bit CRC Hardware Integrity: Every frame is mathematically protected against electrical noise and corrupted bytes.

Here is how simple it is to decouple the protocol from the hardware transport layer:

// 1. Define your custom hardware transmission callback void my_uart_tx(uint8_t *data, uint16_t len) { uart_write_bytes(UART_NUM_1, data, len); }

// 2. Initialize the BAVA instance with your callback bava_init(&bava_node, my_uart_tx);

// 3. Feed incoming bytes from any bus directly into the state machine void on_uart_rx_interrupt(uint8_t incoming_byte) { bava_process_byte(&bava_node, incoming_byte); }

How we built it

We built BAVA from the ground up in modular, standard C99 to ensure native compilation across 8-bit, 16-bit, and 32-bit architectures without external dependencies.

State Machine & Stream Parser: Implemented an event-driven byte-by-byte finite state machine (FSM) that decodes synchronization preambles and CRC checksums on the fly.

Object Dictionary Engine: Created a compile-time indexed lookup table that binds variable addresses directly to unique IDs.

Empirical Benchmarking Testbed: Interfaced an ESP32 DevKit V1 with a bare-metal STM32F401 Black Pill over high-speed serial links. We ran continuous stress tests for over $40,000$ milliseconds.

Ecosystem Packaging: Packaged the library into standard distributions, structuring it for the ESP-IDF Component Registry and Arduino.

Challenges we ran into

Eliminating Race Conditions: Preventing "split reads" between high-frequency UART receive interrupts (ISRs) and user-space control loops required designing platform-specific locking abstractions that behave identically on dual-core FreeRTOS ESP32s and single-core bare-metal STM32s.

True Zero-Copy Memory Routing: Ensuring incoming byte streams could be directly dereferenced into application structs without intermediate ring buffer copies, while maintaining strict byte alignment across different compiler ABIs.

Accomplishments that we're proud of

We mathematically and empirically validated the protocol's efficiency. During a $40,000$ ms continuous stress test at $20\text{Hz}$, we achieved:

$$\text{Execution Latency} \approx 64.56 \, \mu\text{s}$$

$$\text{Dynamic Heap Consumption} = 0 \, \text{Bytes}$$

$$\text{Task Stack Footprint} = 96 \, \text{Bytes}$$

100% Signal Integrity: Achieved zero frame drops, zero CRC rejections, and zero UART break errors across our testing benchmarks.

Official Registry Acceptance: Successfully merged the BAVA Protocol into the official Arduino Library Registry, making it downloadable by millions of embedded developers globally.

What we learned

Building for embedded systems requires designing for the hardware first: software abstractions are only as good as their electrical timing and memory determinism.

The critical importance of memory layout: how compiler structure packing (attribute((packed))), endianness differences, and memory barriers impact cross-platform binary protocols.

How to navigate and satisfy the strict automated linting and indexing specifications of major developer package registries.

What's next for BAVA Protocol

Hardware Kinematics Testbed: Integrating BAVA across multi-axis robotic arms to validate real-time kinematic control loop synchronization under heavy electromagnetic noise.

DMA Acceleration: Implementing native hardware Direct Memory Access (DMA) support for STM32 and ESP32 to offload byte processing entirely from the CPU core.

Academic Publication: Publishing an IEEE-formatted research paper detailing the empirical benchmarks of BAVA compared to traditional IoT serial protocols.

Built With

  • arduino
  • c
  • embedded
  • esp32
  • espidf
  • protocol
  • stm32
Share this project:

Updates

Submission history