精华内容
下载资源
问答
  • 从零开始学USB(转)

    2019-06-30 14:31:30
    从零开始学USB(一、基础知识1) 从零开始学USB(二、基础知识2) 从零开始学USB(三、基础知识3) 从零开始学USB(四、USB系统结构) 从零开始学USB(五、USB的电器特性) 从零开始学USB(六、USB通讯的数据格式) ...

    看到别人写的USB博客太棒了,但是没有加以整理,这里整理一下方便自己后面学习。

    1. 从零开始学USB(一、基础知识1)
    2. 从零开始学USB(二、基础知识2)
    3. 从零开始学USB(三、基础知识3)
    4. 从零开始学USB(四、USB系统结构)
    5. 从零开始学USB(五、USB的电器特性)
    6. 从零开始学USB(六、USB通讯的数据格式)
    7. 从零开始学USB(七、端点、管道、接口、配置、设备)
    8. 从零开始学USB(八、USB的数据流模型)
    9. 从零开始学USB(九、USB的传输类型(1))
    10. 从零开始学USB(十、USB的描述符)
    11. 从零开始学USB(十一、USB包的结构)
    12. 从零开始学USB(十二、USB包的分类和具体格式)
    13. 从零开始学USB(十三、USB的四种传输类型(2))
    14. 从零开始学USB(十四、USB数据传输的组织形式)
    15. 从零开始学USB(十五、USB的设备状态)
    16. 从零开始学USB(十六、标准的USB请求)
    17. 从零开始学USB(十七、USB的枚举)
    18. 从零开始学USB(十八、USB的class)
    19. 从零开始学USB(十九、USB接口HID类设备(一)_HID描述符)
    20. 从零开始学USB(二十、USB接口HID类设备(二)_报表描述符Main类)
    21. 从零开始学USB(二十一、USB接口HID类设备(三)_报表描述符Global类)
    22. 从零开始学USB(二十二、USB接口HID类设备(四)_报表描述符Local类)
    23. 从零开始学USB(二十三、USB接口HID类设备(五)_报表描述符总结)
    24. 从零开始学USB(二十四、最简单的USB驱动开始)
    25. 从零开始学USB(二十五、4.19版本的内核支持usb驱动)
    26. 从零开始学USB(二十六、usb鼠标驱动驱动实例分析[1]简介)
    27. 从零开始学USB(二十七、usb鼠标驱动驱动实例分析[2]管道)
    28. 从零开始学USB(二十八、usb鼠标驱动驱动实例分析[3]传输)
    展开全文
  • 从零开始学USB(一、基础知识1) 原创 ...

    1.什么是USB?

    USB是Universal Serial Bus的缩写,中文译为通用串行总线。

    正如USB的第一个单词表述的那样,为了通用。

    那么我们看一下,还有哪些总线不是串行的,哪些是不通用的串行总线

    下表来自《USB Complete》里面对一些常见总线所总结的一些区别:

    当然上表中关于SPI的2.1M肯定是不对的,之前学习单片机的时候用STM32的SPI接口读写SD卡,现在都可以支持40Mbps的速率了。

     

    2.为什么要有USB?

    上面已经提到了,在USB出现之前,其实计算机领域中,已经存在众多的接口,而且不同的应用领域,已有一些相对来说是广泛使用的各种接口了。

    但是,对于计算机等使用的普通用户来说,由于接口太多,而容易被搞得晕头转向。再加上各个接口从硬件形状和软件配置也都不一样,导致不兼容,为了不同的应用,而要配置多种不同的硬件接口,设置对于有些硬件接口来说,还需要手动去配置一些更细节的参数。

    关于USB出现之前,计算机领域中的接口太多太繁杂,可以用下面这张,关于PC机箱背后的接口的图片来说明:

    PC机箱后面的众多接口

    PC机箱后面的众多接口

    比如老式的台式电脑中,主机箱通常需要包括键盘鼠标用的PS2接口,UART串口,SCSI接口,PCI接口,耳麦接口,话筒接口,网口,并口,调制解调器,显示屏等接口。

     

    有了USB接口之后的PC机箱背后的接口

    总的来说,在USB出现之前,各种接口太多,而且都不太容易使用,互相之间的兼容性也较差,因此,才出现了USB。

    而万能的USB接口出现的话,整个PC机箱背后的接口,就不那么繁杂,显得清静多了:

     

    而在有了USB后的台式机中,鼠标,键盘,调制解调器,复印机,打印机,移动硬盘,以及相对于USB出现更后的设备大多数都选择了USB接口。

    USB出现的最初的目的,根据USB规范中的解释,是为了:

    1. 将PC和电话能连起来

      由于大家都认识到,下一代的应用,肯定是实现计算机设备和通讯设备的完美融合。而且,为了实现移动领域内的人机数据的交互,也需要方便且不贵的连接方案。

      <p>但是,计算机领域和通讯领域却是各自为政的发展,没有考虑互联性。由此,USB的出现,就是为了解决这一类互联问题的</p>
      </li>
      <li>方便用户使用
      <p>以前的一些设备,多数不支持即插即用,而且很多设备还需要懂行的用户去手动配置,然后才可以正常工作</p>
      
      <p>而USB的出现,使得用户不用关心设备的细节,不需要去另外再配置什么参数,直接插上就可以用了,而且还支持即插即用,很是方便</p>
      </li>
      <li>接口扩展性要好
      <p>之前的众多接口,导致不同的应用,需要使用不同的接口,很是繁琐。</p>
      
      <p>USB的出现,支持众多的应用,都使用统一的USB的接口,方便了用户,不需要再搞懂各种接口的用途和差异。</p>
      </li>
      

    总的来说,USB的出现,是希望通过此单个的USB接口,同时支持多种不同的应用,而且用户用起来也很方便,直接插上就能用了,也方便不同的设备的之间的互联。

    说白了,就相当于在之前众多的接口之上,设计出一个USB这么个万能的接口,以后各种外设,都可以用这一种接口即可。

    这估计也是USB的名称中的Universal通用的这一个词的来历吧。

    3.USB的通用标识

     

    说明:USB基础主要是说一些概念性的东西,所以大多信息都是来自网络,如有侵权麻烦留言联系我删除。

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

    展开全文
  • 从零开始学USB(十七、USB的枚举)

    千次阅读 多人点赞 2019-01-05 23:52:33
    USB枚举,USB Emulation,字面意思看,就是去列举USB,而列举啥呢,其实就是USB的初始化。 简单来说,USB的枚举,对应的就是USB的Host和Device之间的对话,即Host根据Device所报告上来的参数,得知USB的device是啥...

    一、什么是枚举?

    USB枚举,USB Emulation,从字面意思看,就是去列举USB,而列举啥呢,其实就是USB的初始化。
    简单来说,USB的枚举,对应的就是USB的Host和Device之间的对话,即Host根据Device所报告上来的参数,得知USB的device是啥类型的,具有啥功能,然后初始化相关参数,这样主机就可以根据这些信息来加载合适的驱动程序。只要枚举成功了,那么就已经成功大半了。接下来,就USB Device就可以正常工作了。
    所以,可以简单的理解为,USB枚举,就是USB设备的初始化(init)。

    二、枚举的步骤

    下面列出USB2.0协议中,给出的枚举步骤。

    1. The hub to which the USB device is now attached informs the host of the event via a reply on its status change pipe (refer to Section 11.12.3 for more information). At this point, the USB device is in the Powered state and the port to which it is attached is disabled.
    2. The host determines the exact nature of the change by querying the hub.
    3. Now that the host knows the port to which the new device has been attached, the host then waits for at least 100 ms to allow completion of an insertion process and for power at the device to become stable.The host then issues a port enable and reset command to that port. Refer to Section 7.1.7.5 for sequence of events and timings of connection through device reset.
    4. The hub performs the required reset processing for that port (see Section 11.5.1.5). When the reset signal is released, the port has been enabled. The USB device is now in the Default state and can draw no more than 100 mA from VBUS. All of its registers and state have been reset and it answers to the default address.
    5. The host assigns a unique address to the USB device, moving the device to the Address state.
    6. Before the USB device receives a unique address, its Default Control Pipe is still accessible via the default address. The host reads the device descriptor to determine what actual maximum data payload size this USB device’s default pipe can use.
    7. The host reads the configuration information from the device by reading each configuration zero to n-1, where n is the number of configurations. This process may take several milliseconds to complete.
    8. Based on the configuration information and how the USB device will be used, the host assigns a configuration value to the device. The device is now in the Configured state and all of the endpoints in this configuration have taken on their described characteristics. The USB device may now draw the amount of VBUS power described in its descriptor for the selected configuration. From the device’s point of view, it is now ready for use.

    When the USB device is removed, the hub again sends a notification to the host. Detaching a device disables the port to which it had been attached. Upon receiving the detach notification, the host will update its local topological information.

    上面USB2.0协议中给的步骤太官方化了,下面我根据网友的总结和自己的理解,用白话来描述一下。

     

    1.设备上电

    用户把USB设备插入USB端口(主机下的根hub或主机下行端口上的hub端口)或给系统启动时设备上电。此时,USB设备处于加电状态,它所连接的端口是无效的。

    2.检测电压变化,报告主机

    USB设备上电后,一直监测USB设备接口电平变化HUB检测到有电压变化,将利用自己的中断端点将信息反馈给主控制器有设备连接。

    这一步是HUB给主机报告有设备连接。(如下图,空闲状态,接上设备HUB总线电平会变化)

    3.主机了解连接设备

    每个hub利用它自己的中断端点向主机报告它的各个端口的状态(对于这个过程,设备是看不到的,也不必关心),报告的内容只是hub端口的设备连接/断开的事件。如果有连接/断开事件发生,那么host会发送一个 Get_Port_Status请求(request)给hub以了解此次状态改变的确切含义。Get_Port_Status等请求属于所有hub都要求支持的hub类标准请求(standard hub-class requests)。

    4.Hub检测所插入的设备是高速还是低速

     hub通过检测USB总线空闲(Idle)时差分线的高低电压来判断所连接设备的速度类型,当host发来Get_Port_Status请求时,hub就可以将此设备的速度类型信息回复给host。USB 2.0规范要求速度检测要先于复位(Reset)操作。

    根据是D+还是D-被拉高来判断到底是什么设备(全速/低速)插入端口(全速、高速设备的区分在前面的文章中有描述)

    5.hub复位设备

    主机一旦得知新设备已连上以后,它至少等待100ms以使得插入操作的完成以及设备电源稳定工作。然后主机控制器就向hub发出一个 Set_Port_Feature请求让hub复位其管理的端口(刚才设备插上的端口)。hub通过驱动数据线到复位状态(D+和D-全为低电平 ),并持续至少10ms。当然,hub不会把这样的复位信号发送给其他已有设备连接的端口,所以其他连在该hub上的设备自然看不到复位信号,不受影响。(如下图,hub的每个接口是单独检测的)
     

    6. Host检测所连接的全速设备是否是支持高速模式

     因为根据USB 2.0协议,高速(High Speed)设备在初始时是默认全速(Full Speed )状态运行,所以对于一个支持USB 2.0的高速hub,当它发现它的端口连接的是一个全速设备时,会进行高速检测,看看目前这个设备是否还支持高速传输,如果是,那就切到高速信号模式,否则就一直在全速状态下工作。
    同样的,从设备的角度来看,如果是一个高速设备,在刚连接bub或上电时只能用全速信号模式运行(根据USB 2.0协议,高速设备必须向下兼容USB 1.1的全速模式)。随后hub会进行高速检测,之后这个设备才会切换到高速模式下工作。假如所连接的hub不支持USB 2.0,即不是高速hub,不能进行高速检测,设备将一直以全速工作。

    7.Hub建立设备和主机之间的信息通道
    主机不停地向hub发送Get_Port_Status请求,以查询设备是否复位成功。Hub返回的报告信息中有专门的一位用来标志设备的复位状态。
    当hub撤销了复位信号,设备就处于默认/空闲状态(Default state),准备接收主机发来的请求。设备和主机之间的通信通过控制传输,默认地址0,端点号0进行。此时,设备能从总线上得到的最大电流是100mA。(所有的USB设备在总线复位后其地址都为0,这样主机就可以跟那些刚刚插入的设备通过地址0通信。)

    8.主机发送Get_Descriptor请求获取默认管道的最大包长度

    默认管道(Default Pipe)在设备一端来看就是端点0。主机此时发送的请求是默认地址0,端点0,虽然所有未分配地址的设备都是通过地址0来获取主机发来的请求,但由于枚举过程不是多个设备并行处理,而是一次枚举一个设备的方式进行,所以不会发生多个设备同时响应主机发来的请求。
    设备描述符的第8字节代表设备端点0的最大包大小。虽然说设备所返回的设备描述符(Device Descriptor)长度只有18字节,但系统也不在乎,此时,描述符的长度信息对它来说是最重要的,其他的瞄一眼就过了。当完成第一次的控制传输后,也就是完成控制传输的状态阶段,系统会要求hub对设备进行再一次的复位操作(USB规范里面可没这要求)。再次复位的目的是使设备进入一个确定的状态。

    9.主机给设备分配一个地址

    主机控制器通过Set_Address请求向设备分配一个唯一的地址。在完成这次传输之后,设备进入地址状态(Address state),之后就启用新地址继续与主机通信。这个地址对于设备来说是终生制的,设备在,地址在;设备消失(被拔出,复位,系统重启),地址被收回。同一个设备当再次被枚举后得到的地址不一定是上次那个了。
    10.主机获取设备的信息

    主机发送 Get_Descriptor请求到新地址读取设备描述符,这次主机发送Get_Descriptor请求可算是诚心,它会认真解析设备描述符的内容。设备描述符内信息包括端点0的最大包长度,设备所支持的配置(Configuration)个数,设备类型,VID(Vendor ID,由USB-IF分配), PID(Product ID,由厂商自己定制)等信息。
    之后主机发送Get_Descriptor请求,读取配置描述符(Configuration Descriptor),字符串等,逐一了解设备更详细的信息。事实上,对于配置描述符的标准请求中,有时wLength一项会大于实际配置描述符的长度(9字节),比如255。这样的效果便是:主机发送了一个Get_Descriptor_Configuration 的请求,设备会把接口描述符,端点描述符等后续描述符一并回给主机,主机则根据描述符头部的标志判断送上来的具体是何种描述符。
    接下来,主机就会获取配置描述符。配置描述符总共为9字节。主机在获取到配置描述符后,根据里面的配置集合总长度,再获取配置集合。配置集合包括配置描述符,接口描述符,端点描符等等。
    如果有字符串描述符的话,还要获取字符串描述符。另外HID设备还有HID描述符等。

    11.主机给设备挂载驱动(复合设备除外)

    主机通过解析描述符后对设备有了足够的了解,会选择一个最合适的驱动给设备。  然后tell the world(announce_device)说明设备已经找到了,最后调用设备模型提供的接口device_add将设备添加到 usb 总线的设备列表里,然后 usb总线会遍历驱动列表里的每个驱动,调用自己的 match(usb_device_match) 函数看它们和你的设备或接口是否匹配,匹配的话调用device_bind_driver函数,现在就将控制权交到设备驱动了。   
    对于复合设备,通常应该是不同的接口(Interface)配置给不同的驱动,因此,需要等到当设备被配置并把接口使能后才可以把驱动挂载上去。

    12.设备驱动选择一个配置
    驱动程序根据前面设备回复的信息,发送Set_Configuration请求来正式确定选择设备的哪个配置(Configuration)作为工作配置(对于大多数设备来说,一般只有一个配置被定义)。至此,设备处于配置状态(Configured),当然,设备也应该使能它的各个接口(Interface)。
    对于复合设备,主机会在这个时候根据设备接口信息,给它们挂载驱动。
     

     

    USB协议定义了设备的6种状态,仅在枚举过程中,设备就经历了4个状态的迁移:上电状态(Powered),默认状态(Default),地址状态(Address)和配置状态(Configured)(其他两种是连接状态(Attached)挂起状态(Suspend),前面文章中有描述)。

     

    三、举例

     

    下面以一个鼠标的枚举过程为例,来学习枚举的过程。

    注:这个鼠标是一个低速设备,从传输后面的LS就可以看出。

    可以看到,鼠标的枚举总共经历了0~10共11个传输(标号11的传输为中断传输,已经不是枚举使用的控制传输了)

    下面就根据这11个传输,单独分析,学习总结USB设备的枚举(这里是从上面总结的枚举的第八步开始的)。

     

     

    3.1.获取设备描述符

    3.1.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 00 01 00 00 12 00

    注:这个阶段的设备地址(address)用的0,当然默认端点(endpoint)也是0。

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

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

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

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

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

    从上一节的学习可以很容易得到,这是一个获取设备描述符的请求。

    3.1.2 数据传输分析

    设备给主机回复的数据为18个字节HEX:12 01 00 02 00 00 00 08 64 0D 18 C0 01 43 01 02 00 01 

    接下来看一下设备给主机回复的设备描述符信息。

    /* USB_DT_DEVICE: Device descriptor */
    struct usb_device_descriptor {
    	__u8  bLength             = 0x12;    //该描述符长度为18字节
    	__u8  bDescriptorType     = 0x1;     //从16节的表9-5可知,1代表的描述符时设备描述符            
    
    	__le16 bcdUSB             = 0x200;   //该位表示版本号,使用BCD码表示,即USB2.0版本        
    	__u8  bDeviceClass        = 0x0;     //0代表由接口指出类信息
    	__u8  bDeviceSubClass     = 0x0;     //子类,bDeviceClass 域为零,此域也须为零
    	__u8  bDeviceProtocol     = 0x0;     //协议码,0代表没指定任何协议
    	__u8  bMaxPacketSize0     = 0x8;     //端点0,最大包支持8个字节(低速8个字节)
    	__le16 idVendor           = 0x046D;  //厂商标志(学习可以不用关心)
    	__le16 idProduct          = 0xC010;  //产品标志(学习可以不用关心)
    	__le16 bcdDevice          = 0x431;  //设备发行号,用BCD码表示,4.31版本(学习可以不用关心)
    	__u8  iManufacturer       = 0x1;     //描述厂商信息的字符串描述符的索引值
    	__u8  iProduct            = 0x2;     //描述产品信息的字串描述符的索引值
    	__u8  iSerialNumber       = 0x0;     //描述设备序列号信息的字串描述符的索引值
    	__u8  bNumConfigurations  = 0x1;     //可能的配置描述符数目,这个鼠标设备就支持一个配置
    } __attribute__ ((packed));
    

     

    3.1.3 状态阶段

    状态阶段比较简单,是以一个固定的,数据数量为0的 事务结束这次控制传输。

    本次控制传输如果有数据包,状态阶段的令牌包和最后一个数据包方向相反。

    本次控制传输如果无数据包,则固定的IN令牌包,结束这次控制传输。

     

    3.2 再次对设备复位

    hub通过驱动数据线到复位状态(D+和D-全为低电平 ),并持续至少10ms(可以看到这里hub对设备的复位时间是10.113ms)。

    3.3 设置地址

     

    数据为HEX:00 05 03 00 00 00 00 00

    注:这个阶段的设备地址(address)用的0,当然默认端点(endpoint)也是0。

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

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

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

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

    第七八字节同上。

    本次传输(设置地址)无可选的数据阶段。

    同时既然设备地址已经设置好,那么下一阶段,就应该用新的设置的设备地址了。

     

    3.4 再次获取设备描述符

     

    这次要注意,这里以及使用新分配的设备地址3了,而不是默认地址0。同时后面也都会使用新分配的地址来通信

    当然这里因为是再次获取的设备描述符,所以它和3.1分析的数据是一样的。这里就不再次分析了,直接搬过来。

    3.4.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 00 01 00 00 08 00

    注:这个阶段的设备地址(address)用的0,当然默认端点(endpoint)也是0。

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

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

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

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

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

    从上一节的学习可以很容易得到,这是一个获取设备描述符的请求。

    3.4.2 数据传输分析

    设备给主机回复的数据为18个字节HEX:12 01 00 02 00 00 00 08 64 0D 18 C0 01 43 01 02 00 01 

    接下来看一下设备给主机回复的设备描述符信息。

    /* USB_DT_DEVICE: Device descriptor */
    struct usb_device_descriptor {
    	__u8  bLength             = 0x12;    //该描述符长度为18字节
    	__u8  bDescriptorType     = 0x1;     //从16节的表9-5可知,1代表的描述符是设备描述符            
    
    	__le16 bcdUSB             = 0x200;   //该位表示版本号,使用BCD码表示,即USB2.0版本        
    	__u8  bDeviceClass        = 0x0;     //0代表由接口指出类信息
    	__u8  bDeviceSubClass     = 0x0;     //子类,bDeviceClass 域为零,此域也须为零
    	__u8  bDeviceProtocol     = 0x0;     //协议码,0代表没指定任何协议
    	__u8  bMaxPacketSize0     = 0x8;     //端点0,最大包支持8个字节(低速8个字节)
    	__le16 idVendor           = 0x046D;  //厂商标志(学习可以不用关心)
    	__le16 idProduct          = 0xC010;  //产品标志(学习可以不用关心)
    	__le16 bcdDevice          = 0x4301;  //设备发行号,用BCD码表示,43.01版本(学习可以不用关心)
    	__u8  iManufacturer       = 0x1;     //描述厂商信息的字符串描述符的索引值
    	__u8  iProduct            = 0x2;     //描述产品信息的字串描述符的索引值
    	__u8  iSerialNumber       = 0x0;     //描述设备序列号信息的字串描述符的索引值
    	__u8  bNumConfigurations  = 0x1;     //可能的配置描述符数目,这个鼠标设备就支持一个配置
    } __attribute__ ((packed));
    

     

     

    3.5 获取配置描述符

    3.5.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 00 02 00 00 09 00

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

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

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

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

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

    从上一节的学习可以很容易得到,这是一个获取配置描述符的请求。

    3.5.2 数据传输分析 

    设备给主机回复的数据为9个字节HEX:09 02 22 00 01 01 00 A0 32

    接下来看一下设备给主机回复的配置描述符信息。

     struct usb_config_descriptor {
    	__u8  bLength            = 0x09;    //此描述符长度为9
    	__u8  bDescriptorType    = 0x02;    ///从16节的表9-5可知,2代表的配置描述符 
    
    	__le16 wTotalLength      = 0x22;    //此配置信息的总长为34字节(包括配置,接口,端点和设备类及厂商定义的描述符)
    	__u8  bNumInterfaces     = 0x01;    //表示有一个接口描述符
    	__u8  bConfigurationValue= 0x01;    //在SetConfiguration()请求中用1作参数来选定此配置
    	__u8  iConfiguration     = 0x00;    //描述此配置的字串描述表索引
    	__u8  bmAttributes       = 0xA0;    //D7: 保留(设为一)D6: 自给电源 D5: 远程唤醒 D4..0:保留(设为一)   表示这是一个由总线供电,并支持远程唤醒功能(可以睡眠节约电)
    	__u8  bMaxPower          = 0x32;    //在此配置下的总线电源耗费量。以 2mA 为一个单位 即2 * 50 = 100ms
    } __attribute__ ((packed));

    3.5.3 状态阶段

    所有的状态阶段都遵循3.1.3的要求,这里不再分析。

     

    3.6 获取其它描述符

    上一步在配置描述符中已经知道了配置描述符+接口描述符+端点描述符+设备类描述符+厂商定义的描述符的总字节长度为34个字节。

    本次传输,就会一次性的全部获取过来。

    一张图片放不下,分两次截图放下。

    3.6.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 00 02 00 00 22 00

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

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

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

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

    第六七字节为0x22,即代表返回的数据不应该多于34个字节(因为实际上次读取配置描述符已经知道多个描述符总和为34字节了)。

    从上一节的学习可以很容易得到,这是一个获取配置描述符的请求。

    3.6.2 数据传输分析 

    设备给主机回复的数据为34个字节HEX:

    09 02 22 00 01 01 00 A0 32 09 04 00 00 01 03 01 02 00 09 21 11 01 00 01 22 34 00 07 05 81 03 05 00 0A

    接下来看一下设备给主机回复的配置描述符信息。

    第一步肯定是先拆分数据了。

    从我描述符学习这一章可以知道 (如下链接)

    https://blog.csdn.net/qq_16777851/article/details/85222030

    所有描述的第一个字节都是这个描述符的长度,那么我们只要根据第一个字节确定这描述符的个数,一次类推,就能查分成多个描述符。

    1. 09 02 22 00 01 01 00 A0 32
    2. 09 04 00 00 01 03 01 02 00
    3. 09 21 11 01 00 01 22 34 00
    4. 07 05 81 03 05 00 0A

    拆分后的如上所示,每行的第一个字节都是本行所代表的描述符的字节数。

    3.6.2.1 配置描述符 

    09 02 22 00 01 01 00 A0 32

    第一行的在3.5节已经分析过了,是配置描述符。

    3.6.2.2 接口描述符

    09 04 00 00 01 03 01 02 00

    从第二个字节的04,通常查看16节的表9-5可以知道,这是一个接口描述符。

    struct usb_interface_descriptor {
    	__u8  bLength              = 0x09;    //该描述符的字节数
    	__u8  bDescriptorType      = 0x04;    //描述符类型,4代表接口描述符
    
    	__u8  bInterfaceNumber     = 0x0;     //接口号,当前配置支持的接口数组索引(从零开始)
    	__u8  bAlternateSetting    = 0x0;     //可选设置的索引值,这里无
    	__u8  bNumEndpoints        = 0x01;    //端点描述符数量,1个    
    	__u8  bInterfaceClass      = 0x03;    //接口所属的类值,由USB说明保留,	3代表人机接口类(HID)
    	__u8  bInterfaceSubClass   = 0x01;    //子类码 这些值的定义视bInterfaceClass域而定
    	__u8  bInterfaceProtocol   = 0x02;    //协议码:bInterfaceClass 和bInterfaceSubClass 域的值而定
    	__u8  iInterface           = 0x00;    //描述此接口的字串描述表的索引值
    } __attribute__ ((packed));
    

    前面章节,没有学到类这个分类概念,这里把用到的这个先列出来,下一节再学习由接口描述符中,指定的各种设备类型。

     

    USB Class Codes    

    Base Class

    Descriptor Usage

    Description

    00h

    Device

    Use class information in the Interface Descriptors

    01h

    Interface

    Audio  

    02h

    Both

    Communications and CDC Control

    03h

    Interface

    HID (Human Interface Device)

    05h

    Interface

    Physical

    06h

    Interface

    Image

    07h

    Interface

    Printer

    08h

    Interface

    Mass Storage

    09h

    Device

    Hub

    0Ah

    Interface

    CDC-Data

    0Bh

    Interface

    Smart Card

    0Dh

    Interface

    Content Security

    0Eh

    Interface

    Video

    0Fh

    Interface

    Personal Healthcare

    10h

    Interface

    Audio/Video Devices

    11h

    Device

    Billboard Device Class

    12h

    Interface

    USB Type-C Bridge Class

    DCh

    Both

    Diagnostic Device

    E0h

    Interface

    Wireless Controller

    EFh

    Both

    Miscellaneous

    FEh

    Interface

    Application Specific

    FFh

    Both

    Vendor Specific

     

    类-子类-协议码 最终得到我们这个是一个鼠标设备。有一个端点,可想而知就是输入端点,比较鼠标就是一个输入类设备。

    3.6.2.3 HID类描述符

    09 21 11 01 00 01 22 34 00

    因为标准的USB2.0协议没定义class的信息,所以只能去USB官网查找补充资料。

    下面是USB1.11版本的HID手册中的HID描述符信息。

    下面是linux内核中定义的HID描述符。

    /*
     * USB types, the second of three bRequestType fields
     */
    #define USB_TYPE_MASK			(0x03 << 5)
    #define USB_TYPE_STANDARD		(0x00 << 5)        //标准的
    #define USB_TYPE_CLASS			(0x01 << 5)        //类的
    #define USB_TYPE_VENDOR			(0x02 << 5)        //厂商自己定义的
    #define USB_TYPE_RESERVED		(0x03 << 5)        //保留的
    
    
    /*
     * HID class descriptor types
     */
    
    #define HID_DT_HID			    (USB_TYPE_CLASS | 0x01)
    #define HID_DT_REPORT			(USB_TYPE_CLASS | 0x02)
    #define HID_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)
    
    
    struct hid_class_descriptor {
    	__u8  bDescriptorType;
    	__le16 wDescriptorLength;
    } __attribute__ ((packed));
    
    struct hid_descriptor {
    	__u8  bLength;
    	__u8  bDescriptorType;
    	__le16 bcdHID;
    	__u8  bCountryCode;
    	__u8  bNumDescriptors;
    
    	struct hid_class_descriptor desc[1];
    } __attribute__ ((packed));
    
    /**********************************************************/
    
    struct hid_class_descriptor {
    	__u8  bDescriptorType     = 0x22;    //HID_DT_REPORT,表示这个类描述符是一个报告类的描述符
    	__le16 wDescriptorLength  = 0x0034;  //描述符的总字节数为52字节
    } __attribute__ ((packed));
    
    struct hid_descriptor {
    	__u8  bLength         = 0x09;    //描述符长度
    	__u8  bDescriptorType = 0x21;    //HID_DT_HID 
    	__le16 bcdHID         = 0x0111;  //1.11版本,bcd码表示
    	__u8  bCountryCode    = 0x0;     //本地化支持,0不支持
    	__u8  bNumDescriptors = 0x1;     //表示这设备有1个类描述符
    
    	struct hid_class_descriptor desc[1];
    } __attribute__ ((packed));
    

    报表描述符看后面分析,注意将来就用这里的52来读取报表描述符的字节数。

    3.6.2.4 端点描述符

    07 05 81 03 05 00 0A

    这里05,在标准的描述符表中有,所以很容易查找,这是一个端点描述符。

    struct usb_endpoint_descriptor {
    	__u8  bLength            = 0x07;    //该描述符占用7个字节
    	__u8  bDescriptorType    = 0x05;    //是一个端点描述符
    
            //Bit3..0:端点号 Bit6..4:保留,为零 Bit7:方向,如果控制端点则略。 
            //0:输出端点(主机到设备) 1:输入端点(设备到主机) 所以在这是一个端点号为1的输入端点
    	__u8  bEndpointAddress   = 0x81;    
    	__u8  bmAttributes       = 0x3;     //00=控制传送 01=同步传送 10=批传送 11=中断传送   这是一个中断端点            
    	__le16 wMaxPacketSize    = 0x0005;  //最大包大小为5个字节
    	__u8  bInterval          = 0x0A;    //周期数据传输端点的时间间隙。1ms * 10 = 10ms
    
    	/* NOTE:  these two are _only_ in audio endpoints. */
    	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
            /* 下面两个只有在图像视频类中才会有 */
    	__u8  bRefresh;
    	__u8  bSynchAddress;
    } __attribute__ ((packed));
    

     

    3.7 获取字符串描述符语言ID

    3.7.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 00 03 00 00 FF 00

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

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

    第三四字节传的是0x0300 ,查看9-5描述符表,得知高字节表示描述符类型,01表示设备,02表示配置,3表示字符串;低字节表示索引。比如设备有多个配置,那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口,通过索引选择不同的接口。所以这里高字节的3表示字符串,低字节为索引0。

    第四五字节为0x0,当这个请求的是字符串描述符时,则表示Langurage ID。

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

    从上一节的学习可以很容易得到,这是一个获取字符串描述符的请求。

    3.7.2 数据传输分析 

    设备给主机回复的数据为4个字节HEX:04 03 09 04

    接下来看一下设备给主机回复字符串描述符信息。

    struct usb_string_descriptor {
    	__u8  bLength            = 0x04;    //长度4字节
    	__u8  bDescriptorType    = 0x03;    //3代表字符串描述符
    
    	__le16 wData[1]          = 0x0409;	/* UTF-16LE encoded 代表0x0409的语言编码 */
    } __attribute__ ((packed));
    
    

    0x0409代表的是美式英语,0x0804代表的是简体中文,这个具体的语言编码可以从USB或其它类似网站获取到。

    既然以及获取到了具体的语言ID,那么就可以用前面设备描述符中读到的厂商和产品字符串描述符的索引index读到具体的商家和产品信息了。对应的字符串,并按照响应的语言格式来解析了。

     

    3.8 获取字符串描述符(产品信息)

    今天先分析到

    3.8.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 02 03 09 04 FF 00 

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

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

    第三四字节传的是0x0302 ,查看9-5描述符表,得知高字节表示描述符类型,01表示设备,02表示配置,3表示字符串;低字节表示索引。比如设备有多个配置,那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口,通过索引选择不同的接口。所以这里高字节的3表示字符串,低字节为索引2

    第四五字节为0x0409,当这个请求的是字符串描述符时,则表示Langurage ID,0x0409表示美式英语

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

    从上一节的学习可以很容易得到,这是一个获取字符串描述符的请求,索引值为2。

    从前面设备描述符中的字符串描述符的索引值可以看出,2代表是索引的产品信息。

    3.8.2 数据传输分析 

    设备给主机回复的数据为36个字节HEX:

    24 03 55 00 53 00 42 00 20 00 4F 00 70 00 74 00 69 00 63 00 61 00 6C 00 20 00 4D 00 6F 00 75 00 73 00 65 00 

    接下来看一下设备给主机回复字符串描述符信息。

    struct usb_string_descriptor {
    	__u8  bLength            = 0x24;       //36字节的字符串描述符
    	__u8  bDescriptorType    = 0x3;        //3表示字符串描述符
    
    	__le16 wData[1];		/* UTF-16LE encoded,一个字符用16bit表示 */
    } __attribute__ ((packed));
    
    

    当然,因为美式英语都死ASCII码内的字符表示的,所以高字节都是保留为0的,如果是简体中文,繁体中文,日语,韩语这类一个字符需要两个字节表示的则高字节也要用到。

    简单对照ASCII码表,即可找到数字对应的这几个字符。

    USB Optical Mouse

    即得到这个产品的信息,这是一个USB的光点鼠标。

     

    3.9 获取字符串描述符(商家信息)

     

    3.9.1 建立阶段的请求分析

    请求数据为8个字节HEX:80 06 01 03 09 04 FF 00 

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

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

    第三四字节传的是0x0302 ,查看9-5描述符表,得知高字节表示描述符类型,01表示设备,02表示配置,3表示字符串;低字节表示索引。比如设备有多个配置,那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口,通过索引选择不同的接口。所以这里高字节的3表示字符串,低字节为索引1

    第四五字节为0x0409,当这个请求的是字符串描述符时,则表示Langurage ID,0x0409表示美式英语

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

    从上一节的学习可以很容易得到,这是一个获取字符串描述符的请求,索引值为1。

     

    从前面设备描述符中的字符串描述符的索引值可以看出,1代表是索引的厂商信息。

    3.9.2 数据传输分析 

    设备给主机回复的数据为18个字节HEX:

    12 03 4C 00 6F 00 67 00 69 00 74 00 65 00 63 00 68 00 

    接下来看一下设备给主机回复字符串描述符信息。

    struct usb_string_descriptor {
    	__u8  bLength            = 0x14;       //18字节的字符串描述符
    	__u8  bDescriptorType    = 0x3;        //3表示字符串描述符
    
    	__le16 wData[1];		/* UTF-16LE encoded,一个字符用16bit表示 */
    } __attribute__ ((packed));
    
    

    当然,因为美式英语都死ASCII码内的字符表示的,所以高字节都是保留为0的,如果是简体中文,繁体中文,日语,韩语这类一个字符需要两个字节表示的则高字节也要用到。

    简单对照ASCII码表,即可找到数字对应的这几个字符。

    Logitech

    即得到这个厂商的信息,这是一个罗技的产品。

     

    3.10 设置配置描述符

    3.10.1 建立阶段的请求分析

    请求数据为8个字节HEX:00 09 01 00 00 00 00 00 

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

    第二个字节0x09查看表9-4可以得到这是一个SET_CONFIGURATION,即设置配置

    第三四字节传的是0x1,查看9-3标准请求表,得知这里1就是配置的值。

    第四五字节为0x0,在设置配置里,无意义。

    第六七字节为0x0,在设置配置里,无意义。

    从上一节的学习可以很容易得到,这是一个设置配置描述符的请求。

    3.10.2 无数据阶段

     

    3.11 设置限定报表

    3.11.1 建立阶段的请求分析

    请求数据为8个字节HEX: 21 0A 00 00 00 00 00 00 

    第一个字节0x21拆分可以得到,这是一个主机发给接口(bit0~bit4)的一个类(bit5~bit6)的请求命令,请求的结果是主机给接口发送类命令(bit7 == 0)

    因为这是一个HID类设备,这里有是设置的类设备,标准手册没有,所以查看HID手册,

    可见这里就是使能Set_Idle功能,Set_Idle请求使中断输入管道上的特定报告静默,直到发生新事件或经过指定的时间。

    详细来Set_Idle可以看HID手册,说的比较清晰。

    3.11.2 无数据阶段

     

    3.12 获取HID报表描述符

     

     

    设置限定报表和获得报表信息,都属于HID类中的特殊的类描述符,暂时还没学习,在后面章节慢慢学习...

    这篇博文就不再加了,后面学完后,我会在这里贴上响应链接,保证知识完整性。

     

     

     

     

    展开全文
  • 从零开始学USB(四、USB系统结构)

    千次阅读 多人点赞 2018-12-14 21:35:49
    一个USB系统可以三个定义区域来描述: USB互联 USB设备 USB主机 USB互连是USB设备与USB主机连接和通信的方式。 这包括以下内容: 总线拓扑:USB设备与主机之间的连接模型。 层间关系:USB在系统中的每一层都要...

    一个USB系统可以从三个定义区域来描述:

    • USB互联
    • USB设备
    • USB主机

    USB互连是USB设备与USB主机连接和通信的方式。 这包括以下内容:

    总线拓扑:USB设备与主机之间的连接模型。
    层间关系:USB在系统中的每一层都要完成一定的任务。
    数据流模型:数据在生产者之间通过USB在系统中移动的方式和消费者。
    任务规划:USB提供可以共享的互连机制。通过规划对互连机制的访问,可以支持同步 

    1.总线拓扑结构

    USB设备和USB主机通过USB总线连接。USB的物理连接是一个星型结构,集线器(HUB)位于每个星形结构的中心,每一段都是主机和某个集线器,或某一功能设备之间的一个点到点的连接,也可以是一个集线器或功能模块之间的点到点的连接。

    上图给出了USB的拓扑结构。

    由于时间限制允许集线器和电缆传播时间,最大层数允许为7(包括根层)。

    请注意,在七层中,主机和任何设备之间的通信路径中最多可以支持五个非根集线器。

    Host端有一个Root Hub,可提供一个或多个USB下行端口,每个端口可以连接一个USB Hub或一个USB Device。USB Hub,是用于USB 端口扩展的,即USB Hub可以将一个USB端口扩展为多个端口,图1中的每个Func(Function)就是一个USB Device,如USB键盘,USB鼠标,USB MODEM,USB硬盘等等。

    Compound Device是指带一个Hub和一个或多个不可删除的USB Device的复合设备,一个USB系统可连接多达127个Function。

     

    USB主机(USB Host):任何USB系统中只有一个主机。 主机系统的USB接口称为主机控制器。 主机控制器可以以硬件,固件或的组合来实现软件。 根集线器集成在主机系统内以提供一个或多个端点。PC端的USB都是Host,所以将两台PC的USB口通过A-A USB电缆连接起来,是不能实现通信,如果将两个host连起来通信,这样一来的一个USB的系统有了两个的host,与它的网络协议冲突。此处,OTG引入了一个新的概念,HNP(Host Negotiation Protocol),主机协商协议,允许两个设备之间互相协商谁去当Host。不过,即使在OTG中,也只是同一时刻,只存在单个的Host,而不允许存在多个Host的。

    USB设备:

    • 集线器:提供可以访问USB总线的更多的接入点。
    • 功能部件:向系统提供特定的功能,如鼠标,键盘,音响等。

    当然,一个USB设备要能正常工作,必须满足一下条件:

    1. 支持USB协议
    2. 可以对诸如配置和复位等标准的USB操作做出相应
    3. 具有标准的描述消息

    注意:一个USB系统只能有一个USB主控制器,用8位地址表示下面的USB设备, 一共128个地址。但是USB主控制器下面必须带一个Root Hub, hub也算一个设备,换句话说, 还剩下 127个地址给用户。

     

    展开全文
  • 从零开始学USB(十八、USB的class)

    千次阅读 2019-01-08 23:20:44
    关于USB的Class,对于学习USB协议的人,估计早就听到过此名词了。 而对于USB的Class的分类,此处先列出那个最基本的分类表: Base Class Descriptor Usage Description 00h ...
  • 从零开始学USB(十、USB的描述符)

    万次阅读 多人点赞 2018-12-23 14:10:27
    USB设备使用描述符报告其属性。描述符是具有定义格式的数据结构。每个描述符都以字节宽度字段开头,该字段包含描述符中的总字节数,后跟一个标识描述符类型的字节宽度字段。 使用描述符允许简单地存储各个配置的...
  • 当然,现在只是简单的开始usb设备驱动开始,后面再慢慢的分析usb总线,usb的hub之类。 先给出代码,后面再一句一句分析。 #include &lt;linux/kernel.h&gt; #include &lt;linux/slab.h&gt; #...
  • 从零开始学USB(三、基础知识3)

    千次阅读 多人点赞 2018-12-12 21:32:14
    1. USB 2.0协议内容概览 当前最新的USB协议,已经发展到USB 3.0了。但是主流的USB设备和技术,还是以USB 2.0居多。所以此文,主要是以USB 2.0为基础来学习USB协议的基础知识,当然,会在相关内容涉及到USB 3.0的...
  • USB是串行总线,所以数据是一位一位地在数据线上传送的。既然是一位一位传送的,就存在着一个数据位的先后问题。 USB采用的是LSB在前的方式,即现出来的是最低位的数据,接下来是次低位....最后是最高位(MSB)。一...
  • 设备可以连接到HUB上或者HUB上拔出.USB设备总线上拨出后的状态在规范没定义,只说明一旦USB连到总线要求的操作以及属性。 上电(Powered)  USB设备的电源可来自外部电源,也可从USB接口的集线器而来。电源来自...
  • USB电缆:标准的USB电缆包括一对用于电源分配的20~28AWG规格的线对和一对28AWG规格的双绞线,并具有屏蔽和完整的保护层。 高速(480 Mb / s)和全速(12 Mb / s)要求使用带有两根电源导线和双绞线信号导线的屏蔽...
  • 从零开始学USB(二、基础知识2)

    千次阅读 多人点赞 2018-12-08 21:40:55
    USB设备,物理上的逻辑结构来说,包含了主机Host端和设备Device端。 其中,主机Host端,有对应的硬件的USB的主机控制器Host Controller,而设备端,连接的是对应的USB设备。 1.1. USB控制器类型:OHCI,UHCI,...
  • 需要系统的不同视图不同实施者的角度解释具体的USB要求。 几个重要的必须支持概念和功能,以便为最终用户提供所需的可靠操作今天的个人电脑。 USB以分层的方式呈现,以便于解释和允许特定USB产品的实施者专注于...
  • 所有USB设备都响应设备默认控制管道上主机的请求。 这些请求是使用控制传输进行的。 请求和请求的参数将在Setup数据包中发送到设备。 主机负责建立表9-2中列出的字段中传递的值。 每个Setup数据包都有8个字节。 ...
  • 从零开始学USB(六、USB通讯的数据格式)

    千次阅读 多人点赞 2018-12-16 16:59:48
    USB中用NRZI来编码数据 前面章节已经学习过了USB的引脚定义了,但是对于其中的USB 2.0的两根数据线D+和D-所对应的数据传输,却没有详细介绍。此处就是介绍,在此串行数据线中,数据是如何被编码和传送的。 USB所...
  • 前面章节学习了USB的包的简要结构组成。本节四种分类上来学习一下他们的使用场景。   一、令牌包 令牌由PID组成,指定IN,OUT或SETUP数据包类型以及ADDR和ENDP字段。 PING特殊令牌包也具有与令牌包相同的...
  • 在前面的十一节中,学习了USB中传输中一个包是由多个域组成。 https://blog.csdn.net/qq_16777851/article/details/85226005   在前面的十二节中,学习了USB传输中学习了包的形式有哪些(令牌包、数据包、应答包...
  • 消息管道传输的数据以USB定义的结构传输,但USB允许特定设备的结构化数据在USB定义的消息数据有效负载内传输。 USB还定义了对于任何管道(流或消息),数据经过总线时都要进行分组,但最终在总线事务的数据有效载荷...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 141
精华内容 56
关键字:

从零开始学usb