Добрый день! Пишу драйвер виртуального СОМ порта (тут немного о нём
https://forum.shelek.ru/index.php/topic,28632.0.html). В стандартном СОМ порте обрабатываются события по маскам EV_BREAK, EV_CTS, EV_DSR, EV_ERR... В тестовой программе я работаю с портом асинхронно. Ниже пример чтения с маской EV_TXEMPTY (Из буфера передачи передан последний символ).
Во время установки идёт пакет IOCTL_SERIAL_SET_WAIT_MASK и во время WaitCommEvent IOCTL_SERIAL_WAIT_ON_MASK. В моём драйвере эти пакеты не обрабатываются, а в стандартном всё честно.
В своём драйвере нужно тоже реализовать работу с масками, но нужно знать как система реагирует, кто ей сообщает, что событие по маске сработало и поток будет продолжать работу?
byte[] buffer = new byte[1024];
COMSTAT comstat; //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов
uint btr, mask, signal, temp; //переменная temp используется в качестве заглушки
int tempRead = 0;
overlpdRead.hEvent = CreateEvent(IntPtr.Zero, true, true, null); //создать сигнальный объект-событие для асинхронных операций
SetCommMask(handle, EV_TXEMPTY); //установить маску на срабатывание по событию приёма байта в порт
while (true) //пока поток не будет прерван, выполняем цикл
{
WaitCommEvent(handle, out mask, ref overlpdRead); //ожидать события приёма байта (это и есть перекрываемая операция)
signal = WaitForSingleObject(overlpdRead.hEvent, Timeout.Infinite); //приостановить поток до прихода байта
if (signal == WAIT_OBJECT_0) //если событие прихода байта произошло
{
if (GetOverlappedResult(handle, ref overlpdRead, out temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
if ((mask & EV_TXEMPTY) != 0) //если произошло именно событие прихода байта
{
ClearCommError(handle, out temp, out comstat); //нужно заполнить структуру COMSTAT
btr = comstat.cbInQue; //и получить из неё количество принятых байтов
if (btr>0) //если действительно есть байты для чтения
{
fixed (byte* p = buffer)
{
ReadFile(handle, p, (int)btr, ref tempRead, ref overlpdRead);