|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Win32API: Оптимальная организация асинхронного чтения COM-порта в отдельном потоке |
|
Win32API: Оптимальная организация асинхронного чтения COM-порта в отдельном потоке
|
Ветеран Сообщения: 784 |
Профиль | Отправить PM | Цитировать Нашёл в инете несколько неплохих док по работе с COM-портом на Win32API (Титов, Кузан, Терехов и др.).
В одной из них предлагается следующий код для потока: procedure TReadThread.Execute; var ComStat: TComStat; dwMask, dwError: DWORD; OverRead: TOverlapped; Buf: array[0..$FF] of Byte; dwRead: DWORD; begin OverRead.hEvent := CreateEvent(nil, True, False, nil); if OverRead.hEvent = Null then raise Exception.Create('Error creating read event'); FreeOnTerminate := True; while not Terminated do begin if not WaitCommEvent(hPort, dwMask, @OverRead) then begin if GetLastError = ERROR_IO_PENDING then WaitForSingleObject(OverRead.hEvent, INFINITE) else raise Exception.Create('Error waiting port event'); end; if not ClearCommError(hPort, dwError, @ComStat) then raise Exception.Create('Error clearing port'); dwRead := ComStat.cbInQue; if dwRead > 0 then begin if not ReadFile(hPort, Buf, dwRead, dwRead, @OverRead) then raise Exception.Create('Error reading port'); // В Buf находятся прочитанные байты // Далее идет обработка принятых байтов end; end; {while} end; Допустим, в этом фрагменте кода подразумевается, что порт отслеживает только событие прихода во входной буфер первого символа (т.е. установили только флаг RXChar функцией SetCommEvent). Тогда всё сработает корректно. Но если порт отслеживает несколько событий ? - следовало бы определить тип события, которое установило hEvent в сигнальное сотояние. И если это не приход символа, то снова вызывать функцию WaitCommEvent, затем WaitForSingleObject, пока не возникнет событие прихода симола. Но как определить тип события, ведь в структуре OverRead (типа Overlapped) нет полей с информацией о типе произошедшего события, а данные по указателю dwMask не будут определять тип произошедшего события, т.к. функция WaitCommEvent завершится до наступления события (т.е. параметр wdMask функции WaitCommEvent при асинхронных операциях бесполезен) ? 2. Функция ClearCommError в данном фрагменте кода используется только для того, чтобы получить число символов во входном буфере (cbInQue) ? Или здесь обязателен сброс признака ошибки (т.е. что будет, если ошибку не сбросить) ? 3. Может ли функция WaitCommEvent в данном фрагменте вернуть 0 (теоретически), в коде этот случай не рассматривается... Т.е. может ли произойти событие в ходе выполнения этой функции (после сброса hEvent'а функцией) ? 4. Можно ли получить число символов во входном буфере без использования функции ClearCommError ? |
|
Отправлено: 22:50, 13-11-2006 |
Ветеран Сообщения: 784
|
Профиль | Отправить PM | Цитировать Неужели с Com-портом никто не работал ?
|
Отправлено: 21:46, 15-11-2006 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать никакой специфики тут нет. Просто читайте программу.
while not Terminated do begin // >> 3. Может ли функция WaitCommEvent в данном фрагменте вернуть 0 (теоретически), // >> в коде этот случай не рассматривается... // это почему? // bool WaitCommEvent(...) bool - это 0(false) или 1(true) if not WaitCommEvent(hPort, dwMask, @OverRead) then begin // вернула 0 // "не дождались", а ошибка - "идёт передача данных", // дожидаемся окончания это передачи if GetLastError = ERROR_IO_PENDING then WaitForSingleObject(OverRead.hEvent, INFINITE) else raise Exception.Create('Error waiting port event'); end; // not WaitCommEvent // сюда попадаем только когда началась передача данных // если порт был занят, подождали. Если нет, попали сюда сразу if not ClearCommError(hPort, dwError, @ComStat) then raise Exception.Create('Error clearing port'); |
Отправлено: 09:27, 16-11-2006 | #3 |
Новый участник Сообщения: 1
|
Профиль | Отправить PM | Цитировать Объясните мне плиз, функция WaitCommEvent() запрашивает событие по маске, а функция WaitForSingleObject ждет это событие, так получается? И тогда цикл while останавливается или продолжает выполнятся?
|
Отправлено: 10:02, 19-02-2007 | #4 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Загрузка - восстановление загрузки ХР через Windows 7 (каждая система на отдельном диске) | Vatko | Microsoft Windows 2000/XP | 1 | 09-12-2009 13:49 | |
[решено] Запуск php скрипта в потоке или что то вроде? | BASSON_XVI | Вебмастеру | 8 | 27-07-2009 05:43 | |
Delphi - WinApi||C++Builder(Delphi) SplashScreen в отдельном потоке? | XCodeR | Программирование и базы данных | 4 | 12-03-2007 19:51 | |
LILO и WinMe на отдельном х-драйве | penguinius | Общий по Linux | 6 | 28-05-2005 21:30 | |
программирование только с win32api | Guest | Microsoft Windows 95/98/Me (архив) | 1 | 27-04-2004 07:53 |
|