USB总线协议基础知识
控制传输(Control Transfers)
: 或许你已经注意到了,一个usb host端口并不是仅仅支持一个Usb function.如图1,
通过usb hub,一个usb host端口可以连接usb鼠标,usb键盘,Usb写字板......。要连接这么多东西在同一个
usb host上,我们通常会有一个基本问题,即usb host如何识别这些被连接在它的端口上的设备呢。正如通常的
主从式通讯系统一样,如rs485多机通讯,我们通常是用一个特定的地址标志每一个从设备。对这里的usb,我们
采用同样的方法,将为每个挂接在该usb host上的usb function指定一个特定地址,通过这个特定地址来识别
每个usb function.看来这将是一个usb function在数据传输之前必须解决的问题--得到它的地址分配。
这个“地址指定”的过程需要usb host通知usb function才能完成,这个交互过程就是一个控制式传输。通过
这个“控制式传输”,usb host将指定地址给usb function ,以为即将进行的正式通讯做好准备工作。这里细心
的读者可能已经注意到了,既然usb host总要分配地址给usb function才能进行正式的数据传输工作,那么
usb host将如何与一个初始时未分配地址的usb function进行交互来分配地址呢。这里,是这样解决的:
usb协议保留了一个“通用地址”0,usb host 通过这个地址0来和初始未分配地址的usb function进行通讯,进行一
些初始的准备工作,诸如这里的为它非配一个特定地址。后面我们就会了解到,usb除了配置地址外,还有一些
其它参数需要事先主从双方达成共识。这些参数也都是通过控制式传输完成的。一个Usb 的控制式传输如图二:
一个Usb的控制式传输分为两个或三个阶段进行传输:setup stage,data stage(视情况而定),status stage。
- 首先是setup stage,联系上节所说的Usb传输模式,usb Host总是先发起第一个packet--这里它
- 首先发起setup,
- 之后发起以data0为起始的setup data,
- 最后usb function回应ack结束一次交互。
- 其次如果有data stage,类似的,还是按照上节说的usb传输模式,
-
- usb host总是先发起第一个Packet--Out(或in),
- 之后usb host(或usb function)发起以data1为起始的payload data,
- 最后Usb fuction(或usb host)回应ack结束一次交互。
- 如果数据未传完,继续data stage,同上继续。
-
- 最后是status stage,类似的,
- usb host首先发起第一个Packet--in(或out),
- 之后usb function(或usb host)发起以data1为起始的Null data(0长度),
- 最后Usb host(或usb function)回应ack结束一次交互。
如此,整个控制式传输结束。 你或许有疑问,data stage为什么进行了多次而非一次完成?实际上,usb总是将
一批大量的数据分成了许多小段来进行传输,称为一个pay load。这样传输的目的是容易对传输进行控制。既然
一次大量的数据总是被分成一段一段来分次传输,那么这里就出现了一个需要事先确定的参数(wMaxPacketSize):即每次即这个小段有多大。这个参数如地址指派一样,正式传输之前需要事先达成共识。通过控制式传输,现在我们
已经完成了usb function的地址指定等参数的设置工作,下一步可以进行正式的数据传输了。
块传输(bulk Transactions)
我们终于等到usb function 配置完成,现在我们的任务是要传送一批数据,这里可以使用批量数据传输(bulk Transactions)。 一个批量传输总是按照如图所示方式进行,
- 首先,usb host发起第一个Packet--in(或out),表示要开始数据传输了。
- 其次,usb function(或usb host)发起以data1(或data0)为起头的payload data,开始一次交互。
- 再其次,usb host(或Usb function)发起ack回应这次交互。 如果数据还为传完,继续上述过程,即:
- 首先,usb host再次发起一个Packet--in(或out),表示又要开始数据传输了。
- 其次,usb function(或usb host)发起以data0(或data1)为起头的payload data,开始又一次交互。
- 再次,usb host(或Usb function)发起ack回应这次交互。
这里的疑问依然是为什么一次可能传完的数据为什么分成多次进行传输,原因在上次介绍控制式传输式已经说明。
后面我们就会明白,为什么这样可以方便控制传输过程。 仔细看看控制式的data stage采用的传输方式,是否
就是批量传输方式呢?!注意,每次payload data的“牵头人”(preamble)在轮番掉换,先是data1,接着data0,
再是data1,......如此接替,只要有一次交互出现问题,这个接替规则就会被打破进而被Usb host识别而发现
传输异常。所以这个交替的“牵头人”规则是可靠数据传输的所采取的措施之一。
同步传输(Isochronous Transactions)和中断式传输(Interrupt Transactions)
在批量数据传输中,触发一次批量数据传输总是“被动”的,就是说需要数据传输时Usb host并不会主动发起
传输,而是需要得到你的指令。当你告诉它:“一切ok,让我们开始吧!” 这时它才开始数据传输。这种方式
显然在某些情况下并不适合。比如音视频流,你无法要求它听从你的“指挥”,让它等你发指令给usb host,
然后开始一次传输。我们需要的是一种“及时”传输。一个好的方案就是设置一个timer,按照tick发起usb传输。
这个tick通常以1ms(usb full speed)为最小单位。这时,可以设置为每次1ms tick出现,usb host“自动”发起一
次数据传输。那么这种方案具体如何来实现呢?看来最基本的要素便是一个发出tick的timer,而这个“timer”
需要usb host和usb function(事实上还要包括usb hub)双方均能“看到”,从而协调工作,否则单方面的
timer又有何意义?这个"timer"(或tick)在usb中使用一个特殊的packet实现,即是SOF。这个SOF由USB HOST
相当精确的以每1.00 ms ±0.0005 ms的时间周期发送给usb device,来在二者之间定时。从而usb function能
够“及时”的了解到“现在时刻”。 现在我们在usb host和usb function之间建立起了“对时”机制。那么接下
来看看刚才设想的“自动”传输如何实现。事实上,一旦usb host及usb function双方建立了一种时间机制,那
么这种“自动”传输是很容易实现的。usb 实现同步式传输或中断式传输总是以一种类似于批量数据传输的方式
进行的,唯一不同的是传输的触发不再是“被动”的,而是由SOF所建立的tick触发。
- 首先,时间到达,usb host发起第一个Packet--in(或out),表示要开始数据传输了。
- 其次,usb function(或usb host)发起以data1(或data0)为起头的payload data,开始一次交互。
- 再其次,如果是中断式传输,usb host(或Usb function)发起ack回应这次交互,如果是同步式传输,
- 该步跳过。
如此重复上述步骤,即usb host等待下一个tick到达,并开始新一轮的交互。
这里我们注意到了,同步式传输和中断式传输二者虽然都是时间触发,但是中断式传输需要ack应答,而相反,
同步式传输不需要。这个最大的区别决定了同步式传输是一种非可靠传输,但是因此换来了更多的usb传输时间。
也因此,同步式传输的 payload data(对应wMaxPacketSize )通常相较于其他传输方式比较大,因为它消掉了
ack所占有数据传输时间。这里还有一个地方值得注意的是tick的设定,这个tick也是需要事先usb host 和
usb function达成共识的参数之一。
评论