1 个不稳定版本
0.1.0 | 2024 年 1 月 9 日 |
---|
#898 in Unix APIs
81KB
1.5K SLoC
Uds.rs
通过 socketcan 提供异步 UDS 通信
为了正确的行为,您需要具有已应用补丁的 Linux 内核:https://lore.kernel.org/linux-can/[email protected]/#r
层次结构
模块 uds - 顶层模块,包含 UdsClient,通过 UdsClient 为用户服务提供所有交互,UdsClient 使用的服务存储在单独的模块中 - 例如,查看 read_data_by_identifier.rs,其中描述了服务模块的结构
模块 communication - 基本通信框架。此模块的目的是为 UdsClient 提供发送和接收功能。
所有通信都旨在主要使用 ISO 14229-1:2013 中 UDS 的定义。
示例
为了正确的行为,需要使用以下命令正确设置 can 接口
sudo ip l set dev can0 up type can bitrate 500000
示例用法
use uds_rs::{UdsClient, UdsError};
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), UdsError> {
// Create client
let c = UdsClient::new("can0", 0x774, 0x70A)?;
// read ecu VIN
let read_data_result = c.read_data_by_identifier(&[0xf18a]).await;
match read_data_result {
Ok(x) => println!("Read data by identifier received {:#x?}", x),
Err(e) => eprintln!(
"Read single data by identifier failed with error: {:#x?}",
e
),
};
// reading dtc
let read_dtc_information = c.report_dtc_by_status_mask(0xff).await;
match read_dtc_information {
Ok(x) => println!("Read dtc by status mask: {:#x?}", x),
Err(e) => eprintln!("Clear diagnostic information failed with error: {:#x?}", e),
}
// clear all stored dtc
let clear_dtc_information = c.clear_diagnostic_information(0xffffff).await;
match clear_dtc_information {
Ok(x) => println!("{:#x?}", x),
Err(e) => eprintln!("Clear diagnostic information failed with error: {:#x?}", e),
};
Ok(())
}
开发注意事项
通信架构
当前的通信架构严格绑定请求-响应。最好将这些两种交互分开。一个用于写入的生产者和一个用于读取的消费者。
这个缺点在 NRC(0x78) - RequestCorrectlyReceivedResponsePending 时最为明显,此时服务器发出的积极响应被忽略。
如果没有实现这一点,就不可能添加像 ReadDataByPeriodicIdentifier 这样的异步服务。
服务实现
每个服务由三个步骤组成
组合函数 - 将服务方法参数和其他所需数据序列化为 Vec<u8>
发送和接收 - 将组合的向量传递给通信后端并返回响应
解析函数 - 解析接收到的原始响应 &[u8] 并将其序列化到 UdsMessage
依赖关系
~6–18MB
~182K SLoC