Всем доброго времени суток! Имеется программируемая клавиатура собственного производства. Необходимо организовать с ней обмен данными через порт ps/2. Посмотрев стандартный драйвер в ddk, я понял что не справится он с этой задачей, т.е. придется писать свой драйвер? я вижу такой путь: добавить IOCTL типа IOCTL_INTERNAL_I8042_CONTROLLER_WRITE_BUFFER, на чтение и запись непосредственно в контроллер в драйвер pnpi8042. И выставлять какой-то флаг для перехвата данных, или данные посылать с какого-то спец кода, которого нет в обмене ps/2. я в драйвера под windows еще юнец, скажите, туда ли я смотрю, или есть лучший путь ? заранее, спасибо.
я согласен с вами. и планировал это делать типа как _outp или WRITE_PORT_XXX, но для начала интересно где это делать в коде драйвера i8024.sys ? чтобы при приеме данных садиться на его прерывание, и при необходимости читать данные для себя?
есть хороший ioctl - IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. посмотри в его сторону. хук вызывается почти сразу из ISR и там можно сделать что угодно.
а можно ли будет с его помощью читать/писать в порт 8042 байты данных, например 0x00, 0x01, 0xff (т.е. организовать полноценный обмен данными) ? т.е. это будет что-то типа фильтра между портом8042 и драйвером клавиатуры или я не правильно понимаю? если по записи в порт еще более-менее понятно - использование PI8042_ISR_WRITE_PORT callback, то по чтению с порта - пока не ясно вообще - или при чтении тоже вернется структура _INTERNAL_I8042_HOOK_KEYBOARD ? но по вашим словам я понимаю задача может быть решена с использованием стандартного драйвера?
я не разбирался с остальными полями структуры, потому как организовал свой минидрайвер 8042 ps/2, единственное для чего мне требуется стандартный - хук на ISR через IOCTL_INTERNAL_I8042_HOOK_KEYBOARD. это я у себя в отладчике так сделал. вероятно, тебе будет вполне достаточно стандартного
А этот IOCTL можно ли вызывать из user-mode ? Т.е. например, я из юзер моде вызываю такой IOCTL: Код (Text): DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_SET_INDICATORS, &OutputBuffer, DataLength, NULL, 0, &ReturnedLength, NULL)) Т.е. вообще не влезая ни в какие драйвера, обойтись только user-mode ?
Это internal device i/o control code. он обрабатывается там внутри по IRP_MJ_INTERNAL_DEVICE_CONTROL и может быть передан только драйвером драйверу через IoBuildDeviceIoControlRequest с параметром Internal = TRUE. Да и как ты себе представляешь ISR-хук в юзермоде? Который выполняется на DIRQL
Уважаемый, Great! К сожалению, я пока и из kernel-mode не представляю Т.е. я понял, что я делаю "пустой" драйвер, в котором "регистрирую" этот хук, и работаю со своим драйвером, который будет отдавать мне все данные клавиатуры, и посылать ей мои данные. Теперь я правильно понял ?
начитался книг, сделал около 300 BSOD и пришел пока к следующему: пока про запись в порт: у меня есть мой драйвер, в котором я делаю следующее в соем ioctl запросе: Код (Text): WRITE_PORT_UCHAR( KEYBOARD_PORT_60, 0x01); но в мою клавиатуру приходит почему-то 0xff (команда сброса), притом независимо от посылаемого значения. нюанс такой: моя клава не отвечает контроллеру никогда, никаких ACK, за что он, как я понимаю, выставляет recv timeout (bit 6, port 0x64 read). вопрос такой: при выполнении WRITE_PORT_UCHAR на порт 0x60 я пишу не сразу в клаву, а всё это проходит обработку контроллером сначала ? или я ошибаюсь? когда подключаю осциллограф - то тоже вижу что идет 0xff, хотя когда я подключаю осциллограф к клаве и шлю данные - он показывает что там не 0xff (более точно не показывает ) но вот еще в одной книге нашел следующее: "Программно-вызываемое прерывание BIOS INT 16h... Функции задаются в регистре AH при вызове: AH = 00 - чтение и выборка слова из буфера ... AH = 05 - запись слова в буфер " Как этим воспользоваться, и вообще нужно ли мне это (в смысле пригодится ли) ? А также даны "ячейки BIOS DATA AREA" - там вообще я понимаю что адреса ( указатели на начало и конца буффера и на сам буффер). Может напрямую в буфер писать или лиху я заморачиваюсь? спасибо Great и katrus за ЦУ.
sja По одной строчки не скажешь. Перед отправке данных нужно проверить чтобы входной буффер контроллера 8042 был пуст. А если отправлять в клавиатуру то и выходной. Порты 60h и 64h это порты контроллера 8042.
Отлично, я проверяю готов ли контроллер к передаче данных по 1 биту статус - регистра (64h read). и всё еще не ясно: вопрос такой: при выполнении WRITE_PORT_UCHAR на порт 0x60 я пишу не сразу в клаву, а всё это проходит обработку контроллером сначала ? или я ошибаюсь?
sja В начале данные попадает в входной буффер контроллера 8042. А он уже решает куда дальше. Если установлен флаг c/d (код/данные) то он воспринимает входной буфер как код. Если нет как данные. Флаг этот устанавливается если мы пишем через порт 64h если через 60h то не выставляется. После записи в входной буфер выставляется флаг входной буфер полон. Дальше из входного он может передать в выходной и отправить в клавиатуру. А может просто податься на порт выхода. А может попасть в системный регистр. Это определяет команда которая была подано до этого или неподана. Если не было команды то данные отправляются прямиком в клавиатуру.
Pavia, спасибо. У меня было это на аглицком, но прочитав по-русски, я еще раз пересмотрел ман по ps/2, оказалась, что ошибка была в том (что 0xff всегда принимает) - надо было клоки клавой генерить - поправили передается доброе теперь. Теперь вопрос как ловить данные с клавы. я планирую использовать wxWidgets для GUI, т.е. у меня не будет доступа к очереди сообщений венды. Я понимаю best way (согласно совету Даоса Great) использовать IOCTL_INTERNAL_I8042_HOOK_KEYBOARD для ps/2? а как ловить данные с ps/2 и с usb клав отдельно ?
Great Большое спасибо за ссылку. Теперь хук подключается, и ловит скан-коды - просто чума! Теперь возникли следующие вопросы: 1. Как ловить эти скан коды в моей app что в user-mode? Или чере ioctl каждые несколько миллисекунд проверять пришло-ли что-нибудь ? 2. Проблема при выгрузке драйвера - как вернуть клаву обратно ? А то любую клавишу жму и BSOD... пробовал так: Код (Text): hookkbd.IsrRoutine = NULL; но если, туда я раньше что-то писал (всмысле callback на мою функцию), то это толку не приносит