UHCI的数据流控制

来源:互联网 发布:如何下载广联达软件 编辑:程序博客网 时间:2024/06/07 12:07

UHCI的数据结构和数据流控制

一、数据结构

主要涉及到三个数据结构:Frame list 、Transfer Descriptors(TD)、Queue Head(QH)。Frame list必须要4K字节对齐;而TD和QH需要16字节对齐,一般情况本身的结构大小要超过16字节。

三者之间的关系如下图所示:

其中Frame list base address从UHCI的IO Register中读到的,uhcispec中有介绍。Frame counter也是在IO register中读到,也base address共同得到当前UHCI需要处理的Frame list中的Frame pointer。

剩下的问题就是如何控制Frame pointer中TD、QH的数据流。

 

关于TD和QH的数据结构问题:

1、Frame list pointer:

Frame list pointer指第一个需要调度的结构体的地址。

Q:表示Link pointer指向的是TD(0)还是QH(1)。

T:表示告知HC,该Frame是否有有效的数据流入口。1、表示空的frame;0表示有效入口。

2、Transfer Descriptor

针对同步、中断、控制、bulk传输,有四种不同的TD,当然结构大同小异,只是部分控制bit不一样而已。按理说会有8个Dword,实际使用前4个Dword,最后4个Dword是留给software使用的。


 

Link pointer指指向另外一个TD或者QH。

Vf:告知HC,该深度遍历还是广度遍历。深度遍历就是跑向Link pointer的指向的TD;广度遍历跑向Link pointer指向的另外一个QH。1=depth first;0=breadth first。

Q:表示Link pointer指向的是TD(0)还是QH(1)。

T:1=Link pointer无效;0=Link pointer是有效的。该bit告知HC本TD中link pointer是否指向另外一个数据流入口。如果TD在一个队列里中,该bit代表告知HC,队列中已经没有另外的有效数据流入口了。也就是说本TD是最后一个TD。

 

另外的字段说明请看spec。

在status字段中,bit23是active bit。也就是说,Software将所有的QH或者TD设置好,Frame list base address也设置好之后,在将该bit置位,则HC马上开始USB的数据传输。在等待若干time之后判断是否得到ACK。

 

Buffer Pointer指本TD中需要传输的数据内容。大小必须不小于MAX Length中定义的size。

 

3、Queue Head

QH是特别针对控制、bulk和中断传输定义的结构。而同步传输中不会使用QH。必须16字节对齐。

QHLP:此字段指向下一个横向数据表的地址,可以是QH或者TD。一般情况是QH(多个队列)。

Q:表示Link pointer指向的是TD(0)还是QH(1)。

T:告知HC,本QH已经是本次调度序列中最后一个QH了。1=last QH;0=pointer有效,指向TD或者QH。

 

 

二、如何控制数据流

HCD设定HC的register:Frame list baseaddress和frame list index,并通过hc的run、stop控制HC执行调度序列。

HC首先从Frame list中读取一个入口,判断bit0 是否是pointer address有效;判断bit1 是指定TD还是QH;另外一个字段即pointer address。

如果针对isochronous传输,Frame list则指向TD,如果没有isochronous传输,则指向QH。如果指向TD,则HC获取到入口地址开始在USB总线上传输数据,每个TD包含的link pointer指向下一个入口,TD或者QH;如果是指向QH的,HC就会按照QH中的结构来相应处理。

 

1、  处理同步传输的描述符

同步传输的描述符是link到frame list中,每1ms发生一次数据的传送。所以同步传输的控制也要保证host端到端点之间的固定频率的数据传送。同步TD的处理如下:

1)、HC获取对应的Isochronous TD;

2)、HC decode TD的各个字段,来做相应的传输控制。

3)、HC产生USB token,开始传送 usb数据。

4)、当传输过程完成,HC将更新状态,标志TD非活跃状态。

5)、HC获取当前TD中link pointer指向的TD或者QH。

6)、类似的同样处理TD或者QH。

 

 

2、  处理bulk、control和interrupt的传输描述符

像bulk、control和interrupt TD传输数据是通过QH队列来实现的。步骤如下:

1)、HC从Frame list中获得QH,并确认是否有有效的入口。

2)、如果数据(TD or QH)入口有效,HC从QH的元素指针中获取TD或者QH,如果是TD,则跳转到3);如果QH则跳转到1);如果是无效的入口,直接跳转到10)

3)、HC解析TD字段,觉得采取何种方式传输。

4)、HC产生USB token,并开始执行传输,setup阶段。

5)、等传输过程结束,HC更新状态。

6)、如果传输结束并成功,TD被标志位非活跃状态,并跳转到9)

7)、如果此次传输没有成功,但是error次数没有达到门限值,那么TD将依旧重新开始活跃。跳转到10)

8)、如果此次传输失败,而且error也达到了门限值,那么TD将被标志成非活跃态,跳转到10)

9)、HC将当前TD的link pointer写入到当前QH结构中的元素指针中(也就是将QH中之前处理完的TD从链表中移除),如果link pointer的Vf bit置位了(depth),(将当前QH传递过去)跳转到2);否则直接进入10)

10)、HC从当前QH的QH linkpointer中获取到QH或者TD的指向。如果该QH link pointer的T位置位的话,HC进入idle转跳等待1ms 帧时间的消耗完。

11)、UHCI的处理过程继续以此流程进行下去。

数据流控制的结构图如下:

 

下图是一个队列的实例:

 

原创粉丝点击