STM32F0实战:基于HAL库开发【4.5】

张开发
2026/4/9 23:28:19 15 分钟阅读

分享文章

STM32F0实战:基于HAL库开发【4.5】
21.1.6 USB的事务处理事务处理Transaction是主机与设备间通信的基础事务是由包组成的一次事务处理由一个令牌包、一个数据包和一个握手包组成。令牌包表示事务处理的开始它的类型决定了事务处理的类型USB协议中定义了7种类型的令牌包因此事务处理也有7种类型其中最重要的3种事务处理分别是SETUP事务处理、IN事务处理和OUT事务处理。在事务处理过程中其令牌包包含有事务类型、传输方向、地址和端点号数据包包含有本次事务处理要传输的数据当事务处理不需要发送数据时将不再发送数据包握手包用于数据的接收一方向发送一方报告此次事务处理是否成功。1.SETUP事务处理SETUP事务处理是事务处理的特殊形式只应用在控制传输设置阶段用于对设备进行配置。SETUP事务处理的数据传输方向总是从主机到设备SETUP事务处理流程如图21-3所示。2.IN事务处理IN事务处理用于实现设备到主机方向的数据传输。一个完整的IN事务处理流程如图21-4所示。在正常的数据处理情况下设备响应主机的IN令牌包并向主机返回数据。如果主机向设备发送的IN令牌包在传输过程中出现错误设备接收不到正确的IN令牌包此时设备将忽略此IN令牌包不对该令牌包做应答如果设备接收到正确的IN令牌包但是设备的IN端点被挂起无法向主机发送数据此时设备将向主机发送STALL握手包如果设备接收到正确的IN令牌包但是设备因为某种原因无法向主机提供数据此时设备将向主机发送NAK握手包如果设备接收到正确的IN令牌包并且向主机发送了数据包但数据包在传输过程中出现错误主机接收不到正确的数据包主机将忽略错误的数据包不做响应。图21-4 IN事务处理流程3.OUT事务处理OUT事务处理用于实现主机到设备方向的数据传输一个完整的OUT事务处理流程如图21-5所示。在正常的数据传输情况下设备响应主机的OUT令牌包并接收主机发送的数据。如果主机向设备发送的OUT令牌包在传输过程中出现错误设备接收不到正确的OUT令牌包则不对该令牌包做出应答如果接收到正确的OUT令牌包并且主机向设备发送数据包但是在传输的过程中数据包出现错误此时设备将忽略错误的数据包不做响应如果接收到正确的OUT令牌包但是设备的OUT端点被挂起无法接收主机发来的数据此时设备将向主机发送STALL握手包如果接收到正确的OUT令牌包但是设备由于某种原因无法接收主机发来的数据此时设备将向主机发送NAK握手包如果设备的数据触发位和接收到的数据包的触发位不一致设备将丢弃该数据包然后向主机发送ACK握手包。21.1.7 USB数据传输的类型USB设备中的每一个有效端点都会与主机间建立一个通道每个通道以一种方式进行传输传输分为多个阶段每个阶段分别由不同的事务组成。USB协议定义了4种传输类型分别是批量传输、中断传输、同步传输和控制传输。1.批量传输该类传输用于传输大量的数据要求传输不能出错但是对传输的时间没有要求适用于打印机、扫描仪和存储设备等。在数据传输过程中当USB总线带宽紧张时会自动降低自身的传输速率为其他传输类型让出自己的带宽。当USB总线空闲时会占用较多的带宽以提高自身的传输速率。批量传输可以发送大量的数据而不会阻塞USB总线但其传输时间和传输速率得不到保障。2.中断传输中断传输适用于那些只传输少量数据并且请求传输的频率不高的一类设备USB总线为中断传输保留了总线带宽以保证中断传输能在规定的时间内完成。3.同步传输同步传输用于传输大量的、速率恒定的且对周期有要求的数据。同步传输适用于音频和视频类设备因为这类传输需要及时发送和接收数据但对数据的正确性要求不高。USB总线为同步传输保留了总线带宽以保证其一直使用准确的传输速率因此传输时间是确定和可预测的。4.控制传输控制传输是USB传输中最重要的传输类型只有在正确地执行完控制传输后才能执行其他类型的传输。控制传输适用于少量的对传输时间和传输速率没有要求但必须保证传输完成的应用。控制传输用于USB主机和设备间的配置、命令和状态通信所有USB设备都支持控制传输当设备连接到主机时首先开始的是控制传输使用默认的地址0和端点0交换信息包括读取设备的描述符和设置设备地址等。21.1.8 USB设备描述符每一个USB设备都有自己特有的配置如设备的类型、供应商信息、接口和端点数量等。USB设备使用各种描述符来说明设备或设备中某个组件的信息。描述符是一种数据结构通常被保存在USB设备的固件程序中用于使主机了解设备的具体信息。USB设备必须具有的描述符有设备描述符、配置描述符、接口描述符和端点描述符而其他的描述符如字符串描述符、设备限定描述符、速率配置描述符则是可选的。1.设备描述符Device descriptor设备描述符用于说明设备的总体信息包括设备的类型、设备支持的协议、供应商、产品名称、设备版本号、设备所支持的配置数等目的是让主机获取所插入USB设备的属性以便加载合适的驱动程序。一个USB设备只能有一个设备描述符固定为18字节的长度它是主机向设备获取的第一个描述符。设备描述符的具体结构可以参考以下代码uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] { 0x12, /* bLength域 描述符长度 */ USB_DESC_TYPE_DEVICE, /* bDescriptorType域 描述符类型 */ 0x00, /* bcdUSB域 USB版本号BCD编码 */ 0x02, 0x02, /* bDeviceClass域 设备类代码 */ 0x02, /* bDeviceSubClass域 设备子类代码 */ 0x00, /* bDeviceProtocol域 设备协议代码 */ USB_MAX_EP0_SIZE, /* bMaxPacketSize域 端点0支持的最大数据包长度 */ LOBYTE(USBD_VID), /* idVendor域 供应商IDVID */ HIBYTE(USBD_VID), /* idVendor域 供应商IDVID */ LOBYTE(USBD_PID_FS), /* idProduct域 产品IDPID */ HIBYTE(USBD_PID_FS), /* idProduct域 产品IDPID */ 0x00, /* bcdDevice域 设备版本号BCD编码 */ 0x02, USBD_IDX_MFC_STR, /* iManufacturer域 供应商字符串描述符索引1 */ USBD_IDX_PRODUCT_STR, /* iProduct域 产品字符串描述符索引2 */ USBD_IDX_SERIAL_STR, /* iSerialNumber域 设备序号字符串描述符索引3 */ USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations域 USB设备支持的配置数 */ } ;2.配置描述符Configuration descriptor配置描述符用于说明USB设备的配置特性包括配置信息的总长度、支持接口的个数、配置的属性及设备可以从总线获取的最大电流等。一个USB设备可以包含一个或多个配置如USB设备的低速模式和高速模式可以分别对应一个配置每一个配置都对应一个配置描述符配置描述符长度固定为9字节。配置描述符的具体结构可以参考以下代码uint8_t Configuration_Descriptor [9] { 0x09, /* bLength域 配置描述符长度 */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType域 配置描述符 */ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength域 配置信息总长度 */ 0x00, 0x02, /* bNumInterfaces域 2个接口 */ 0x01, /* bConfigurationValue域 配置值 */ 0x00, /* iConfiguration域 字符串描述符描述配置索引 */ 0xC0, /* bmAttributes域 配置属性自供电 */ 0x32, /* MaxPower域 设备从总线上获取最大电流0mA */ }3 .接口描述符Interface descriptor接口描述符用于说明USB设备中各个接口的特性包括接口号、接口使用的端点数、所属的设备类及其子类等。一个配置可以包含一个或多个接口每个接口都必须有一个接口描述符。接口是一组端点的集合用户能够在USB处于配置状态时改变这些设置。接口描述符的具体结构可以参考以下代码uint8_t Interface_Descriptor [9] { 0x09, /* bLength域 接口描述符长度9字节 */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType域 接口描述符 */ 0x00, /* bInterfaceNumber域 接口数量 */ 0x00, /* bAlternateSetting域 复用设置 */ 0x01, /* bNumEndpoints域 接口使用的端点数单一端点 */ 0x02, /* bInterfaceClass域 接口所属USB设备类通信接口类 */ 0x02, /* bInterfaceSubClass域 接口所属USB设备子类抽象控制模型 */ 0x01, /* bInterfaceProtocol域 接口采用的USB设备类协议通用AT命令 */ 0x00, /* iInterface域 接口字符串描述符索引接口 */ }.端点描述符Endpoint descriptor端点是设备上一个能够存储多字节的缓冲器数据的传输都是与设备端点相关的。主机在接收和发送数据时也有相应的缓冲器但是主机并没有端点。端点描述符用于定义端点所支持的传输类型和传输方向等信息其长度为7字节。端点0无描述符而其他端点必须包含描述符。端点描述符的具体结构可以参考以下代码uint8_t Endpoint_Descriptor2[7] { 0x07, /* bLength域 端点描述符长度7字节 */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType域 端点类型 */ CDC_CMD_EP, /* bEndpointAddress域 端点地址 */ 0x03, /* bmAttributes域 端点特性中断 */ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize域 端点支持最大数据包长度 */ HIBYTE(CDC_CMD_PACKET_SIZE), 0x10, /* bInterval域 轮询间隔 */ }21.1.9 标准设备请求标准设备请求可以理解成USB主机向设备发出的命令。在控制传输的SETUP阶段主机发送标准设备请求至设备并使用默认的控制管道所有的USB设备都要求对主机发给自己的请求做出响应。USB规范定义了11个标准设备请求每个设备请求有8字节。以上是8种常用的设备请求具体数据结构和编码值见表21-2和表21-3其他设备请求的字段结构详见表21-4。表21-2 USB标准设备请求的数据结构21.1.10 USB的设备状态USB设备有多种状态有些状态对于主机来说是可见的而有些状态是设备内部的。USB设备状态有以下几种。1连接状态当USB设备通过电缆连接到主机或Hub的下行端口时即进入连接状态此时USB总线开始向USB设备供电直至电源稳定工作。2上电状态当连接到主机上的USB设备得到稳定的总线电源后便处于上电状态。此时设备还没有被复位不能对任何事务进行处理设备可以从USB总线上获取电源也可以自供电。3默认状态当USB设备上电后会响应主机发出的复位信号进行复位操作。复位结束后USB设备进入默认状态。这时USB设备可以从总线上获得不超过100mA的电流并使用默认的设备地址0进行事务处理。4地址状态USB设备复位结束后USB主机重新为设备分配一个地址这个地址是唯一的此时设备便处于地址状态。在地址状态后设备将不再使用默认的地址而使用新分配的地址进行之后的总线活动。5配置状态在USB设备被使用之前设备必须先被配置主机发出一个带有非零配置值的配置请求SET_CONFIGURATION设备在正确处理配置请求后便进入配置状态。在配置状态下所有的寄存器返回至默认值。6挂起状态USB协议规定如果USB设备在3ms内没有检测到总线活动将自动进入挂起状态以降低功耗。上电后的USB设备无论是否被分配新的地址或被配置都必须时刻准备进入挂起状态。21.1.11 USB总线的枚举过程当一个USB设备连接至USB总线上时主机会发现有新的设备插入但是不知道插入的设备是什么所以主机就会开始询问它是什么设备、用途是什么、负荷能力怎样这个询问的过程就是枚举的过程。当新的设备插入时并没有为其分配地址因此主机与其通信使用默认地址0这时主机首先发送一个获取设备描述符指令包设备接到该指令包后返回自己设备的设备描述符通过设备描述符主机会了解USB设备的基本属性比如支持的传输数据长度、电流负荷、支持USB版本等。主机知道设备的数据长度、电流大小等基本属性后就会给设备分配一个属于它的地址之后就开始发送获取设备配置请求询问设备的具体配置。设备接到指令包后就开始发送9字节的设备配置字其中包括设备配置字的总长度。这样主机就知道设备的配置到底有多长然后主机再次发送获取设备配置请求指令包这时设备就开始上传所有的配置字。这时主机已经弄清楚了所插入设备的工作方式和特性就可以正常工作了。USB总线枚举的详细过程如下。1当USB设备插入到Hub端口时有上拉电阻的一根数据线被拉高到幅值90%的电压约3VHub检测到它的一根数据线是高电平就认为有设备插入并能根据是D还是D-被拉高来判断是低速、全速还是高速设备。检测到设备后Hub继续给设备供电。2每个Hub利用它自己的中断端点向主机报告其各个端口的状态内容是Hub端口的设备连接/断开事件。如果有连接/断开事件发生那么主机会向Hub发送一个获取接口状态请求以了解此次端口状态改变的情况Hub收到该请求后会将插入到该端口设备的速度信息低速、全速、高速反馈给主机。3主机知道有新设备连接后等待至少100ms以使插入操作完成和设备电源稳定。然后USB主机控制器向Hub发送一个获取接口特性请求让Hub复位该端口。Hub通过驱动设备的数据线到复位状态D和D-均为低电平并持续至少10ms。4根据USB2.0协议高速设备在开始时默认使用全速模式所以对于一个支持USB2.0的高速Hub当它发现其端口连接的是一个全速设备时会进行高速检测看看目前这个设备是否还支持高速模式如果是就切换到高速模式否则就一直在全速模式下运行。从设备的角度来看如果是一个高速设备在刚连接到Hub或上电时只能用全速模式随后Hub会进行高速检测之后这个设备才会切换到高速模式下工作。5主机不停地向Hub发送获取接口状态请求以查询设备是否复位成功。Hub返回的报告信息有一位专门用来标志设备的复位状态。当设备复位成功后Hub将撤销复位信号设备便处于默认状态并使用默认地址0和端点0来接收主机发来的请求。此时设备能从总线上获得的最大电流是100mA。6主机给设备发送获取设备描述符请求设备返回18字节的设备描述符。这是主机第一次得到设备描述符主机并不会分析各个字段的含义只会读取设备描述符中端点0所支持的最大数据包长度设备描述符的第8字节。当控制传输的状态阶段完成后主机会要求Hub再对设备进行一次复位操作。7USB主机控制器通过设置地址请求向设备分配一个唯一的地址在完成这次控制传输后设备将进入地址状态之后将使用新的地址继续与主机通信。新的地址对于设备来说是终身制的只要设备不被拔出、复位或者系统重启那么该地址将一直存在。8主机再一次向设备发送获取设备描述符请求这次主机将会认真解析设备描述符的内容包括端点0支持的最大数据包长度、设备所支持的配置数、供应商IDVID、产品IDPID等信息。之后主机发送获取配置描述符请求。主机先获得9字节的配置描述符其中包括配置描述符和其下层的所有描述符的总长度。接着主机再一次发送获取配置描述符请求这一次设备会把配置描述符、接口描述符和端点描述符一并发给主机。9此时主机会弹出窗体提示发现新设备的信息。主机通过解析获得的描述符已经对设备有足够的了解会选择一个最合适的驱动程序给设备并将设备添加到USB总线的设备列表中并把对设备的控制权交给驱动程序。10驱动程序会要求设备重新发送描述符并为设备选择一个合适的配置值。在通过描述符获悉设备的状况后驱动程序向设备发送一个带有所需配置值的设置配置请求。设备接收到请求后使能所要求的配置这样设备便处于配置状态此时设备可以进行数据传输。

更多文章