精华内容
下载资源
问答
  • USB笔记 标准请求 清除特性 Clear Feature 格式 bmRequestType bRequest wValue wIndex wLength Data 00000000B00000001B00000010B CLEAR_FEATURE Feature Selector ZeroInterfaceEndpoint Zero None 功能...

    USB笔记 标准请求 清除特性 Clear Feature

    格式

    bmRequestTypebRequestwValuewIndexwLengthData
    00000000B
    00000001B
    00000010B
    CLEAR_FEATUREFeature SelectorZero
    Interface
    Endpoint
    ZeroNone

    功能

    这个请求用于清除或禁用特定的特性(feature)。

    bmRequestType

    共有三种接收端Recipient:设备(Device),接口(Interface),端点(Endpoint)。

    1.设备

    bmRequestType00000000B
      bmRequestType.Recipient0b00000(Device)
      bmRequestType.Type0b00(Standard)
      bmRequestType.Direction0b0(Host-to-Device)

    接收端:设备(Device)

    类型:标准(Standard)

    方向:主机到设备(Host-to-Device)

    2.接口

    bmRequestType00000001B
      bmRequestType.Recipient0b00001(Interface)
      bmRequestType.Type0b00(Standard)
      bmRequestType.Direction0b0(Host-to-Device)

    接收端:接口(Interface)

    类型:标准(Standard)

    方向:主机到设备(Host-to-Device)

    3.端点

    bmRequestType00000010B
      bmRequestType.Recipient0b00010(Endpoint)
      bmRequestType.Type0b00(Standard)
      bmRequestType.Direction0b0(Host-to-Device)

    接收端:端点(Endpoint)

    类型:标准(Standard)

    方向:主机到设备(Host-to-Device)

    bRequest

    CLEAR_FEATURE: 0x01

    wValue

    所要清除的特性(feature)。

    wValue字段的特性选择器(Feature selector)值应当与接收端相匹配,既与bmRequestType.Recipient位设置的Recipient相匹配。当接收端是设备时,只能使用设备特性选择器值;当接收端是接口时,只能使用接口特性选择器值;当接收端是端点时,只能使用端点特性选择器值。

    特性选择器(feature selector)值与接收端的对应,参照下表。

    Feature SelectorRecipientValue含有该Feature的协议
    ENDPOINT_HALTEndpoint0USB1.0/USB1.1/USB2.0/USB3.0/USB3.1/USB3.2
    FUNCTION_SUSPENDInterface0USB3.0/USB3.1/USB3.2
    DEVICE_REMOTE_WAKEUPDevice1USB1.0/USB1.1/USB2.0/USB3.1/USB3.2
    TEST_MODEDevice2USB2.0/USB3.1/USB3.2
    b_hnp_enableDevice3USB3.1/USB3.2
    a_hnp_supportDevice4USB3.1/USB3.2
    a_alt_hnp_supportDevice5USB3.1/USB3.2
    WUSB_DEVICEDevice6USB3.1/USB3.2
    U1_ENABLEDevice48USB3.0/USB3.1/USB3.2
    U2_ENABLEDevice49USB3.0/USB3.1/USB3.2
    LTM_ENABLEDevice50USB3.0/USB3.1/USB3.2
    B3_NTF_HOST_RELDevice51USB3.1/USB3.2
    B3_RSP_ENABLEDevice52USB3.1/USB3.2
    LDM_ENABLEDevice53USB3.1/USB3.2

    wIndex

    1.设备

    当wValue字段的特性选择器(Feature selector)值的接收端是设备时(既使用的是设备特性选择器值),wIndex字段值为0。

    2.接口

    当wValue字段的特性选择器(Feature selector)值的接收端是接口时(既使用的是接口特性选择器值),wIndex字段值为接口号,格式如下所示。

    D7D6D5D4D3D2D1D0
    Interface Number
    D15D14D13D12D11D10D9D8
    Reserved (Reset to zero)

    Bit 7…5用于表示接口号,其他bits保留为0。

    3.端点

    当wValue字段的特性选择器(Feature selector)值的接收端是端点时(既使用的是端点特性选择器值),wIndex字段值为端点号,格式如下所示。

    D7D6D5D4D3D2D1D0
    DirectionReserved (Reset to zero)Endpoint Number
    D15D14D13D12D11D10D9D8
    Reserved (Reset to zero)

    Bit 7,方向(Direction)位被设置为0时表示指定端点号的OUT端点,被设置为1时则表示IN端点。对于控制管道,请求中的方向(Direction)位应该设置为0,但设备可以接受方向(Direction)位的任何一个值。

    Bit 3…0用于表示端点号。

    其他bits保留为0。

    wLength

    wLength字段固定为0x0000。

    如果wLength不为零,则无效,不指定设备的行为。

    Data

    无数据阶段(Data stage)。

    说明

    ClearFeature()请求如果使用不能清除、不存在的特性(feature),或者使用不存在的接口或端点,将导致设备以请求错误来响应,返回STALL。

    对于USB 2.0,这个请求可以清除DEVICE_REMOTE_WAKEUP和ENDPOINT_HALT特性。Test_Mode功能无法通过ClearFeature()请求清除。

    对于Enhanced SuperSpeed,这个请求可以清除ENDPOINT_HALT、LTM_ENABLE、U1_ENABLE和U2_ENABLE特性。只有当设备处于配置状态时,设备才会处理U1_ENABLE、U2_ENABLE、 LTM_ENABLE。

    Clear Feature(ENDPOINT_HALT)这个请求会将bulk, interrupt, isochronous 的数据切换(data toggle)重置为DATA0 (USB 2.0)、Sequence Numbers重置为零(Enhanced SuperSpeed) 和重置增强型超高速批量端点(Enhanced SuperSpeed bulk endpoints)的突发大小(burst size)。

    集线器(Hubs)支持其他特性。

    支持的状态

    支持地址状态(Address state)和配置状态(Configured state),具体如下:

    默认状态(Default state):未定义设备处于默认状态时,接收到该请求时的设备行为。

    地址状态(Address state):当设备处于地址状态时,该请求有效;使用默认控制管道以外的接口或端点,将导致设备响应请求错误。

    配置状态(Configured state):当设备处于配置状态时,这是一个有效的请求。

    示例

    Clear Feature

    Setup packet

    Clear Feature Setup packet


    [参考资料]

    Universal Serial Bus Specification Revision 1.0

    Universal Serial Bus Specification Revision 1.1

    Universal Serial Bus Specification Revision 2.0

    Universal Serial Bus 3.0 Specification

    Universal Serial Bus 3.1 Specification

    Universal Serial Bus 3.2 Specification

    USB Complete, 5th Edition


    本文链接:https://blog.csdn.net/u012028275/article/details/114765691

    展开全文
  • 所有USB设备都响应设备默认控制管道上主机的请求。 这些请求是使用控制传输进行的。 请求和请求的参数将在Setup数据包中发送到设备。 主机负责建立表9-2中列出的字段中传递的值。 每个Set...

    所有USB设备都响应设备默认控制管道上主机的请求。 这些请求是使用控制传输进行的。 请求和请求的参数将在Setup数据包中发送到设备。 主机负责建立表9-2中列出的字段中传递的值。 每个Setup数据包都有8个字节。

     

    一、bmRequestType(向谁请求)

    D7:传输方向

    • 0 = 主机至设备;
    • 1 = 设备至主机;

    D6..5:命令类型

    • D6D5=00:标准请求命令; 
    • D6D5=01:类请求命令;
    • D6D5=10:用户定义命令;
    • D6D5=11:保留。

    D4..0:接受者类型

    • 0=设备;
    • 1=接口;
    • 2=端点;
    • 3=其它
    • 4..31 保留

    这个域表明此请求的特性。特别地,这个域表明了第二阶段控制传输方向。如果wLength域被设作0的话,表明没有数据传送阶段,那Direction位就会被忽略.

    USB说明定义了一系列所有设备必须支持的标准请求。这些请求见下面的表。另外,一个设备类可定义更多的请求。设备厂商也可定义设备支持的请求.

    请求可被导引到设备,设备接口,或某一个设备端结点(endpoint)上。这个请求域也指定了接收者。当指定的是接口或端结点(endpoint)时,wIndex域指出那个接口或端节点。

    二、bmRequest(什么请求)

    这个域标识特别的请求。bmRequestType域的Type字段可修改此域的含义。协议中仅定义Type 字段为0即标准设备请求时bRequest域值的含义。

    三、 wValue域

    此域用来传送当前请求的参数,随请求不同而变。

    四、 wIndex域

    该字段的内容根据请求而有所不同。它用于将参数传递给设备,特定于请求。

    当bmRequestType的Recipient字段为接口或端点时,wIndex域用来表明是哪一个接口或端结。

    图9-2显示了用于指定端点时的wIndex格式。

    Direction位(bit7)设置为零以指示具有指定端点编号的OUT端点,并指定一个以指示IN端点。 对于控制管道,请求应将Direction位设置为零,但设备可以接受Direction位的任一值。

    图9-3显示了用于指定接口时的wIndex格式.

    五、 wLength域

    这个域表明第二阶段的数据传输长度。传输方向由bmRequstType域的Direction位指出。wLength域为0则表明无数据传输。在输入请求下,设备返回的数据长度不应多于wLength,但可以少于。在输出请求下,wLength指出主机发出的确切数据量。如果主机发送多于wLength的数据,设备做出的响应是无定义的。

     

    六、标准设备请求

    本节介绍为所有USB设备定义的标准设备请求。 表9-3概述了标准设备请求,而表9-4和表9-5分别给出了标准请求代码和描述符类型。
    USB设备必须响应标准设备请求,即使设备尚未分配地址或尚未配置。

    \

    七、标准请求码(bRequest的值)

    八、 描述符类型

     

    下面说明几种常见的设备请求

    1.清除特性(clear Feature)

    该请求时用来取消一个特性,其格式如下:

    该请求中的wVlaue表示特性选择器,它对应的值为:0 = 端点,1 = 设备。当某个特点不允许取消,或者特性根本不存在,或者是指向一个根本不存在的接口或端点时,该请求将会导致设备请求失败,如果一个端点被固件设置为停止状态,主机软件也可以发送一个值为0的CLEAR_FEATURE命令清除该端点的停止状态。

    2.获得描述符(GetDescriptor)

    该请求可以获得USB设备中存在的特定的描述符,其格式如下:

    该请求中的wValue的高字节表示要取的设备描述符,低字节表示描述符的索引值,描述的类型见上面9-5表。

    wIndex的值为0或语言ID;当要取的值为字符串描述符时,该域的值为语言ID;当为其它的描述符时,该域为0。

    wLength表示要返回的数据长度,如果SETUP阶段的地址使用的是预设地址0,(ENDP字段为0),这时wLength值会大于实际的描述的值。这是为什么? 原因是哟用户预设的地址0来取得设备描述符时,不管多少个字节,用户最多只能取前8个字节,即在控制传输过程只有一次数据阶段。但是,如果用户新的地址(ENDP字段不为0)来取得设备描述符时。这时wLength的值就要注意了。

    3.设置地址(SetAddress)

    该请求给USB设备设备值地址,从而可以对该USB设备进行下一步的访问,其格式如下:

    该请求与其他请求有一个重要的不同点,该请求下,USB设备一直不改变它的地址,直到该请求的状态阶段被 成功的完成,而其他请求的操作都是在状态阶段之前完成。

    4.设置配置(SetConfiguration)

    该请求对设备进行设备值。其格式如下:

    该请求中的wValue域的低字节表示设置的值,该值必须为0或者与配置描述符中的配置值相匹配。如果设置值等于0,表示设备在地址状态。如果wIndex或wLength为非0值,那么该请求不执行。

    5.获得接口(GetInterface)

    此请求返回指定接口的选定备用设置。

    某些USB设备的配置具有互斥设置的接口。 此请求允许主机确定当前选择的备用设置。
    如果wValue或wLength不是上面指定的,则不指定设备行为。如果指定的接口不存在,则设备将响应请求错误。

    • 默认状态:未指定在设备处于“默认”状态时收到此请求时的设备行为。
    • 地址状态:设备给出了请求错误响应。
    • 已配置状态:当设备处于已配置状态时,这是一个有效请求

     

    6.获得状态(Get State)

    bmRequestType字段的Recipient位指定所需的收件人。 返回的数据是指定收件人的当前状态。
    如果wValue或wLength不是上面指定的,或者如果设备状态请求的wIndex不为零,则不指定设备的行为。

    如果指定的接口或端点不存在,则设备将响应请求错误。

    • 默认状态:未指定在设备处于“默认”状态时收到此请求时的设备行为。
    • 地址状态:如果指定了端点0以外的接口或端点,则设备将响应请求错误。
    • 已配置状态:如果指定了不存在的接口或端点,则设备将响应请求错误。

     

    对设备的GetStatus()请求返回如图9-4所示的信息.

    自供电字段指示设备当前是否为自供电。 如果D0复位为零,则器件由总线供电。 如果D0设置为1,则设备是自供电的。 SetFeature()或ClearFeature()请求不能更改Self Powered字段。
    “远程唤醒”字段指示设备当前是否已启用以请求远程唤醒。 禁用支持远程唤醒的设备的默认模式。 如果D1复位为零,则禁用设备发出远程唤醒信号的能力。 如果D1设置为1,则启用设备发出远程唤醒信号的能力。 可以使用DEVICE_REMOTE_WAKEUP功能选择器通过SetFeature()和ClearFeature()请求修改远程唤醒字段。 器件复位时,该字段复位为零。

     

    对接口的GetStatus()请求返回如图9-5所示的信息。

     

    对端点的GetStatus()请求返回如图9-6所示的信息。

    需要为所有中断和批量端点类型实现暂停功能。如果端点当前已暂停,则“暂停”功能将设置为1。否则,暂停功能将重置为零。可以选择使用SetFeature(ENDPOINT_HALT)请求设置暂停功能。当由SetFeature()请求设置时,端点表现出相同的停顿行为,就好像该字段已由硬件条件设置一样。如果导致暂停的条件已被删除,则通过ClearFeature(ENDPOINT_HALT)请求清除暂停功能会导致端点不再返回STALL。对于使用数据切换的端点,无论端点是否具有暂停功能集,ClearFeature(ENDPOINT_HALT)请求始终会导致数据切换重新初始化为DATA0。即使请求的配置或接口与当前配置或接口相同,Halt功能也会在SetConfiguration()或SetInterface()请求后重置为零。

    既不要求也不建议为默认控制管道实现暂停功能。 但是,设备可以设置默认控制管道的暂停功能,以反映功能错误情况。 如果该功能设置为1,则设备将在每个标准请求的数据和状态阶段将STALL返回到管道,但GetStatus(),SetFeature()和ClearFeature()请求除外。 对于特定于类的特定于供应商的请求,设备无需返回STALL。

     

     

    结合上面的格式我们分析一下下面的SETUP令牌事务的作用。

    结合前面的学习,我们知道了,host发给device的数据SETUP数据是HEX: 80 06 00 01 00 00 40 00

     

    第一个字节0x80拆分可以得到,这是一个主机发给设备(bit0~bit4)的一个标准(bit5~bit6)的请求命令,请求的结果是要求设备给Host返回(bit7 == 1)。

    第二个字节0x06查看表9-4可以得到这是一个GET_DESCRIPTOR,即获取描述符 的请求。

    第三四自己传的是0x0100 ,查看描述符表,得知高字节表示描述符类型,01表示设备,02表示配置;低字节表示索引。比如设备有多个配置,那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口,通过索引选择不同的接口。所以这里高字节的1代表 设备,低字节在本设备没用到。

    第四五字节为0x0,这个参数如果为0,则不关心;如果为非零,则表示Langurage ID,每一位都有对应的意义。

    第六七字节为0x40,即代表返回的数据不应该多于64字节。


    分析总结:该SETUP事务为主机获取从机的设备描述符。

     

    接下来再看一个例子:

    结合前面的学习,我们知道了,host发给device的数据SETUP数据是HEX: 00 05 03 00 00 00 00 00 

    第一个字节0x0,这是一个主机发给设备(bit0~bit4)的一个标准(bit5~bit6)的请求命令,请求的结果是主机和设备发送(bit7 == 0)信息。

    第二个字节0x05,从table 9-4可以看到,SET_ADDRESS,是主机给从机设置地址。

    第三四个字节合起来是0x03,对照标准的设备请求表,可以知道,这是就是主机给设备分配的设备地址3。

    第五六字节合起来是0x0,从标准的设备请求表可以看到,这里没任何作用,只是为了满足标准的SETUP令牌请求格式。

    第七八字节同上。

    分析总结:该请求为,主机给设备设置从机地址为3。

     

    接下来看最后一个例子:

    结合前面的学习,我们知道了,host发给device的数据SETUP数据是HEX: 80 06 02 03 09 04 FF 00 

    第一个字节0x0,这是一个主机发给设备(bit0~bit4)的一个标准(bit5~bit6)的请求命令,请求的结果是设备给Host返回(bit7 == 1)信息。

    第二个字节0x06,从table 9-4可以看到,Get_DESCRIPTOR,是主机获取从机描述符。

    第三四个字节合起来是0x03 02,对照标准的设备请求表,可以知道,这是就是主机请求获取设备的字符串描述符,且为第二个索引。

    第五六字节合起来是0x04 09,对照标准的设备请求表,可以知道,这里是指定字符串描述符的语言ID。

    第七八字节合起来是0xFF,表示即代表返回的字符串长度不应该多于255个字节。

     

    分析总结:该请求为主机获取设备的字符串描述符。

      版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
      原文链接:https://blog.csdn.net/qq_16777851/article/details/85715436

      展开全文
    • USB基础知识了解

      2020-07-29 15:02:54
      USB 的重要关键字: 端点:位于 USB 设备或主机上的一个数据缓冲区,用来存放和发送 USB 的各种数据,每 一个端点都有唯一确定的地址,有不同的传输特性(如输入端点、输出端点、配置端点、 批量传输端点)。 帧:...

      USB 的重要关键字:

      1. 端点:位于 USB 设备或主机上的一个数据缓冲区,用来存放和发送 USB 的各种数据,每
        一个端点都有唯一确定的地址,有不同的传输特性(如输入端点、输出端点、配置端点、
        批量传输端点)。
      2. 帧:时间概念,在 USB 中,一帧就是 1ms,它是一个独立的单元,包含了一系列总线动
        作,USB 将 1 帧分为好几份,每一份就是一个 USB 传输动作。
      3. 上行、下行:设备到主机为上行,主机到设备为下行。
        Q1:USB 的传输线结构是怎样的?
        一条 USB 传输线分别由地线、电源线、D+和 D-构成。D+和 D-是差分输入线,使用 3.3V
        电压,与 CMOS 的 5V 电平不同。电源线和地线可为设备提供 5V 电压,最大电流为 500mA,
        可在编程中设置。
        Q2:数据是如何在 USB 传输线里传送的?
        数据在 USB 传输线里是由低位到高位发送的。
        Q3:USB 的编码方案是怎样的(了解即可)?
        USB 采用不归零取反来传输数据,当传输线上的差分数据输入 0 时就取反,输入 1 时就
        保持原值,为了确保信号发送的准确性,当在 USB 总线上发送一个包时,传输设备就要进
        行位插入操作(即在数据流中每连续 6 个 1 后就插入一个 0),从而强迫 NRZI 码发生变化。
        Q4:USB 的数据格式是怎样的?
        USB 数据格式是由二进制数字串构成的,首先数字串构成域(有七种),域再构成包,
        包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、并行传输、批量传输和
        控制传输)。下面简单介绍一下域、包、事务和传输,注意它们之间的关系。
      4. 域:是 USB 数据最小的单位,由若干位组成,域可分为七个类型:
      1. 同步域(SYNC):八位,固定值为 0000 0001,用于本地时钟与输入同步;
      2. 标识域(PID):由四位标识符+四位标识符反码构成,表明包的类型和格式(这是
        一个很重要的部分,这里可计算出,USB 的标识码有 16 种,具体分类见 Q5);
      3. 地址域(ADDR):七位地址,设备在主机上的地址,地址 000 0000 被命名为零地
        址,是任何一个设备第一次连接到主机时,在被主机配置、枚举前的默认地址,由
        此可以知道为什么一个 USB 主机只能接 127 个设备的原因;
      4. 端点域(ENDP):四位,一个 USB 设备有的端点数最大为 16 个;
      5. 帧号域(FRAM):11 位,每一个帧都有一个特定的帧号,帧号域最大容量 0x800,
        对于同步传输有重要意义(同步传输为四种传输类型之一,见下文);
      6. 数据域(DATA):长度 为 0~1023 字节,在不同的传输类型中,数据域的长度各不
        相同,但必须为整数个字节的长度;
      7. 校验域(CRC):对令牌包和数据包(对于包的分类见下文)中非 PID 域进行校验的
        一种方法,CRC 校验在通讯中应用很广泛,是一种很好的校验方法。CRC 码的除法
        是模 2 运算,不同于十进制中的除法;
      1. 包:由域构成的包有四种类型:令牌包、数据包、握手包和特殊包,前三种是重要的包,
        不同的包的域结构不同。
      1. 令牌包:可分为输入包、输出包、设置包和帧起始包(注意这里的输入包是用于设
        置输入命令的,输出包是用来设置输出命令的,而不是放数据的)。其中输入包、
        输出包和设置包的格式都是一样的:
        SYNC+PID+ADDR+ENDP+CRC5(五位的校验码)
        帧起始包的格式:
        SYNC+PID+11 位的 FRAM+CRC5(五位的校验码)
      2. 数据包:分为 DATA0 和 DATA1 包,当 USB 发送数据时,当一次发送的数据长度大
        于相应端点的容量时,就需要把数据包分为好几个包,分批发送,DATA0 包和 DATA1
        包交替发送,即如果第一个数据包是 DATA0,那第二个数据包就是 DATA1。但也有
        例外情况,在同步传输中,所有的数据包都是 DATA0,格式如下:
        SYNC+PID+0~1023 字节
      3. 握手包:结构最为简单,格式如下:
        SYNC+PID
        (上面每种包都有不同类型,USB1.1 共定义了十种包,见 Q5)
      1. 事务:分别有 IN、OUT 和 SETUP 三大事务,每种事务都由令牌包、数据包和握手包三
        个阶段构成(这里用阶段的意思是因为这些包的发送都有一定的时间先后顺序)。事务
        的三个阶段如下:
      1. 令牌包阶段:启动一个输入、输出或设置的事务;
      2. 数据包阶段:按输入、输出发送相应的数据;
      3. 握手包阶段:返回数据接收情况,在同步传输的 IN 和 OUT 事务中没有这个阶段,
        这是比较特殊的。
        事务的三种类型如下:
      4. IN 事务:
        a) 令牌包阶段——主机发送一个 PID 为 IN 的输入包给设备,通知设备要往主机
        发送数据;
        b) 数据包阶段——设备跟据情况会做出三种反应(注意:数据包阶段也不总是传
        送数据的,根据传输情况还会提前进入握手包阶段):
        i. 设备端点正常,设备往主机里面发送数据包(DATA0 与 DATA1 交替 );
        ii. 设备正忙:无法往主机发送数据包就发送 NAK 无效包,IN 事务提前结束,
        到了下一个 IN 事务才继续;
        iii. 相应设备端点被禁止,发送错误包 STALL 包,事务也就提前结束了,总线
        进入空闲状态。
        c) 握手包阶段——主机正确接收到数据之后就会向设备发送 ACK 包。
      5. OUT 事务:
        a) 令牌包阶段——主机发送一个 PID 为 OUT 的输出包给设备,通知设备要接收
        数据;
        b) 数据包阶段——主机箱设备发送数据,DATA0 与 DATA1 交替;
        c) 握手包阶段——设备根据情况会做出三种反应:
        i. 设备端点接收正确,设备向主机返回 ACK,通知主机可以发送新的数据,
        如果数据包发生了 CRC 校验错误,将不返回任何握手信息;
        ii. 设备正忙,无法往主机发送数据包就发送 NAK 无效包,通知主机再次发
        送数据;
        iii. 相应设备端点被禁止,发送错误包 STALL 包,事务提前结束,总线直接进
        入空闲状态。
      6. SETUP 事务:
        a) 数据包阶段——主机发送一个 PID 为 SETUP 的输出包给设备,通知设备要接收
        数据;
        b) 数据包阶段——主机向设备发送数据(注意:这里只有一个固定为 8 个字节的
        DATA0 包,这 8 个字节的内容就是标准的 USB 设备请求命令,共有 11 条,见
        Q7);
        c) 握手包阶段——设备接收到主机的命令信息后,返回 ACK,此后总线进入空闲
        状态,并准备下一个传输(在 SETUP 事务后通常是一个 IN 或 OUT 事务构成的
        传输)。
      1. 传输:传输由 OUT、IN、SETPU 事务其中的事务构成,传输有四种类型,中断传输、批
        量传输、同步传输和控制传输。其中中断传输和批量传输的结构一样,同步传输有最简
        单的结构,而控制传输是最重要的也是最复杂的传输。
      1. 中断传输:由 OUT 事务和 IN 事务构成,用于键盘、鼠标等 HID 设备的数据
      2. 批量传输:由 OUT 事务和 IN 事务构成,用于大容量数据传输,没有固定的传输速
        率也不占用带宽,当总线忙时,USB 会优先进行其他类型的数据传输,而暂时停止
        批量传输
      3. 等时传输:由 OUT 事务和 IN 事务构成,有两个特殊的地方,第一,在同步传输的
        IN 和 OUT 事务中是没有返回包阶段的;第二,在数据包阶段所有的数据包都是
        DATA0
      4. 控制传输:最重要的也是最复杂的传输,控制传输由三个阶段构成(初始设置阶段、
        可选数据阶段、状态信息步骤),每一个阶段都可以看成一个传输,也就是说控制
        传输其实是由三个阶段构成的,用来于 USB 设备初次连接到主机之后,主机通过
        控制传输来交换信息,设备地址和读取设备的描述符,使得主机识别设备,并安装
        相应的驱动程序,这是每一个 USB 开发者都要关心的问题。
        a) 初始设置步骤:就是一个由 SETUP 事务构成的传输
        b) 可选数据步骤:就是一个由 IN 或 OUT 事务构成的传输,这个步骤是可选的,
        要看初始设置步骤有没有要求读/写数据(由 SETUP 事务的数据包阶段发送的
        标准请求命令决定)
        c) 状态信息步骤:这个步骤就是要获取状态信息,由 IN 或 OUT 事务构成的传输,
        但要注意这里的 IN 和 OUT 事务与之前的 IN 和 OUT 事务有两点不同:
        i. 传输方向相反,通常 IN 表示设备向主机发送数据,OUT 表示主机向设备
        发送数据;而在这里,IN 表示主机向设备发送数据,OUT 表示设备向主
        机发送数据,这是为了和可选数据步骤相结合;
        ii. 在这个步骤里,数据包阶段的数据包都是 0 长度的,即 SYNC+PID+CRC16
        思考:这些传输模式在实际操作中应通过什么方式设置?
        Q5:标识码有哪些?
        标识码由四位数据组成,可以表示十六种标识码。在 USB1.1 规范里,只用了十种标识
        码,USB2.0 使用了十六种标识码。标识码的作用是用来说明包的属性的,标识码是和数据
        包联系在一起的。数据包分为令牌包、数据、握手和特殊包四种,标识码分别有以下十六种:
      1. 令牌包:
        0x01 输出(OUT)启动一个方向为主机到设备的传输,并包含了设备的地址和标号
        0x09 出入(IN)启动一个方向为设备到主机的传输,并包含了设备地址和标号
        0x05 帧起始(SOF)表示一个帧的开始,并包含了相应的帧号
        0x0d 设置(SETUP)启动一个控制传输,用于主机对设备的初始化
      2. 数据包:
        0x03 偶数据包(DATA0)
        0x0b 奇数据包(DATA1)
      3. 握手包:
        0x02 确认接收到无误的数据包(ACK)
        0x0a 无效,接收(发送)端正忙而无法接收(发送)信息
        0x0e 错误,端点被禁止或不支持控制管道请求
      4. 特殊包:
        0x0c 前导,用于启动下行端口的低速设备的数据传输
        Q6:USB 主机是如何识别 USB 设备的?
        当 USB 设备插上主机时,主机就通过一系列的动作来对设备进行枚举配置(配置是属
        于枚举的一个态,态表示暂时的状态),这些态如下:
      5. 接入态(Attached):设备接入主机后,主机通过检测信号线上的电平变化来发现设备
        的接入;
      6. 供电态(Powered):就是给设备供电,分为设备接入时的默认供电值和配置阶段后的
        供电值(按数据中要求的最大值,可通过编程设置)
      7. 缺省态(Default):USB 在被配置前,通过缺省地址 0 与主机进行通信
      8. 地址态(Address):经过配置,USB 设备被复位后,就可以按主机分配给它的唯一地址
        来与主机通信,这种状态就是地址态
      9. 配置态(Configured):通过各种标准的 USB 请求命令来获取设备的各种信息,并对设
        备的某些信息进行改变或设置
      10. 挂起态(Suspended):总线在给设备供电 3ms 内没有任何操作,即 USB 总线处于空闲
        状态的话,该设备就要自动进入挂起状态。在进入挂起状态后,总的电流功耗不超过
        280uA
        Q7:标准的 USB 设备请求命令究竟是什么?
        标准的 USB 设备请求命令是用在控制传输中的“初始设置步骤”里的数据包阶段(即
        DATA0,由八个字节构成),标准 USB 设备请求命令共有 11 个,大小都是 8 个字节,具有相
        同的结构,由 5 个字段构成(字段是标准请求命令的数据部分),结构如下(括号中的数字
        表示字节数,首字母 bm、b、w 分别表示位图、字节、双字节):
        bmRequestType(1)+bRequest(1)+wvalue(2)+wIndex(2)+wLength(2)
        各字段的意义如下:
      11. bmRequestType:D7D6D5D4D3D2D1D0
        D7 =0 主机到设备,
        =1 设备到主机
        D6D5 =00 标准请求命令
        =01 类请求命令
        =10 用户定义的命令
        =11 保留值
        D4D3D2D1D0 =00000 接收者为设备
        =00001 接收者为设备
        =00010 接收者为端点
        =00011 接收者为其他接收者
        =其他,其他保留值
      12. bRequest:请求命令代码,在标准的 USB 命令中,每一个命令都定义了编号,编号的值
        就是字段的值,编号与命令名称如下(要注意这里的命令代码与其他字段结合使用,可
        以说命令代码是标准请求命令代码的核心,正是因为这些命令代码而决定了 11 个 USB
        标准请求命令):
      1. 0 GET_STATUS:用来返回特定接收者的状态
      2. 1 CLEAR_FEATURE:用来清除或禁止接收者的某些特性
      3. 3 SET_FEATURE:用来启用或激活命令接收者的某些特性
      4. 5 SET_ADDRESS:用来给设备分配地址
      5. 6 GET_DESCRIPTOR:用于主机获取设备的特定描述符
      6. 7 SET_ DESCRIPTOR:修改设备中有关的描述符,或者增加新的描述符
      7. 8 GET_CONGFIGURATION:用于主机获取设备当前的配置值(与上面的不同)
      8. 9 SET_CONGFIGURATION:用于主机知识设备采用的要求的配置
      9. 10 GET_INTERFACE:用于获取当前某个接口描述符编号
      10. 11 SET_INTERFACE:用于主机请求设备用某个描述符来描述接口
      11. 12 SYNCH_FRAME:用于设备设置和报告一个端点的同步帧
        Q8:在标准 USB 请求命令中,经常会看到 DESCRIPTOR,这是什么?
        DESCRIPTOR 即描述符,是一个完整的数据结构,可以通过 C 语言等编程实现,并存储
        在 USB 设备中,用于描述一个 USB 设备的所有属性,USB 主机通过一系列命令来要求设备
        发送这些信息的。它的作用就是通过如问答节中的命令操作来给主机传递信息,从而让主机
        知道设备具有什么功能、属于哪一类设备、要占多少带宽、使用哪类传输方式及数据量的大
        小,只有主机确定了这些信息之后,设备才能真正开始工作。标准的描述符有 5 种,USB 为
        这些描述符定义了编号:
        1——设备描述符
        2——配置描述符
        3——字符描述符
        4——接口描述符
        5——端点描述符
      1. 设备描述符
        struct DEVICE DESCRIPTOR_STRUCT
        {
        BYTE bLenght; //设备描述符的字节数大小,为 0x12
        BYTE bDESCRIPTORType; //描述符类型编号,为 0x01
        WORD bcdUSB; //USB 版本号
        BYTE bDeviceClass; //USB 分配的设备类代码,0x01~0xfe 为标准设备类,
        //0xff 为厂商自定义类型
        //0x00 不是在设备描述符中定义的,如 HID
        BYTE bDeviceSubClass; //usb 分配的子类代码,同上,值由 USB 规定和分配的
        BYTE bDeviceProtocl; //USB 分配的设备协议代码,同上
        BYTE bMaxPacketSize0; //端点 0 的最大包的大小
        WORD idVendor; //厂商编号
        WORD idProduct; //产品编号
        WORD bcdDevice; //设备出厂编号
        BYTE iManufacturer; //描述厂商字符串的索引
        BYTE iProduct; //描述产品字符串的索引
        BYTE iSerialNumber; //描述设备序列号字符串的索引
        BYTE bNumConfiguration; //可能的配置数量
        }
      2. 配置描述符
        struct _CONFIGURATION_DESCRIPTOR_STRUCT
        {
        BYTE bLength; //设备描述符的字节数大小,为 0x12
        BYTE bDESCRIPTORType; //描述符类型编号,为 0x01
        WORD wTotalLength; //配置所返回的所有数量的大小
        BYTE bNumInterface; //此配置所支持的接口数量
        BYTE bConfigurationVale; //Set_Configuration 命令需要的参数值
        BYTE iConfiguration; //描述该配置的字符串的索引值
        BYTE bmAttribute; //供电模式的选择
        BYTE MaxPower; //设备从总线提取的最大电流
        }
      3. 字符描述符
        struct _STRING_DESCRIPTOR_STRUCT
        {
        BYTE bLength; //设备描述符的字节数大小,为 0x12
        BYTE bDESCRIPTORType; //描述符类型编号,为 0x01
        BYTE SomeDESCRIPTOR[36]; //UNICODE 编码的字符串
        }
      4. 接口描述符
        struct _INTERFACE_DESCRIPTOR_STRUCT
        {
        BYTE bLength; //设备描述符的字节数大小,为 0x12
        BYTE bDESCRIPTORType; //描述符类型编号,为 0x01
        BYTE bInterfaceNunber; //接口的编号
        BYTE bAlternateSetting; //备用的接口描述符编号
        BYTE bNumEndpoints; //该接口使用端点数,不包括端点 0
        BYTE bInterfaceClass; //接口类型
        BYTE bInterfaceSubClass; //接口子类型
        BYTE bInterfaceProtocol; //接口所遵循的协议
        BYTE iInterface; //描述该接口的字符串索引值
        }
      5. 端点描述符
        struct _ENDPOIN_DEscriptOR_STRUCT
        {
        BYTE bLength; //设备描述符的字节数大小,为 0x12
        BYTE bDescriptorType; //描述符类型编号,为 0x01
        BYTE bEndpointAddress; //端点地址及输入输出属性
        BYTE bmAttribute; //端点的传输类型属性
        WORD wMaxPacketSize; //端点收、发的最大包的大小
        BYTE bInterval; //主机查询端点的时间间隔
        }
      展开全文
    • usb驱动开发之USB协议枚举过程详解

      千次阅读 2017-09-08 09:30:34
      本文把usb的枚举过程通过文字、程序和图形三种形式描述出来,并形成对照。 一 枚举过程之文字描述  •主机集线器监视着每个端口的信号电压,当有新设备接入时便可觉察。(集线器端口的两根信号线的每一根都有15kΩ...

      当usb插入之后,主机是如何识别usb的,并且对它做了什么?这个过程专业术语就叫枚举。本文把usb的枚举过程通过文字、程序和图形三种形式描述出来,并形成对照。

       枚举过程之文字描述

               •主机集线器监视着每个端口的信号电压,当有新设备接入时便可觉察。(集线器端口的两根信号线的每一根都有15kΩ的下拉电阻,而每一个设备在D+都有一个1.5kΩ的上拉电阻。当用USB线将PC和设备接通后,设备的上拉电阻使信号线的电位升高,因此被主机集线器检测到。)

         • 连接了设备的 HUB在 HOST 查询其状态改变端点时返回对应的 bitmap,告知HOST 某个PORT状态发生了改变。 
         • 主机向 HUB查询该PORT的状态,得知有设备连接,并知道了该设备的基本特性。  
         • 主机等待(至少 100mS)设备上电稳定,然后向 HUB 发送请求,复位并使能该PORT。 
         • HUB执行PORT复位操作,复位完成后该PORT就使能了。现在设备进入到defalut状态,可以从Vbus获取不超过 100mA 的电流。主机可以通过 0地址与其通讯。 
         1 主机通过0地址向该设备发送get_device_descriptor标准请求,获取设备的描述符。目的是取得却缺省控制管道所支持的最大数据包长度,该长度包含在设备描述符的bMaxPacketSize0字段中,其地址偏移量为7,主机读取64字节,但实际不一定能读到,因为这时候还不知道一次能读取的最大长度,但是肯定能读到前8个字节,因为可能的值为(8,16,32,64).
         • 主机再次向 HUB发送请求,复位该PORT。 
         2 主机通过标准请求 set_address给设备分配地址。 
         3 主机通过新地址向设备发送 get_device_descriptor标准请求,获取设备的描述符。 
         4 主机通过新地址向设备发送其他 get_configuration请求,获取设备的配置描述符。

         5 根据配置描述符的wTotalLength字段(地址偏移为2,总共两个字节,即偏移地址3表示高8位,偏移地址2表示低8位),表示该配置描述符及其包含的接口描述符、端点描述符和供应商描述等的总长度。英文原文:Total length of data returned for this configuration.Includesthe combined length of all descriptors (configuration, interface,endpoint,and class- or vendor-specific)returned for this configuration. 再次发送get_configuration请求,获取数据长度为wTotalLength。

         6 根据配置信息,主机选择合适配置,通过 set_configuration请求对设备而进行配置。这时设备方可正常使用。

      二 枚举过程之程序描述

      这是uboot中usb_hub.c和usb.c中精简之后的代码,可以大致看出整个过程。文字描述中的1-6都有对应的函数,前面几项描述由于uboot和linux内核的实现稍有差别,就不列出来了,只简单描述,读者自己可以查看源码。uboot是通过在命令行usb start,调用到do_usb()->usb_init()->usb_scan_devices()->usb_new_device(dev)->usb_hub_probe()->usb_hub_configure()->usb_hub_port_connect_change()。也就是说是插入u盘之后,手动输入命令,使用了一个查询过程。函数实现简单、清晰,易入手。

        内核源码也是在hub.c中,usb_hub_init()->kthread_run(hub_thread,NULL, "khubd")-> hub_thread-> hub_events()->hub_port_connect_change()。当有usb设备插入时,会唤醒hub_thread线程,从而调用hub_events执行,检测端口状态变化。

      void usb_hub_port_connect_change(struct usb_device *dev, int port)
      {
                /* 获取端口状态变化信息*/
                usb_get_port_status(dev, port + 1,portsts) ;
       
                /* Clear the connection change status 清除端口变化 */
                usb_clear_port_feature(dev, port + 1,USB_PORT_FEAT_C_CONNECTION);
       
              /*等待至少100ms,等待插入设备稳定*/
                mdelay(200);
       
                /* Reset the port 对设备的第一次操作,复位设备;对设备的第一次操作一定是复位。先复位,后获取
            *注意hub端口和usb设备是不同的操作,前面usb_get_port_status是对hub 端口的操作。*/
                hub_port_reset(dev, port,&portstatus) ;
               /*等待设备复位完成*/
                mdelay(200);
       
                 /*好戏来了*/
                usb_new_device(usb);
               
      }
      int usb_new_device(struct usb_device *dev)
      {
              /*包大小先初始化一个值64*/
              dev->maxpacketsize = PACKET_SIZE_64;
              /*1 获取设备描述符,读取长度64*/
              err = usb_get_descriptor(dev,USB_DT_DEVICE, 0, desc, 64);
              /*获取最大包长度*/
              dev->descriptor.bMaxPacketSize0 =desc->bMaxPacketSize0;
       
              /* reset the port for the second time第二次复位设备 */
              err = hub_port_reset(dev->parent,port, &portstatus);
       
       
              dev->epmaxpacketin[0] =dev->descriptor.bMaxPacketSize0;
              dev->epmaxpacketout[0] =dev->descriptor.bMaxPacketSize0;
       
              switch(dev->descriptor.bMaxPacketSize0) {
              case 8:
                     dev->maxpacketsize  = PACKET_SIZE_8;
                     break;
              case 16:
                     dev->maxpacketsize =PACKET_SIZE_16;
                     break;
              case 32:
                     dev->maxpacketsize =PACKET_SIZE_32;
                     break;
              case 64:
                     dev->maxpacketsize =PACKET_SIZE_64;
                     break;
              }
              dev->devnum = addr;
       
              /*2 设置设备地址*/
              err = usb_set_address(dev); /* setaddress */
       
              mdelay(10);    /* Let the SET_ADDRESS settle */
       
              tmp = sizeof(dev->descriptor);
       
              /*3 用新设置的地址获取设备描述符*/
              err = usb_get_descriptor(dev,USB_DT_DEVICE, 0, tmpbuf, sizeof(dev->descriptor));
       
              memcpy(&dev->descriptor, tmpbuf,sizeof(dev->descriptor));
       
              /* only support for one config for now*/
              /*4 和 5封装成了一个函数 获取配置描述符*/
              usb_get_configuration_no(dev, tmpbuf,0);
              usb_parse_config(dev, tmpbuf, 0);
              usb_set_maxpacket(dev);
              /* we set the default configuration here*/
             /*6 配置设备*/
              usb_set_configuration(dev,dev->config.desc.bConfigurationValue);
       
              return 0;
      }
      int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, int cfgno)
      {
      	struct usb_configuration_descriptor *config;
      	config = (struct usb_configuration_descriptor *)&buffer[0];
      	/*4 获取配置描述符,仅配置描述使长度为9*/
      	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
      	/*当前配置下的描述符总长度*/
      	tmp = le16_to_cpu(config->wTotalLength);
      	/*5 再一次获取当前配置下的全部配置、接口、端点信息*/
      	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);
      	return result;
      }

      三  枚举过程之图形描述

      枚举的总过程,看过下面的分解过程,再回头看这个总图就非常容易了。


      1. 获取设备描述符GET_DESCRIPTOR

            总线复位及向默认地址0发送GET_DESCRIPTOR指令包,请求设备描述。第一获取描述符要先复位设备,然后等待至少100ms(100ms可以满足大多数设备),这里实际只等待了43ms。如图一所示:


                                                                                          图一

      1)Index[4 - 5]:表示USB插入总线复位
      2)Index[7 - 8]:表示主机向默认地址发送GET_DESCRIPTOR指令包,详细信息也抓出来了,如图所示:

                                                                        
      3)Index[15 - 17]:表示设备向主机发送设备描述数据Index[16]
      4)Index[18 - 19]:表示主机完成GET_DESCRIPTOR指令后,给设备发送一个空应答;
       
      数据是由二进制数字串构成的,首先数字串构成域(有七种:同步域(SYNC)、标识域(PID)、地址域(ADDR)、端点域(ENDP)、数据域(DATA)、帧号域(FRAM)、校验域(CRC)),域再构成包(比如握手包:格式如下  SYNC+PID,ACK属于PID的一种),包再构成事务(IN、OUT、SETUP,每一种事务都由令牌包、数据包、握手包三个阶段构成),事务最后构成传输(中断传输、并行传输、批量传输和控制传输)。关于usb包结构,请看下一篇文章,这里先知道是这么回事就行。
      这里先解析一下设置事务的值:80 06 00 01 00 00 40 00
      /* device request (setup) */
      struct devrequest {
      unsigned char requesttype;
      unsigned char request;
      unsigned shortvalue;
      unsigned shortindex;
      unsigned shortlength;
      } __attribute__ ((packed));
      requesttype=0x80,request=0x06,value=0x0100,index=0x0000,length=0x0040;
      根据usb2.0协议9.4.3节描述,获取描述符时requesttype=0x80,request=0x06,这个是协议规定的。
      value=0x0100,高字节表示描述符类型,01表示设备,02表示配置;低字节表示索引。比如设备有多个配置,那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口,通过索引选择不同的接口。
      index=0x0000,这个参数如果为0,则不关心;如果为非零,则表示Langurage ID,每一位都有对应的意义。
      length=0x0040,表示请求的数据包长度为64.
      所以本次设置事务的目的明确了,获取设备描述符,长度为64字节。
      输入事务,是usb设备对请求进行回应,传输了16个字节的数据,为什么是传输了16个字节而不是64字节,看看偏移地址7 bMaxPacketSize0=0x10,即该设备的最大包传输大小为16字节,如果超过16字节,需要多次传输。实际设备描述符大小为18,可以看第三步的图,传输完16字节之后,主机再次发送令牌环,设备把剩下的2字节传输完成。这里我们只要获得 bMaxPacketSize0值就可以了,所以接下来直接对其进行了复位操作,否则设备还在等待传输剩余的2个字节呢。
      struct usb_device_descriptor {
      u8 bLength;
      u8 bDescriptorType;
      u16 bcdUSB;
      u8 bDeviceClass;
      u8 bDeviceSubClass;
      u8 bDeviceProtocol;
      u8 bMaxPacketSize0;
      u16 idVendor;
      u16 idProduct;
      u16 bcdDevice;
      u8 iManufacturer;
      u8 iProduct;
      u8 iSerialNumber;
      u8 bNumConfigurations;
      } __attribute__ ((packed));
      输出事务:因为获取描述符之前把设备包大小的初始值设为了64,所以输入事务之后,就认为传输完成,主机发送了一个输出事务,响应设备,已经收到数据。

      2. 设置地址SET_ADDRESS

           再次复位总线及向设备发送SET_ADDRESS指令包,设置设备地址。如图二所示:
       
                                                                                           图二
      1)Index[22 - 23]:表示再次总线复位,该复位自动完成,不是手工插拔USB完成
      2)Index[25 - 27]:表示主机向默认地址发送SET_ADDRESS指令包,详细信息如图所示:
                                                 
      设置地址为1

      3)Index[29 - 31]:表示设备完成SET_ADDRESS指令后,给主机发送一个空应答;


      设置地址为0x0002,由于我是从网上找的图,所以两幅图地址设置的不一样,这里注意一下就行。

      3.请求设备描述符GET_DESCRIPTOR

          向第二步设定的设备地址发送GET_DESCRIPTOR指令包,请求设备描述。如图三所示:
       
                                                                                            图三
      1)Index[33 - 35]:表示主机向地址01发送GET_DESCRIPTOR指令包,详细信息如图
                                                                     
      2)Index[41 - 43]:表示设备向主机发送设备描述数据Index[42]
      3)Index[45 - 47]:表示设备向主机发送设备描述数据Index[46]
      4)Index[48 - 50]:表示主机完成GET_DESCRIPTOR指令后,给设备发送一个空应答
         

      4. 请求配置描述符GET_DESCRIPTOR

      向第二步设定的设备地址发送GET_DESCRIPTOR指令包,请求配置描述。如图四所示:
       
                                                                                        图四
      1)Index[52 - 54]:表示主机向地址01发送GET_DESCRIPTOR指令包,详细信息如图所示
                                                             
      2)Index[57 - 59]:表示设备向主机发送配置描述数据Index[58]
      3)Index[60 - 62]:表示主机完成GET_DESCRIPTOR指令后,给设备发送一个空应答;
       
      解析输入事件获取的配置信息:
      struct usb_configuration_descriptor {
      u8 bLength;                      /*09,描述符长度为9*/
      u8 bDescriptorType;/* 0x2, 表示配置描述符*/
      u16 wTotalLength;          /*0x002E,表示当前配置下的各种描述信息总长度为46*/
      u8 bNumInterfaces;        /*0x01,当前配置下共一个接口*/
      u8 bConfigurationValue; /*0x01,当前配置索引,当设置某一配置时,给SetConfiguration(x)传递的参数*/
      u8 iConfiguration;/*0x00,字符串描述索引*/
      u8 bmAttributes;/*0x60,属性信息*/
      u8 bMaxPower;/*0x01当前配置最大消耗电流*/
      } __attribute__ ((packed));

      5. 读取完整设备描述及配置描述

      再次读取配置描述符,读取长度46字节。
       
          09 02 2E 00 01 01 00 60 01 和第四步获得的一样
          09 04 00 00 04 00 00 00 00 描述符长度也是09,04表示是一个接口描述符
          07 05 81 03 08 00 c8 描述符长度为07,05表示端点描述符
          07 05 01 03 08 00 c8
          07 05 82 02 40 00 00
          07 05 02 02 40 00 00
      接口描述符详解:
      struct usb_interface_descriptor {
      u8 bLength;                     /*0x09,描述符长度*/
      u8 bDescriptorType;/* 0x04 ,表示接口描述符*/
      u8 bInterfaceNumber;    /*0,接口号为0*/
      u8 bAlternateSetting;    /*0,接口的可选设置*/
      u8 bNumEndpoints;     /*04,当前接口共4个端点*/
      u8 bInterfaceClass;       /*0*/
      u8 bInterfaceSubClass; /*0*/
      u8 bInterfaceProtocol;  /*0*/
      u8 iInterface;                /*0*/
      } ;
      struct usb_endpoint_descriptor {
      u8 bLength;                     /*07,描述符长度*/
      u8 bDescriptorType;/* 0x5 ,表端点描述符*/
      u8 bEndpointAddress; /*0x81,bit[7] =1,表示输入端点,0表示输出端点;bit[6:4],保留;bit[3:0]端点号,为1*/
      u8 bmAttributes; /*0x03,bit[1:0]=11,表传输类型为中断传输*/
      u16 wMaxPacketSize; /*0x0008,当前端点最大发送和接收包大小*/
      u8 bInterval; /*0xc8,查询时发送数据的间隔时间*/
      } ;

      6 配置设备SET_CONFIGURATION

             向第二步设定的设备地址发送SET_CONFIGURATION指令包,设置配置描述。如图六所示:
       
                                                                           图六
      1)Index[139 - 141]:表示主机向地址01发送SET_CONFIGURATION指令包,详细信息如下:
                                                  
      2)Index[143 - 145]:表示设备完成SET_CONFIGURATION指令后,给主机发送一个空应答
      至此,枚举过程结束,设备可通过驱动与主机通信了。
       
      /* device request (setup) */
      struct devrequest {
      unsigned char requesttype;  /*0x00,表请求设置*/
      unsigned char request;        /*0x09,表示设置配置*/
      unsigned shortvalue;   /*0x0001,使用配置,必须匹配从配置描述符都过来的bConfigurationValue*/
      unsigned shortindex;   /*0x0000,协议规定设为0*/
      unsigned shortlength;  /*0x0000,协议规定设为0*/
      } __attribute__ ((packed));

      四 总结

      下面举几个例子来说明USB的通讯过程:
      1:主机想要向设备传送一串数据。 过程如下:
      (1) 主机向从机发送 “令牌包”,令牌包的类型为输出包,表示主机要向从机发送数据了。
      (2) 主机向从机发送完令牌以后,USB处理器件根据发送的令牌,会将中断状态寄存器标志置位,从机CPU通过查询USB处理器件的中断状态寄存器,对主机的令牌包进行响应
      (3)从机判别出中断类型,于是,准备从主机接收数据。
      (4) 从机准备好了,于是主机开始发送“数据包” 这时,USB处理器件会自动将从主发送过来的数据放如它的内部缓冲区内,接收完这个数据包后,从机向主机发送“应答包” 
      这就是一个完整的通讯过程。
      由以上可以看出,USB若是想要传送数据,那么主机必须先发一个 IN 或OUT的令牌包,然后发送DATA0,或DATA1数据包。
      简单的用现实生活中的事件进行描述:  老板想让员工去做一件事情,老板 先会发出命令,告诉要做什么事情,员工准备好以后呢,老板再把做这件事情的经费发放给员工,当员工把发放的经费清点以后,发现数目正确,他会给老板一个回应信息,告诉老板,钱已经收到了,而且数目正确。
      老板想让员工做的事:  对应USB通讯里的令牌包。
      老板想要发放的经费:  对应USB通讯里的数据包。
      员工给老板的回应:    对应USB通讯里的握手包。
      这里尤其需要注意一个问题就是:
      USB主机向设备发送令牌包的时候,接收令牌是有USB器件来完成的,而不是有从机CPU来完成的,如主机发送一个如下的令牌:
      SYNC+PID+ADDR+ENDP+CRC5
      USB器件回根据PID的类型来判断是哪种类型的令牌 根据ADDR的值来判断是否是和自己通讯,根据ENDP的值来判断是和哪个端点进行通讯,根据校验来判断,数据传送是否无误。根据以上的令牌包信息,USB器件会将其内部的中断状态寄存器相应的位置位,从机CPU可以查询这个中断状态寄存器来进行相应的操作。





      展开全文
    • adb命令大全

      千次阅读 多人点赞 2019-06-03 22:19:07
      INSTALL_FAILED_MISSING_FEATURE 应用使用了设备不可用的功能 INSTALL_FAILED_CONTAINER_ERROR 1. sdcard 访问失败;2. 应用签名与 ROM 签名一致,被当作内置应用。 1. 确认 sdcard 可用,或者安装到...
    • 关于stall 包的场景,usb2.0 spec中有详细的说明。且收到stall后,软件必须做出相应的处理才能使通信恢复正常。 一级标题 一、STALL包分类: 参看usb2.0 spec,STALL包分为两类,一类是protocol STALL,一类是...
    • USB笔记 标准设备请求 Standard Device Requests 这里主要列举出所有设备定义的标准设备请求。分别概述了标准设备请求(Standard Device Requests)和给出了标准请求代码(Standard Request Codes)和描述符类型...
    • USB 之二 USB2.0 规范详解 第二部分

      千次阅读 多人点赞 2018-04-20 14:23:01
      注意 对于物理特性仅做简单说明 ...  USB 设备第一次连接到主机时, 要接收主机枚举( Enumeration) 和配置(Configuration) ,目的是让主机知道设备功能、是哪一类的USB 设备、占用多少资源、使用了...
    • usb 驱动

      千次阅读 2012-08-10 19:42:08
      1. USB host Controller驱动程序  * 处理USB状态,管理并报告状态信息  * 数据并/传转换  * 生成frame或者microframe  * 处理数据传输的请求  * 处理USB总线协议  * 进行差错检测和控制  * 处理电源...
    • STM32 USB学习笔记8

      千次阅读 2016-03-11 11:05:52
      主机环境:Windows 7 SP1 ...现在分析USB器件库核心文件的最后一个文件usbd_ctlreq,该文件提供了标准请求的处理,跟USB2.0协议的第九章节紧密关联。在Setup阶段根据bmRequest字段的内容分为:设备请
    • usb-request

      千次阅读 2016-12-28 10:57:05
      usb device request  在usb 系统中device 中每个实现功能的endpoint在主机中定义为channel,而主机的某一channelh和devecie的特定endpoint配对构成以个pipe.所有的usb系统都是主机通过默认的Control Pipe 发送...
    • USB提供了一套自顶向下的识别方法,从hub_event出发,检查是否真的有端口发生了改变,如果坐实是port被触发了,则进入port_event。 先去获取hub的状态 if (hub_port_status(hub, port1, &portstatus, &...
    • android usb转串口数据通信示例

      万次阅读 2017-09-15 09:45:47
      usb转串口数据通信示例。物联网开发中也会经常用到usb转串口,对android手机进行通信。一般都会用otc线进行转换。我在GitHub下来一份代码,亲测可用。并进行了修改封装。GitHub网址:...
    • 清除特性 Clear Feature (01H),节操完寄存器返回应答 A:[To Device]清除设备的远程唤醒功能,并返回一个空包. B:[To Endpoint]解禁端点. case XUSBPS_REQ_CLEAR_FEATURE: switch(SetupData->bmRequestType & ...
    • USB协议本身不是我本篇博客的介绍,网上有前辈们已经写了很好的总结。本篇博客将聚焦于USB驱动框架上,下一篇博客将介绍USB驱动开发 在网上找到了一个图 开发的重点是USB设备驱动程序,不过我们可以从USB总线驱动...
    • 标准的USB描述符 当USB设备第一次连接到主机上时,要接收主机的枚举和配置,目的就是让主机知道该设备具有什么功能、是哪一类的USB设备、需要占用多少USB的资源、使用了哪些传输方式以及传输的数据量多大等等。...
    • USB枚举

      2021-03-30 09:35:32
      USB设备枚举一般会经过插入、供电、初始化、分配地址,配置,获取设备描述符、获取配置描述符、获取字符串描述符和配去置设备这么几个过程。
    • USB基础知识

      2019-08-22 17:33:11
      USB基础知识 前言 本文将从USB的插入检测、身份识别、数据传输三个方面对USB通讯整个过程扫盲,其中有些知识点的详细信息会放在文章最下面的附录中供查看,从而保证文章的整体简洁。在进入主题之前,首先了解一下...
    • USB学习笔记(2)USB协议 本文对前面提到的USB枚举过程中的标准请求以及各种描述符做出大致解释,方便后面的实操。 1. USB标准请求 USB协议定义了一个8字节的标准设备请求,主要用在设备的枚举过程。这8字节的数据是...
    • USB 3.0规范中译本第9章 设备框架

      千次阅读 2020-03-15 22:01:39
      ... 设备框架可以被分成三层: 最底层是总线接口层,传送和接收包。 中间层处理在总线接口和设备的各种端点之间路由数据。如同USB 2.0,端点时最终的数据消费者或提供者。它可以被想作是数据源或...
    • 这本来是linux下的问题,由于在用户级的app里调用了驱动函数对usb设备进行了clear halt的操作,linux的开发者于是在log里打印出这个警告,用以提示程序员们:这样做可能有问题!具体请膜拜这个帖子:...
    • A1: 一条USB的传输线分别由地线、电源线、D+、D-四条线构成,D+和D-是差分输入线,它使用的是3.3V的电压(注意哦,与CMOS的5V电平不同),而电源线和地线可向设备提供5V电压,最大电流为500MA(可以在编程中设置的,...
    • 官方提供的USBD驱动太随意,根本没法直接使用,折腾好久原因是我的开发板上面使用了一个很老的HUB芯片,是USB1.1的,导致没法使用USB2.0,后续测试都是基于USB1.1的,实际上USB2.0会更简单,因为支持的bluk可以支持...
    • USB PD快充协议

      万次阅读 2020-04-05 09:30:14
      USB PD快充协议
    • USB 协议分析(含基本协议和 USB 请求和设备枚举)

      万次阅读 多人点赞 2018-08-30 00:49:29
      1.2 USB 信号(差分信号) 1.3 USB 信号编码(NRZI) 1.4 USB 字节序 1.5 USB 设备检测 2. 通信协议 2.1 包组成(Packets Content) 2.1.1 PID 域 2.1.2 Address 地址域 2.1.3 Frame Number 帧号域 2.1.4 ...
    • USB枚举过程

      千次阅读 2018-11-21 22:06:08
      本人在学习STM32 USB使用的过程中,收集网上的资料,阅读别人博文,拼凑零碎知识,边看边学,记录下学习过程。推荐看《圈圈教你玩USB》。 枚举前的工作 根据STM32的USB库做移植,介绍枚举过程,SetSystem函数是一些...
    • USB协议详解

      万次阅读 多人点赞 2019-03-13 14:58:11
      本博客整理自网络,仅供学习参考,如有侵权,联系删除。... 一个transfer(传输)由一个或多个transaction(事务)构成,一个transaction...USB的数据通讯首先是基于传输(transfer)的,传输的类型有:中断传输、批量传输...
    • 八、USB标准请求指令

      千次阅读 2019-01-13 23:21:29
      控制传输是最重要和结构最复杂的一种传输类型。整个USB枚举的过程,都是使用了控制传输。USB枚举过程中的指令,我们称为标准的USB设备请求指令。包括了: 标准USB设备请求指令 ... CLEAR_FEATURE 1 主机清...
    • 1.usbClassGetInterfaceSetting中接口数量改为1,因为这里有2个接口 RESULT usbClassGetInterfaceSetting(uint8_t Interface, uint8_t ... return USB_UNSUPPORT; } else if (Interface > 1) { retu...

    空空如也

    空空如也

    1 2 3 4 5 ... 20
    收藏数 2,591
    精华内容 1,036
    热门标签
    关键字:

    clearfeatureusb