Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как работают маски отслеживаемых событий при работе с COM портом?  (Прочитано 8002 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Artemprodigy
Интересующийся

ua
Offline Offline

« : 02-08-2012 12:20 » 

Добрый день! Пишу драйвер виртуального СОМ порта (тут немного о нём 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);
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 02-08-2012 12:59 » 

этот пример вам не поможет?
DDK\6001.18001\src\kernel\serial\
DDK\7600.16385.1\src\serial\serial\
Цитата
ULONG IsrWaitMask;
    // This mask will always be a subset of the IsrWaitMask.  While
    // at device level, if an event occurs that is "marked" as interesting
    // in the IsrWaitMask, the driver will turn on that bit in this
    // history mask.  The driver will then look to see if there is a
    // request waiting for an event to occur.  If there is one, it
    // will copy the value of the history mask into the wait request, zero
    // the history mask, and complete the wait request.  If there is no
    // waiting request, the driver will be satisfied with just recording
    // that the event occured.  If a wait request should be queued,
    // the driver will look to see if the history mask is non-zero.  If
    // it is non-zero, the driver will copy the history mask into the
    // request, zero the history mask, and then complete the request.
    //
    ULONG HistoryMask;
    // This is a pointer to the where the history mask should be
    // placed when completing a wait.  It is only accessed at
    // device level.
    //
    // We have a pointer here to assist us to synchronize completing a wait.
    // If this is non-zero, then we have wait outstanding, and the isr still
    // knows about it.  We make this pointer null so that the isr won't
    // attempt to complete the wait.
    //
    // We still keep a pointer around to the wait request, since the actual
    // pointer to the wait request will be used for the "common" request completion
    // path.
    //
« Последнее редактирование: 02-08-2012 13:14 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Artemprodigy
Интересующийся

ua
Offline Offline

« Ответ #2 : 02-08-2012 15:18 » 

Спасибо! Но был бы мой драйвер karnel mode, было бы ещё лучше. А что по поводу UMDF драйвера? Что скажешь по поводу этой функции http://msdn.microsoft.com/en-US/library/windows/hardware/ff558835%28v=vs.85%29.aspx , и если можно маленький алгоритм, по работе и обработке с масками, по коду из DDK\7600.16385.1\src\serial\serial\ сложновато мне разобраться.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 02-08-2012 16:16 » new

а чего по этой функции сказать? там вроде все написано... вопроса не понял.
описание масок тут http://msdn.microsoft.com/en-us/library/windows/hardware/hh439605(v=vs.85).aspx
плюс стоит посмотреть описание самих аппаратных сигналов в порту - думаю что нибудь прояснится по логике их формирования.
Цитата
Значение   Предназначение
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   Последний символ в буфере вывода данных был отправлен.
« Последнее редактирование: 02-08-2012 16:19 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines