分类: 嵌入式
2013-07-27 16:21:33
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,就是每调用一次系统都会对其中的一些初始化变量初始化一次,这些变量主要有usbKbdMutex、usbKbdListMutex、usbKbdList,如果有多个USB键盘那么就会调用多次,这显然也对这些初始化变量初始化了多次,这显然是不对的。修正的办法是将这几个初始化过程保存在函数usrUsbKbdInit中。
2. LOCAL STATUS usbKbdDevDelete
(
USB_KBD_DEV * pUsbKbdDev
)
主要删除USB_KBD_DEV结构的链:将pUsbKbdDev->ioDev从iosDvList中删除;将pUsbKbdDev->pUsbKbdNode节点从usbKbdList链中删除;以及usbKbdDevCreate函数专门为该设备建立的数据结构:pUsbKbdDev->pUsbKbdNode和pUsbKbdDev。其delete的内容仅仅与当前参数指定的设备有关,并不修改其他的USB键盘设备,而usbKbdDevCreate函数则是初始化了和所有USB键盘设备有关的变量,因此不能简单地理解为usbKbdDevCreate函数的逆过程。
3. LOCAL STATUS usbKbdDevFind
(
SIO_CHAN * pChan,
USB_KBD_DEV ** ppUsbKbdDev
)
从usbKbdList链中找到其元素pSioChan等于参数pChan的USB_KBD_DEV结构。
4. LOCAL void usbKbdDrvAttachCallback
(
void * arg,
SIO_CHAN *pChan,
UINT16 attachCode
)
回调函数,当有USB键盘插入或拔掉的时候调用。
该函数的执行分为两种情况:如果是新插入了USB键盘,则调用usbKbdDevCreate函数进行该键盘的驱动初始化;如果是USB键盘设备被拔掉了,则调用usbKbdDevDelete函数删除与该设备相关的结构,然后调用函数usbKeyboardSioChanUnlock(pChan)删除pChan结构。
图6.43表明了pChain和结构指针pUsbKbdDev的关系。更详细的分析可以结合图6.42以及i8250串口驱动一章。
图6.43 USB键盘对应的IO数据结构关联
注意区分回调函数本身和回调注册函数。对于USB键盘来说,共有两类回调函数,一类是USB键盘接收到数据之后需要调用回调函数处理数据,如回调函数usbKeyboardIrpCallback,该回调函数的注册由函数initKbdIrp在在调用函数usbKeyboardDynamicAttachRegister来完成的。
第二类回调函数就是USB设备的插拔时需要调用的回调函数,这个回调函数又分为两个层次:USBD层将USB设备(对应一个client)注册为一个回调函数usbKeyboardAttachCallback,当USBD层发现这一类设备插拔时调用回调函数usbKeyboardAttachCallback,这个回调函数是由函数usbdDynamicAttachRegister在USBD层注册的;另一个层次是对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 中来执行。