使用embassy在nrf52833上实现一个蓝牙网关功能。因为要跟主芯片通信,于是定义了link层通信协议:

构思了link层要实现的功能:

帧的解析封装都比较好实现:
///发送封装
pub fn pack_send_msg(
func_code: FuncCode,
msg_id: u16,
msg: &[u8],
) -> Result<Vec<u8, MSG_DATA_LEN_MAX>, ComLinkError> {
let mut buf = Vec::new();
buf.push(0xA5)?; //frame head high byte
buf.push(0x5A)?; //frame head low byte
buf.push(func_code.into())?; //function code
buf.extend_from_slice(&msg_id.to_be_bytes())?; //msg id
buf.extend_from_slice(&(msg.len() as u16).to_be_bytes())?; //msg length
buf.extend_from_slice(msg)?; //msg data
let crc = crc16(0xffff, &buf[2..]);
buf.extend_from_slice(&crc.to_be_bytes())?; //crc16
Ok(buf)
}
pub struct MsgParser {
state: ParseState, //parse state
calc_crc: u16, //calculated crc value
msg: MsgRecv, // msg storage when parsing
}
#[derive(Debug, Clone, Default)]
struct DataVec(Vec<u8, MSG_RECV_PARSE_BUF_LEN>);
impl Format for DataVec {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", Bytes(&self.0))
}
}
#[derive(Debug, Clone, Default, Format)]
pub struct MsgRecv {
func_code: FuncCode,
msg_id: u16,
msg_len: u16,
data: DataVec,
recv_crc: u16, //received crc value
}
///接收解析
pub fn parse(&mut self, data: &[u8]) -> MsgRecvVec {
let mut msg_recv_vec = MsgRecvVec::default();
let mut i = 0;
while i < data.len() {
match self.state {
ParseState::BeginH => {
if data[i] == 0xA5 {
self.state = ParseState::BeginL;
}
i += 1;
}
ParseState::BeginL => {
if data[i] == 0x5A {
self.state = ParseState::FuncCode;
} else

最低0.47元/天 解锁文章
1436

被折叠的 条评论
为什么被折叠?



