Rust USB HID设备开发库usbd-hid的使用,实现跨平台人机交互设备驱动开发
Rust USB HID设备开发库usbd-hid的使用,实现跨平台人机交互设备驱动开发
usbd-hid是一个用于usb-device的USB HID实现库,它还包含一个用于生成HID描述符的过程宏。
安装
在项目目录中运行以下Cargo命令:
cargo add usbd-hid
或者在Cargo.toml中添加以下行:
usbd-hid = "0.8.2"
示例代码
以下是使用usbd-hid库实现一个简单USB鼠标设备的完整示例:
use usb_device::class_prelude::*;
use usbd_hid::descriptor::MouseReport;
use usbd_hid::hid_class::HIDClass;
// 定义USB供应商ID和产品ID
const VENDOR_ID: u16 = 0x1234;
const PRODUCT_ID: u16 = 0x5678;
fn main() {
// 初始化USB设备
let usb_bus = UsbBus::new(peripherals.USB);
// 创建HID类实例
let mut hid = HIDClass::new(&usb_bus, MouseReport::desc(), 10);
// 创建USB设备
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(VENDOR_ID, PRODUCT_ID))
.manufacturer("Rust HID")
.product("Mouse Device")
.serial_number("123456")
.device_class(0)
.build();
loop {
// 检查USB总线状态
usb_dev.poll(&mut [&mut hid]);
// 创建鼠标移动报告
let report = MouseReport {
x: 5, // X轴移动
y: 0, // Y轴移动
buttons: 0, // 按钮状态
wheel: 0, // 滚轮
pan: 0, // 水平滚轮
};
// 发送报告
hid.push_input(&report).ok();
// 简单延迟
delay.delay_ms(100u32);
}
}
完整示例代码
以下是一个更完整的USB键盘设备实现示例:
use usb_device::class_prelude::*;
use usbd_hid::descriptor::KeyboardReport;
use usbd_hid::hid_class::HIDClass;
// 定义USB供应商ID和产品ID
const VENDOR_ID: u16 = 0x1234;
const PRODUCT_ID: u16 = 0x5679;
fn main() {
// 初始化USB设备总线
let usb_bus = UsbBus::new(peripherals.USB);
// 创建HID类实例,使用键盘报告描述符
let mut hid = HIDClass::new(&usb_bus, KeyboardReport::desc(), 10);
// 创建USB设备
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(VENDOR_ID, PRODUCT_ID))
.manufacturer("Rust HID Keyboard")
.product("Keyboard Device")
.serial_number("KBD-123")
.device_class(0)
.build();
loop {
// 处理USB事件
usb_dev.poll(&mut [&mut hid]);
// 创建键盘按键报告
let report = KeyboardReport {
modifier: 0, // 修饰键(Shift/Ctrl等)
reserved: 0, // 保留位
leds: 0, // LED状态(Num Lock等)
keycodes: [0x04, 0, 0, 0, 0, 0], // 按键码(0x04是字母a)
};
// 发送键盘报告
hid.push_input(&report).ok();
// 延迟一段时间
delay.delay_ms(500u32);
}
}
功能说明
- HID描述符生成:通过过程宏自动生成HID描述符
- 跨平台支持:可在多种嵌入式平台上使用
- 多种报告类型:支持鼠标、键盘等多种HID设备类型
1 回复
Rust USB HID设备开发库usbd-hid的使用指南
完整示例代码
下面是一个完整的嵌入式USB HID键盘设备示例,基于STM32微控制器:
// src/main.rs
#![no_std]
#![no_main]
use panic_halt as _;
use cortex_m_rt::entry;
use stm32f1xx_hal::{prelude::*, pac, usb::{Peripheral, UsbBus}};
use usb_device::prelude::*;
use usbd_hid::descriptor::KeyboardReport;
use usbd_hid::hid_class::HidClass;
#[entry]
fn main() -> ! {
// 初始化硬件
let dp = pac::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
// 配置时钟
let clocks = rcc.cfgr
.use_hse(8.MHz())
.sysclk(48.MHz())
.pclk1(24.MHz())
.freeze(&mut flash.acr);
// 配置GPIO
let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
// 配置USB外设
let usb_dm = gpioa.pa11.into_floating_input(&mut gpioa.crh);
let usb_dp = gpioa.pa12.into_floating_input(&mut gpioa.crh);
let usb = Peripheral { usb: dp.USB, pin_dm: usb_dm, pin_dp: usb_dp };
// 创建USB总线
let usb_bus = UsbBus::new(usb);
// 创建HID键盘设备
let mut keyboard = HidKeyboard::new(usb_bus);
// 主循环
loop {
// 轮询USB事件
keyboard.poll();
// 模拟按键按下'A'
keyboard.send_key(0x04); // 0x04是HID键盘'A'的键码
// 简单延时
cortex_m::asm::delay(8_000_000);
}
}
struct HidKeyboard {
usb_dev: UsbDevice<'static, UsbBus<Peripheral>>,
hid: HidClass<'static, UsbBus<Peripheral>, KeyboardReport>,
}
impl HidKeyboard {
fn new(usb_bus: &'static UsbBus<Peripheral>) -> HidKeyboard {
// 创建HID类实例
let hid = HidClass::new(usb_bus, KeyboardReport::desc(), 60);
// 创建USB设备
let usb_dev = UsbDeviceBuilder::new(usb_bus, UsbVidPid(0x16c0, 0x27dd))
.manufacturer("Rust HID")
.product("Keyboard")
.serial_number("1.0")
.device_class(0)
.build();
HidKeyboard { usb_dev, hid }
}
fn send_key(&mut self, key: u8) {
// 创建键盘报告
let report = KeyboardReport {
modifier: 0, // 无修饰键
reserved: 0, // 保留位
leds: 0, // LED状态
keycodes: [key, 0, 0, 0, 0, 0], // 最多6个按键
};
// 发送报告
self.hid.push_input(&report).ok();
// 发送空报告表示按键释放
let release_report = KeyboardReport {
modifier: 0,
reserved: 0,
leds: 0,
keycodes: [0, 0, 0, 0, 0, 0],
};
self.hid.push_input(&release_report).ok();
}
fn poll(&mut self) {
// 轮询USB事件
if !self.usb_dev.poll(&mut [&mut self.hid]) {
return;
}
// 检查USB状态
match self.usb_dev.state() {
UsbDeviceState::Configured => {
// 设备已配置,可以发送报告
}
_ => {
// 其他状态处理
}
}
}
}
项目配置文件
Cargo.toml
[package]
name = "stm32-hid-keyboard"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
panic-halt = "0.2"
stm32f1xx-hal = { version = "0.8", features = ["rt", "stm32f103", "medium"] }
usb-device = "0.3"
usbd-hid = "0.7"
.cargo/config.toml (嵌入式目标配置)
[target.thumbv7m-none-eabi]
runner = "probe-rs run --chip STM32F103C8"
[build]
target = "thumbv7m-none-eabi"
代码说明
-
硬件初始化:
- 配置STM32的时钟系统
- 初始化USB外设所需的GPIO引脚
-
USB配置:
- 创建USB总线实例
- 设置USB设备的VID/PID、厂商信息等
-
HID键盘实现:
- 使用
KeyboardReport
结构体定义键盘报告格式 - 实现按键发送功能,包括按键按下和释放
- 处理USB状态变化
- 使用
-
主循环:
- 定期轮询USB事件
- 模拟按键按下操作
这个完整示例展示了如何在STM32微控制器上创建一个简单的USB HID键盘设备。实际使用时,可以根据需要修改按键处理逻辑或添加更多功能。