在OHCI层,主要完成如下功能:
l
通过控制端口读写数据(包含
SETUP
、
DATA
、
STATUS
等
3
个
TD
);
l
通过控制端口发送设置命令(没有
DATA
的
TD
);
l
通过批量端口读数据;
l
通过批量端口写数据;
l
中断处理程序;
本层将
OHCI
的
ED
和
TD
作为自己内部的对象进行包装,上层对象通过调用本层接口完成所需要的功能,而不必关心
ED
和
TD
的细节。
通过
OHCI
接口进行数据收发,最主要的工作就是确定
ED
和
TD
队列。在网上广为流传的周立功公司的相关资料以及该公司出版的《
ARM
嵌入式系统软件开发实例》(一)、(二)中,关于
ED
和
TD
的处理非常复杂,甚至为此建立了一个管理机制,包括队列的建立、插入、删除、释放等一系列操作。
其实对于一般的嵌入式系统来说,没有必要把
ED
和
TD
搞得这么复杂。在我们的系统中,
ED
和
TD
的管理非常简单:把待处理的命令构建为
ED
和
TD
队列,然后执行,等到执行完毕再根据上层代码的需要构建新的队列。也就是说只有等到上一个命令全部执行完毕后,才可以执行下一个命令。这样的处理机制完全可以适应绝大多数的嵌入式系统了。
基本上来说,每个端点使用一个
ED
,譬如对于控制端口的命令,使用一个
ED
即可,而对于批量端口,则会使用到两个
ED
,分别对应批量出和批量入端口。
对于端点来说,代码中需要注意的参数有如下几个:
l
ED
的
ToggleCarry
用来确定
ED
使用哪个数据区收发收据,对于控制端点来说,根据
USB
规范,每个控制命令总是从
Data0
开始的,后面再进行切换。因此控制端点的
ToggleCarry
字段随便设置,而批量端点的该字段需要得到上一次传送完毕后的
ToggleCarry
的值。
l
TD
的
DataToggle
用来确定
TD
使用哪个数据区收发数据。该字段有
2
个比特,高位
=0
表示使用
ED
的
ToggleCarry
字段的值作为要使用的数据区,
=1
表示自己控制使用哪一个数据区。根据
USB
规范,对于控制端点收发数据来说,需要
TD
自己控制使用哪一个数据区。而对于批量端点,不需要
TD
自己控制,交由
ED
进行控制。