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

全部博文(56)

文章存档

2016年(1)

2014年(7)

2013年(48)

分类: 嵌入式

2013-07-27 16:21:33

原创,转载请注明出处。



6.2.8 函数库usrUsbKbdInit

usrUsbKbdInit函数库实现了用文件系统访问的方法实现对USB键盘的访问控制。函数usbKbdDevCreate安装了一个USB键盘并将相应的驱动函数装进相应的访问函数表,这样就可以通过标准的fopen、close、read、write等类型的访问接口对USB键盘进行访问。

1. STATUS usbKbdDevCreate

    (

    char * name,

    SIO_CHAN * pSioChan

    )

为一个USB键盘创建一个文件系统访问接口,以方便后面的文件系统访问函数进行访问。比如当系统发现新插入了一个USB键盘之后,就可以调用函数usbKbdDevCreate ("/usbKb/0", pSioChan)来创建一个USB键盘的驱动。

关于文件系统可以参考串口驱动一章的分析,这里不再过多描述。

这个函数存在一个bug,就是每调用一次系统都会对其中的一些初始化变量初始化一次,这些变量主要有usbKbdMutexusbKbdListMutexusbKbdList,如果有多个USB键盘那么就会调用多次,这显然也对这些初始化变量初始化了多次,这显然是不对的。修正的办法是将这几个初始化过程保存在函数usrUsbKbdInit中。

2. LOCAL STATUS usbKbdDevDelete

    (

    USB_KBD_DEV * pUsbKbdDev

    )

主要删除USB_KBD_DEV结构的链:将pUsbKbdDev->ioDeviosDvList中删除;将pUsbKbdDev->pUsbKbdNode节点从usbKbdList链中删除;以及usbKbdDevCreate函数专门为该设备建立的数据结构:pUsbKbdDev->pUsbKbdNodepUsbKbdDev。其delete的内容仅仅与当前参数指定的设备有关,并不修改其他的USB键盘设备,而usbKbdDevCreate函数则是初始化了和所有USB键盘设备有关的变量,因此不能简单地理解为usbKbdDevCreate函数的逆过程。

3. LOCAL STATUS usbKbdDevFind

    (

    SIO_CHAN * pChan,

    USB_KBD_DEV ** ppUsbKbdDev

    )

usbKbdList链中找到其元素pSioChan等于参数pChanUSB_KBD_DEV结构。

4. LOCAL void usbKbdDrvAttachCallback

    (

    void * arg,

    SIO_CHAN *pChan,

    UINT16 attachCode

    )

回调函数,当有USB键盘插入或拔掉的时候调用。

该函数的执行分为两种情况:如果是新插入了USB键盘,则调用usbKbdDevCreate函数进行该键盘的驱动初始化;如果是USB键盘设备被拔掉了,则调用usbKbdDevDelete函数删除与该设备相关的结构,然后调用函数usbKeyboardSioChanUnlockpChan)删除pChan结构。

图6.43表明了pChain和结构指针pUsbKbdDev的关系。更详细的分析可以结合图6.42以及i8250串口驱动一章。

图6.43 USB键盘对应的IO数据结构关联

注意区分回调函数本身和回调注册函数。对于USB键盘来说,共有两类回调函数,一类是USB键盘接收到数据之后需要调用回调函数处理数据,如回调函数usbKeyboardIrpCallback,该回调函数的注册由函数initKbdIrp在在调用函数usbKeyboardDynamicAttachRegister来完成的。

第二类回调函数就是USB设备的插拔时需要调用的回调函数,这个回调函数又分为两个层次:USBD层将USB设备(对应一个client)注册为一个回调函数usbKeyboardAttachCallback,当USBD层发现这一类设备插拔时调用回调函数usbKeyboardAttachCallback,这个回调函数是由函数usbdDynamicAttachRegisterUSBD层注册的;另一个层次是对USB键盘设备来说,当发现一个USB键盘设备插拔时可能需要调用多个回调函数,每个回调函数则是由usbKeyboardDynamicAttachRegister函数注册到reqList链中,函数库usrUsbKbdinit来说则只需要注册一个回调函数即可。图6.44描述了USB键盘各层热插拔回调函数之间的关系。

图6.44 USB键盘各层热插拔回调函数之间的关系

5. LOCAL int usbKbdOpen

    (

    USB_KBD_DEV * pUsbKbdDev,

    char     * name,

    int flags,

    int         mode

    )

打开一个usbKbdDrv设备。

6. STATUS usbKbdDrvUnInit (void)

usrUsbKbdInit函数的逆过程。

7. LOCAL int usbKbdClose

    (

    USB_KBD_DEV * pUsbKbdDev

    )

关闭一个usbKbdDrv设备。

8. LOCAL int usbKbdIoctl

    (

    USB_KBD_DEV * pUsbKbdDev,

    int request,

    void * arg

    )

直接调用函数usbKeyboardIoctl

9. LOCAL int usbKbdRead

    (

    USB_KBD_DEV * pUsbKbdDev,

    UCHAR *buffer, 

    UINT32 nBytes    

    )

USB键盘轮询的方式对USB键盘获取的键码进行访问,每调用函数usbKbdRead一次只能获取一个字符,因此nBytes是无效的。

10. int usbKbdWrite

    (

    USB_KBD_DEV * pUsbKbdDev,

    UCHAR * buffer,

    UINT32   nBytes

    )

USB键盘不支持写操作。

11. void usrUsbKbdInit (void)

初始化函数库。主要是

l 调用函数usbKeyboardDevInit初始化函数库usbKeyboardLib

l 调用函数usbKeyboardDynamicAttachRegister对回调函数usbKbdDrvAttachCallback进行注册。

注意:这里存在bug,参考函数usbKbdDevCreate,需要把三个变量的初始化过程放在函数usrUsbKbdInit 中来执行。


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