π¦ pcobs
postcard + crc + cobs = structured data over anything
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_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?;
let my_struct = ?;
π Quick Start
[]
= "1"
= { = "1", = ["derive"] }
use ;
use ;
// Sender
let data = SensorData ;
let mut buf = ;
let len = serialize?;
stream.write_all?;
stream.write_all?; // COBS delimiter
// Receiver
let mut buf = ;
let n = read_until_delimiter?;
let decoded: SensorData = deserialize?;
π Packet Format
ββββββββββββββββββββββββββββββββββββββββββ¬βββββββ
β 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
π 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