postcard + crc + cobs = structured data over anything
no_std • zero-allocation • embedded-ready
You've got structs. You need to send them over UART/TCP/USB/whatever.
pcobs gives you:
- 📝 postcard — compact serde serialization,
no_stdfriendly - 🔐 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)?;[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)?;┌────────────────────────────────────────┬──────┐
│ Payload │ CRC-16 │ 0x00 │
│ postcard(your data) │ checksum │ │
│────────────────────────────────────────│ │
│ COBS frame │ delim│
│ no zeros in encoded data │ │
└────────────────────────────────────────┴──────┘
Steps:
- Serialize your struct with postcard
- Append CRC-16 checksum (2 bytes)
- COBS-encode the whole thing
- Send over your transport, appending a 0x00 delimiter
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 |
Works over anything that moves bytes:
- 📡 UART / Serial
- 🌐 TCP sockets
- 🔌 USB bulk endpoints
- 📻 Radio (LoRa, BLE, etc.)
- 🧪 Pipes / files for testing
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