|
关于2440,ce5中的串口COM_Write函数的WaitReturn = WaitForSingleObject
[复制链接]
- ULONG
- COM_Write(HANDLE pHead, /*@parm [IN] HANDLE returned by COM_Open.*/
- PUCHAR pSourceBytes, /*@parm [IN] Pointer to bytes to be written.*/
- ULONG NumberOfBytes /*@parm [IN] Number of bytes to be written. */
- )
- {
- PHW_OPEN_INFO pOpenHead = (PHW_OPEN_INFO)pHead;
- PHW_INDEP_INFO pSerialHead = pOpenHead->pSerialHead;
- ULONG BytesWritten = 0;
- ULONG TotalWritten = 0;
- PHWOBJ pHWObj = NULL;
- PVOID pHWHead = NULL;
- PHW_VTBL pFuncTbl = NULL;
- ULONG TotalTimeout; // The Total Timeout
- ULONG Timeout; // The Timeout value actually used
- ULONG WaitReturn;
- DEBUGMSG (ZONE_WRITE|ZONE_FUNCTION,
- (TEXT("+COM_WRITE(0x%X, 0x%X, %d)\r\n"), pHead,
- pSourceBytes, NumberOfBytes));
- // Check validity of handle
- if ( !pSerialHead || !pSerialHead->OpenCnt ) {
- DEBUGMSG (ZONE_WRITE|ZONE_ERROR,
- (TEXT("COM_WRITE, device not open\r\n") ));
- SetLastError (ERROR_INVALID_HANDLE);
- return(ULONG)-1;
- }
- // Make sure the caller has access permissions
- if ( !(pOpenHead->AccessCode & GENERIC_WRITE) ) {
- DEBUGMSG(ZONE_USR_READ|ZONE_ERROR,
- (TEXT("COM_Write: Access permission failure x%X\n\r"),
- pOpenHead->AccessCode));
- SetLastError (ERROR_INVALID_ACCESS);
- return(ULONG)-1;
- }
- #ifdef DEBUG
- if ( IsBadReadPtr(pSourceBytes, NumberOfBytes) ) {
- DEBUGMSG (ZONE_WRITE|ZONE_ERROR,
- (TEXT("COM_WRITE, bad read pointer\r\n") ));
- SetLastError(ERROR_INVALID_PARAMETER);
- return(ULONG)-1;
- }
- #endif
- COM_INC_USAGE_CNT(pOpenHead);
- pHWObj = pSerialHead->pHWObj;
- pHWHead = pSerialHead->pHWHead;
- pFuncTbl = pHWObj->pFuncTbl;
- /* Lock out other threads from messing with these pointers.
- */
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write wait for CritSec %x.\r\n"),
- &(pSerialHead->TransmitCritSec1)));
- EnterCriticalSection(&(pSerialHead->TransmitCritSec1));
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write Got CritSec %x.\r\n"),
- &(pSerialHead->TransmitCritSec1)));
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write wait for CritSec %x.\r\n"),
- &(pSerialHead->TxBufferInfo.CS)));
- TxEnterCS(pSerialHead);
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write got CritSec %x.\r\n"),
- &(pSerialHead->TxBufferInfo.CS)));
- pSerialHead->fAbortTransmit = 0;
- // Clear any pending event
- WaitForSingleObject(pSerialHead->hTransmitEvent,0);
- pSerialHead->TxBufferInfo.Permissions = GetCurrentPermissions();
- pSerialHead->TxBufferInfo.TxCharBuffer = pSourceBytes;
- pSerialHead->TxBufferInfo.Length = NumberOfBytes;
- TxRead(pSerialHead) = 0;
- pSerialHead->TxBytesSent = 0;
- pSerialHead->TxBytesPending = NumberOfBytes;
- // Make sure an event isn't hanging around from a previous write time out.
- ResetEvent( pSerialHead->hTransmitEvent );
- TxLeaveCS(pSerialHead);
- DEBUGMSG (ZONE_WRITE|ZONE_FUNCTION,
- (TEXT("COM_Write released CritSec: %x.\r\n"),
- &(pSerialHead->TxBufferInfo.CS)));
- // We call the same write routine that a TX_INTR does. It queus as
- // much data as possible, then returns. From then on, the normal
- // interrupt mechanism kicks in.
- DoTxData( pSerialHead );
- TotalTimeout = pSerialHead->CommTimeouts.WriteTotalTimeoutMultiplier*NumberOfBytes +
- pSerialHead->CommTimeouts.WriteTotalTimeoutConstant;
- if ( !TotalTimeout )
- Timeout = INFINITE;
- else
- Timeout = TotalTimeout;
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write wait for transmission complete event %x.\r\n"),
- pSerialHead->hTransmitEvent));
- [color=#FF0000]WaitReturn = WaitForSingleObject (pSerialHead->hTransmitEvent, Timeout);[/color]
- [color=#FF0000]这里在等啥事件啊?这个事件是怎么发生的啊?由谁产生的?在哪里被处理的?[/color]
- // In the absense of WaitForMultipleObjects, we use flags to
- // handle errors/aborts. Check for aborts or asynchronous closes.
- if ( pSerialHead->fAbortTransmit ) {
- DEBUGMSG(ZONE_USR_READ,(TEXT("COM_Write - Aborting write\r\n")));
- goto LEAVEWRITE;
- }
- if ( !pSerialHead->OpenCnt ) {
- DEBUGMSG(ZONE_WRITE|ZONE_ERROR,
- (TEXT("COM_Write - device was closed\n\r")));
- SetLastError(ERROR_INVALID_HANDLE);
- goto LEAVEWRITE;
- }
- #ifdef DEBUG
- if ( WAIT_TIMEOUT == WaitReturn ) {
- // Timeout
- DEBUGMSG (ZONE_WARN, (TEXT("Write timeout %d, %d\r\n"), NumberOfBytes, pSerialHead->TxBytesPending));
- } else {
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write completed normally.\r\n")));
- }
- #endif
- LEAVEWRITE:
- // Regardless of timeout, we need to clear the TxBufferInfo
- // to prevent ISR from possibly coming around and trying to use
- // the buffer after we have returned to the caller.
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write wait for CritSec %x.\r\n"),
- &(pSerialHead->TxBufferInfo.CS)));
- TxEnterCS(pSerialHead);
- DEBUGMSG (ZONE_WRITE, (TEXT("COM_Write got CritSec %x.\r\n"),
- &(pSerialHead->TxBufferInfo.CS)));
- pSerialHead->TxBufferInfo.Permissions = 0;
- pSerialHead->TxBufferInfo.TxCharBuffer = NULL;
- pSerialHead->TxBufferInfo.Length = 0;
- pSerialHead->TxBytesPending = 0;
- TxRead(pSerialHead) = 0;
- TxLeaveCS(pSerialHead);
- DEBUGMSG (ZONE_WRITE|ZONE_FUNCTION,
- (TEXT("COM_Write released CritSec: %x.\r\n"),
- &(pSerialHead->TxBufferInfo.CS)));
- LeaveCriticalSection(&(pSerialHead->TransmitCritSec1));
- DEBUGMSG (ZONE_WRITE|ZONE_FUNCTION,
- (TEXT("COM_Write released CritSec: %x. Exiting\r\n"),
- &(pSerialHead->TransmitCritSec1)));
- /* OK, the Transmitter has gone empty.
- */
- EvaluateEventFlag(pSerialHead, EV_TXEMPTY);
- if ( pSerialHead->DCB.fRtsControl == RTS_CONTROL_TOGGLE ) {
- pFuncTbl->HWClearRTS(pHWHead);
- }
- COM_DEC_USAGE_CNT(pOpenHead);
- DEBUGMSG (ZONE_WRITE|ZONE_FUNCTION,
- (TEXT("-COM_WRITE, returning %d\n\r"),pSerialHead->TxBytesSent));
- return(pSerialHead->TxBytesSent);
- }
复制代码
|
|