📄 rngdrv.c
字号:
#include "vxWorks.h"#include "ioLib.h"#include "iosLib.h"#include "rngLib.h"#include "semLib.h"#include "objLib.h"#include "selectLib.h"#include "rngDrv.h"typedef struct { DEV_HDR devHdr; RING_ID rngId; SEM_ID writeSem; SEM_ID readSem; SEL_WAKEUP_LIST selList; } RNG_DEV;#ifdef DEBUG#define RNG_ERR(errNum) rngError (__FILE__, __LINE__, (errNum))#else#define RNG_ERR(errNum) (errno = (errNum))#endif LOCAL int rngDrvNum;LOCAL int rngTimeout = WAIT_FOREVER;extern int errno;/* Forward declarations */int rngOpen ();int rngRead ();int rngWrite ();int rngIoctl ();LOCAL void rngDeleteDev();LOCAL void rngError();STATUS rngDrv () { /* If driver already installed, just return OK */ if (rngDrvNum > 0) return (OK); /* Add driver to the driver table and save driver number (entry * in table) */ if ((rngDrvNum = iosDrvInstall (rngOpen, NULL, rngOpen, NULL, rngRead, rngWrite, rngIoctl)) == ERROR) { RNG_ERR (errno); return (ERROR); } return (OK); }STATUS rngDevCreate (devName, nBytes) char * devName; /* Name of device to create */ int nBytes; /* Size of ring buffer to create */ { RNG_DEV * pRngDev; /* Fail if driver not installed */ if (rngDrvNum < 1) { RNG_ERR (S_ioLib_NO_DRIVER); return (ERROR); } /* Allocate a device descriptor and zero it out */ if ((pRngDev = (RNG_DEV *) malloc (sizeof (RNG_DEV))) == NULL) { RNG_ERR (errno); return (ERROR); } bzero (pRngDev, sizeof (RNG_DEV)); /* Initialize selectLib */ selWakeupListInit (&pRngDev->selList); /* Create a ring buffer and save the ring ID in the device descriptor */ if ((pRngDev->rngId = rngCreate (nBytes)) == NULL) { RNG_ERR (errno); rngDeleteDev (pRngDev); return (ERROR); } /* Create mutex semaphores to guard access to ring buffer */ if ((pRngDev->readSem = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE)) == NULL) { RNG_ERR (errno); rngDeleteDev (pRngDev->rngId); return (ERROR); } if ((pRngDev->writeSem = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE)) == NULL) { RNG_ERR (errno); rngDeleteDev (pRngDev); return (ERROR); } /* Add the device desriptor into the device list */ if (iosDevAdd (&pRngDev->devHdr, devName, rngDrvNum) == ERROR) { RNG_ERR (errno); rngDeleteDev (pRngDev); return (ERROR); } return (OK); }LOCAL void rngDeleteDev (pRngDev) RNG_DEV * pRngDev; { if (pRngDev == NULL) return; if (pRngDev->rngId) rngDelete (pRngDev->rngId); if (pRngDev->readSem) semDelete (pRngDev->readSem); if (pRngDev->writeSem) semDelete (pRngDev->writeSem); free (pRngDev); }int rngOpen (pDevHdr, mode, flag) DEV_HDR * pDevHdr; int mode; int flag; { return ((int) pDevHdr); }int rngWrite (devId, pBuf, nBytes) int devId; char * pBuf; int nBytes; { RNG_DEV * pRngDev = (RNG_DEV *) devId; int bytesWritten; /* While writing to ring buffer, need to insure exclusive write access */ if (semTake (pRngDev->writeSem, rngTimeout) == ERROR) { if (errno == S_objLib_OBJ_TIMEOUT) return (0); else { RNG_ERR (errno); return (ERROR); } } /* Fill ring buffer until we have finished request */ bytesWritten = rngBufPut (pRngDev->rngId, pBuf, nBytes); if (bytesWritten > 0) selWakeupAll (&pRngDev->selList, SELREAD); /* Release mutex write semaphore */ semGive (pRngDev->writeSem); /* Return number of bytes read or ERROR */ return (bytesWritten); }int rngRead (devId, pBuf, nBytes) int devId; char * pBuf; int nBytes; { RNG_DEV * pRngDev = (RNG_DEV *) devId; int bytesRead; /* Insure that there are no other readers */ if (semTake (pRngDev->readSem, rngTimeout) == ERROR) { if (errno == S_objLib_OBJ_TIMEOUT) return (0); else { RNG_ERR (errno); return (ERROR); } } /* Read the ring buffer */ bytesRead = rngBufGet (pRngDev->rngId, pBuf, nBytes); /* If we read anything, inform select */ if (bytesRead > 0) selWakeupAll (&pRngDev->selList, SELWRITE); /* Release mutex read semaphore */ semGive (pRngDev->readSem); return (bytesRead); }int rngIoctl (devId, cmd, arg) int devId; int cmd; int arg; { RNG_DEV * pRngDev = (RNG_DEV *) devId; int status; switch (cmd) { case FIOSELECT: selNodeAdd (&pRngDev->selList, (SEL_WAKEUP_NODE *) arg); if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELREAD) && (rngNBytes (pRngDev->rngId) > 0)) selWakeup ((SEL_WAKEUP_NODE *) arg); if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELWRITE) && (rngFreeBytes (pRngDev->rngId) > 0)) selWakeup ((SEL_WAKEUP_NODE *) arg); break; case FIOUNSELECT: selNodeDelete (&pRngDev->selList, (SEL_WAKEUP_NODE *) arg); break; case GET_NUM_BYTES: status = rngNBytes (pRngDev->rngId); break; case GET_FREE_BYTES: status = rngFreeBytes (pRngDev->rngId); break; default: RNG_ERR (S_ioLib_UNKNOWN_REQUEST); status = ERROR; break; } return (status); }LOCAL void rngError (filename, lineNum, errNum) char * filename; int lineNum; int errNum; { errno = errNum; printErr("Error in %s on line %d: ", filename, lineNum); printErrno (errNum); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -