当前位置:首页 > 嵌入式 > 《嵌入式技术与智能系统》
[导读]CherryUSB是一个轻量级、高性能的开源USB主从协议栈,由国内开发者维护,专为资源受限的带USB外设的嵌入式系统设计。近年来,随着带USB外设的嵌入式设备逐渐增多,CherryUSB成为了一个可靠稳定的选择。相比其他USB协议栈,CherryUSB更注重用户阅读体验、驱动全面性、稳定性和高性能,降低了开发者入门的门槛,发挥出了嵌入式设备中USB的优势。本文对CherryUSB主机和从机代码进行原理性的分析,并基于rt-thread artpi2开源硬件平台,进行CherryUSB主从机的应用实践,为嵌入式USB开发提供参考和借鉴。


1. 引言

CherryUSB项目于2022年发布,旨在为资源受限的嵌入式系统提供一套简洁易学且高效的USB协议栈[1]。在设计上,CherryUSB采用树状化编程,所有类驱动和USBIP驱动模板化设计,没有复杂的C语言语法,方便用户学习和新增驱动。对用户常用的数据收发API采用类比法,将复杂USB通信类比为UART + DMA通信,简化了通信逻辑,方便用户使用。为了突出USB的性能,主从驱动直接对接寄存器操作,并且使用零拷贝、硬件DMA直通和中断快响应等技术,充分释放USB硬件带宽。

自发布以来,CherryUSB得到了众多开发者和半导体企业的支持,包括博流智能、先楫、平头哥、飞腾、恩智浦、乐鑫、匠心创、博通、嘉楠等。并应用到众多嵌入式设备,包括鼠标、键盘、可视门铃、网络通信、图传、存储、调试、bootrom等应用。并且CherryUSB采用Apache 2.0授权,可免费在商用解决方案中使用。

随着热度的提升,有越来越多的开源项目使用 CherryUSB,同样CherryUSB也对火热的开源项目进行了支持,包括daplink,blackmagic,lvgl,lwip,nuttx,zephyr等,并加入到rt-thread国产OS项目中,成为rt-thread标准USB协议栈。

USB协议栈是一个庞大的体系,如何化繁为简,降低用户开发门槛,理解USB的实现原理,是一个难题。本文将对CherryUSB的主机和从机代码进行原理性分析,提取关键信息,帮用户理清脉络,并使用rt-thread artpi2开源硬件进行移植和主从应用的实践。

2. CherryUSB从机协议栈概述

CherryUSB从机协议栈主要包括从机控制器IP驱动,USB设备枚举,USB驱动加载。其中,设备枚举和驱动加载部分包括USB描述符注册,USB接口驱动注册,USB端点注册。CherryUSB设备协议栈支持多种USB设备类驱动,包括CDC、HID、MSC、VIDEO、AUDIO、RNDIS、MTP等,基本涵盖所有常用类驱动。本章将从IP驱动设计切入,分析从机协议栈的整个实现原理。

2.1. 从机控制器IP设计

USB从机控制器IP是一种专用集成电路设计模块,用于实现USB协议栈的数据链路层功能,使嵌入式系统能够作为USB从设备与主机建立通信。负责管理PHY交互、数据包处理、端点配置和传输调度等底层操作,同时向上层软件提供标准寄存器定义。而从机控制器IP驱动则是根据这些寄存器定义,进行一些配置,使得USB设备能够与主机进行通信。目前,在CherryUSB中,支持多种从机控制器IP,商业性的IP包括MUSB、DWC2、FOTG210等。下面我们以DWC2为例,分析该IP的设计思路。

1) DWC2 IP寄存器定义

DWC2 IP寄存器包含全局寄存器、从机寄存器、主机寄存器三类。从机寄存器中又包含端点寄存器组,包括IN端点寄存器组和OUT端点寄存器组,各支持最大16组。寄存器组的定义如下:

typedef struct

{

__IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */

uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h */

__IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */

uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch */

__IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */

__IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h */

__IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */

uint32_t Reserved18; /*!< Reserved 900h + (ep_num*20h) + 1Ch-900h + (ep_num * 20h) + 1Ch */

} DWC2_INEndpointTypeDef;

typedef struct

{

__IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h */

uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h */

__IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h */

uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch */

__IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h */

__IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h */

uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch */

} DWC2_OUTEndpointTypeDef;

从上述寄存器总结如下表1,从中得出,数据的传输,主要是依靠端点,并配置端点相关的寄存器,下表1中IN代表发送,OUT代表接收:

Table 1. DWC2 IP endpoint register description

CherryUSB原理性分析和应用实践

2) DWC2 IP中断

DWC2的中断标志有很多,这里只列举常用的一些中断,包括:

USB_OTG_GINTSTS_OEPINT

USB_OTG_GINTSTS_IEPINT

USB_OTG_GINTSTS_USBRST

USB_OTG_GINTSTS_USBSUSP

USB_OTG_GINTSTS_WKUINT

USB_OTG_GINTSTS_OEPINT和USB_OTG_GINTSTS_IEPINT代表是端点中断,其余几个表示USB的一些状态。在端点中断中,又进一步划分

  • USB_OTG_GINTSTS_OEPINT

Table 2. DWC2 IP OUT endpoint interrupt register description

CherryUSB原理性分析和应用实践


  • USB_OTG_GINTSTS_IEPINT

Table 3. DWC2 IP IN endpoint interrupt register description

CherryUSB原理性分析和应用实践

根据表2和表3,可以分析出,从机控制器IP的特点包括:多组端点寄存器、发送(IN)完成中断、接收(OUT)完成中断、复位\挂起\恢复等状态中断。同样地,其余从机控制器IP也是包含这些特点,根据这些特点,从而能够帮助我们定义从机控制器驱动的API。

2.2. 从机控制器驱动设计

根据从机控制器IP的特点,CherryUSB中制定了通用标准的从机控制器驱动API (cherryusb/common/ usb_dc.h)。如下表4所示。

Table 4. CherryUSB device controller API

CherryUSB原理性分析和应用实践

API和寄存器中大量提到了USB的一个名词:端点(endpoint) [2]。端点是USB设备内部的基本通信结构单元,本质上是一块缓冲区存储器,用作数据传输的源或目的地,并通过管道(pipe)进行传输。端点具有方向性,包括IN和OUT方向;端点支持一种传输方式,包括控制传输、批量传输、中断传输、同步传输[3];端点传输一个包时有最大数据包长度限制,称为MPS。这里,我们采用类比法,将端点比作DMA通道,端点的发送与接收看作是外设发送和接收,端点的传输方式看作是UART\SPI\I2C传输等等,端点的完成中断看作是DMA通道完成中断。当我们采用类比法以后,可以更快地理解端点的含义和作用,更快的理解从机控制器IP和驱动的设计思想。

2.3. 从机协议栈设计

在USB中,另一个重要的概念叫做setup包[4],它是主机和从机枚举所定义的一个格式,如图1所示。主机和从机通过端点0进行控制传输,并发送setup包给到从机,从机会执行到usbd_event_ep0_setup_complete_handler函数,该函数则是用于处理获取的setup包,并按照不同的bRequest执行不同的处理,最终完成USB的枚举以及接口驱动的加载工作。

CherryUSB原理性分析和应用实践

Figure 1. Format of setup packet

1. setup包格式

下图2完整描述了CherryUSB从机协议栈的执行过程和调用关系,和从机控制器IP驱动设计紧密结合。

CherryUSB原理性分析和应用实践

Figure 2. CherryUSB device stack framework

2. CherryUSB 设备协议栈框图

3. CherryUSB主机协议栈概述

CherryUSB主机协议栈主要包括主机控制器IP驱动,USB设备枚举和驱动加载。相比于从机的一对一的通信方式,主机更具复杂性,由于是一对多的方式,同时需要支持多个USB设备,因此,在CherryUSB中,采用了RTOS的接管,如果使用bare mental的方式管理,增加例如死等,状态机的代码,会让用户在阅读和使用上变得非常麻烦,并且也让代码的健壮性变得不可控。CherryUSB主机协议栈支持多种USB设备类驱动,包括CDC、HID、MSC、VIDEO、AUDIO、RNDIS、HUB等,可以支持1托多个USB设备,每个设备还可以是复合设备(支持多种USB类接口的设备)。本章同从机一样,从主机控制器IP设计入手进行分析。

3.1. 主机控制器IP设计

