Здравствуйте Rom , Вы писали:
R>Всем привет!
R>Кто может подсказать, как вывести COM-порт из комы на функции WaitCommEvent(...), чтобы корректно завершить поток, в котором порт работает на приёме? Открываю порт для синхронного чтения. Вот ниже код.
R>R>BOOL C_USPDTR::Connect(LPCSTR port)
R>{
R> COMMCONFIG cfg;
R> DWORD dwRes;
R> Disconnect();
R> memset(&cfg,0,sizeof(cfg));
R> cfg.dwSize = sizeof(cfg);
R> if(::CommConfigDialog(port,NULL,&cfg) != IDOK) return FALSE;
R> cfg.dcb.fBinary = TRUE;
R> cfg.dcb.XoffLim = 512;
R> cfg.dcb.XonLim = 2048;
R> cfg.dcb.fParity = TRUE;
R> cfg.dcb.fNull = TRUE;
R> hComm = ::CreateFile(port,
R> GENERIC_READ | GENERIC_WRITE,
R> 0,
R> NULL,
R> OPEN_EXISTING,
R> 0,
R> NULL);
R> if(hComm == INVALID_HANDLE_VALUE)
R> {
R> ::MessageBox(NULL,"Âûáðàííûé ïîðò çàíÿò!","Îøèáêà îòêðûòèÿ ïîðòà",MB_OK);
R> Disconnect();
R> return FALSE;
R> }
R> ::FlushFileBuffers(hComm);
R> if(!::SetCommState(hComm,&cfg.dcb))
R> {
R> dwRes = ::GetLastError();
R> ::MessageBox(NULL,"Îøèáêà èíèöèàëèçàöèè ïîðòà!",NULL,MB_OK);
R> }
R>
R> COMMTIMEOUTS to;
R> DWORD rttc = 100 * 11 * 1000 / cfg.dcb.BaudRate;
R> DWORD rit = 11 * 1000 / cfg.dcb.BaudRate;
R> to.ReadIntervalTimeout = rit ? rit : 1;
R> to.ReadTotalTimeoutConstant = rttc ? rttc : 1;
R> to.ReadTotalTimeoutMultiplier = to.ReadIntervalTimeout;
R> to.WriteTotalTimeoutConstant = 0;
R> to.WriteTotalTimeoutMultiplier = 0;
R> if(!::SetCommTimeouts(hComm,&to))
R> {
R> dwRes = ::GetLastError();
R> ::MessageBox(NULL,"Îøèáêà èíèöèàëèçàöèè ïîðòà!",NULL,MB_OK);
R> }
R> ::GetCommTimeouts(hComm,&to);
R> ::PurgeComm(hComm,PURGE_RXABORT|PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
R> connect = TRUE;
R> ::AfxBeginThread(RecvThread,(LPVOID)NULL);
R> return TRUE;
R>}
R>//////////////////////////////////////////////////////////////////////////
R>void C_USPDTR::Disconnect()
R>{
R> if(hComm!=INVALID_HANDLE_VALUE)
R> {
R> connect = FALSE;
R> ::EscapeCommFunction(hComm,SETBREAK);
R> ::SetCommBreak(hComm);
R> ::PurgeComm(hComm,PURGE_RXABORT|PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
R> ::SetCommBreak(hComm);
R> ::WaitForSingleObject(eStopRecvEvent.m_hObject,INFINITE);
R> ::CloseHandle(hComm);
R> hComm = INVALID_HANDLE_VALUE;
R> }
R>}
R>////////////////////////////////////////////////////////////////////////////////////////
R>UINT C_USPDTR::RecvThread(LPVOID param)
R>{
R> DWORD dwEvent, dwBytesRead;
R> OVERLAPPED ol;
R> UART_PACKET packet;
COMSTAT cs;
R> memset( (LPVOID)&ol, 0, sizeof(ol) );
R> ol.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
::SetCommMask( hComm, EV_RXCHAR | EV_BREAK | EV_ERR);
R> while(connect)
R> {
R> if( ::WaitCommEvent(hComm, &dwEvent, NULL) )
R> {
R> if( dwEvent & EV_RXCHAR )
R> {
R> ::ReadFile( hComm, &packet.head, sizeof(UART_PACKET_HEAD),
R> &dwBytesRead, NULL);
R> packet.pBuf = new BYTE[ packet.head.data_size ];
R> ::ReadFile( hComm, packet.pBuf, packet.head.data_size,
R> &dwBytesRead, NULL);
R> }
R> if(dwEvent & EV_BREAK )
R> {
R> connect = FALSE;
R> break;
R> }
if ((dwEvtMask & EV_ERR)!=0)
{ DWORD dwError;
//sprintf(str,"EVENT: EV_ERR"); Le(str);
ClearCommError(hComm,&dwError,&cs);
}
else break;// А else и не будет, больше не заказано было
R> }
R> }
R> ::SetEvent(eStopRecvEvent.m_hObject);
R> return 0;
R>}
R>
R>В функции Disconnect() (там сейчас полная каша
) ни SetCommBreak(..), ни PurgeComm(..) не приводят к выходу из WaitCommEvent(..) .........
Посмотрите старый пример — программу Tty.exe, где-то она была у MS в примерах. Я дописал
случай с EV_ERR. Попробуйте.