Expand description
§serialmessage
serialmessage
enables you to pack serial data into a fast, reliable,
and packetized form for communicating with e.g. a Microcontroller. It is compatible with
the Arduino SerialTransfer and Python pySerialTransfer
libraries by PowerBroker2. This crate is designed to be used
with any serial crate you desire, and does therefore not implement any serial
communication on its own. This crate is optionally fully no_std compatible and can
be used on any Microcontroller of your choice.
The message format:
- uses start and stop bytes
- uses packet ids
- uses consistent overhead byte stuffing
- uses CRC-8 (Polynomial 0x9B with lookup table)
- allows the use of dynamically sized packets (packets can have payload lengths anywhere from 0 to 254 bytes)
- can transfer bytes, ints, floats, structs, arrays, vectors
§Packet Anatomy:
01111110 00000000 11111111 00000000 00000000 00000000 ... 00000000 10000001
| | | | | | | | | | | | | | | | |______|__Stop byte (constant)
| | | | | | | | | | | | | | |______|___________8-bit CRC
| | | | | | | | | | | | |_|____________________Rest of payload
| | | | | | | | | | |______|________________________2nd payload byte
| | | | | | | | |______|_________________________________1st payload byte
| | | | | | |______|__________________________________________# of payload bytes
| | | | |______|___________________________________________________COBS Overhead byte
| | |______|____________________________________________________________Packet ID
|______|_____________________________________________________________________Start byte (constant)
§Examples
§Basic Example
use serialmessage::{SerMsg, ParseState};
let send_data_vec: Vec<u8> = vec![1, 2, 3, 4];
let send_msg = SerMsg::create_msg_vec(&send_data_vec, 1).unwrap();
// Send the message bytes with a serial crate of your choice
//Parsing received bytes
let mut ser_msg = SerMsg::new();
let (parse_state, _parsed_bytes) = ser_msg.parse_read_bytes(&send_msg);
match parse_state {
ParseState::DataReady => {
let rcvd_data = ser_msg.return_read_data();
assert_eq!(&send_data_vec, rcvd_data);
}
_ => {
println!("Parsestate: {:?}", parse_state);
}
}
§no_std zerocopy Example
use serialmessage::{SerMsg, ParseState};
use zerocopy::{AsBytes, FromBytes};
#[repr(C, packed)]
#[derive(FromBytes, AsBytes, Debug, Clone, Copy, PartialEq)]
struct ExampleData {
i_32: i32,
f_32: f32,
}
let send_struct = ExampleData {i_32: 26, f_32: 55.845};
let send_bytes = send_struct.as_bytes();
let (send_msg, msg_len) = SerMsg::create_msg_arr(send_bytes, 1).unwrap();
// Send: send_msg[..msg_len];
//Parsing received bytes
let mut ser_msg = SerMsg::new();
let (parse_state, _parsed_bytes) = ser_msg.parse_read_bytes(&send_msg[..msg_len]);
match parse_state {
ParseState::DataReady => {
let rcvd_struct = ExampleData::read_from(ser_msg.return_read_data()).unwrap();
assert_eq!(send_struct, rcvd_struct);
}
_ => {
println!("Parsestate: {:?}", parse_state);
}
}
Structs§
- SerMsg
- Struct that implements all the functionality of this crate
Enums§
- Parse
State - Shows the progress/error when parsing bytes with SerMsg.parse_read_bytes().