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);
    }
}

功能说明

  1. HID描述符生成:通过过程宏自动生成HID描述符
  2. 跨平台支持:可在多种嵌入式平台上使用
  3. 多种报告类型:支持鼠标、键盘等多种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"

代码说明

  1. 硬件初始化:

    • 配置STM32的时钟系统
    • 初始化USB外设所需的GPIO引脚
  2. USB配置:

    • 创建USB总线实例
    • 设置USB设备的VID/PID、厂商信息等
  3. HID键盘实现:

    • 使用KeyboardReport结构体定义键盘报告格式
    • 实现按键发送功能,包括按键按下和释放
    • 处理USB状态变化
  4. 主循环:

    • 定期轮询USB事件
    • 模拟按键按下操作

这个完整示例展示了如何在STM32微控制器上创建一个简单的USB HID键盘设备。实际使用时,可以根据需要修改按键处理逻辑或添加更多功能。

回到顶部