Chinaunix首页 | 论坛 | 博客
  • 博客访问: 477277
  • 博文数量: 56
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1957
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-07 23:02
文章分类

全部博文(56)

文章存档

2016年(1)

2014年(7)

2013年(48)

分类: 嵌入式

2013-07-25 22:05:09

原创文章,转帖请注明出处。

6.2.5 函数库usbHcdLib

USBD通过HCD实现了对HC的控制,HCD主要为USBD提供了11个通用函数接口,从而使得USBD层不需要了解底层的细节,只需要直接调用这些函数就能完成对HC的控制。这11个函数接口分别为usbHcdAttach、usbHcdDetach、usbHcdSetBusState、usbHcdIrpSubmit、usbHcdIrpCancel、usbHcdCurrentFrameGet、usbHcdPipeCreate、usbHcdPipeDestroy、usbHcdPipeModify、usbHcdSofIntervalGet、usbHcdSofIntervalSet。这些函数从实现上来说都比较简单,它只是提供了简单的封装,而真正底层的实现则是由usbHcdOhciLib.c来完成的。其层次结构如图6.27所示。

图6.27 HCD层函数库的层次关系

下面是hcdLib.c库中各个函数的简单分析。

1. LOCAL VOID hrbInit 

    (

    pHRB_HEADER pHrb, 

    pHCD_NEXUS pNexus, 

    UINT16 function,

    UINT16 totalLen

    )

初始化一个HRB_HEADER结构变量,通过设置HRB_HEADER结构变量可以调用HCD_NEXUS.hcdExecFunc函数完成不同的功能。

2. STATUS usbHcdAttach

    (

    HCD_EXEC_FUNC hcdExecFunc,

    pVOID param,

    USB_HCD_MNGMT_CALLBACK callback,

    pVOID callbackParam,

    pHCD_NEXUS pNexus,

    pUINT16 pBusCount

)

这个函数指定了一个USB总线的HCD函数入口hcdExecFunc,通过调该函数完成attach,同时也将该函数及hrb.header.handle作为参数初始化了变量HCD_NEXUS

3. STATUS usbHcdDetach

    (

    pHCD_NEXUS pNexus

)

通过调用函数pNexus->hcdExecFunc完成了dettach,它的执行过程usbHcdAttach相反。

4. STATUS usbHcdSetBusState

    (

    pHCD_NEXUS pNexus,

    UINT16 busNo,

    UINT16 busState

)

通过调用函数pNexus->hcdExecFunc来设定USB总线busNo的状态:USB_BUS_SUSPEND或者USB_BUS_RESUME

5. STATUS usbHcdCurrentFrameGet

    (

    pHCD_NEXUS pNexus,

    UINT16 busNo,

    pUINT32 pFrameNo,

    pUINT32 pFrameWindow

)

返回当前帧号和帧窗口。

6. STATUS usbHcdIrpSubmit

    (

    pHCD_NEXUS pNexus,

    HCD_PIPE_HANDLE pipeHandle,

    pUSB_IRP pIrp

)

该函数向HCD提交一个IRP

7. STATUS usbHcdIrpCancel

    (

    pHCD_NEXUS pNexus,

    pUSB_IRP pIrp

)

通知HCD取消一个IRP。当然,并不能保证一个IRP在提交给HCD后还能够在正常执行前取消。

8. STATUS usbHcdPipeCreate

    (

    pHCD_NEXUS pNexus,

    UINT16 busNo,

    UINT16 busAddress,

    UINT16 endpoint,

    UINT16 transferType,

    UINT16 direction,

    UINT16 speed,

    UINT16 maxPacketSize,

    UINT32 bandwidth,

    UINT16 interval,

    pUINT32 pTime,

    pHCD_PIPE_HANDLE pPipeHandle

)

创建一个HCDpipe,其结构为HCD_PIPE。如果是interrupt或者isochronous pipeHCD需要计算传输给定的字节数的数据需要的时间(纳秒),计算公式参见usb1.1规范5.9.3

如果有足够的带宽可用,则这段带宽将会被HCD保留给该pipe,并在usbHcdPipeDestory函数执行的时候释放。

interrupt pipe来说,bandwidth指的是每帧数据要发送的字节数;对于isochronous pipe来说,bandwidth指的是每秒传输的字节数;而对controlbulk来说,该数值为0

serviceInterval:仅适用于中断传输pipe,标明该pipe的最大潜伏期(latency,单位毫秒)。如果一个设备的serviceInterval数值为20,说明该设备每20毫秒需要服务一次。

最坏条件下packet的传输时间在pTime中被返回。

9. STATUS usbHcdPipeDestroy

    (

    pHCD_NEXUS pNexus,

    HCD_PIPE_HANDLE pipeHandle

)

删除pipeHandle指定的HCD层的HCD_PIPE结构变量以及分配的资源。

10. STATUS usbHcdPipeModify

    (

    pHCD_NEXUS pNexus,

    HCD_PIPE_HANDLE pipeHandle,

    UINT16 busAddress,

    UINT16 maxPacketSize

)

修改pipe属性。一个pipe的两个特性:device addressmaxPacketSize,有可能在pipe被创建之后被修改。这主要发生在一个设备默认的控制pipe上,这是因为起初host并不知道一个设备的deviceAddressmaxPacketSize,它需要首先通过默认的deviceAddressmaxPacketSize通过默认控制pipe对设备进行讯问后才能得到设备真正的maxPacketSize并对设备分配地址。那么这时候USBD层、HCD层的deviceAddressmaxPacketSize都需要重新修改。

11. STATUS usbHcdSofIntervalGet

    (

    pHCD_NEXUS pNexus,

    UINT16 busNo,

    pUINT16 pSofInterval

)

获取SOF间隔。所谓帧间隔就是连续两个SOF信号之间的时间差。这里的帧间隔的描述单位为高速(high speed)总线上的发送1bit数据所用的时间。SOF典型的时间间隔为1ms,那么对高速设备来说数据率为12Mbps1ms传输12kb,因此典型的SOF间隔的数值为12000

12. STATUS usbHcdSofIntervalSet

    (

    pHCD_NEXUS pNexus,

    UINT16 busNo,

    UINT16 sofInterval

)

设置SOF间隔。

阅读(2276) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~