20 个不稳定版本 (9 个破坏性更新)
0.10.0 | 2024年5月2日 |
---|---|
0.9.3 | 2024年3月27日 |
0.9.2 | 2024年2月26日 |
0.9.1 | 2023年9月25日 |
0.1.0 | 2019年2月10日 |
#111 in 解析器实现
每月406次下载
1.5MB
28K SLoC
dlt_parse
一个用于基本解析和写入 DLT(诊断日志和跟踪)数据包的零分配 Rust 库。目前仅支持解析和写入头部以及解析详细消息。
用法
默认情况下,禁用了 serde
,如果将 dlt_parse
作为依赖项添加到您的 Cargo.toml
,则启用了 std
[dependencies]
dlt_parse = "0.10.0"
如果您还想使用 serde
支持,您必须激活 serde
功能
[dependencies]
dlt_parse = { version = "0.10.0", features = ["serde"] }
如果您想以 no_std
模式使用该包,您必须禁用默认功能
[dependencies]
dlt_parse = { version = "0.10.0", default-features = false }
什么是 dlt_parse?
dlt_parse 是一个库,旨在为 DLT(诊断日志和跟踪)数据包提供序列化和反序列化函数。它应该能够尽可能快地分析 DLT 数据包的记录,以及编写将 DLT 数据包发送到网络的服务器。
一些关键点包括
- 它是完全用 Rust 编写的,并且经过彻底测试。
- 特别注重不使用分配或系统调用。
- 可以在
no-std
环境中使用该包。 - 该软件包仍在开发中,将会继续变化。
示例:序列化和切片/反序列化 DLT 数据包
在此示例中,将一个非详细 DLT 数据包进行序列化和反序列化。具体来说,将序列化的数据包转换为 DltPacketSlice。这有利于,在访问有效载荷或头部中的特定字段时,不需要反序列化所有字段。请注意,还可以使用 DltHeader::read 函数完全反序列化 DLT 头部。如果大多数头部字段都会使用,这可能是合理的。
use self::dlt_parse::{DltHeader, DltLogLevel, DltExtendedHeader, SliceIterator};
let header = {
let mut header = DltHeader {
is_big_endian: true, // payload & message id are encoded with big endian
message_counter: 0,
length: 0,
ecu_id: None,
session_id: None,
timestamp: None,
extended_header: Some(DltExtendedHeader::new_non_verbose_log(
DltLogLevel::Debug,
[b'a', b'p', b'p', b'i'],// application id
[b'c', b't', b'x', b'i'],// context id
))
};
header.length = header.header_len() + 4 + 4; // header + message id + payload
header
};
// buffer to store serialized header & payload
let mut buffer = Vec::<u8>::with_capacity(usize::from(header.length));
buffer.extend_from_slice(&header.to_bytes());
// write payload (message id 1234 & non verbose payload)
{
// for write_all
use std::io::Write;
// write the message id & payload
buffer.write_all(&1234u32.to_be_bytes()).unwrap(); // message id
buffer.write_all(&[5,6,7,9]); // payload
}
// packets can contain multiple dlt messages, iterate through them
for dlt_message in SliceIterator::new(&buffer) {
match dlt_message {
Ok(dlt_slice) => {
// check what type of message was received
match dlt_slice.typed_payload() {
Ok(typed_payload) => {
use dlt_parse::DltTypedPayload::*;
match typed_payload {
UnknownNv(p) => {
println!(
"non verbose message 0x{:x} (unknown) with {} bytes of payload.",
p.msg_id,
p.payload.len(),
);
}
LogNv(p) => {
println!(
"non verbose log message 0x{:x} with log level {:?} and {} bytes of payload.",
p.msg_id,
p.log_level,
p.payload.len(),
);
}
LogV(p) => {
println!(
"verbose log message with log level {:?} and values:",
p.log_level
);
for value in p.iter {
println!(" {:?}", value);
}
}
TraceNv(p) => {
println!(
"non verbose trace message 0x{:x} of type {:?} and {} bytes of payload.",
p.msg_id,
p.trace_type,
p.payload.len(),
);
}
TraceV(p) => {
println!(
"verbose trace message with of type {:?} and values:",
p.trace_type
);
for value in p.iter {
println!(" {:?}", value);
}
}
NetworkNv(p) => {
println!(
"non verbose network message 0x{:x} of type {:?} and {} bytes of payload.",
p.msg_id,
p.net_type,
p.payload.len(),
);
}
NetworkV(p) => {
println!(
"verbose network message with of type {:?} and values:",
p.net_type
);
for value in p.iter {
println!(" {:?}", value);
}
}
ControlNv(p) => {
println!("non verbose control message {:?} with service id: {} and {} bytes of payload.", p.msg_type, p.service_id, p.payload.len());
}
ControlV(p) => {
println!("verbose control message {:?} with values:", p.msg_type);
for value in p.iter {
println!(" {:?}", value);
}
}
}
}
Err(err) => {
println!("message with payload error received: {}", err);
}
}
},
Err(err) => {
//error parsing the dlt packet
println!("ERROR: {:?}", err);
}
}
}
包括解析以太网和 UDP 头部的完整示例,可以在 examples/print_messages_ids.rs 中找到
参考
许可
根据您的选择,本作品受Apache License 2.0或MIT许可协议的许可。相应的许可文本可在LICENSE-APACHE文件和LICENSE-MIT文件中找到。
贡献
除非您明确声明,否则您有意提交以包含在本作品中的任何贡献,均应按照上述许可协议进行许可,无需任何额外条款或条件。