USB主机控制器IP是一个为嵌入式系统提供实现USB主机功能的硬件模块,主要负责总线仲裁,数据传输调度,USB协议的处理,并向上层软件提供标准寄存器定义。而主机控制器IP驱动则是根据这些寄存器定义,进行配置并能够与USB设备进行通信。CherryUSB支持多个主机控制器IP,商业性的IP包括DWC2、MUSB、OHCI、EHCI、XHCI等。其中MUSB和DWC2部分模式采用寄存器配置,OHCI/EHCI/XHCI和部分DWC2部分模式采用描述符链表配置,前者更多是把功能交给软件做,而后者则是将复杂功能交给硬件做,降低了软件的负载率,但是同时也增加了软件的编写难度。OHCI/EHCI/XHCI是intel制定的一套主机控制器标准,目前也是市面上最流行也是最通用的,也是最推荐使用的。由于主机控制器设计较为复杂,本章只简单介绍中断设计相关。如下表5所示。

Table 5. Interrupt of USB host controller

CherryUSB原理性分析和应用实践

从上述寄存器功能可以看出,无论主机控制器如何设计,都是具备相似点的,无非只是软件编写方式的不同。在这里pipe和从机的端点是对应的,一个端点对应一个pipe,自然一个pipe对应一个端点,但是由于主机是一对多的方式,因此存在多个相同的端点,但是属于不同的USB设备,因此,在主机中,统称为pipe。借助中断,我们可以定义出主机控制器IP的驱动。

3.2. 主机控制器驱动设计

主机控制器IP驱动,CherryUSB参考了linux的urb设计[5],也是采用urb (usb request block)的方式,urb内容如下:

struct usbh_urb {

usb_slist_t list;

void *hcpriv;

struct usbh_hubport *hport;

struct usb_endpoint_descriptor *ep;

uint8_t data_toggle;

uint32_t interval;

struct usb_setup_packet *setup;

uint8_t *transfer_buffer;

uint32_t transfer_buffer_length;

int transfer_flags;

uint32_t actual_length;

uint32_t timeout;

int errorcode;

uint32_t num_of_iso_packets;

uint32_t start_frame;

usbh_complete_callback_t complete;

void *arg;

#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__)

struct usbh_iso_frame_packet *iso_packet;

#else

struct usbh_iso_frame_packet iso_packet[0];

#endif

};

  • hport对应一个USB设备,当前urb将会在哪个USB设备上使用

  • ep对应一个USB设备上的一个端点,当前urb会和该USB设备的哪个端点通信

  • setup表示控制传输对应的setup包

  • transfer_buffer则表示传输的地址

  • transfer_buffer_length表示传输的长度

  • actual_length表示最终发送或者接收的实际长度

虽然urb看上去内容很多,但是实际上,和从机协议栈一样,最终都是端点通信,并且都会触发端点的完成中断,只不过在主机叫做pipe完成中断,同样也是可以类比成UART + DMA的形式,将pipe比作DMA通道,传输比作一个外设,比如UART/SPI/I2C,完成中断比作是DMA通道完成中断。

3.3. 主机协议栈设计

主机协议栈主要是对接入的USB设备进行枚举,并且解析描述符,再根据描述符找到对应的USB类驱动,并初始化类驱动,最后提供用户可用的API供调用,对拔出的设备,进行资源的释放。关于主机协议栈整体调用,如图3所示。

在主机中,有一个叫做hub的概念,USB hub (USB集线器)是一种允许多个USB设备连接到一个单个USB端口的设备。它基本上是USB接口的分线器或扩展器。每个hub上的USB接口,称为hubport,每个hubport可以接入一个USB设备,因此 USB 设备的枚举就是通过hub上的hubport进行。而hub又分roothub和external hub,roothub代表主机控制器本身,external hub自身是一个USB设备,具备连接多个USB设备的功能,如图4所示。因此在CherryUSB中会创建一个hub守护线程,作用就是探测hub上所有USB接口是否有插入和拔出事件,如果是插入事件,则进行枚举和驱动加载,如果是拔出事件则进行资源释放。如果接入的是hub设备,则通过hub通信继续检测插拔事件,最终都会通过统一的一个hub守护线程去操作hub上的所有USB端口。

