📄 wdbvisiondrv.c
字号:
case VISION_RX_QUEUE_SIZE: { free (pFd->rxQueue.pData); if (visionInitQueue (&pFd->rxQueue, arg) == ERROR) { status = ERROR; } break; } case VISION_TX_QUEUE_SIZE: { free (pFd->txQueue.pData); if (visionInitQueue (&pFd->txQueue, arg) == ERROR) { status = ERROR; } break; } default: /* Unknown Function */ { status = ERROR; break; } } return (status); }/***************************************************************************** visionFillRxQueue - read from a memory file into receive queue** This routine read from a memory file intp recive queue.** RETURNS: The number of bytes read, or ERORR*/LOCAL int visionFillRxQueue ( VDRIV_DEV * pDev /* file descriptor of file to close */ ) { volatile VDRIV_DEV *pFd = pDev; int nRead = 0; int numBytes; char data; VDR_ULONG ioStatus; VDR_ULONG recvBytes = 0; static VDR_UCHAR buffer[VISION_PKT_MTU]; /* * If we are looping back data then extract the data from the * loopback QUEUE and place it in the Receive QUEUE. */ if (pFd->loopMode == VISION_LPBK_MODE) { ENTER_CRITSECT (pFd->loopCrSection); numBytes = visionBytesInQueue (&pFd->loopQueue); EXIT_CRITSECT (pFd->loopCrSection); if (numBytes != 0) { for ( ;; ) { ENTER_CRITSECT (pFd->loopCrSection); numBytes = visionRemoveFromQueue (&pFd->loopQueue, &data, 1); EXIT_CRITSECT (pFd->loopCrSection); if (numBytes == 0) { break; } else { ENTER_CRITSECT (pFd->rxCrSection); numBytes = visionAddToQueue (&pFd->rxQueue, &data, 1); EXIT_CRITSECT (pFd->rxCrSection); if (numBytes == 1) { nRead ++; } else { break ; /* RNR - need to deal with this better */ } } } } } /* * Now that we have dealt with the loopback information lets see * see if there is any data waiting for us. */ ioStatus = pFd->inter.readFunc (pFd->inter.privateData, (VDR_UCHAR*)buffer, (VDR_ULONG)VISION_PKT_MTU, &recvBytes); if ((ioStatus == VDR_SUCCESS) && (recvBytes != 0)) { ENTER_CRITSECT (pFd->rxCrSection); numBytes = visionAddToQueue (&pFd->rxQueue, buffer, recvBytes); EXIT_CRITSECT (pFd->rxCrSection); if (recvBytes != numBytes) { return (0); /* RNR - needs thinking about */ } nRead += numBytes; } return (nRead); }/***************************************************************************** visionStartPollTask - spawns a polling task to simulate Tx and Rx interrupts** This routine spawns a polling task to simulate Tx and Rx interrupts** RETURNS: OK or ERROR*/ LOCAL int visionStartPollTask ( VDRIV_DEV *pVisionDrv, int taskPriority ) { int taskId; if (taskIdCurrent) /* insure we're multitasking */ { /* * See if the task is already known. In which ase we only * need to start it up again. */ taskId = taskNameToId ("tVisionDrv"); if (taskId == ERROR) { pVisionDrv->pollTaskId = taskSpawn ("tVisionDrv", /* name */ taskPriority, /* runtime priority */ 0, /* options */ 5000, /* Stack size */ (int(*)())visionDrvPollTask, /* Entry point of task */ (int)pVisionDrv, /* Arg #01 , device info */ 0, /* Arg #02 , not used */ 0, /* Arg #03 , not used */ 0, /* Arg #04 , not used */ 0, /* Arg #05 , not used */ 0, /* Arg #06 , not used */ 0, /* Arg #07 , not used */ 0, /* Arg #08 , not used */ 0, /* Arg #09 , not used */ 0); /* Arg #10 , not used */ if (pVisionDrv->pollTaskId == ERROR) { return (ERROR); } } else { if (taskRestart (taskId) == ERROR) { return (ERROR); } } } else /* need to be multitasking */ { return (ERROR); } return (OK); }/***************************************************************************** visionDrvPollTask - background polling task to simulate Rx and Tx interrupts.** This routine is the background polling task to simulate Rx and Tx * interrups.** RETURNS: N/A*/ LOCAL void visionDrvPollTask ( VDRIV_DEV *pDev ) { volatile VDRIV_DEV *pFd = (VDRIV_DEV*)pDev; for ( ;; ) { visionPoll (pDev); DELAY_TASK (pFd->pollDelay); } }/***************************************************************************** visionPoll - poll and service Tx/Rx emulator descriptor buffers and Tx/Rx* queues.** This routine poll and service Tx/Rx emulator descriptor buffers and Tx/Rx * queues.** RETURNS: OK or ERROR (return status not used as this point)*/ LOCAL int visionPoll ( VDRIV_DEV *pDev ) { volatile VDRIV_DEV *pFd = (VDRIV_DEV*)pDev; int bytesInQueue; int bytesToWrite; static VDR_UCHAR localXmitBuf[VISION_PKT_MTU]; VDR_ULONG ioStatus; VDR_ULONG writeStatus; /* Handle any Rx data present in the Rx emulator descriptor */ ENTER_CRITSECT (pFd->rxCrSection); visionFillRxQueue ((VDRIV_DEV*)pFd); EXIT_CRITSECT (pFd->rxCrSection); /* Send any Tx data present in the Tx queue */ ENTER_CRITSECT (pFd->txCrSection); bytesInQueue = visionBytesInQueue (&pFd->txQueue); if (bytesInQueue != 0) { bytesToWrite = visionRemoveFromQueue (&pFd->txQueue, (char*)localXmitBuf, VISION_PKT_MTU); EXIT_CRITSECT (pFd->txCrSection); /* * bytesToWrite should be equal to bytesInQueue or queue * locking mechanism is not working. */ if (bytesToWrite != bytesInQueue) { } while (bytesToWrite > 0) { /* * If emulator is not busy, generate a transmission and * let the emulator pick up the data. */ ioStatus = pFd->inter.writeStatusFunc (pFd->inter.privateData, &writeStatus); if ((ioStatus == VDR_SUCCESS) && (writeStatus == VDR_WRITE_COMPLETE)) { ioStatus = pFd->inter.writeFunc (pFd->inter.privateData, localXmitBuf, bytesToWrite); if (ioStatus == VDR_FAILURE) { return (ERROR); } bytesToWrite = 0; } else /* Emulator busy reading buffer */ { DELAY_TASK (pFd->pollDelay); } } } else { EXIT_CRITSECT (pFd->txCrSection); } return (OK); }/***************************************************************************** visionInitQueue - create a VISION_QUEUE.** This routine create a VISION_QUEUE.** RETURNS: OK if queue created or ERROR if faild to create queue*/ LOCAL int visionInitQueue ( volatile VISION_QUEUE *pQueue, int qSize ) { /* Setup the various fields to indicate an empty QUEUE */ pQueue->nofChars = 0; pQueue->size = qSize; pQueue->head = 0; pQueue->tail = 0; /* Actually allocate the QUEUE buffer space */ if ((pQueue->pData = cacheDmaMalloc (qSize)) == NULL) { return (ERROR); } return (OK); }/***************************************************************************** visionAddToQueue - adds a string of characetrs to an VISION_QUEUE.** This routine adds a string of characetrs to an VISION_QUEUE.** RETURNS: number of characters placed into the buffer.*/ LOCAL int visionAddToQueue ( volatile VISION_QUEUE *pQueue, /* Queue to be manipulated */ char *pStr, /* Data to be inserted */ int size /* Amount of data supplied */ ) { int i; /* See of there is any room left in the QUEUE */ if (pQueue->nofChars >= pQueue->size) { return (0); } /* * If the entire string won't fit in buffer then only place the * data that will fit into buffer. */ if (size > (pQueue->size - pQueue->nofChars)) { size = pQueue->size - pQueue->nofChars; } for (i = 0 ;i < size ; i ++) { pQueue->pData[pQueue->head++] = *pStr++; /* Wrap-around the queue's data */ pQueue->head %= pQueue->size; } pQueue->nofChars += size; return (size); }/***************************************************************************** visionRemoveFromQueue - gets a string from an VISION_QUEUE** This routine gets a string from an VISION_QUEUE.** RETURNS: number of characters read from buffer.*/ LOCAL int visionRemoveFromQueue ( volatile VISION_QUEUE *pQueue, /* Queue to be extracted from */ char *str, /* Retrieved data area */ int size /* Amount of data requested */ ) { int i; /* * If there is not enough characters in buffer to fill it then only * put in what we have. */ if (size > pQueue->nofChars) { size = pQueue->nofChars; } if (size == 0) /* sanity check */ { return (0); } /* Extract the requested data from the QUEUE */ for (i = 0; i < size; i ++) { *str++ = pQueue->pData[pQueue->tail++]; /* Wrap-around the buffer's data */ pQueue->tail %= pQueue->size; } /* Decrement the remaining count by what as extracted */ pQueue->nofChars -= size; return (size); }/***************************************************************************** visionSpaceInQueue - returns space available in queue** This routine returns space available in queue** RETURNS: number of characters available in queue buffer.*/ LOCAL int visionSpaceInQueue ( volatile VISION_QUEUE *pQueue ) { return (pQueue->size - pQueue->nofChars); } /***************************************************************************** visionBytesInQueue - returns number of bytes in queue** This routine returns number of bytes in queue** RETURNS: number of bytes in the queue*/ LOCAL int visionBytesInQueue ( volatile VISION_QUEUE *pQueue ) { return (pQueue->nofChars); }/***************************************************************************** visionFlushQueue - resets queue to empty** This routine resets queue to empty** RETURN: number of characters flushed from queue.*/ LOCAL int visionFlushQueue ( volatile VISION_QUEUE *pQueue ) { int charsFlushed; charsFlushed = pQueue->nofChars; pQueue->nofChars = 0; pQueue->head = pQueue->tail = 0; return (charsFlushed); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -