在主机控制器里,介绍几个重要的结构

来源:互联网 发布:淘宝客推广渠道 编辑:程序博客网 时间:2024/05/16 03:16
 

在主机控制器里,介绍几个重要的结构:

一:ED(endpoint descriptor)

总共16字节对齐。

先看第一字主要描述了硬件配置信息。

[6:0]为设备地址(function address)

[10:7]是端点地址(endpoint number)

[12:11]是数据方向,00:方向定义在TD  01: OUT  10:INT   11:TD

[13]置位时是低速否则全速

[14] 当此位被设置,HC继续在链表中的下一个端点描述符,而不试图访问的TD队列或发出任何端点的USB令牌

[15]置位表示同步格式的TD,否则表示通用的TD

[26:16]端点最大数据包MaximumPacketSize  

 

第二字

[31:4] TDQueueTailPointer  如果TailP HeadP是相同的,那么列表中不包含TD HC可以处理。如果TailP和HeadP不同,则该列表包含要处理的TD。

 

第三字

[0] 此位设置是由主机控制器表明,处理的端点上的TD队列中暂停时,通常是由于错误处理TD。

[1] toggleCarry  就是关于数据data0 data1 data0 data1 data0

[31:4] TDQueueHeadPointer  指向下一个在该端点上要处理的TD

 

第四字

[31:4]指向下一个端点描述符

 

端点描述符被链接成一个链表被主机控制器处理,当一个端点描述符的nextED不为零时,该端点描述符会被链接入

 

当主控制器访问端点,它会检查跳过和暂停位,以确定是否允许任何endpointis进一步处理。如果任何位被设置,那么主机控制器的进步到下一个endpointon列表。如果既没有跳过也不暂停位被设置,那么主机控制器比较HeadP来TailP。如果他们是不一样的,那么endpointpointed由HeadP定义主机控制器的将传输一个数据包到/从其中一个缓冲区

 

这种链接公约假定主机控制器驱动程序的“尾巴”的端点描述符队列的队列。它通过链接一个新的端点描述符到端点描述符指针TailP然后更新TailP指向刚才添加的端点描述符。

 

当一个TD完成后,将其从队列上取消链接,加到完成队列上。把该TD的下一个TD连接到headP

 

跳过位是由主控制器驱动程序设置和清除,当它想跳过处理端点的主机控制器。这可能是必要的,主机控制器驱动程序时,必须修改HeadP的值和端点描述符链表删除的overhead prohibitive。

 

由主控制器,当它遇到一个错误,在处理TD暂停位。

当在错误的TD移动到完成队列,主机控制器的更新HeadP和设置暂停位,造成主控制器跳过端点描述符已停止,直到被清除。主机控制器驱动程序,清除错误条件时已得到纠正,并转移到/从端点应恢复暂停位。主机控制器驱动程序不应该写HeadP/ toggleCarry/暂停的除非已停止设置,跳过,或教育署已经从名单中剔除。

 

当端点描述符的D字段是10B(IN)的,主控制器可以发出一个IN令牌到指定的的端点点后,在检测到HeadP和TailP是不一样的后。

 

当F字段是零时,表示的是通用传输描述符,是16字节的的。

当F字段是零时 ,表示的是通用传输描述符,是32字节的。HeadP 和TailP

指向一个TD

 

在ohci.h文件中。ED结构如下,与上面的想对应

struct ed {

      

       __hc32                hwINFO;     

      

#define ED_DEQUEUE     (1 << 27)

      

#define ED_ISO         (1 << 15)

#define ED_SKIP        (1 << 14)

#define ED_LOWSPEED   (1 << 13)

#define ED_OUT        (0x01 << 11)

#define ED_IN            (0x02 << 11)

       __hc32                hwTailP;

       __hc32                hwHeadP;    

#define ED_C             (0x02)                 

#define ED_H             (0x01)                 

       __hc32                hwNextED;   

 

      

       dma_addr_t          dma;             

       struct td        *dummy;       

 

      

       struct ed              *ed_next;     

       struct ed              *ed_prev;     

       struct list_head    td_list;   

 

      

       u8                 state;            

#define ED_IDLE        0x00            

#define ED_UNLINK   0x01            

#define ED_OPER             0x02            

 

       u8                 type;            

 

      

       u8                 branch;

       u16               interval;

       u16               load;

       u16               last_iso;

 

      

       u16               tick;

} __attribute__ ((aligned(16)));

  

下面看看传输描述符

 

 

通用传输描述符也是16字节。

第一字:

[8] bufferRounding 如果该位为0,那么最后一个数据包从一个端点传输描述符必须准确填写定义的数据缓冲区后。如果该位为1,那么最后一个数据包可能小于所定义的缓冲区,而不会造成错误条件对传输描述符后。

[10:19] Direction/PID  

 

 

[23:21] DelayInterrupt  

此字段包含这个传输描述符中断延时计数。当一个TD完成了HC可能等待DelayInterrupt帧然后产生一个中断。如果DelayInterrupt是111B,那么就完成这个传输描述符没有中断

[25:24] DataToggle  

[27:26]  ErrorCount  对于每一个传输错误,这个值是递增。 如果ErrorCount是2,出现另一个错误,错误类型是记录中的ConditionCode字段和完成队列中。当交易完成后,没有错误ErrorCount复位为0。

[31:28] ConditionCode  此字段包含上次尝试事务状态。

 

第二字:

CurrentBufferPointer  包含的下一个内存位置将被转移到/从端点访问物理地址。一个0值表示一个零长度数据包或所有的字节都被转移

第三字:

NEXT TD This entry points to the next TD on the list of TDs linked to this endpoint  

 

第四字

BufferEnd

包含这个传输描述符物理地址的缓冲区中的最后字节

 

当主机控制器成功地传输,或从一个的端点传输完成,指向的字节BufferEnd。成功完成后,主机控制器设置CurrentBufferPointer为零,设置ConditionCode成NOERROR,和取消的通用TD到完成队列。
传输也可完成从一个端点一个数据包时不填充缓冲区,超过最大长度一个数据一个大小一个字节。在这种情况下,CurrentBufferPointer是更新后立即写入存储器的最后一个字节为指向的内存字节。然后,如果在通用TD bufferRounding位被设置,那么这种情况下被视为一个正常完成和主机控制器设置ConditionCode领域NOERROR和退休的通用TD完成队列。如果通用TD bufferRounding位没有设置,那么这种情况下视为错误和主机控制器设置ConditionCode领域DATAUNDERRUN和端点描述符停止位设置为通用TD取消。

 

传输错误分为三类:

transmission :CRC Erors, BITSTUFFING errors, DEVICENOTRESPONDING errors.

发生在通信上面

sequence :列发生错误时,数据接收的字节数不匹配,预计从端点字节数。

system :主机控制器环境照成的错误

 

transmission 传输错误可以从发。当ErrorCount 计数到2是再次发生错误,那么就会移除这个TD,和这个端点会被暂停

Data toggle不匹配将导致transmission 错误

PID检测中的错误为PIDCHECKFAILURE.

 

Sequence errors occur only on reads from an endpoint to the Host Controller (IN).

序列错误只发生在读数据从一个端点到主机。

序列错误包括两个错误data overrun   data underrun.