4. 基于CherryUSB的应用开发

本章中,我们将基于RT-Thread ART-PI2开源硬件,进行CherryUSB的主机和从机移植和应用开发。

4.1. 使用从机枚举虚拟串口

首先根据CherryUSB官方文档(https://cherryusb.cherry-embedded.org/quick_start/transplant#usb-device)完成从机的基础移植,主要包含非USBIP相关的内容,包括USB引脚,USB时钟,USB中断等,这些不属于USBIP驱动中的内容。由于我们使用RT-Thread ART-PI2,可以直接使用ART-PI2官方仓库(https://github.com/RT-Thread-Studio/sdk-bsp-stm32h7r-realthread-artpi2),并选择art_pi2_cherryusb_usbdev_cdc_acm工程编译即可。具体则是在env环境中使用menuconfig勾选CherryUSB模块,选择USBIP和cdc acm类和demo并保存,如图5所示。

CherryUSB原理性分析和应用实践

Figure 3. CherryUSB host stack framework

3. CherryUSB主机协议栈框图

CherryUSB原理性分析和应用实践

Figure 4. USB hub topological structure

4. USB hub拓扑结构

CherryUSB原理性分析和应用实践

Figure 5. CherryUSB device menuconfig

5. CherryUSB从机menuconfig配置

然后执行scons --target=mdk5,并在main函数中调用cdc_acm_init初始化cdc acm设备,然后编译构建即可。最终将会在电脑上显示一个USB COM口,并可以进行数据的通信。如图6所示。

CherryUSB原理性分析和应用实践

Figure 6. CDC ACM read write test

6. CDC ACM读写测试

4.2. 使用主机枚举U盘

主机的移植可以参考CherryUSB官方文档 ,同样在ART-PI2官方仓库中也包含主机的例程,选择art_pi2_cherryusb_usbhost工程[6],并使用menuconfig勾选USBIP和MSC类设备并保存,如图7所示。CherryUSB将会对接到RT-Thread的DFS (虚拟文件系统)组件中。

CherryUSB原理性分析和应用实践

Figure 7. CherryUSB host menuconfig

7. CherryUSB主机menuconfig配置

然后执行scons--target=mdk5,并在main函数中使用usbh_initialize初始化主机协议栈初始化,然后编译构建即可。

当我们插入一个U盘时,协议栈会识别并进行枚举,加载MSC驱动,最终注册到DFS组件中,可以使用‘ls’,‘cat’,‘echo’相关API进行访问。如图8所示。

CherryUSB原理性分析和应用实践

Figure 8. CherryUSB host flash drive test

8. CherryUSB主机接入U盘测试

5. 结语

CherryUSB的设计是为了让用户更好地理解和使用USB,将复杂的功能采用简易代码和类比等形式简化,并实现了众多USB类设备,统一了USBIP驱动,降低了用户移植到新嵌入式系统中的难度,也方便了嵌入式开发者进行应用开发或者是IP验证。CherryUSB希望通过这些来吸引更多的开发者和企业用户。希望通过本文,读者对CherryUSB的原理有个初步的了解,不必拘泥于复杂的USB概念,而是从USBIP设计入手去发现规律,总结规律,从而形成一个大体的框架,最终对USB的整体会有一个很深入的理解。

CherryUSB近年来得到了很多开发者和企业的支持,在很多产品当中都有CherryUSB的身影,项目也是趋于高度稳定,期待CherryUSB在未来能够支持更多的硬件支持,支持更多的开源项目,成为一个主流标准的USB协议栈[7]。


参考文献

[1] CherryUSB官方文档[EB/OL], 2025-08-04.
[2] The Micriμm USB Team. 嵌入式协议栈uc/USB-Device [M]. 何小庆, 译. 北京: 航空航天大学出版社, 2015.
[3] 刘荣. 圈圈教你玩USB [M]. 第3版. 北京: 航空航天大学出版社, 2022.
[4] USB Implementers Forum (2000) Universal Serial Bus Specification Revision 2.0.
[5] (2000) Linux Project USB Request Block.
[6] (2025) RT-Thread Artpi2 Project.
[7] 王小强. 多种嵌入式平台通用USB2.0协议栈的研究与设计[D]: [硕士学位论文]. 成都: 电子科技大学, 2009.
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