📄 usrusbkbdinit.c
字号:
/* usrUsbKbdInit.c - Initialization of the USB Keyboard driver */
/* Copyright 1999-2002 Wind River Systems, Inc. */
/*
Modification history
--------------------
xxx,14mar05,adh SPR 106676 -- keyboard does not work in target shell, implement redirect
01i,15oct04,ami Apigen Changes
01h,05oct04,pdg Fix for SPR #94286
01g,03jun04,hch Fix warning for usbKbdRead and playWithKeyboard.
01f,05nov03,cfc USB2 Development Integration
01f,29oct03,cfc USB2 merge
01f,23sep03,cfc Fixed issue of overflowing driver table
01e,06sep03,cfc Decrement keyboard ctr when detached
01d,30jan02,wef fixed DevFind routine.
01c,08dec01,wef fixed some warnings
01b,02feb01,wef Added ios functionality - allows for open, close, read,
ioctl, etc access to the printer.
01a,23aug00,wef Created
*/
/*
DESCRIPTION
This configlette initializes the USB keyboard driver. This assumes the
USB host stack has already been initialized and has a host controller
driver attached.
This configlette demonstrates how a user might integrate a USB class
driver into the vxWorks file system. usbKbdDevCreate () intalls a USB
keyboard and its associated driver functions into the driver table allowing
the keyboard to be accesed with standard fopen, close, read, write, etc. type
calls.
There is an included test routine playWithKeyboard () that demonstrates
using the ios functionality
INCLUDE FILES: iosLib.h, vxWorks.h, iv.h, ioLib.h, tyLib.h, intLib.h,
errnoLib.h, sioLib.h, stdlib.h, stdio.h, logLib.h,
selectLib.h, drv/usb/usbKeyboardLib.h, usb/usbHid.h
*/
/* includes */
#include "drv/usb/usbKeyboardLib.h"
#include "usb/usbHid.h"
#include "vxWorks.h"
#include "iv.h"
#include "ioLib.h"
#include "iosLib.h"
#include "tyLib.h"
#include "intLib.h"
#include "errnoLib.h"
#include "sioLib.h"
#include "stdlib.h"
#include "stdio.h"
#include "logLib.h"
#include "selectLib.h"
#include "msgQlib.h"
#if (ATTACH_USB_KEYBOARD_TO_SHELL == TRUE)
#undef USB_KEYBOARD_POLLING
#define USB_KEYBOARD_POLLING FALSE
#endif
/* defines */
#define TX_BUF_NUM 0x10000
#define USB_KBD_MUTEX_TAKE(tmout) \
semTake (usbKbdMutex, (int) (tmout))
#define USB_KBD_MUTEX_GIVE \
semGive (usbKbdMutex)
#define USB_KBD_LIST_SEM_TAKE(tmout) \
semTake (usbKbdListMutex, (int) (tmout))
#define USB_KBD_LIST_SEM_GIVE \
semGive (usbKbdListMutex)
#define KBD_NAME_LEN_MAX 100
#define USB_KBD_NAME "/usbKb/"
#define CTRL_Z 26 /* ASCI code for ^Z */
/* data types */
/* typedefs */
typedef struct usb_kbd_node
{
NODE node;
struct usb_kbd_dev * pUsbKbdDev;
} USB_KBD_NODE;
typedef struct usb_kbd_dev /* USB_KBD_DEV */
{
DEV_HDR ioDev;
SIO_CHAN * pSioChan;
UINT16 numOpen;
UINT32 bufSize;
MSG_Q_ID buff;
#if (ATTACH_USB_KEYBOARD_TO_SHELL == TRUE)
int origFd;
int shellFd;
#endif
SEL_WAKEUP_LIST selList;
USB_KBD_NODE * pUsbKbdNode;
} USB_KBD_DEV;
/* local variables */
LOCAL SEM_ID usbKbdMutex; /* mutex semaphore */
LOCAL SEM_ID usbKbdListMutex; /* mutex semaphore to protect list */
LOCAL UINT32 kbdCount = 0;
LOCAL LIST usbKbdList; /* all USB keyboards in the system */
LOCAL int usbKbdDrvNum = 0; /* driver number */
LOCAL BOOL enterPressed;
/* forward declarations */
LOCAL void usbKbdDrvAttachCallback (void * arg, SIO_CHAN *pChan,
UINT16 attachCode);
LOCAL int usbKbdReadPoll (USB_KBD_DEV * pUsbKbdDev, char * buffer,
UINT32 nBytes);
LOCAL int usbKbdReadInt (USB_KBD_DEV * pUsbKbdDev, char *buffer,
UINT32 nBytes);
LOCAL int usbKbdClose (USB_KBD_DEV * pUsbKbdDev);
LOCAL int usbKbdWrite (USB_KBD_DEV * pUsbKbdDev, char * buffer,
UINT32 nBytes);
LOCAL int usbKbdOpen (USB_KBD_DEV * pUsbKbdDev, char * name,
int flags, int mode);
LOCAL int usbKbdIoctl (USB_KBD_DEV * pUsbKbdDev, int request, void * arg);
LOCAL STATUS usbKbdDevFind (SIO_CHAN *pChan, USB_KBD_DEV ** ppUsbKbdDev);
LOCAL STATUS usbKbdDevDelete (USB_KBD_DEV * pUsbKbdDev);
LOCAL STATUS usbKbdTxCallback (void *callbackParam, char aChar);
#if (ATTACH_USB_KEYBOARD_TO_SHELL == TRUE)
LOCAL void redirectShellInput(USB_KBD_DEV * pDev) {
pDev->shellFd = open("/usbKb/0",0,0);
if (pDev->shellFd <= 0) {
printf ("Could not open fd for shell redirection\n");
return;
}
pDev->origFd = ioGlobalStdGet (0);
shellOrigStdSet (0,pDev->shellFd);
shellRestart(0);
ioTaskStdSet(taskNameToId("tShell"),0,pDev->shellFd);
}
LOCAL void restoreShellInput(USB_KBD_DEV * pDev) {
shellOrigStdSet (0,pDev->origFd);
shellRestart(0);
if (pDev->shellFd > 0)
close (pDev->shellFd);
}
#endif
/*******************************************************************************
*
* usbKbdDevCreate - create a VxWorks device for an USB keyboard
*
* This routine creates a device on a specified serial channel. Each channel
* to be used should have exactly one device associated with it by calling
* this routine.
*
* For instance, to create the device "/ /0", the proper call would be:
* \cs
* usbKbdDevCreate ("/usbKb/0", pSioChan);
* \ce
*
* Where pSioChan is the address of the underlying SIO_CHAN serial channel
* descriptor (defined in sioLib.h).
* This routine is typically called by the USB keyboard driver, when it detects
* an insertion of a USB keyboard.
*
* RETURNS: OK, or ERROR if the driver is not installed, or the
* device already exists, or failed to allocate memory.
*
* ERRNO: none
*/
STATUS usbKbdDevCreate
(
char * name, /* name to use for this device */
SIO_CHAN * pSioChan /* pointer to core driver structure */
)
{
USB_KBD_NODE * pUsbKbdNode = NULL; /* pointer to device node */
USB_KBD_DEV * pUsbKbdDev = NULL; /* pointer to USB device */
if (pSioChan == (SIO_CHAN *) ERROR)
{
printf ("pSioChan is ERROR\n");
return (ERROR);
}
/* allocate memory for the device */
if ((pUsbKbdDev = (USB_KBD_DEV *) calloc (1, sizeof (USB_KBD_DEV))) == NULL)
{
printf ("calloc returned NULL - out of memory\n");
return (ERROR);
}
pUsbKbdDev->pSioChan = pSioChan;
/* allocate memory for this node, and populate it */
pUsbKbdNode = (USB_KBD_NODE *) calloc (1, sizeof (USB_KBD_NODE));
/* record useful information */
pUsbKbdNode->pUsbKbdDev = pUsbKbdDev;
pUsbKbdDev->pUsbKbdNode = pUsbKbdNode;
/* add the node to the list */
USB_KBD_LIST_SEM_TAKE (WAIT_FOREVER);
lstAdd (&usbKbdList, (NODE *) pUsbKbdNode);
USB_KBD_LIST_SEM_GIVE;
/* allow for select support */
selWakeupListInit (&pUsbKbdDev->selList);
/* start the device in the only supported mode */
#if (USB_KEYBOARD_POLLING == FALSE)
sioIoctl (pUsbKbdDev->pSioChan, SIO_MODE_SET, (void *) SIO_MODE_INT);
if ((*pSioChan->pDrvFuncs->callbackInstall) (pSioChan,
SIO_CALLBACK_PUT_RCV_CHAR,
(STATUS (*) (void *, ...)) usbKbdTxCallback,
(void *) pUsbKbdDev)!= OK) {
printf ("ERROR INSTALLING SIO_CALLBACK_GET_TX_CHAR callback for Keybaord\n");
return;
}
pUsbKbdDev->bufSize = 512;
pUsbKbdDev->buff = msgQCreate (pUsbKbdDev->bufSize, sizeof(char), MSG_Q_FIFO);
#else
sioIoctl (pUsbKbdDev->pSioChan, SIO_MODE_SET, (void *) SIO_MODE_POLL);
pUsbKbdDev->bufSize = 0;
pUsbKbdDev->buff = NULL;
#endif
/* add the device to the I/O system */
if (iosDevAdd (&pUsbKbdDev->ioDev, name, usbKbdDrvNum) != OK) {
printf ("Failed adding keyboard %s in iolib\n",name);
return ERROR;
}
#if (ATTACH_USB_KEYBOARD_TO_SHELL == TRUE)
redirectShellInput(pUsbKbdDev);
#endif
return OK;
}
/*******************************************************************************
*
* usbKbdDevDelete - delete a VxWorks device for an USB keyboard
*
* This routine deletes a device on a specified serial channel.
*
* This routine is typically called by the USB keyboard driver, when it detects
* a removal of a USB keyboard.
*
* RETURNS: OK, or ERROR if the driver is not installed.
*
* ERRNO: none
*
* \NOMANUAL
*/
LOCAL STATUS usbKbdDevDelete
(
USB_KBD_DEV * pUsbKbdDev /* keyboard device to read from */
)
{
int status = OK; /* holder for the return value */
if (usbKbdDrvNum <= 0)
{
errnoSet (S_ioLib_NO_DRIVER);
return (ERROR);
}
/* remove the device from the I/O system */
iosDevDelete (&pUsbKbdDev->ioDev);
/* remove from list */
USB_KBD_LIST_SEM_TAKE (WAIT_FOREVER);
lstDelete (&usbKbdList, (NODE *) pUsbKbdDev->pUsbKbdNode);
USB_KBD_LIST_SEM_GIVE;
/* free memory for the device */
#if (ATTACH_USB_KEYBOARD_TO_SHELL == TRUE)
restoreShellInput(pUsbKbdDev);
#endif
free (pUsbKbdDev->pUsbKbdNode);
#if (USB_KEYBOARD_POLLING == FALSE)
msgQDelete (pUsbKbdDev->buff);
#endif
free (pUsbKbdDev);
return (status);
}
/*************************************************************************
*
* usbKbdDevFind - find the USB_KBD_DEV device for an SIO channel
*
* This function finds the USB_KBD_DEV device for the specified SIO Channel
*
* RETURNS: OK, or ERROR
*
* ERRNO: none
*
* \NOMANUAL
*/
LOCAL STATUS usbKbdDevFind
(
SIO_CHAN * pChan, /* pointer to affected SIO_CHAN */
USB_KBD_DEV ** ppUsbKbdDev /* pointer to an USB_KBD_DEV */
)
{
USB_KBD_NODE * pUsbKbdNode = NULL; /* pointer to USB device node */
USB_KBD_DEV * pTempDev; /* pointer to an USB_KBD_DEV */
if (pChan == NULL)
return (ERROR);
/* protect it from other module's routines */
USB_KBD_LIST_SEM_TAKE (WAIT_FOREVER);
/* loop through all the devices */
for (pUsbKbdNode = (USB_KBD_NODE *) lstFirst (&usbKbdList);
pUsbKbdNode != NULL;
pUsbKbdNode = (USB_KBD_NODE *) lstNext ((NODE *) pUsbKbdNode))
{
pTempDev = pUsbKbdNode->pUsbKbdDev;
/* return as soon as you find it */
if (pTempDev->pSioChan == pChan)
{
* (UINT32 *) ppUsbKbdDev = (UINT32) pTempDev;
USB_KBD_LIST_SEM_GIVE;
return (OK);
}
}
USB_KBD_LIST_SEM_GIVE;
return (ERROR);
}
/*************************************************************************
*
* usbKbdDrvAttachCallback - receives attach callbacks from keyboard SIO driver
*
* This is the callback function which is called whenever the keyboard device
* is connected
*
* RETURNS: N/A
*
* ERRNO: none
*
* \NOMANUAL
*/
LOCAL void usbKbdDrvAttachCallback
(
void * arg, /* caller-defined argument */
SIO_CHAN *pChan, /* pointer to affected SIO_CHAN */
UINT16 attachCode /* defined as USB_KBD_xxxx */
)
{
USB_KBD_DEV * pUsbKbdDev=NULL; /* keyboard device */
char kbdName [KBD_NAME_LEN_MAX]; /* keyboard name */
USB_KBD_MUTEX_TAKE(WAIT_FOREVER);
/* A keyboard has been attached. */
if (attachCode == USB_KBD_ATTACH)
{
/* Lock this particular channel for this particular keyboard */
if (usbKeyboardSioChanLock (pChan) != OK)
{
printf("usbKeyboardSioChanLock () returned ERROR\n");
}
else
{
/* plugs the name /usbKb/x into the kbdName variable */
sprintf (kbdName, "%s%d", USB_KBD_NAME, kbdCount);
/* Create the keyboard device, do all the ios stuff (drvInstall,
* devAdd...)
*/
if (usbKbdDevCreate (kbdName, pChan) != OK)
{
printf("usbKbdDevCreate() returned ERROR\n");
}
/* now we can increment the counter */
kbdCount++;
if (usbKbdDevFind (pChan, &pUsbKbdDev) != OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -