7个版本
0.2.3 | 2024年5月20日 |
---|---|
0.2.2 | 2024年5月9日 |
0.1.1 | 2024年4月29日 |
0.1.0-预发布版 | 2024年3月25日 |
22在财务
每月 112次下载
475KB
12K SLoC
JCM USB通信协议
该库是JCM USB设备通信协议的纯Rust实现。
兼容性
该库与以下协议规范兼容
- ID-008
示例使用
以下是一个示例启动程序
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::{thread, time};
use jcm::{Error, Result};
/// Dummy event responder that sends `ACK` responses to all device-sent events.
fn ack_event_responder(
stop: Arc<AtomicBool>,
event_recv: crossbeam::channel::Receiver<jcm::Message>,
event_res_send: crossbeam::channel::Sender<jcm::Message>,
) -> Result<()> {
thread::spawn(move || -> Result<()> {
while !stop.load(Ordering::Relaxed) {
if let Ok(event) = event_recv.try_recv() {
event_res_send
.try_send(
jcm::Message::new().with_data(
event
.data()
.clone()
.with_additional(&[jcm::ResponseCode::Ack.into()]),
),
)
.map_err(|err| Error::Usb(format!("error sending event response: {err}")))?;
}
thread::sleep(time::Duration::from_millis(100));
}
Ok(())
});
Ok(())
}
fn main() -> Result<()> {
env_logger::Builder::from_default_env()
.format_timestamp_millis()
.try_init()
.ok();
let usb = Arc::new(Mutex::new(jcm::usb::UsbDeviceHandle::find_usb()?));
let stop = Arc::new(AtomicBool::new(false));
let (event_send, event_recv) = crossbeam::channel::unbounded();
let (response_send, response_recv) = crossbeam::channel::unbounded();
let (event_res_send, event_res_recv) = crossbeam::channel::unbounded();
jcm::usb::poll_device_message(
Arc::clone(&usb),
Arc::clone(&stop),
event_send,
event_res_recv,
response_send,
)?;
jcm::usb::wait_for_power_up(&event_recv, &event_res_send).ok();
ack_event_responder(Arc::clone(&stop), event_recv, event_res_send)?;
let req: jcm::Message = jcm::MessageData::from(jcm::UidRequest::new_set(0x1)).into();
let res = jcm::usb::poll_request(Arc::clone(&usb), &req, &response_recv, 3)?;
log::info!("UID response: {res}");
let req: jcm::Message = jcm::MessageData::from(jcm::StatusRequest::new())
.with_uid(1)
.into();
let res = jcm::usb::poll_request(Arc::clone(&usb), &req, &response_recv, 3)?;
log::debug!("Raw status response: {res}");
let res = jcm::StatusResponse::try_from(&res)?;
log::info!("Status response: {res}");
stop.store(true, Ordering::SeqCst);
Ok(())
}
辅助函数
以下函数是常见例程的辅助函数
jcm::usb::poll_device_message
:轮询设备发送的消息jcm::usb::wait_for_power_up
:在跨线程通道上等待PowerUp
事件jcm::usb::poll_request
:轮询发送请求消息到设备,给定重试次数
每个函数都很简短,所以重实现它们相对直接。
例如,您可能希望使用不同的跨线程通道原语、互斥锁类型等。
依赖关系
~0.1–12MB
~84K SLoC