4 个稳定版本
1.1.1 | 2021 年 11 月 12 日 |
---|---|
1.1.0 | 2021 年 3 月 18 日 |
1.0.1 | 2021 年 3 月 10 日 |
#486 在 嵌入式开发
24KB
204 行
crc8-rs
注意:我强烈建议您使用 crc 包 而不是此包
crc8-rs 是 Rust 中 8 位循环冗余校验的最小化无堆栈 no_std 实现。这允许我们检查数据的完整性,因此主要用于在不可靠或嘈杂的连接中传输数据。例如,这包括与嵌入式系统和网络连接的连接。
请参阅文档。
特性
此包提供处理 8 位系统中 CRC 的最小化函数。提供的函数包括 fetch_crc8
、has_valid_crc8
和 insert_crc8
。这应该使处理大多数常见的 CRC 场景变得简单。由于此包采用的最小化方法,二进制大小应保持较小。这对于嵌入式硬件特别合适。
使用方法
将此添加到项目的 Cargo.toml 中
[dependencies]
crc8-rs = "1.1"
通常有两种使用此包的方法。我们可以使用普通缓冲区或使用 struct
方法包装 CRC。让我们来看看两种方法。
使用普通缓冲区
在传输端,我们会有类似的代码如下。
use crc8_rs::{ has_valid_crc8, insert_crc8 };
// We are given a data buffer we would like to transfer
// It is important to leave a unused byte at the end for the CRC byte
let data: [u8; 256] = [
// ...snip
];
// We can insert a CRC byte to the data buffer, this will be the last byte
// This time we use the generator polynomial of `0xD5`
let crc_data: [u8; 256] = insert_crc8(data, 0xD5);
// Now we are able to verify that the CRC is valid
assert!(has_valid_crc8(crc_data, 0xD5));
// Transfer the data...
然后在接收端,我们会有如下代码。
use crc8_rs::has_valid_crc8;
// We receive the CRCed data from some source
// This buffer has the CRC byte as the last byte
let crc_data: [u8; 256] = // ...snip
// Now we can conditionally unpack it and use the data
if has_valid_crc8(crc_data, 0xD5) {
// The data is contained in the crc_data
let data = crc_data;
// ...snip
} else {
panic!("CRC is invalid!")
}
包装 CRC
如果我们想从一些给定的数据中形成数据包,我们可能在传输数据时附加一个 CRC 字节来验证数据的完整性。
use crc8_rs::insert_crc8;
// Define a example packet structure
struct Packet {
header: [u8; 4],
content: [u8; 247],
footer: [u8; 4],
}
impl Packet {
fn to_data_buffer(&self) -> [u8; 256] {
let mut data = [0; 256];
// First we insert the packet data into the buffer
for i in 0..4 { data[i] = self.header[i] }
for i in 0..247 { data[i + 4] = self.content[i] }
for i in 0..4 { data[i + 251] = self.footer[i] }
// We use the generator polynomial `0xD5` here.
insert_crc8(data, 0xD5)
}
}
接收给定的缓冲区现在非常简单。
use crc8_rs::has_valid_crc8;
struct ReceivedPacket {
header: [u8; 4],
content: [u8; 247],
footer: [u8; 4],
}
impl ReceivedPacket {
fn receive(data: [u8; 256]) -> Option<ReceivedPacket> {
// Before we construct the instance, we first check the CRC
if has_valid_crc8(data, 0xD6) {
Some(ReceivedPacket {
// ...snip
})
} else {
None
}
}
}
许可证
使用 MIT 许可证授权。