|
@@ -1,6 +1,21 @@
|
|
|
#include "stdafx.h"
|
|
|
#include "Serial.h"
|
|
|
|
|
|
+VOID _dprintf(CHAR* pszStr, ...)
|
|
|
+{
|
|
|
+ const int LOGLEN = 3072;
|
|
|
+ char szData[LOGLEN] = { 0 };
|
|
|
+ _stprintf_s(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")).GetString());
|
|
|
+ int len = strlen(szData);
|
|
|
+ va_list args;
|
|
|
+ va_start(args, pszStr);
|
|
|
+ _vsnprintf_s(szData + len, LOGLEN - len, LOGLEN - len, pszStr, args);
|
|
|
+ va_end(args);
|
|
|
+ if (szData[strlen(szData) - 1] != '\n')
|
|
|
+ strcat_s(szData, "\n");
|
|
|
+ OutputDebugStringA(szData);
|
|
|
+}
|
|
|
+
|
|
|
DCB *CBaseSerial::GetState()
|
|
|
{
|
|
|
return IsOpen() && ::GetCommState(_hCommHandle, &_DCB) == TRUE ? &_DCB : NULL;
|
|
@@ -45,8 +60,9 @@ LPCOMMTIMEOUTS CBaseSerial::GetTimeouts()
|
|
|
return IsOpen() && ::GetCommTimeouts(_hCommHandle, &_CO) == TRUE ? &_CO : NULL;
|
|
|
}
|
|
|
|
|
|
-bool CBaseSerial::SetTimeouts(COMMTIMEOUTS CO)
|
|
|
+bool CBaseSerial::SetTimeouts(DWORD ReadIntervalTimeout , DWORD ReadTotalTimeoutMultiplier , DWORD ReadTotalTimeoutConstant , DWORD WriteTotalTimeoutMultiplier , DWORD WriteTotalTimeoutConstant )
|
|
|
{
|
|
|
+ COMMTIMEOUTS CO = {ReadIntervalTimeout, ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant, WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant};
|
|
|
return IsOpen() ? ::SetCommTimeouts(_hCommHandle, &CO) == TRUE : false;
|
|
|
}
|
|
|
|
|
@@ -113,8 +129,7 @@ DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime
|
|
|
|
|
|
COMSTAT Stat;
|
|
|
DWORD dwError;
|
|
|
- if (::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0)
|
|
|
- {
|
|
|
+ if (::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0) {
|
|
|
::PurgeComm(_hCommHandle, PURGE_RXABORT | PURGE_RXCLEAR);
|
|
|
return 0;
|
|
|
}
|
|
@@ -124,25 +139,33 @@ DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime
|
|
|
if (!Stat.cbInQue)
|
|
|
return 0;
|
|
|
#endif
|
|
|
+ _dprintf("缓冲区数据量:%ld", Stat.cbInQue);
|
|
|
|
|
|
unsigned long uReadLength = 0;
|
|
|
|
|
|
- if (!::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, &_ReadOverlapped))
|
|
|
- {
|
|
|
- if (::GetLastError() == ERROR_IO_PENDING)
|
|
|
- {
|
|
|
- WaitForSingleObject(_ReadOverlapped.hEvent, dwWaitTime);
|
|
|
-
|
|
|
- while (!::GetOverlappedResult(_hCommHandle, &_ReadOverlapped, &uReadLength, false))
|
|
|
- {
|
|
|
- Sleep(50);
|
|
|
+ if (!::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, &_ReadOverlapped)) {
|
|
|
+
|
|
|
+ if (::GetLastError() == ERROR_IO_PENDING) {
|
|
|
+ while (!::GetOverlappedResult(_hCommHandle, &_ReadOverlapped, &uReadLength, false)) {
|
|
|
+ dwError = ::GetLastError();
|
|
|
+ if ( dwError == ERROR_IO_PENDING ) {
|
|
|
+ Sleep(50);
|
|
|
+ _dprintf("读等待:%ld", dwError);
|
|
|
+ } else if ( dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE ) {
|
|
|
+ _dprintf("读完成:%ld,%ld,%ld", dwError, uReadLength,_ReadOverlapped.InternalHigh);
|
|
|
+
|
|
|
+ if ( _ReadOverlapped.InternalHigh )
|
|
|
+ uReadLength = _ReadOverlapped.InternalHigh;
|
|
|
+ else
|
|
|
+ uReadLength = Stat.cbInQue;
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ _dprintf("读错误:%ld", dwError);
|
|
|
+ uReadLength = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- if (::GetLastError() != ERROR_IO_INCOMPLETE)
|
|
|
- uReadLength = 0;
|
|
|
}
|
|
|
- else
|
|
|
- uReadLength = 0;
|
|
|
}
|
|
|
|
|
|
return uReadLength;
|
|
@@ -166,8 +189,24 @@ DWORD CBaseSerial::Write(LPVOID Buffer, DWORD dwBufferLength)
|
|
|
|
|
|
unsigned long uWriteLength = 0;
|
|
|
if (!::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, &_WriteOverlapped)) {
|
|
|
- if (::GetLastError() != ERROR_IO_PENDING) {
|
|
|
- uWriteLength = 0;
|
|
|
+ if (ERROR_IO_PENDING == GetLastError()) {
|
|
|
+ while (!GetOverlappedResult(_hCommHandle, &_WriteOverlapped, &uWriteLength, FALSE)) {
|
|
|
+ _dprintf("GetOverlappedResult");
|
|
|
+ dwError = GetLastError();
|
|
|
+ if (ERROR_IO_PENDING == dwError) {
|
|
|
+ _dprintf("写等待");
|
|
|
+ continue;
|
|
|
+ } else if (dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE){
|
|
|
+ uWriteLength = _WriteOverlapped.InternalHigh;
|
|
|
+ _dprintf("写完成:%ld", dwError);
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ _dprintf("写出错:%ld",dwError);
|
|
|
+ uWriteLength = 0;
|
|
|
+ ClearCommError(_hCommHandle, &dwError, NULL);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -185,15 +224,46 @@ DWORD CBaseSerial::ReadSync(LPVOID Buffer, DWORD dwBufferLength)
|
|
|
if (!IsOpen())
|
|
|
return 0;
|
|
|
|
|
|
+ COMSTAT Stat;
|
|
|
DWORD dwError;
|
|
|
- if (::ClearCommError(_hCommHandle, &dwError, NULL) && dwError > 0)
|
|
|
- {
|
|
|
- ::PurgeComm(_hCommHandle, PURGE_RXABORT | PURGE_RXCLEAR);
|
|
|
+
|
|
|
+ DWORD dwLastLen = 0;
|
|
|
+ ULONGLONG ulTick = GetTickCount();
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ if (GetTickCount() - ulTick > 3000) {
|
|
|
+ _dprintf("读出错: 超过3秒仍未读完");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0 ) {
|
|
|
+ ::PurgeComm(_hCommHandle, PURGE_RXABORT | PURGE_RXCLEAR);
|
|
|
+ _dprintf("读出错: ClearCommError出错");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (Stat.cbInQue != 0 && dwLastLen == Stat.cbInQue)
|
|
|
+ break;
|
|
|
+ dwLastLen = Stat.cbInQue;
|
|
|
+ Sleep(100);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Stat.cbInQue == 0) {
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ if (dwBufferLength < Stat.cbInQue) {
|
|
|
+ _dprintf("读出错: 缓冲数据过大 %ld > %ld", dwBufferLength, Stat.cbInQue);
|
|
|
+ }
|
|
|
+
|
|
|
DWORD uReadLength = 0;
|
|
|
- ::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, NULL);
|
|
|
+ if ( !::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, NULL) )
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ _dprintf("读出错:%ld", dwError);
|
|
|
+ }
|
|
|
|
|
|
return uReadLength;
|
|
|
}
|
|
@@ -208,7 +278,11 @@ DWORD CBaseSerial::WriteSync(LPVOID Buffer, DWORD dwBufferLength)
|
|
|
::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR);
|
|
|
|
|
|
unsigned long uWriteLength = 0;
|
|
|
- ::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, NULL);
|
|
|
+ if ( !::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, NULL) )
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ _dprintf("写出错:%ld", dwError);
|
|
|
+ }
|
|
|
|
|
|
return uWriteLength;
|
|
|
}
|