内容原创,未经本人同意请勿转载。联系本人:jianshu_kevin@126.com
我想通过上文的《USB协议(一)》可以看出,USB虽然好用,但是对于程序员来说,这可是相当不简单的一块硬骨头,要啃下来没有一定的实力估计是很困难了。好的产品都是这样的,把简单留给用户,把复杂留给自己。
谈到通信,肯定就要想到数据线,没错USB通信就靠两根线D+,D-
,相当的简单对吧。可是我告诉你对于软件来说可不是这两根线这么简单。对于软件而言USB通信的基本单位端点以及基于端点的管道。
端点是USB芯片提供的基本通信单位,主机和设备之间的通信就是通过管道来实现的,管道的两头分别对应:主机的缓存,设备的端点。请看下面这幅图。
一. USB device 的另外一种描述方式
如果单从通信角度来说一个USB device可以这么描述:
device
{
interface1
{
pipe1
{
buffer,
endpoint
}
pipe2
{
buffer,
endpoint
}
...
}
interface2
{
pipe1
{
buffer,
endipoint
}
pipe2
{
buffer,
endpoint
}
pipe3
{
buffer,
endpoint
}
...
}
...
}
从上图可以看出如下包含关系
- 管道包含:缓存+端点
- 接口包含:多个管道
- 设备包含:多个接口
二. 为什么需要interface
到这里可能有人要问了,有管道了不就可以直接通信了吗,为什么还要封装成接口。这就不得不说很遗憾,endpoint只能单向通信,要么是host->device,要不是devie->host(端点0除外,后面再说)。而设备通信往往都是双向的,所以为了满足设备的功能,USB协议将多个管道组合到一起就形成了一个接口。
三. function对应interface
一个接口就可以完成USB主机和设备之间的通信了,对于普通设备而言,这个就可以看作一个设备了。USB的世界也是这个样子,但是USB这里,一个接口代表一个function,也就是一个USB虚拟设备。
例如:我手上的MTK设备,USB插入后可以枚举出两个串口,一个通AT指令,一个用来抓log。那么这两个虚拟串口就对应两个function,也就是两个接口。