Подкиньте идейку или ссылку как прочитать регистр статуса модема (0x3FE) из драйвера режима ядра. У меня READ_PORT_UCHAR выдает постоянно 0xFF. Заранее спсаибо.
http://www.wasm.ru/article.php?article=drvw2k03 См. почти в конце, где ссылка http://void.ru/?do=printable&id=701 А вообще-то есть библиотеки для работы с COM-портами. Я например прекрасно управлялся с модемом из Visual Basic-a, Паскаля и Дельфи.
valterg, спасибо. Но я наверное неправильно выразился. У меня драйвер не может прочитать значение регистра состояния модема. Похоже ядро ОС запрещает доступ к прямому в/в. Функции, описанные Робертсом не помогли :-(. Чего то не то может я наворотил.
Не пойму как ядро что-то запретить может драйверу. В любом случае - попробуй просто прочитать в драйвере с помощью IN. И погляди. Может там вообще идёт высокий импенданс. Может порт промаплен по другому адресу(Диагностика\Ресурсы\IO) Я проверил у себя - 3FE читается 34 30 ...
Kola, pIrp = IoBuildDeviceIoControlRequest(IOCTL_SERIAL_GET_MODEMSTATUS, pSerialDevice, NULL, 0, &ModemStatus, 4, FALSE, NULL, &Iosb); IoCallDriver(pSerialDevice, pIrp); меня не устраивает, т.к. код выполняется на IRQL>DISPATCH_LEVEL
Может сам UART настроен так? Через IoCallDriver выдает реальное значение, а вот in al,dx - 0xFF. В исходнике родного драйвера serial сказано что значение 0xFF возвращается если не было прерывания или занато. Что делать?
возможно единственный выход - это редизайн, штобы нужный код (IoCallDriver) вызывался на низком IRQL неприятно конечно, но...
http://www.wasm.ru/forum/index.php?action=vthread&forum=7&topic=1110 http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=1237 http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=4062
а можно по поддробней для чайников. у меня такая же проблемма. мне в инсте задание дали написать драйвер для прямого доступа к регистрам com-порта а они не читаются (0хff) на всех читаемых портах. последнии ссылки из темы пустые.
Может еще кому-то актуально. Сам когда-то разбирался, но информации нигде не нашел, пришлось копать самому. Последовательный порт, в отличие от параллельного, практически на всех машинах поддерживает управление электропитанием. В IDLE MODE последовательный порт выключен, поэтому доступа к его регистрам нет, прерывание порта тоже выключено (точнее не назначено). При открытии порта драйвер SERIAL вызывает драйвер ACPI, который включает порт и назначает прерывание. Простейший вариант - работать через драйвер. Второй вариант - открыть порт через драйвер, работать напрямую, потом закрыть порт. Последний (извращенный, но работающий) вариант, когда нужен полный доступ с прерыванием - читаю параметры нужного порта из реестра Registry\Machine\Hardware\Description\System\MultifunctionalAdapter\xxx\SerialController\x\ConfigurationData, получаю вектор прерывания по номеру из реестра (HalGetInterruptVector), подключаюсь к драйверу SERIAL0 или SERIAL1 (IoGetDeviceObjectPointer), посылаю драйверу IRP "SURPRISE_REMOVE"( другие IRP не помогают остановить драйвер мимо диспетчера в/в), потом отключаюсь (ObDereferenceObject). Теперь система порт не видит до следующей перезагрузки, порт, ясное дело, выключен. Только после остановки дравера SERIAL я могу подключиться к прерыванию порта. Осталось только включить порт. Ничего другого не придумал, как работать напрямую с регистрами ACPI. Код может работать не на всех машинах, тем не менее: Код (Text): mov edx,2eh ;адрес регистра ACPI - может быть 370h, 3f0h mov ebx,[PortAddr] ;адрес com порта xor ecx,ecx ;логический номер устройства ACPI PortEnable1: inc cl cmp cl,7 ; ищем в промежутке 1...7 jnc PortEnablex mov al,055h ; открываем доступ к регистрам ACPI out dx,al jmp short $+2 mov al,87h out dx,al ;reset ACPI jmp short $+2 out dx,al ;reset ACPI jmp short $+2 mov al,7 ;команда адреса out dx,al jmp short $+2 inc edx ;на регистр данных mov al,cl out dx,al ;пишем адрес jmp short $+2 dec edx mov al,61h ;команда младшего адреса порта out dx,al jmp short $+2 inc edx in al,dx ;читаем младший адрес dec edx cmp al,bl ;совпадает с нашим портом? jnz PortEnable1 ;нет, не наше устройство mov al,60h ;команда старшего адреса порта out dx,al jmp short $+2 inc edx in al,dx ;читаем dec edx cmp al,bh ;совпадает с нашим портом? jnz PortEnable1 ;нет, не наше устройство ; устройство найдено mov al,70h ;команда прерывания порта out dx,al jmp short $+2 inc edx mov eax,[PortInt] ;номер прерывания из реестра out dx,al ;устанавливаем jmp short $+2 dec edx mov al,30h ;команда enable device out dx,al jmp short $+2 inc edx mov al,1 ;открываем устройство out dx,al jmp short $+2 dec edx xor ecx,ecx PortEnablex: mov al,0aah ;закрываем доступ к регистрам ACPI out dx,al ret Уточнение: это регистры не ACPI, а PNP принадлежат микросхеме ввода-вывода, поэтому могут быть разными на разных чипах.
Может кто нибудь подсказать, как с помощью драйвера ACPI включить COM порт и назначить прерывание? PS: У меня та же проблема что и у CodeWorm (READ_PORT_UCHAR из регистра 0x3FB порта COM1 выдает 0xFF), но к сожалению ссылки Four-F: http://www.wasm.ru/forum/index.php?action=vthread&forum=3&topic=5013 и http://www.wasm.ru/forum/index.php?action=vthread&forum=7&topic=1110 http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=1237 http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=4062 не работают. Заранее благодарю