15,471
社区成员
发帖
与我相关
我的任务
分享
hComArray[iLoop] = CreateFile(szComPort, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
if (hComArray[iLoop] == INVALID_HANDLE_VALUE)
{
return;
}
SetCommMask(hComArray[iLoop], EV_RXCHAR|EV_TXEMPTY );
SetupComm(hComArray[iLoop], 10240, 10240);
PurgeComm(hComArray[iLoop], PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
COMMTIMEOUTS commTimeOuts;
commTimeOuts.ReadIntervalTimeout = MAXDWORD;
commTimeOuts.ReadTotalTimeoutConstant = 0;
commTimeOuts.ReadTotalTimeoutMultiplier = 0;
commTimeOuts.WriteTotalTimeoutConstant = 2000;
commTimeOuts.WriteTotalTimeoutMultiplier = 50;
SetCommTimeouts(hComArray[iLoop], &commTimeOuts);
DCB dcb;
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
SetCommState(hComArray[iLoop], &dcb);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommWatchProc, (LPVOID)(&iComIndexArray[iLoop]), 0, &dwThreadID);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommRequestProc, (LPVOID)(&iComIndexArray[iLoop]), 0, &dwThreadID);
UINT CommWatchProc(LPVOID lpPara)
{
try
{
int iComIndex = *(int*)lpPara;
InitializeCriticalSection(&mutexArray[iComIndex]);
memset(bufferGlobalArray[iComIndex], 0, 10240);
memset(bufferGlobalBackupArray[iComIndex], 0, 10240);
iBufferGlobalStartIndexArray[iComIndex] = 0;
iBufferGlobalEndIndexArray[iComIndex] = -1;
HANDLE hEventWait100 = CreateEvent(NULL, TRUE, FALSE, NULL);
BYTE buffer[1024] = {0};
OVERLAPPED osReader = {0};
COMSTAT comStat = {0};
DWORD dwByteRead = 0, dwLastError = 0, dwWaitRet = 0, dwError = 0;
BOOL bThreadDone = FALSE, bRet = TRUE, bWaitingOnRead = FALSE;
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while (!bThreadDone)
{
SetLastError(ERROR_SUCCESS);
if (!bWaitingOnRead)
{
bRet = ReadFile(hComArray[iComIndex], buffer, 1024, &dwByteRead, &osReader);
if (!bRet)
{
dwLastError = GetLastError();
if (ERROR_IO_PENDING == dwLastError)
bWaitingOnRead = TRUE;
else
{
bThreadDone = TRUE;
continue;
}
}
else
{
if (dwByteRead)
ProcessRcvBuffer(buffer, dwByteRead, iComIndex);
}
}
if (bWaitingOnRead)
{
dwWaitRet = WaitForSingleObject(osReader.hEvent, INFINITE);
switch (dwWaitRet)
{
case WAIT_OBJECT_0:
SetLastError(ERROR_SUCCESS);
bRet = GetOverlappedResult(hComArray[iComIndex], &osReader, &dwByteRead, FALSE);
if (!bRet)
{
dwLastError = GetLastError();
if (dwLastError == ERROR_OPERATION_ABORTED)
continue;
else if (dwLastError == ERROR_IO_INCOMPLETE)
{
WaitForSingleObject(hEventWait100, 100);
continue;
}
else
bThreadDone = TRUE;
}
else
{
if (dwByteRead)
ProcessRcvBuffer(buffer, dwByteRead, iComIndex);
}
bWaitingOnRead = FALSE;
break;
case WAIT_TIMEOUT:
WaitForSingleObject(hEventWait100, 100);
break;
default:
break;
}
}
memset(buffer, 0, 1024);
WaitForSingleObject(hEventWait100, 100);
}
CloseHandle(osReader.hEvent);
CloseHandle(hEventWait100);
DeleteCriticalSection(&mutexArray[iComIndex]);
}
catch (...)
{
}
return 0;
}
UINT CommRequestProc(LPVOID lpPara)
{
try
{
int iComIndex = *((int*)lpPara), iLoop = 0, iLoopAnother = 0;
CString szComPort;
szComPort.Format(TEXT("\\\\.\\COM%d"), iComIndex+1);
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//...
for (;;)
{
if (!ComIsAvailable(hComArray[iComIndex]))
{
CloseHandle(hComArray[iComIndex]);
hComArray[iComIndex] = INVALID_HANDLE_VALUE;
TerminateThread(hWatchThreadArray[iComIndex], 1);
CloseHandle(hWatchThreadArray[iComIndex]);
hWatchThreadArray[iComIndex] = INVALID_HANDLE_VALUE;
BOOL bLoop = TRUE;
while (bLoop)
{
hComArray[iComIndex] = CreateFile(szComPort, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
if (hComArray[iComIndex] == INVALID_HANDLE_VALUE)
{
CloseHandle(hComArray[iComIndex]);
WaitForSingleObject(hEvent, 5000);
}
else
{
SetCommMask(hComArray[iComIndex], EV_RXCHAR|EV_TXEMPTY );
SetupComm(hComArray[iComIndex], 10240, 10240);
PurgeComm(hComArray[iComIndex], PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
COMMTIMEOUTS commTimeOuts;
commTimeOuts.ReadIntervalTimeout = MAXDWORD;
commTimeOuts.ReadTotalTimeoutConstant = 0;
commTimeOuts.ReadTotalTimeoutMultiplier = 0;
commTimeOuts.WriteTotalTimeoutConstant = 2000;
commTimeOuts.WriteTotalTimeoutMultiplier = 50;
SetCommTimeouts(hComArray[iComIndex], &commTimeOuts);
DCB dcb;
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
SetCommState(hComArray[iComIndex], &dcb);
DWORD dwThreadID = 0;
hWatchThreadArray[iComIndex] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommWatchProc, lpPara, 0, &dwThreadID);
bLoop = FALSE;
}
}
}
//定期询问设备
}
CloseHandle(hEvent);
}
catch (...)
{
DWORD dwLastError = GetLastError();
}
return 0;
}
BOOL ComIsAvailable(HANDLE hCom)
{
BOOL bRet = TRUE;
DWORD dwLastError = 0, dwBytesWritten = 0;
BYTE byNothing[4] = {0};
DWORD dwSize = sizeof(byNothing);
OVERLAPPED overlapped = {0};
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetLastError(0);
if (!WriteFile(hCom, byNothing, dwSize, &dwBytesWritten, &overlapped))
{
dwLastError = GetLastError();
if (ERROR_IO_PENDING == dwLastError)
{
SetLastError(0);
while(!GetOverlappedResult(hCom, &overlapped, &dwBytesWritten, TRUE))
{
dwLastError = GetLastError();
if (dwLastError == ERROR_IO_INCOMPLETE)
continue;
else
{
bRet = FALSE;
break;
}
}
}
}
CloseHandle(overlapped.hEvent);
return bRet;
}
void ProcessSndBuffer(BYTE *buffer, DWORD size, int comIndex)
{
try
{
SetLastError(0);
OVERLAPPED m_osWrite;
COMSTAT ComStat;
DWORD dwErrorFlags, dwBytesWritten, dwRes;
BOOL bWriteStat;
memset(&m_osWrite, 0, sizeof(m_osWrite));
m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ClearCommError(hComArray[comIndex], &dwErrorFlags, &ComStat);
PurgeComm(hComArray[comIndex], PURGE_TXABORT | PURGE_TXCLEAR);
bWriteStat = WriteFile(hComArray[comIndex], buffer, size, &dwBytesWritten, &m_osWrite);
if(!bWriteStat)
{
DWORD dwLastError = GetLastError();
if(GetLastError() == ERROR_IO_PENDING)
{
SetLastError(0);
while(!GetOverlappedResult(hComArray[comIndex], &m_osWrite, &dwBytesWritten, TRUE))
{
DWORD dwError = GetLastError();
if (dwError == ERROR_IO_INCOMPLETE)
continue;
else
break;
}
}
}
dwRes = GetLastError();
CloseHandle(m_osWrite.hEvent);
}
catch (...)
{
}
}
过程基本上都是bWriteStat等于FALSE,然后GetLastError等于PENDING,而GetOverlappedResult一次就返回TRUE了,dwBytesWritten也不等于零。m_osWrite.Internal等于零。看上去好像没什么不对的,但设备就特么没收到东西。。。重新启动软件,就能够写进去了。。。