int serialMonitorWaitLines (SerialDevice *serial) { DWORD event; if (WaitCommEvent(serial->package.fileHandle, &event, NULL)) return 1; logWindowsSystemError("WaitCommEvent"); return 0; }
int raw_serial::waitfordata(size_t data_count, _u32 timeout, size_t * returned_size) { COMSTAT stat; DWORD error; DWORD msk,length; if (returned_size==NULL) returned_size=(size_t *)&length; if ( isOpened()) { size_t rxqueue_remaining = rxqueue_count(); if (rxqueue_remaining >= data_count) { *returned_size = rxqueue_remaining; return 0; } } while ( isOpened() ) { msk = 0; SetCommMask(_serial_handle, EV_RXCHAR | EV_ERR ); if(!WaitCommEvent(_serial_handle, &msk, &_wait_o)) { if(GetLastError() == ERROR_IO_PENDING) { if (WaitForSingleObject(_wait_o.hEvent, timeout) == WAIT_TIMEOUT) { *returned_size =0; return ANS_TIMEOUT; } GetOverlappedResult(_serial_handle, &_wait_o, &length, TRUE); ::ResetEvent(_wait_o.hEvent); }else { ClearCommError(_serial_handle, &error, &stat); *returned_size = stat.cbInQue; return ANS_DEV_ERR; } } if(msk & EV_ERR){ // FIXME: may cause problem here ClearCommError(_serial_handle, &error, &stat); } if(msk & EV_RXCHAR){ ClearCommError(_serial_handle, &error, &stat); if(stat.cbInQue >= data_count) { *returned_size = stat.cbInQue; return 0; } } } *returned_size=0; return ANS_DEV_ERR; }
/*------------------------------------------------------------------------------ -- FUNCTION: PortIOThreadProc -- -- DATE: Oct 13, 2010 -- -- REVISIONS: Nov 05, 2010 -- Modified the function to also listen for a "disconnect" event, -- and to break in that case. ProcessRead() is now called once a -- complete packet is confirmed (as opposed to sending the -- contents of the buffer to ProcessRead() as soon as they arrive). -- -- Nov 29, 2010 -- Renamed function from ReadThreadProc(). The event handling is -- from the original function, but the response to each event has -- changed. -- -- DESIGNER: Dean Morin -- -- PROGRAMMER: Dean Morin, Daniel Wright -- -- INTERFACE: DWORD WINAPI PortIOThreadProc(HWND hWnd) -- hWnd - the handle to the window -- -- RETURNS: 0 because threads are required to return a DWORD. -- -- NOTES: -- While connected, this thread will loop and wait for characters -- to arrive at the port, or for a timeout to occur, then call the -- appropriate function. This function uses overlapped I/O. ------------------------------------------------------------------------------*/ DWORD WINAPI PortIOThreadProc(HWND hWnd) { OVERLAPPED ol = {0}; DWORD dwEvent = 0; DWORD dwError = 0; COMSTAT cs = {0}; HANDLE* hEvents = NULL; PSTATEINFO psi = NULL; PWNDDATA pwd = (PWNDDATA) GetWindowLongPtr(hWnd, 0); if ((ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { DISPLAY_ERROR("Error creating event in read thread"); } hEvents = (HANDLE*) malloc(sizeof(HANDLE) * PORT_IO_EVENTS); hEvents[0] = CreateEvent(NULL, FALSE, FALSE, TEXT("disconnected")); hEvents[1] = ol.hEvent; psi = (PSTATEINFO) malloc(sizeof(STATEINFO)); InitStateInfo(psi); DL_STATE = psi->iState; while (pwd->bConnected) { SetCommMask(pwd->hPort, EV_RXCHAR); if (!WaitCommEvent(pwd->hPort, &dwEvent, &ol)) { ProcessCommError(pwd->hPort); } dwEvent = WaitForMultipleObjects(PORT_IO_EVENTS, hEvents, FALSE, psi->dwTimeout); ClearCommError(pwd->hPort, &dwError, &cs); if (dwEvent == WAIT_OBJECT_0) { // the connection was severed break; } else if (dwEvent == WAIT_OBJECT_0 + 1 && cs.cbInQue) { // data arrived at the port ReadFromPort(hWnd, psi, ol, cs.cbInQue); } else if (dwEvent == WAIT_TIMEOUT) { // a timeout occured ProcessTimeout(hWnd, psi); } else if (dwEvent == WAIT_FAILED) { DISPLAY_ERROR("Invalid event occured in the Port I/O thread"); } ResetEvent(ol.hEvent); } if (!PurgeComm(pwd->hPort, PURGE_RXCLEAR)) { DISPLAY_ERROR("Error purging read buffer"); } CloseHandle(ol.hEvent); CloseHandle(hEvents[0]); free(hEvents); return 0; }
void VirtualSerialDevice::commEventOccurred() { DWORD event = d->commEventMask; if (event & EV_RXCHAR) { emit readyRead(); } ResetEvent(d->commEventOverlapped.hEvent); WaitCommEvent(d->portHandle, &d->commEventMask, &d->commEventOverlapped); }
static int source_wait(serial_source src, struct timeval *deadline) /* Effects: waits until deadline for some data on source. deadline can be NULL for indefinite waiting. Returns: 0 if data is available, -1 if the deadline expires */ { #ifndef LOSE32 struct timeval tv; fd_set fds; int cnt; if (src->recv.bufpos < src->recv.bufused) return 0; for (;;) { if (deadline) { gettimeofday(&tv, NULL); tv.tv_sec = deadline->tv_sec - tv.tv_sec; tv.tv_usec = deadline->tv_usec - tv.tv_usec; if (tv.tv_usec < 0) { tv.tv_usec += 1000000; tv.tv_sec--; } if (tv.tv_sec < 0) return -1; } FD_ZERO(&fds); FD_SET(src->fd, &fds); cnt = select(src->fd + 1, &fds, NULL, NULL, deadline ? &tv : NULL); if (cnt < 0) { if (errno == EINTR) continue; message(src, msg_unix_error); return -1; } if (cnt == 0) return -1; return 0; } #else // LOSE32 // FIXME: the deadline is ignored here DWORD eventMask; SetCommMask(src->hComm, EV_RXCHAR); if (!WaitCommEvent(src->hComm, &eventMask, NULL)) { return -1; } return 0; #endif }
//initializes the dongle COM port void initCOMPort() { DCB dcb = {}; COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = 15; timeouts.ReadTotalTimeoutConstant = 15; timeouts.ReadTotalTimeoutMultiplier = 15; timeouts.WriteTotalTimeoutConstant = 20; timeouts.WriteTotalTimeoutMultiplier = 10; osReaderDongle.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); osWriteDongle.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); osStatusDongle.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); hCOMDongle = CreateFile(COMPORTDONGLE, GENERIC_READ | GENERIC_WRITE, 0, NULL, //COM3 on the NUC OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (hCOMDongle == INVALID_HANDLE_VALUE) { prints(L"ERROR OPENING DONGLE COM PORT\n"); } else { prints(L"USB dongle COM port 3 opened\n"); } ZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); if (!GetCommState(hCOMDongle, &dcb)) { prints(L"Dongle GetCommState failed with error %X.\n", GetLastError()); } dcb.BaudRate = 19200; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.EvtChar = '\n'; if (!SetCommState(hCOMDongle, &dcb)) { prints(L"Dongle SetCommState failed with error %X.\n", GetLastError()); } if (!SetCommTimeouts(hCOMDongle, &timeouts)) { prints(L"Dongle SetCommTimeouts failed with error %d.\n", GetLastError()); } if (!SetCommMask(hCOMDongle, EV_RXCHAR)) { prints(L"SetCommMask failed with error %d.\n", GetLastError()); } if (WaitCommEvent(hCOMDongle, &dwCommEventDongle, &osStatusDongle)) { prints(L"Main board wait Com event %X\n", dwCommEvent); } else { if (GetLastError() != ERROR_IO_PENDING) { prints(L"WaitCommEvent failed with error %d\n", GetLastError()); } } prints(L"Dongle COM init end\r\n\r\n"); }
// Wait up to msec for data to become available for reading. // return 0 if timeout, or non-zero if one or more bytes are // received and can be read. -1 if an error occurs int Serial::Input_wait(int msec) { if (!port_is_open) return -1; #if defined(LINUX) || defined(MACOSX) fd_set rfds; struct timeval tv; tv.tv_sec = msec / 1000; tv.tv_usec = (msec % 1000) * 1000; FD_ZERO(&rfds); FD_SET(port_fd, &rfds); return select(port_fd+1, &rfds, NULL, NULL, &tv); #elif defined(WINDOWS) // http://msdn2.microsoft.com/en-us/library/aa363479(VS.85).aspx // http://msdn2.microsoft.com/en-us/library/aa363424(VS.85).aspx // http://source.winehq.org/WineAPI/WaitCommEvent.html COMSTAT st; DWORD errmask=0, eventmask=EV_RXCHAR, ret; OVERLAPPED ov; int r; // first, request comm event when characters arrive if (!SetCommMask(port_handle, EV_RXCHAR)) return -1; // look if there are characters in the buffer already if (!ClearCommError(port_handle, &errmask, &st)) return -1; //printf("Input_wait, %lu buffered, timeout = %d ms\n", st.cbInQue, msec); if (st.cbInQue > 0) return 1; ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (ov.hEvent == NULL) return -1; ov.Internal = ov.InternalHigh = 0; ov.Offset = ov.OffsetHigh = 0; if (WaitCommEvent(port_handle, &eventmask, &ov)) { //printf("Input_wait, WaitCommEvent, immediate success\n"); r = 1; } else { if (GetLastError() == ERROR_IO_PENDING) { ret = WaitForSingleObject(ov.hEvent, msec); if (ret == WAIT_OBJECT_0) { //printf("Input_wait, WaitCommEvent, delayed success\n"); r = 1; } else if (ret == WAIT_TIMEOUT) { //printf("Input_wait, WaitCommEvent, timeout\n"); GetCommMask(port_handle, &eventmask); r = 0; } else { // WAIT_FAILED or WAIT_ABANDONED //printf("Input_wait, WaitCommEvent, delayed error\n"); r = -1; } } else { //printf("Input_wait, WaitCommEvent, immediate error\n"); r = -1; } } SetCommMask(port_handle, 0); CloseHandle(ov.hEvent); return r; #endif }
static BOOL readSerial(ClientElem_t *pClient, char* buffer, int maxRead, int* pRead, int timeout) { BOOL res; if (!pClient->pendingCommRd) { res = WaitCommEvent(pClient->serialHdl, &pClient->commMaskRd, &pClient->ovCommRd); if (!res) { int err = GetLastError(); if (err != ERROR_IO_PENDING) { // readfile call error return FALSE; } else { pClient->pendingCommRd = TRUE; *pRead = 0; return TRUE; } } } res = WaitForSingleObject(pClient->ovCommRd.hEvent, timeout); ResetEvent(pClient->ovCommRd.hEvent); if (res == WAIT_TIMEOUT) { *pRead = 0; return TRUE; } else if (res != WAIT_OBJECT_0) { return FALSE; } pClient->pendingCommRd = FALSE; res = ReadFile(pClient->serialHdl, buffer, maxRead, pRead, &pClient->ovRd); if (!res) { int err = GetLastError(); if (err != ERROR_IO_PENDING) { // readfile call error return FALSE; } else { // async op res = WaitForSingleObject(pClient->ovRd.hEvent, timeout); if (res == WAIT_TIMEOUT) { *pRead = 0; return TRUE; } else if (res != WAIT_OBJECT_0) { return FALSE; } res = GetOverlappedResult(pClient->serialHdl, &pClient->ovRd, pRead, FALSE); if (!res) { int err = GetLastError(); return FALSE; } ResetEvent(pClient->ovRd.hEvent); } } else { // sync op } DBG_PRINT("uart-->%i", *pRead); return TRUE; }
/*! Opens a serial port. Note that this function does not specify which device to open. If you need to open a device by name, see QextSerialPort::open(const char*). This function has no effect if the port associated with the class is already open. The port is also configured to the current settings, as stored in the Settings structure. */ bool QextSerialPort::open(OpenMode mode) { unsigned long confSize = sizeof(COMMCONFIG); Win_CommConfig.dwSize = confSize; DWORD dwFlagsAndAttributes = 0; if (queryMode() == QextSerialPort::EventDriven) dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; QMutexLocker lock(mutex); if (mode == QIODevice::NotOpen) return isOpen(); if (!isOpen()) { /*open the port*/ Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL); if (Win_Handle!=INVALID_HANDLE_VALUE) { QIODevice::open(mode); /*configure port settings*/ GetCommConfig(Win_Handle, &Win_CommConfig, &confSize); GetCommState(Win_Handle, &(Win_CommConfig.dcb)); /*set up parameters*/ Win_CommConfig.dcb.fBinary=TRUE; Win_CommConfig.dcb.fInX=FALSE; Win_CommConfig.dcb.fOutX=FALSE; Win_CommConfig.dcb.fAbortOnError=FALSE; Win_CommConfig.dcb.fNull=FALSE; setBaudRate(Settings.BaudRate); setDataBits(Settings.DataBits); setStopBits(Settings.StopBits); setParity(Settings.Parity); setFlowControl(Settings.FlowControl); setTimeout(Settings.Timeout_Millisec); SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG)); //init event driven approach if (queryMode() == QextSerialPort::EventDriven) { Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD; Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0; Win_CommTimeouts.ReadTotalTimeoutConstant = 0; Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0; Win_CommTimeouts.WriteTotalTimeoutConstant = 0; SetCommTimeouts(Win_Handle, &Win_CommTimeouts); if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { qWarning() << "failed to set Comm Mask. Error code:", GetLastError(); return false; } winEventNotifier = new QWinEventNotifier(overlap.hEvent, this); connect(winEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(onWinEvent(HANDLE))); WaitCommEvent(Win_Handle, &eventMask, &overlap); } } } else { return false; } return isOpen(); }
int _flush_uart(int out, int in) { DWORD dw; if(out=FDISCARD) PurgeComm(port, PURGE_TXCLEAR); else if(out) WaitCommEvent(port, &dw, NULL); if(in) PurgeComm(port, PURGE_RXCLEAR); return 0; }
BOOL Serial::Wait(DWORD timeout) { // SetCommMask(m_hComm,EV_RXCHAR); DWORD dwEvent; if(!WaitCommEvent(m_hComm,&dwEvent,NULL)) { } return TRUE; }
void Win_QextSerialPort::monitorCommEvent() { DWORD eventMask = 0; ResetEvent(m_Overlap.hEvent); if (!WaitCommEvent(m_WinHandle, & eventMask, & m_Overlap)) { if (GetLastError() != ERROR_IO_PENDING) { qCritical("WaitCommEvent error %ld\n", GetLastError()); } } if (WaitForSingleObject(m_Overlap.hEvent, INFINITE) == WAIT_OBJECT_0) { //overlap event occured DWORD undefined; if (!GetOverlappedResult(m_WinHandle, & m_Overlap, & undefined, false)) { qWarning("Comm event overlapped error %ld", GetLastError()); return; } if (eventMask & EV_RXCHAR) { if (sender() != this) emit readyRead(); } if (eventMask & EV_TXEMPTY) { DWORD numBytes; GetOverlappedResult(m_WinHandle, & m_OverlapWrite, & numBytes, true); m_pBytesToWriteLock->lockForWrite(); if (sender() != this) { emit bytesWritten(bytesToWrite()); } m_BytesToWrite = 0; m_pBytesToWriteLock->WriteUnlock(); } if (eventMask & EV_DSR) { if (lineStatus() & LS_DSR) { emit dsrChanged(true); } else { emit dsrChanged(false); } } } }
void CSerialPort::WaitEvent(DWORD& dwMask) { ASSERT(IsOpen()); ASSERT(!m_bOverlapped); if (!WaitCommEvent(m_hComm, &dwMask, NULL)) { TRACE(_T("Failed in call to WaitCommEvent\n")); AfxThrowSerialException(); } }
DWORD WaitCommThread( LPVOID Trash ) { DWORD ReasonSatisfied; DWORD Trash2; OVERLAPPED Ol; UNREFERENCED_PARAMETER(Trash); Ol.hEvent = WaitEvent; do { if (!WaitCommEvent( hFile, &ReasonSatisfied, &Ol )) { DWORD LastError = GetLastError(); if (LastError == ERROR_IO_PENDING) { if (!GetOverlappedResult( hFile, &Ol, &Trash2, TRUE )) { WaitForSingleObject(IoSemaphore,-1); printf("Could not do the getoverlapped on the wait: %d\n",GetLastError()); ReleaseSemaphore(IoSemaphore,1,NULL); } } else { WaitForSingleObject(IoSemaphore,-1); printf("Could not start the wait: %d\n",LastError); ReleaseSemaphore(IoSemaphore,1,NULL); } } } while (TRUE); return 1; }
static void ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) { struct ser_windows_state *state; COMSTAT status; DWORD errors; HANDLE h = (HANDLE) _get_osfhandle (scb->fd); state = scb->state; *except = state->except_event; *read = state->ov.hEvent; if (state->in_progress) return; /* Reset the mask - we are only interested in any characters which arrive after this point, not characters which might have arrived and already been read. */ /* This really, really shouldn't be necessary - just the second one. But otherwise an internal flag for EV_RXCHAR does not get cleared, and we get a duplicated event, if the last batch of characters included at least two arriving close together. */ if (!SetCommMask (h, 0)) warning (_("ser_windows_wait_handle: reseting mask failed")); if (!SetCommMask (h, EV_RXCHAR)) warning (_("ser_windows_wait_handle: reseting mask failed (2)")); /* There's a potential race condition here; we must check cbInQue and not wait if that's nonzero. */ ClearCommError (h, &errors, &status); if (status.cbInQue > 0) { SetEvent (state->ov.hEvent); return; } state->in_progress = 1; ResetEvent (state->ov.hEvent); state->lastCommMask = -2; if (WaitCommEvent (h, &state->lastCommMask, &state->ov)) { gdb_assert (state->lastCommMask & EV_RXCHAR); SetEvent (state->ov.hEvent); } else gdb_assert (GetLastError () == ERROR_IO_PENDING); }
bool SerialPort::Drain() { int nbytes = GetDataQueued(); if (nbytes < 0) return false; else if (nbytes == 0) return true; ::SetCommMask(hPort, EV_ERR|EV_TXEMPTY); DWORD events; return WaitCommEvent(hPort, &events, NULL) && (events & EV_TXEMPTY) != 0; }
int sosc_event_loop(const sosc_state_t *state) { OVERLAPPED ov = {0, 0, {{0, 0}}}; HANDLE hres, lo_thd_res; DWORD evt_mask; hres = (HANDLE) _get_osfhandle(monome_get_fd(state->monome)); lo_thd_res = CreateThread(NULL, 0, lo_thread, (void *) state, 0, NULL); if( !(ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) ) { fprintf(stderr, "serialosc: event_loop: can't allocate event (%ld)\n", GetLastError()); return 1; } do { SetCommMask(hres, EV_RXCHAR); if( !WaitCommEvent(hres, &evt_mask, &ov) ) switch( GetLastError() ) { case ERROR_IO_PENDING: break; case ERROR_ACCESS_DENIED: /* evidently we get this when the monome is unplugged? */ return 1; default: fprintf(stderr, "event_loop() error: %d\n", GetLastError()); return 1; } switch( WaitForSingleObject(ov.hEvent, INFINITE) ) { case WAIT_OBJECT_0: while( monome_event_handle_next(state->monome) ); break; case WAIT_TIMEOUT: break; case WAIT_ABANDONED_0: case WAIT_FAILED: fprintf(stderr, "event_loop(): wait failed: %ld\n", GetLastError()); return 1; } } while ( 1 ); ((void) lo_thd_res); /* shut GCC up about this being an unused variable */ return 0; }
void listenToCommands() { initCOMPort(); initUSBRadio(); lastSpeedSentTimer.start(); HANDLE waitHandles[3] = { startSignal, osStatusDongle.hEvent }; stateGoal = goalOnRight; stateBallSeen = ballOnRight; while (true) { float floorX, floorY; int currentx, currenty; findNearestFloorBall(floorX, floorY, currentx, currenty); float angle = atanf(floorY / floorX) * 180.0 / PI; swprintf_s(buffer, L"NX %.2f \n NY %.2f\n ang %.2f", floorX, floorY, angle); SetWindowText(infoGUI, buffer); swprintf_s(buffer, L"greencount %d", fieldGreenPixelCountShare); SetWindowText(infoGUI3, buffer); if (hCOMDongle != INVALID_HANDLE_VALUE) { if (lastSpeedSentTimer.time() > 0.5) { //if we send the speeds too often we get communication timeouts setSpeedBoth(currentDrivingState); lastSpeedSentTimer.start(); } } switch (WaitForMultipleObjects(2, waitHandles, FALSE, 50)) { //case WAIT_OBJECT_0: // prints(L"radio event %X\n", dwCommEvent); // //receiveCommand(); // //WaitCommEvent(hCOMRadio, &dwCommEvent, &osStatus); // break; case WAIT_OBJECT_0: prints(L"Start signal arrived.\n"); SetWindowText(stateStatusGUI, L"started"); dribblerON(); play(); dribblerOFF(); //discharge(); break; case WAIT_OBJECT_0 + 1: //info from the main board controller //prints(L"main board COM event %X\n", dwCommEventDongle); handleMainBoardCommunication(); WaitCommEvent(hCOMDongle, &dwCommEventDongle, &osStatusDongle); //listen to new events, ie beginning character break; } receiveCommand(); } }
static int modem_wait_sock(modem_t *modem, int ms, modem_poll_t flags) { /* This method ignores ms and waits infinitely */ DWORD dwEvtMask; DWORD dwWait; DWORD comerrors; OVERLAPPED o; BOOL result; int ret; HANDLE arHandles[2]; ret = MODEM_POLL_ERROR; arHandles[0] = modem->threadAbort; o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); arHandles[1] = o.hEvent; /* Initialize the rest of the OVERLAPPED structure to zero. */ o.Internal = 0; o.InternalHigh = 0; o.Offset = 0; o.OffsetHigh = 0; assert(o.hEvent); if ((result = WaitCommEvent(modem->master, &dwEvtMask, &o)) == 0) { if (GetLastError() != ERROR_IO_PENDING) { /* Something went horribly wrong with WaitCommEvent(), so clear all errors and try again */ ClearCommError(modem->master, &comerrors, 0); } else { /* IO is pending, wait for it to finish */ dwWait = WaitForMultipleObjects(2, arHandles, FALSE, INFINITE); if (dwWait == WAIT_OBJECT_0 + 1 && !modem->block_read) ret = MODEM_POLL_READ; } } else { if (!modem->block_read) ret = MODEM_POLL_READ; } CloseHandle (o.hEvent); return ret; }
void CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped) { ASSERT(IsOpen()); ASSERT(m_bOverlapped); ASSERT(overlapped.hEvent); if (!WaitCommEvent(m_hComm, &dwMask, &overlapped)) { if (GetLastError() != ERROR_IO_PENDING) { TRACE(_T("Failed in call to WaitCommEvent\n")); AfxThrowSerialException(); } } }
DWORD SerialWrapper::Read(CString& data) { DWORD dwBytesTransferred; DWORD dwCommModemStatus; WaitCommEvent(_hport, &dwCommModemStatus, 0); //wait for character if (dwCommModemStatus & EV_RXCHAR) ReadFile(_hport, _readBuffer, BUFF_SIZE, &dwBytesTransferred, 0); else if (dwCommModemStatus & EV_ERR) return 0;//Error; CString ret((LPCSTR)&_readBuffer, dwBytesTransferred); data.Append(ret); return dwBytesTransferred; }
HRESULT WINAPI CommDev::ReadingThread(LPVOID lpParameter) { DWORD dwCommEvent; DWORD dwRead; BYTE chRead; OVERLAPPED osStatus = {0}; CommDev* pThis = (CommDev *)lpParameter; if(!pThis->m_pLinkDevice) return E_POINTER; if (!SetCommMask(pThis->m_hComm, EV_RXCHAR)) return E_FAIL; osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osStatus.hEvent == NULL) return E_FAIL; for (;;) { if (WaitCommEvent(pThis->m_hComm, (LPDWORD)&dwCommEvent, NULL )) { do { chRead = 0; if (ReadFile(pThis->m_hComm, &chRead, 1, (LPDWORD)&dwRead, &osStatus )) { if(dwRead==1) { EnterCriticalSection(&pThis->m_CriticalSection); _tprintf(_T("%02x\t"),chRead); // pThis->m_RxBuffer.Add(chRead); pThis->timeLastRx = GetTickCount(); LeaveCriticalSection(&pThis->m_CriticalSection); // pThis->m_pLinkDevice->OnCharRecieve(&pThis->m_RxBuffer); pThis->m_pLinkDevice->OnCharRecieve(chRead); } } else break; } while (dwRead); } else { CloseHandle(osStatus.hEvent); return E_FAIL; break; } } CloseHandle(osStatus .hEvent); return S_OK; }
void RS232Interface::WaitForTxEmpty() { #ifdef _WINDOWS DWORD evento; if ( hCom != INVALID_HANDLE_VALUE) { do { WaitCommEvent(hCom, &evento, NULL); } while ( !(evento & EV_TXEMPTY) ); } #endif #ifdef _LINUX_ if ( fd != INVALID_HANDLE_VALUE ) tcdrain(fd); #endif }
bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) { Q_Q(QextSerialPort); DWORD confSize = sizeof(COMMCONFIG); commConfig.dwSize = confSize; DWORD dwFlagsAndAttributes = 0; if (queryMode == QextSerialPort::EventDriven) dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; /*open the port*/ handle = CreateFileW((wchar_t *)fullPortNameWin(port).utf16(), GENERIC_READ|GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, dwFlagsAndAttributes, nullptr); if (handle != INVALID_HANDLE_VALUE) { q->setOpenMode(mode); /*configure port settings*/ GetCommConfig(handle, &commConfig, &confSize); GetCommState(handle, &(commConfig.dcb)); /*set up parameters*/ commConfig.dcb.fBinary = TRUE; commConfig.dcb.fInX = FALSE; commConfig.dcb.fOutX = FALSE; commConfig.dcb.fAbortOnError = FALSE; commConfig.dcb.fNull = FALSE; /* Dtr default to true. See Issue 122*/ commConfig.dcb.fDtrControl = TRUE; /*flush all settings*/ settingsDirtyFlags = DFE_ALL; updatePortSettings(); //init event driven approach if (queryMode == QextSerialPort::EventDriven) { if (!SetCommMask(handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { QESP_WARNING()<<"failed to set Comm Mask. Error code:"<<GetLastError(); return false; } winEventNotifier = new QWinEventNotifier(overlap.hEvent, q); qRegisterMetaType<HANDLE>("HANDLE"); q->connect(winEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onWinEvent(HANDLE)), Qt::DirectConnection); WaitCommEvent(handle, &eventMask, &overlap); } return true; } return false; }
/*------------------------------------------- | Name:comThread | Description: | Parameters: | Return Type: | Comments: | See: ---------------------------------------------*/ DWORD comThread (LPVOID lpParameter) { int i; printf("uart wait on %s...\n",USE_COM); while ( !bComStopped ) { DWORD dwEvtMask = 0; WaitCommEvent( hCom, &dwEvtMask, NULL ); if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR) { //printf("event\n"); do { if (rcvLength = _readCom( hCom, rcvBuffer, MAX_BUFFER )) { for(i=0; i<rcvLength; i++) { //printf("%c\n",rcvBuffer[i]); Sleep(/*5*/ 0); //WriteRS232ReceiveRegister(rcvBuffer[i]); rcvData = rcvBuffer[i]; if(rcv_interrupt_enable) { emuFireInterrupt(72); //Synchro WaitForSingleObject(hRS232PhysicalSimEvent,nRS232PhysicalSimTimeOut); } } } } while ( rcvLength > 0 ); } if ( (dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY ) { } } // get rid of event handle dwThreadID = 0; return 0; }
int Listen( HANDLE CommEventHandle ) { memset(&comm_event_overlap, 0, sizeof(comm_event_overlap)); comm_event_overlap.hEvent = CommEventHandle; // comm event handle int ret; // if (!ReadFileEx(hCommPort, buffer,1, &read_overlap, (LPOVERLAPPED_COMPLETION_ROUTINE)&ReadRequestCompleted)) ret=WaitCommEvent(hCommPort,&dwCommEventMask,&comm_event_overlap); if (!ret) { ret = GetLastError(); if (ret != ERROR_IO_PENDING) { LOG(ERR,"Arduino::WaitCommEvent error: %d",ret); return ret; } } return 0; }
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortFD) { HANDLE serialPortHandle = (HANDLE)serialPortFD; if (serialPortHandle == INVALID_HANDLE_VALUE) return 0; OVERLAPPED overlappedStruct = {0}; overlappedStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (overlappedStruct.hEvent == NULL) { CloseHandle(overlappedStruct.hEvent); return 0; } // Wait for a serial port event DWORD eventMask, numBytesRead, readResult = WAIT_FAILED; if (WaitCommEvent(serialPortHandle, &eventMask, &overlappedStruct) == FALSE) { if (GetLastError() != ERROR_IO_PENDING) // Problem occurred { // Problem reading, close port PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); while (!CloseHandle(serialPortHandle)); serialPortHandle = INVALID_HANDLE_VALUE; env->SetLongField(obj, serialPortHandleField, -1l); env->SetBooleanField(obj, isOpenedField, JNI_FALSE); } else { BOOL continueWaiting = TRUE; while (continueWaiting) { readResult = WaitForSingleObject(overlappedStruct.hEvent, 750); continueWaiting = ((readResult == WAIT_TIMEOUT) && (env->GetIntField(obj, eventFlagsField) != 0)); } if ((readResult != WAIT_OBJECT_0) || (GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesRead, TRUE) == FALSE)) numBytesRead = 0; } } // Return type of event if successful CloseHandle(overlappedStruct.hEvent); return ((eventMask & EV_RXCHAR) > 0) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : (((eventMask & EV_TXEMPTY) > 0) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_WRITTEN : 0); }
DWORD _stdcall PortReadThread(LPVOID lpvoid) { BYTE readByte; DWORD dwCommModemStatus, dwBytesTransferred; comReadSize = 0; // Specify a set of events to be monitored for the port. SetCommMask( *comPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING ); while ( INVALID_HANDLE_VALUE != *comPort && comReadSize < comTargetSize-1 ) { // Wait for an event to occur for the port. WaitCommEvent( *comPort, &dwCommModemStatus, 0 ); // Re-specify the set of events to be monitored for the port. SetCommMask( *comPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING ); if ( dwCommModemStatus & EV_RXCHAR ) { // Loop for waiting for the data. do { // Read the data from the serial port. ReadFile( *comPort, &readByte, 1, &dwBytesTransferred, 0 ); // Add to string if (dwBytesTransferred == 1) { comTargetBuffer[comReadSize] = readByte; comReadSize++; } } while ( dwBytesTransferred == 1 && comReadSize < comTargetSize-1 ); } // Retrieve modem control-register values. // GetCommModemStatus( *comPort, &dwCommModemStatus ); } return 0; }
DWORD WINAPI ReceiveFromDeviceThread(LPVOID) { COMSTAT comstat; //структура текущего состояния порта, в данной программе используется //для определения количества принятых в порт байтов DWORD btr, temp, mask, signal; //переменная temp используется в качестве заглушки //создать сигнальный объект-событие для асинхронных операций olread.hEvent = CreateEvent(NULL, true, true, NULL); //установить маску на срабатывание по событию приёма байта в порт SetCommMask(COMport, EV_RXCHAR); while(true) //пока поток не будет прерван, выполняем цикл { //ожидать события приёма байта (это и есть перекрываемая операция) WaitCommEvent(COMport, &mask, &olread); //приостановить поток до прихода байта signal = WaitForSingleObject(olread.hEvent, INFINITE); //если событие прихода байта произошло if(signal == WAIT_OBJECT_0) { //проверяем, успешно ли завершилась //перекрываемая операция WaitCommEvent if(GetOverlappedResult(COMport, &olread, &temp, true)) //если произошло именно событие прихода байта if((mask & EV_RXCHAR)!=0) { //нужно заполнить структуру COMSTAT ClearCommError(COMport, &temp, &comstat); //и получить из неё количество принятых байтов btr = comstat.cbInQue; //если действительно есть байты для чтения if(btr) { //прочитать байты из порта в буфер программы ReadFile(COMport, bufrd, btr, &temp, &olread); ReadBuf(); //вызываем функцию для вывода данных на экран и в файл } } } } // CloseHandle(olread.hEvent); //перед выходом из потока закрыть объект-событие }
static int open_device(uart_ctx_t* ctx, char* name) { ctx->fh = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (ctx->fh == INVALID_HANDLE_VALUE) { DEBUG_ERROR("CreateFile: invalid handle: error %d", GetLastError()); goto error; } if (!(ctx->in.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { DEBUG_ERROR("CreateEvent: 1: error %d", GetLastError()); goto error; } if (!(ctx->out.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { DEBUG_ERROR("CreateEvent: 1: error %d", GetLastError()); goto error; } if (!(ctx->stat.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { DEBUG_ERROR("CreateEvent: 1: error %d", GetLastError()); goto error; } // SetCommMask(wd->fh, EV_RXCHAR); WaitCommEvent(ctx->fh, &ctx->statm, &ctx->stat); return 0; error: if (ctx->fh != INVALID_HANDLE_VALUE) CloseHandle(ctx->fh); if (ctx->in.hEvent) CloseHandle(ctx->in.hEvent); if (ctx->out.hEvent) CloseHandle(ctx->out.hEvent); if (ctx->stat.hEvent) CloseHandle(ctx->stat.hEvent); return -1; }