Win32 串口编程(四)
7 通信超時(shí)
通信超時(shí)是影響讀寫操作的另一個(gè)重要方面。如果操作所用時(shí)間大于超時(shí)值,則操作完成,ReadFile、WriteFile、GetOverlappedResule或者WaitForSingleObject不會(huì)返回錯(cuò)誤代碼,它們都指示操作成功完成。實(shí)際傳輸?shù)淖止?jié)數(shù)小于請(qǐng)求的字節(jié)數(shù)是操作超時(shí)的唯一指示。如果ReadFile返回TRUE,但是讀取到的字節(jié)數(shù)小于請(qǐng)求的字節(jié)數(shù),則操作超時(shí)了。如果重疊寫操作超時(shí),則重疊事件句柄受信,WaitForSingleObject返回WAIT_OBJECT_0;GetOverlappedResult返回TRUE,dwBytesTransferred指示超時(shí)前已經(jīng)傳輸?shù)淖止?jié)數(shù)。下面的代碼展示了如何處理這種情況:
BOOL WriteABuffer(char * lpBuf, DWORD dwToWrite){? OVERLAPPED osWrite = {0};? DWORD dwWritten;? DWORD dwRes;? BOOL? fRes; ?? // Create this write operation's OVERLAPPED structure hEvent.? osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);? if (osWrite.hEvent == NULL)???? // Error creating overlapped event handle.???? return FALSE; ?? // Issue write? if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) {???? if (GetLastError() != ERROR_IO_PENDING) { ??????? // WriteFile failed, but it isn't delayed. Report error.??????? fRes = FALSE;???? }???? else??????? // Write is pending.??????? dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);??????? switch(dwRes)??????? {?????????? // Overlapped event has been signaled. ?????????? case WAIT_OBJECT_0:??????????????? if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE))????????????????????? fRes = FALSE;??????????????? else {???????????????? if (dwWritten != dwToWrite) {??????????????????? // The write operation timed out. I now need to ??????????????????? // decide if I want to abort or retry. If I retry, ??????????????????? // I need to send only the bytes that weren't sent. ??????????????????? // If I want to abort, I would just set fRes to ??????????????????? // FALSE and return.??????????????????? fRes = FALSE;???????????????? }???????????????? else??????????????????? // Write operation completed successfully.??????????????????? fRes = TRUE;?????????????? }??????????????? break;?????????? ?????????? default:??????????????? // An error has occurred in WaitForSingleObject. This usually ?????????????? // indicates a problem with the overlapped event handle.??????????????? fRes = FALSE;??????????????? break;??????? }???? }? }? else {???? // WriteFile completed immediately. ????? if (dwWritten != dwToWrite) {???????? // The write operation timed out. I now need to ???????? // decide if I want to abort or retry. If I retry, ???????? // I need to send only the bytes that weren't sent. ???????? // If I want to abort, then I would just set fRes to ???????? // FALSE and return.???????? fRes = FALSE;???? }???? else???????? fRes = TRUE;? } ?? CloseHandle(osWrite.hEvent);? return fRes;}SetCommTimeouts 用以設(shè)置端口的通信超時(shí)值;GetCommTimeouts獲取通信超時(shí)。下面是代碼示例:
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 20;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.WriteTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hComm, &timeouts))
?? // Error setting time-outs.
如果設(shè)置COMMTIMOUTS的各個(gè)成員為零,則不會(huì)發(fā)生超時(shí)。非重疊操作會(huì)阻塞直到請(qǐng)求的字節(jié)數(shù)傳輸完成:ReadFile會(huì)阻塞直到所有請(qǐng)求的字符到達(dá)端口;WriteFile會(huì)阻塞直到所有請(qǐng)求的字符被發(fā)送。重疊操作只有在所有字符已經(jīng)傳輸,或者取消操作時(shí)才完成。只有操作完成時(shí)才發(fā)生下列條件:
- WaitForSingleObject always returns WAIT_TIMEOUT if a synchronization time-out is supplied. WaitForSingleObject will block forever if an INFINITE synchronization time-out is used.
- GetOverlappedResult always returns FALSE and GetLastError returns ERROR_IO_INCOMPLETE if called directly after the call to GetOverlappedResult.
Setting the members of the COMMTIMEOUTS structure in the following manner causes read operations to complete immediately without waiting for any new data to arrive:
COMMTIMEOUTS timeouts;timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0;if (!SetCommTimeouts(hComm, &timeouts))// Error setting time-outs.These settings are necessary when used with an event-based read described in the "Caveat" section earlier. In order for ReadFile to return 0 bytes read, the ReadIntervalTimeout member of the COMMTIMEOUTS structure is set to MAXDWORD, and the ReadTimeoutMultiplier and ReadTimeoutConstant are both set to zero.
An application must always specifically set communications time-outs when it uses a communications port. The behavior of read and write operations is affected by communications time-outs. When a port is initially open, it uses default time-outs supplied by the driver or time-outs left over from a previous communications application. If an application assumes that time-outs are set a certain way, while the time-outs are actually different, then read and write operations may never complete or may complete too often.
總結(jié)
以上是生活随笔為你收集整理的Win32 串口编程(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js 原型以及原型链
- 下一篇: html自动适应屏幕分辨率,css如何自