Работа с коммуникационными портами (COM и LPT) в программах для Win32

       

Функция WaitCommEvent


Когда маска отслеживаемых событий задана, Вы можете приостановить выполнение своей программы до наступления события. При этом программа не будет занимать процессор. Это выполняется вызовом функции

   BOOL WaitCommEvent(

      HANDLE       hFile,

      LPDWORD      lpEvtMask,

      LPOVERLAPPED lpOverlapped,

   );

Замечу, что в переменной, адресуемой вторым параметром, не будут устанавливаться внутренние события драйвера (перечислены в описании функции GetCommMask). В единичное состояние установятся только те биты, которые соответствуют реально произошедшим событиям.

Адрес структуры OVERLAPPED требуется для асинхронного ожидания (возможно и такое). Однако пока будем полагать, что порт открыт для синхронных операций, следовательно этот параметр должен быть NULL. Замечу только, что при асинхронном ожидании данная функция может завершиться с ошибкой, если в процессе этого ожидания будет вызвана функция SetCommMask для переустановки маски событий. Кроме того, связанное со структурой OVERLAPPED событие (объект создаваемый функцией CreateEvent, а не событие порта) должно быть с ручным сбросом. Вообще, поведение функции с ненулевым указателем на структуру OVERLAPPED аналогично поведению функций чтения и записи. Теперь коротенький пример:

   #include <windows.h>

   . . .

   DCB           dcb;

   COMMTIMEOUTS  ct;

   HANDLE        port;



   DWORD         mask;

   DWORD         bc;

   char          buf[101];

   . . .

   dcb.DCBlength=sizeof(DCB);

   BuildCommDCB("baud=9600 parity=N data=8 stop=1",&dcb);

   dcb.fNull=TRUE;

   ct.ReadIntervalTimeout=10;

   ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0;

   ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;

   port=CreateFile("COM2",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);

   SetCommState(port,dcb);

   SetCommTimeouts(port,&ct);

   PurgeComm(port,PURGE_RXCLEAR);

   . . .

   SetCommMask(port,EV_RXCHAR);

   WaitCommEvent(port,&mask,NULL);

   ReadFile(port,buf,100,&bc,NULL);

   CloseHandle(port);

   . . .

В данном примере ожидается начало сообщения (первый полученый символ), после чего вызывается функция чтения.

Освобождать процессор на время ожидания хорошо, но хотелось бы параллельно с вводом/выводом делать какую-либо полезную работу. Что бы это стало возможным, необходимо в качестве параметра dwFlagsAndAttributes вместо 0 указать FILE_FLAG_OVERLAPPED. Кроме того, для функций ReadFile, WriteFile и WaitCommEvent необходимо в качестве параметра lpOverlapped указывать адрес правильно инициализированной структуры OVERLAPPED.



Содержание раздела