I need to periodically read from a serial port and process the data received. Fortunately, the time between data packets, packet size and COM port settings are fixed. So I tried implementing the following read function on receipt of the EV_RXCHAR message
and looped it using a SetTimer function:
//Declared in the header OVERLAPPED o; BOOL fSuccess; DWORD dwEvtMask; DWORD NoBytesRead; BYTE abBuffer[255]; CString data; void CGCUGUIDlg::OnStartcom() { m_hComm = ::CreateFile(Com, //String that contains COM port name GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); fnCommState(); DCB dcb = {0}; dcb.DCBlength = sizeof(dcb); Status = GetCommState(m_hComm, &dcb); dcb.BaudRate = CBR_115200; dcb.ByteSize = 8; dcb.StopBits = ONESTOPBIT; dcb.Parity = NOPARITY; SetCommState(m_hComm, &dcb); fSuccess = SetCommMask(m_hComm,EV_RXCHAR); if(!fSuccess) { MessageBox("SetCommMask failed with error %s",LPCTSTR(GetLastError())); return; } else MessageBox("SetCommMask succeeded"); memset( &o, 0, sizeof( o ) ); o.hEvent = CreateEvent( 0, true, 0, 0 ); SetTimer(1,20,0); } void CGCUGUIDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: Add your message handler code here and/or call default if(!WaitCommEvent(m_hComm,&dwEvtMask,&o)) MessageBox("I/O PENDING"); else { MessageBox("I/O RxED"); if(dwEvtMask==EV_RXCHAR) { unsigned char ucData; if(!ReadFile(m_hComm,&abBuffer,sizeof(abBuffer),&NoBytesRead,&o)) { MessageBox("Could not read"); } if(NoBytesRead>0) data.Append(LPCTSTR(abBuffer),NoBytesRead); this->SetDlgItemText(IDC_RXRAW,LPCTSTR(data)); this->UpdateData(FALSE); } //if } //else CDialog::OnTimer(nIDEvent); }
The data is received every 50 milliseconds, so I though polling every 20 milliseconds should be safe. I am using a serial port data emulator to simulate data.
But whenever I run the code, the «I/O PENDING» message keeps popping up. I’m not sure what I am doing wrong.
Could someone point me in the right direction?
Функция WaitCommEvent ожидает какое-то
событие, которое произойдет для заданного
коммуникационного устройства. Пакет
событий, которые проверяются этой функцией,
содержится в маске события, связанной с
дескриптором устройства.
Синтаксис
BOOL WaitCommEvent( HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped );
Параметры
hFile
[in] Дескриптор коммуникационного
устройства. Функция CreateFile возвращает этот
дескриптор.
lpEvtMask
[out] Указатель на переменную,
получающую маску, указывающую тип события,
которое произошло. Если происходит ошибка,
это значение равняется нулю; в противном
случае, этот параметр — одно из ниже
перечисленного значений.
Значение | Предназначение |
---|---|
EV_BREAK | Во время ввода данных было обнаружено прерывание. |
EV_CTS | Сигнал готовности к приему (CTS) изменил состояние. |
EV_DSR | Сигнал готовности модема (DSR) изменил состояние. |
EV_ERR | Произошла ошибка состояния линии. Ошибкой состояния линии являются CE_FRAME, CE_OVERRUN и CE_RXPARITY. |
EV_RING | Был обнаружен индикатор вызова. |
EV_RLSD | Сигнал RLSD (детектор принимаемого линейного сигнала) изменил состояние. |
EV_RXCHAR | Символ был принят и помещен в буфер ввода данных. |
EV_RXFLAG | Символ события был принят и помещен в буфер ввода данных. Символ события определяется в структуре DCB устройства, которое обращается к последовательному порту, используя функцию SetCommState. |
EV_TXEMPTY | Был отправлен последний символ из буфера вывода данных. |
lpOverlapped
[in] Указатель на структуру
OVERLAPPED. Эта структура
требуется, если hFile открывался с флажком
FILE_FLAG_OVERLAPPED.
Если hFile открывался с
FILE_FLAG_OVERLAPPED, параметр
lpOverlapped не должен иметь значение ПУСТО (NULL).
Он должен указывать на допустимую структуру
OVERLAPPED. Если hFile открывался с FILE_FLAG_OVERLAPPED, а
lpOverlapped — ПУСТО (NULL), функция может
неправильно сообщить, что операция
завершилась.
Если hFile открывался с
FILE_FLAG_OVERLAPPED, а lpOverlapped
— не ПУСТО (NULL), функция WaitCommEvent выполняется
как асинхронная операция. В этой ситуации, структура
OVERLAPPED должна содержать дескриптор объекта
события сброса вручную (неавтоматического
сброса) (созданный, при помощи
использования функции CreateEvent).
Если hFile не был открыт с
FILE_FLAG_OVERLAPPED,
WaitCommEvent не возвращает значения до тех пор,
пока не произойдет одно из определенных
событий или ошибка.
Возвращаемые значения
Если функция завершается успешно,
возвращаемое значение не нуль.
Если функция завершается ошибкой,
возвращаемое значение равняется нулю.
Чтобы получить дополнительную информацию
об ошибке, вызовите GetLastError.
Замечания
Функция WaitCommEvent осуществляет текущий
контроль за пакетом событий для заданного
коммуникационного ресурса. Чтобы
установить и сделать запрос текущей маски
события коммуникационного ресурса,
используйте функции SetCommMask и GetCommMask.
Если асинхронная операция не может
завершиться немедленно, функцией
возвращается ЛОЖЬ (FALSE), а функцией GetLastError
возвращается значение ERROR_IO_PENDING, указывая,
что операция исполняет код в фоновом режиме.
Когда это случается, система устанавливает
член hEvent структуры OVERLAPPED в несигнальное
состояние прежде, чем WaitCommEvent возвращает
значение, а затем она устанавливает
структуру в сигнальное состояние, когда
происходит одно из определенных событий
или ошибка. Вызывающий процесс
может использовать одну из функций
ожидания, чтобы выяснить состояние
объекта события, а затем использовать
функцию GetOverlappedResult, чтобы выяснить
результат работы WaitCommEvent. Функция
GetOverlappedResult сообщает об успешном завершении
или сбое операции, а переменная, на которую
указывает параметр lpEvtMask устанавливается
так, чтобы обозначить событие, которое
произошло.
Если процесс пытается изменить маску
события дескриптора устройства, используя
функцию SetCommMask, в то время, когда происходит
асинхронная операция WaitCommEvent, функция
WaitCommEvent возвращает значение немедленно.
Переменная, на которую указывает параметр
lpEvtMask устанавливается в нуль (‘0’).
Код примера
Пример смотри в статье
Мониторинг
коммуникационных событий.
Смотри также
Обзор Коммуникационные
ресурсы, Функции,
используемые коммуникационными ресурсами,
CreateFile,
DCB, GetCommMask,
GetOverlappedResult,
OVERLAPPED, SetCommMask,
SetCommState
Размещение и
|
||
К |
Windows XP |
Да |
л |
Windows 2000 |
Да |
и |
Windows NT |
Да |
е |
Windows Me |
Да |
н |
Windows 98 |
Да |
т |
Windows 95
|
Да |
|
||
С |
Windows 2003 Server |
Да |
е |
Windows 2000 Server |
Да |
р |
Windows NT Server |
Да |
в |
|
|
е |
|
|
р |
|
|
|
Используемая |
Kernel32.lib |
|
Заголовочный файл |
|
|
— объявлено в |
Winbase.h |
|
— включено в |
Windows.h |
|
Unicode |
— |
|
Замечания по |
Не имеется |
Forum Rules |
|