CherryUSB多类设备开发详解:HID/MSC/音频设备驱动实现
CherryUSB多类设备开发详解:HID/MSC/音频设备驱动实现
CherryUSB是一款轻量级且可移植的USB协议栈,支持设备和主机模式,专为嵌入式系统设计。本文将详细介绍如何使用CherryUSB实现HID(人机接口设备)、MSC(大容量存储设备)和音频设备驱动,帮助开发者快速掌握多类USB设备的开发方法。
CherryUSB设备开发基础
CherryUSB采用模块化设计,核心代码位于core/目录,包含设备模式(usbd_core.c)和主机模式(usbh_core.c)的实现。设备类驱动位于class/目录,提供了HID、MSC、音频等常用设备类的支持。
设备开发通用步骤
- 注册设备描述符:定义USB设备描述符、配置描述符和字符串描述符
- 初始化接口:调用对应设备类的初始化函数,如
usbd_hid_init_intf() - 添加端点:配置USB端点并注册回调函数
- 启动USB设备:调用
usbd_initialize()完成设备初始化
HID设备驱动实现
HID设备是最常见的USB设备类型之一,包括键盘、鼠标等。CherryUSB在class/hid/目录提供了完整的HID设备类支持。
HID设备开发关键步骤
- 定义HID报告描述符:描述设备的输入输出报告格式
- 实现HID事件处理:处理USB连接、配置等事件
- 数据传输:通过中断端点实现数据的发送和接收
HID键盘示例
CherryUSB提供了HID键盘模板代码demo/hid_keyboard_template.c,关键实现如下:
// HID报告描述符定义
static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
// ... 报告描述符内容 ...
0xc0 // END_COLLECTION
};
// HID设备初始化
void hid_keyboard_init(uint8_t busid, uint32_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
usbd_initialize(busid, reg_base, usbd_event_handler);
}
HID设备的核心是报告描述符,它定义了设备与主机之间的数据交换格式。对于键盘设备,报告描述符需要描述按键扫描码、修饰键等信息。
MSC设备驱动实现
MSC设备允许嵌入式系统通过USB接口模拟存储设备,CherryUSB在class/msc/目录提供了MSC设备类支持。
MSC设备开发关键步骤
- 实现SCSI命令处理:响应主机的读、写等SCSI命令
- 块设备接口:提供存储介质的读写接口
- 数据传输:通过批量端点实现大容量数据传输
MSC RAM磁盘示例
demo/msc_ram_template.c展示了如何使用RAM模拟存储设备:
// 块设备接口实现
void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
{
*block_num = 1000; // 模拟1000个块
*block_size = BLOCK_SIZE; // 块大小512字节
}
int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
{
if (sector < BLOCK_COUNT)
memcpy(buffer, mass_block[sector].BlockSpace, length);
return 0;
}
int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
{
if (sector < BLOCK_COUNT)
memcpy(mass_block[sector].BlockSpace, buffer, length);
return 0;
}
MSC设备通过实现usbd_msc_get_cap()、usbd_msc_sector_read()和usbd_msc_sector_write()等函数,将存储介质抽象为块设备,供USB协议栈使用。
音频设备驱动实现
CherryUSB支持USB音频设备类,在class/audio/目录提供了音频设备的实现,支持麦克风输入和扬声器输出。
音频设备开发关键步骤
- 配置音频描述符:定义音频流格式、采样率等参数
- 音频数据处理:实现音频数据的接收和发送
- 端点管理:配置同步端点处理实时音频数据
音频设备示例
demo/audio_v1_mic_speaker_multichan_template.c展示了一个支持麦克风和扬声器的音频设备实现:
// 音频配置参数
#define AUDIO_SPEAKER_FREQ 16000U
#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
#define AUDIO_SPEAKER_RESOLUTION_BIT 16u
#define AUDIO_MIC_FREQ 16000U
#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
#define AUDIO_MIC_RESOLUTION_BIT 16u
// 音频端点回调
void usbd_audio_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
}
void usbd_audio_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
ep_tx_busy_flag = false;
}
音频设备需要处理实时数据传输,因此对时序要求较高。CherryUSB通过端点回调函数实现高效的音频数据处理,确保低延迟和流畅的音频体验。
设备驱动测试与调试
CherryUSB提供了丰富的调试工具和示例代码,帮助开发者快速测试和调试USB设备驱动。
调试工具
- USB协议分析:使用
tools/packet capture/目录下的工具捕获和分析USB数据包 - 配置工具:
tools/chryusb_configurator/提供图形化配置界面,简化描述符配置
测试方法
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/che/CherryUSB - 选择示例:根据需求选择
demo/目录下的对应示例 - 配置编译:根据目标平台配置编译选项
- 下载测试:将编译好的固件下载到目标设备进行测试
总结
CherryUSB为嵌入式系统提供了一套完整的USB设备开发解决方案,支持HID、MSC、音频等多种设备类。通过本文介绍的方法,开发者可以快速实现各类USB设备驱动,加速产品开发。
更多详细信息,请参考项目中的官方文档:docs/source/index.rst。无论是初学者还是有经验的开发者,都能通过CherryUSB轻松实现高效、可靠的USB设备。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐



所有评论(0)