Skip to content

darkcodi/pcobs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📦 pcobs

postcard + crc + cobs = structured data over anything

Crates.io Documentation Rust no_std zero-alloc

no_std • zero-allocation • embedded-ready


💡 Why?

You've got structs. You need to send them over UART/TCP/USB/whatever.

pcobs gives you:

  • 📝 postcard — compact serde serialization, no_std friendly
  • 🔐 CRC-16 — catch corrupted packets
  • 🧱 COBS framing — zero-byte delimiters, no escaping hell
  • 💾 Zero allocations — stack-only, no Vec/Box/HashMap
  • no_std — works on bare-metal, no OS required

Two functions. That's it.

let len = serialize(&my_struct, &mut buf)?;
let my_struct = deserialize::<MyStruct>(&mut buf, len)?;

🚀 Quick Start

[dependencies]
pcobs = "1"
serde = { version = "1", features = ["derive"] }
use pcobs::{serialize, deserialize};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct SensorData {
    id: u8,
    value: f32,
    flags: u16,
}

// Sender
let data = SensorData { id: 1, value: 23.5, flags: 0xABCD };
let mut buf = [0u8; 256];
let len = serialize(&data, &mut buf)?;
stream.write_all(&buf[..len])?;
stream.write_all(&[0x00])?; // COBS delimiter

// Receiver
let mut buf = [0u8; 256];
let n = read_until_delimiter(stream, &mut buf)?;
let decoded: SensorData = deserialize(&mut buf, n)?;

📐 Packet Format

┌────────────────────────────────────────┬──────┐
│ Payload                     │ CRC-16   │ 0x00 │
│ postcard(your data)         │ checksum │      │
│────────────────────────────────────────│      │
│ COBS frame                             │ delim│
│ no zeros in encoded data               │      │
└────────────────────────────────────────┴──────┘

Steps:

  1. Serialize your struct with postcard
  2. Append CRC-16 checksum (2 bytes)
  3. COBS-encode the whole thing
  4. Send over your transport, appending a 0x00 delimiter

📏 Buffer Math

Encoding is done in-place - no buffer splitting needed. COBS adds minimal overhead (at most 1 byte per 254 bytes), plus 2 bytes for CRC.

Buffer Max Payload
64 B ~60 B
256 B ~252 B
512 B ~508 B
1024 B ~1018 B

🛠️ Transport Agnostic

Works over anything that moves bytes:

  • 📡 UART / Serial
  • 🌐 TCP sockets
  • 🔌 USB bulk endpoints
  • 📻 Radio (LoRa, BLE, etc.)
  • 🧪 Pipes / files for testing

⚡ Features

  • no_std — works on bare-metal, no OS required
  • Zero allocations — stack-only, no heap, embedded-friendly
  • serde — derive your structs
  • Single-pass encoding
  • In-place decoding

About

Binary encoding for structured data communication

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages