📄 wncandevio.c
字号:
LOCAL STATUS wncUtilIoctlFioCmds
(
WNCAN_DEVIO_FDINFO *fdInfo, /* pointer to DevIO file descriptor */
int command, /* command function code */
int arg /* arbitrary argument */
)
{
WNCAN_DEVIO_DRVINFO* wncDrv = NULL;
WNCAN_DEVICE* canDev = NULL;
int* numBytes = NULL;
int bufSize = 0;
int key;
STATUS retCode=OK;
if (fdInfo == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlFioCmds() ERROR: pointer to DevIO file descriptor is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
wncDrv = fdInfo->wnDevIODrv;
if (wncDrv == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlFioCmds() ERROR: pointer to DevIO driver is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
canDev = wncDrv->wncDevice;
if (canDev == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlFioCmds() ERROR: pointer to DevIO device is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
/* lock device */
semTake(wncDrv->mutex, WAIT_FOREVER);
/* Process the specified command */
switch (command)
{
/* Internal input and output data buffer commands */
case FIOSELECT:
selNodeAdd (&fdInfo->selWakeupList, (SEL_WAKEUP_NODE *) arg);
key = intLock();
if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELREAD) &&
(!rngIsEmpty(fdInfo->fdtype.channel.inputBuf)))
{
/* data available, make sure task does not pend */
selWakeup ((SEL_WAKEUP_NODE *) arg);
}
if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELWRITE) &&
(!rngIsFull(fdInfo->fdtype.channel.outputBuf)))
{
/* device ready for writing, make sure task does not pend */
selWakeup ((SEL_WAKEUP_NODE *) arg);
}
intUnlock(key);
break;
case FIOUNSELECT:
/* delete node from wakeup list */
retCode=selNodeDelete (&fdInfo->selWakeupList, (SEL_WAKEUP_NODE *) arg);
#if DEVIO_DEBUG
if(retCode == ERROR)
logMsg("wncUtilIoctlFioCmds() ERROR: FIOUNSELECT node not in list\n",
0,0,0,0,0,0);
#endif
break;
case FIONFREE:
/* Get #free bytes in output data buffer */
numBytes = (int *) arg;
*numBytes = rngFreeBytes (fdInfo->fdtype.channel.outputBuf);
break;
case FIONREAD:
/* Get #bytes ready to be read from the input data buffer */
numBytes = (int *) arg;
*numBytes = rngNBytes (fdInfo->fdtype.channel.inputBuf);
break;
case FIONWRITE:
/* Get #bytes written to the output data buffer */
numBytes = (int *) arg;
*numBytes = rngNBytes (fdInfo->fdtype.channel.outputBuf);
break;
case FIOFLUSH:
/* Discard all bytes in both input and output data buffers */
key = intLock();
rngFlush (fdInfo->fdtype.channel.inputBuf);
rngFlush (fdInfo->fdtype.channel.outputBuf);
intUnlock(key);
break;
case FIORFLUSH:
/* Discard all bytes in the input data buffer */
key = intLock();
rngFlush (fdInfo->fdtype.channel.inputBuf);
intUnlock(key);
break;
case FIOWFLUSH:
/* Discard all bytes in the output data buffer */
key = intLock();
rngFlush (fdInfo->fdtype.channel.outputBuf);
intUnlock(key);
break;
case FIORBUFSET:
/* Set the input data buffer size; User specifies #msgs */
bufSize = wncUtilCalcRingBufSize (arg);
if (bufSize)
{
key = intLock();
rngFlush(fdInfo->fdtype.channel.inputBuf);
rngDelete(fdInfo->fdtype.channel.inputBuf);
fdInfo->fdtype.channel.inputBuf = rngCreate(bufSize);
if(fdInfo->fdtype.channel.inputBuf == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlFioCmds() ERROR: FIORBUFSET ring create failed\n",
0,0,0,0,0,0);
#endif
retCode=ERROR;
}
intUnlock(key);
}
break;
case FIOWBUFSET:
/* Set the output data buffer size; User specifies #msgs */
bufSize = wncUtilCalcRingBufSize (arg);
if (bufSize)
{
key = intLock();
rngFlush(fdInfo->fdtype.channel.outputBuf);
rngDelete(fdInfo->fdtype.channel.outputBuf);
fdInfo->fdtype.channel.outputBuf = rngCreate(bufSize);
if(fdInfo->fdtype.channel.outputBuf == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlFioCmds() ERROR: FIOWBUFSET ring create failed\n",
0,0,0,0,0,0);
#endif
retCode=ERROR;
}
intUnlock(key);
}
break;
}
/* unlock device */
semGive(wncDrv->mutex);
return retCode;
}
/************************************************************************
*
* wncUtilIoctlDeviceFioCmds - utility routine to process FIO* ioctl()
* commands for a device
*
* This routine performs the processing for FIO* (internal input and
* output data buffer) commands specified via ioctl()
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
*/
LOCAL STATUS wncUtilIoctlDeviceFioCmds
(
WNCAN_DEVIO_FDINFO *fdInfo, /* pointer to DevIO file descriptor */
int command, /* command function code */
int arg /* arbitrary argument */
)
{
WNCAN_DEVIO_DRVINFO* wncDrv = NULL;
WNCAN_DEVICE* canDev = NULL;
int key;
if (fdInfo == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlDeviceFioCmds() ERROR: pointer to DevIO file descriptor is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
wncDrv = fdInfo->wnDevIODrv;
if (wncDrv == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlDeviceFioCmds() ERROR: pointer to DevIO driver is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
canDev = wncDrv->wncDevice;
if (canDev == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlDeviceFioCmds() ERROR: pointer to DevIO device is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
/* lock device */
semTake(wncDrv->mutex, WAIT_FOREVER);
/* Process the specified command */
switch (command)
{
/* Internal input and output data buffer commands */
case FIOSELECT:
selNodeAdd (&fdInfo->selWakeupList, (SEL_WAKEUP_NODE *) arg);
key = intLock();
if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELREAD) &&
(CAN_GetBusStatus(canDev) != WNCAN_BUS_OK))
{
/* bus in an error/warning state, make sure task does not pend */
selWakeup ((SEL_WAKEUP_NODE *) arg);
}
/* there is no blocking for WRITE descriptors for the device */
if (selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELWRITE)
{
selWakeup ((SEL_WAKEUP_NODE *) arg);
}
intUnlock(key);
break;
case FIOUNSELECT:
/* delete node from wakeup list */
selNodeDelete (&fdInfo->selWakeupList, (SEL_WAKEUP_NODE *) arg);
break;
}
/* unlock device */
semGive(wncDrv->mutex);
return OK;
}
/************************************************************************
*
* wncUtilIoctlDeviceCmds - utility routine to process CAN device ioctl()
* commands
*
* This routine performs the processing for CAN device commands specified
* via ioctl()
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
*/
LOCAL STATUS wncUtilIoctlDeviceCmds
(
WNCAN_DEVIO_FDINFO *fdInfo, /* pointer to DevIO file descriptor */
int command, /* command function code */
int arg /* arbitrary argument */
)
{
WNCAN_DEVIO_DRVINFO* wncDrv = NULL;
WNCAN_DEVICE* canDev = NULL;
STATUS status = ERROR; /* pessimistic */
UCHAR* chNum = NULL;
WNCAN_CONFIG* devCfg = NULL;
WNCAN_REG* regCfg = NULL;
if (fdInfo == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlDeviceCmds() ERROR: pointer to DevIO file descriptor is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
wncDrv = fdInfo->wnDevIODrv;
if (wncDrv == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlDeviceCmds() ERROR: pointer to DevIO driver is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
canDev = wncDrv->wncDevice;
if (canDev == NULL)
{
#if DEVIO_DEBUG
logMsg("wncUtilIoctlDeviceCmds() ERROR: pointer to DevIO device is null\n",
0,0,0,0,0,0);
#endif
return ERROR;
}
/* lock device */
semTake(wncDrv->mutex, WAIT_FOREVER);
/* Process the specified command */
switch (command)
{
/* CAN device commands */
case WNCAN_HALT:
{
BOOL stop = (BOOL) arg;
if (stop == TRUE)
CAN_Stop (canDev);
else
CAN_Start (canDev);
}
status = OK;
break;
case WNCAN_SLEEP:
status = CAN_Sleep (canDev);
break;
case WNCAN_WAKE:
status = CAN_WakeUp (canDev);
break;
case WNCAN_TX_ABORT:
CAN_TxAbort (canDev);
status = OK;
break;
case WNCAN_RXCHAN_GET:
chNum = (UCHAR *) arg;
status = CAN_GetRxChannel (canDev, chNum);
break;
case WNCAN_TXCHAN_GET:
chNum = (UCHAR *) arg;
status = CAN_GetTxChannel (canDev, chNum);
break;
case WNCAN_RTRREQCHAN_GET:
chNum = (UCHAR *) arg;
status = CAN_GetRTRRequesterChannel (canDev, chNum);
break;
case WNCAN_RTRRESPCHAN_GET:
chNum = (UCHAR *) arg;
status = CAN_GetRTRResponderChannel (canDev, chNum);
break;
case WNCAN_BUSINFO_GET:
{
WNCAN_BUSINFO* busInfo = (WNCAN_BUSINFO *) arg;
busInfo->busStatus = CAN_GetBusStatus (canDev);
busInfo->busError = CAN_GetBusError (canDev);
}
status = OK;
break;
case WNCAN_CONFIG_SET:
devCfg = (WNCAN_CONFIG *) arg;
/*
Determine which configuration options are being set;
User will 'OR' selected items together into flags, so
we need to parse flags here
*/
if ( (devCfg->flags & WNCAN_CFG_INFO) == WNCAN_CFG_INFO)
{
/* WNCAN_CFG_INFO not applicable for SET; ignore */
status = OK;
}
if ( (devCfg->flags & WNCAN_CFG_GBLFILTER) == WNCAN_CFG_GBLFILTER)
{
status = CAN_SetGlobalRxFilter (canDev, devCfg->filter.mask,
devCfg->filter.extended);
if(status == ERROR)
break;
}
if ( (devCfg->flags & WNCAN_CFG_BITTIMING) == WNCAN_CFG_BITTIMING)
{
status = CAN_SetBitTiming (canDev, devCfg->bittiming.tseg1,
devCfg->bittiming.tseg2,
devCfg->bittiming.brp,
devCfg->bittiming.sjw,
devCfg->bittiming.oversample);
}
break;
case WNCAN_CONFIG_GET:
devCfg = (WNCAN_CONFIG *) arg;
/*
Determine which configuration options are to be retrieved;
User will 'OR' selected items together into flags, so
we need to parse flags here
*/
if ( (devCfg->flags & WNCAN_CFG_INFO) == WNCAN_CFG_INFO)
{
const WNCAN_VersionInfo *verInfo = CAN_GetVersion ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -