分类: LINUX
2008-07-29 09:05:19
主控器(HC)控制总线上包的传输。使用1毫秒的帧。在每帧开始时,主控器产生一个帧开始(SOF, Start of Frame)包。
SOF包用于同步帧的开始和跟踪帧的数目。包在帧中被传输,或由host 到设备(out),或由设备到host(in)。传输总是由host发起(轮询传输)。因此每条USB总线只能有一个host。每个包的传输都有一个状态 阶段,数据接收者可以在其中返回ACK(应答接收),NAK(重试),STALL(错误条件)或什么也没有(混乱数据阶段,设备不可用或已断开)。USB 规范 USB specification的第8.5节更详细地解释了包的细节。USB总线上可以出现四中不同类型的传输:控制(control),大块(bulk), 中断 (interrupt)和同步(isochronous)。传输的类型和他们的特性在下面描述(`管道'子节中)。
USB总线上的设备和设备驱动程序间的大型传输被主控器或HC 驱动程序分割为多个包。
到默认端点的设备请求(控制传输)有些特殊。它们由两或三个阶段组成:启动(SETUP),数据(DATA,可 选)和状态(STATUS)。设置(set-up)包被发送到设备。如果存在数据阶段,数据包的方向在设置包中给出。状态阶段中的方向与数据阶段期间的方 向相反,或者当没有数据阶段时为IN。主控器硬件也提供寄存器,用于保存根端口的当前状态和自从状态改变寄存器最后一次复位以来所发生的改变。USB规范 [2]建议使用一个虚拟hub来提供对这些寄存器的访问。虚拟hub必须符合规范第11章中给出的 hub设备类。它必须提供一个默认管道使得设备请求可以发送给它。它返回标准和hub类特定的一组描述符。它也应当提供一个中断管道用来报告其端口发生的 变化。当前可用的主控器规范有两个: 通用主控器接口(UHCI;英特尔)和 开放主控器接口(OHCI;康柏,微软,国家半导体)。 UHCI规范的设计通过要求主控器驱动程序为每帧的传输提供完整的调度,从而减少了硬件复杂性。OHCI类型的控制器自身提供一个更抽象的接口来完成很多工作,从而更加独立。
UHCI主控器维护着带有1024个指向每帧数据结构的帧列表。它理解两种不同的数据类型:传输描述符(TD)和队列头(QH)。每个 TD表示表示与设备端点进行通信的一个包。QH是将一些TD(和QH)划分成组的一种方法。
每个传输由一个或多个包组成。UHCI驱动程序将大的传输分割成多个包。除同步传输外,每个传输都会分配一个 QH。对于每种类型的传输,都有一个与此类型对应的QH,所有这些QH都会被集中到这个QH上。由于有固定的时延需求,同步传输必须首先执行,它是通过帧 列表中的指针直接引用的。最后的同步TD传输引用那一帧的中断传输的QH。中断传输的所有QH指向控制传输的QH,控制传输的QH又指向大块传输的QH。 下面的图表给出了一个图形概览:
这导致下面的调度会在每帧中运行。控制器从帧列表中取得当前帧的指针后,首先为那一帧中的所有的同步 (isochronous)包执行TD。这些TD的最后一个引用那一帧的中断传输的QH。然后主控器将从那个QH下行到各个中断传输的QH。完成那一队列 后,中断传输的QH会将控制器指向到所有控制传输的QH。它将执行在那儿等待调度的所有子队列,然后是在大块QH中排队的所有传输。为了方便处理已完成或 失败的传输,硬件会在每帧末尾产生不同类型的中断。在传输的最后一个TD中,HC驱动程序设置 Interrupt-On-Completion位来标记传输完成时的一个中断。如果TD达到了其最大错误数,就标记错误中断。如果在TD中设置短包侦测 位,且传输了小于所设置的包长度(的包),就会标记此中断以通知控制器驱动程序传输已完成。找出哪个传输已完成或产生错误是主控器驱动程序的任务。当中断 服务例程被调用时,它将定位所有已完成的传输并调用它们的回调。
更详尽的描述请看 UHCI specification。
对OHCI主控器进行编程要容易得多。控制器假设有一组端点(endpoint)可用,并知道帧中不同传输类型 的调度优先级和排序。主控器使用的主要数据结构是端点描述符(ED),它上面连接着一个传输描述符(TD)的队列。 ED包含端点所允许的最大的包大小,控制器硬件完成包的分割。每次传输后都会更新指向数据缓冲区的指针,当起始和终止指针相等时,TD就退归到完成队列 (done-queue)。四种类型的端点各有其自己的队列。控制和大块(bulk)端点分别在它们自己的队列排队。中断ED在树中排队,在树中的深度定 义了它们运行的频度。
帧列表 中断 同步(isochronous) 控制 大块(bulk)
主控器在每帧中运行的调度看起来如下。控制器首先运行非周期性控制和大块队列,最长可到HC驱动程序设置的一个 时间限制。然后以帧编号低5位作为中断ED树上深度为0的那一层中的索引,运行那个帧编号的中断传输。在这个树的末尾,同步ED被连接,并随后被遍历。同 步TD包含了传输应当运行其中的第一个帧的帧编号。所有周期性的传输运行过以后,控制和大块队列再次被遍历。中断服务例程会被周期性地调用,来处理完成的 队列,为每个传输调用回调,并重新调度中断和同步端点。
更详尽的描述请看 OHCI specification。服务层,即中间层,提供了以可控的方式对设备进行访问,并维护着由不同驱动程序和服务层所使用的资源。此层处理下面几方面:
设备配置信息
与设备进行通信的管道
探测和连接设备,以及从设备分离(detach)。