Visual Basic, .NET, ASP, VBScript
 

   
 

В основном занимаюсь ремонтом любых электронных устройств. Еще люблю Вижуал Бейсик. Еще люблю с друзьями в преферанс сыграть. Еще люблю пиво и поспать.

 
     
   
 
   Статья расчитана на читателей, знакомых с устройством и работой LPT-порта.
   Почитать о LPT-портах можно например здесь:
   Я отношусь к тому сорту людей, которые любят подключать к компьютеру разные нестандартные устройства, а так же самому их собирать и работать с ними посредством Visual Basic. Собрав в очередной раз такое устройство (нечто типа расширителя LPT-порта) и подключив его к LPT-порту компьютера я запустил Visual Basic. И с ужасом обнаружил, что в нем напрочь нет никаких средств работы с LPT-портом. Немного погоревав и поматерившись, я полез в интернет с цель выяснить - "А кагого, собственно, хрена их нету". И прежде я спросил себя - "А кагого, собственно, хрена я хочу". И ответил сам себе - "Я хочу в VB манипулировать любым битом любого LPT-порта как мне вздумается, а так же перехватывать их аппаратные прерывания и обрабатывать их (IRQ7 для LPT1) и еще при этом я хочу захватить порт в свое монопольное использование, чтобы никакая другая сволочь, включая спулер печати, не лезла в порт в это время и не создавала мне там кашу. Все это я хочу делать в Windows 9x/Me/NT/2000/XP".
И выяснил я вот что:
  1. Нет таких средств и в других средствах разработки софта для Win32 - включая Delphi и Visual C. Я имею в виду полное и удобное средство. Выполнение встроенных ассемблерных инструкций in и out - не в счет. (здесь горе мое сильно уменьшилось :).

  2. Все устроиства в Win32 имеют свои драйверы, и программы работают с устройствами посредством них. Стало быть, я должен написать драйвер для своего устройства. Микрософт советует создавать драйверы специальным инструментом - DDK (Driver Development Kit - набор для разработки драйверов). Пожалуй, это самый логичный и честный путь решения проблемы. Но вот его недостатки:

    1. Я должен усовершенствовать свои знания языков Ассемблер и Си.
    2. Я должен усовершенствовать свои знания английского языка, поскольку мне не удалось найти русскоязычной документации по этому вопросу.
    3. Я должен разобраться в структурах драйверов, которые совершенно различны для Windows 9x/ME и для Windows NT/2000/XP.
    4. Я должен научиться отлаживать драйверы и привыкнуть к неизбежным "синим экранам смерти", многократно появляющимся в процессе отладки драйвера при малейших ошибках.
    5. Я должен установить DDK (или другой подходящий инструмент).
    6. Наконец, на все это уйдет довольно много времени.

       Слабо прыгнуть в такую прорубь? Я решил пока поискать другие проруби.

  3. Еще один путь - использовать драйверы, встроенные в Windows. Однако в Windows нет функциональностей для общего доступа к портам, есть только специфичные функции. Например API для доступа к принтерам, для доступа к последовательным портам. В VB есть объект Printer, есть контрол MSComm. Но мое устройство совсем не похоже на принтер, значит этот путь не для меня. Что касается MSComm - это прекрасный инструмент для работы со стандартными и нестандартными устройствами через COM-порт. У меня еще не было ситуации, когда бы он меня не удовлетрорил. Если читатели захотят, я расскажу о нем в другой статье.

  4. С портами можно работать и без драйверов. В интернете есть много бесплатных DLL, позволяющих это делать. Например:


       Однако, вот их недостатки:

    1. Все они не умеют перехватывать прерывания.
    2. Все они работают "не честно" по отношению к Windows, т.е. не спрашивают у него "а можно я поработаю вот с этим портом", а просто нагло лезут в порт, при этом возможно создавая кашу для "честных" программ.
    3. Наконец, нет гарантии, что не наступит ситуация, когда эти DLL не смогут выполнить своих функций (например многие не работают в Windows NT/2000/XP).

       Кого устраивает такой способ - дальше можно не читать. Меня не устраивает.

  5. Существуют так называемые драйверы общего назначения (generic), которые обеспечивают "прозрачный" доступ к аппаратуре под Win32 непосредственно из Win32-приложения. Например:

    • DriverX фирмы Tetradyne Software (http://www.tetradyne.com/)
    • IO ActiveX Communications module фирмы JSPayne (http://www.jspayne.com/io/home.html)
    • WinRT, WinRT-VB, WinDK фирмы BSQUARE (http://www.bsquare.com/)
    • Parallel Port Direct I/O Access package - Peter Shoebridge (http://www.zeecube.com/driver.htm)
    • TVicHW32 & TVicPort & TVicLPT фирмы EnTech Taiwan (http://www.entechtaiwan.com/tools.htm)
       Все они имеют разные недостатки, из них главный - они не бесплатные.
   Немного поизучав их, я решил остановиться на TVicHW32 (http://www.entechtaiwan.com/tools.htm). Он представляет из себя драйвер (VxD для Windows 9x/Me и kernel-mode драйвер для Windows NT/2000/XP) и DLL, которую можно подключить к своему проекту и через нее работать с драйвером. Это универсальный инструмент для работы с различной аппаратурой непосредственно из Win32 приложения. На сайте доступна для скачивания полнофункциональная демо-версия с единственным ограничением - при каждом открытии драйвера появляется окно с напоминанием о необходимости регистрации. Пользователь может опробовать инструмент, отладить свою программу и решить - покупать или нет. Вот его преимущества по сравнению с другими инструментам:

  • Все сделано вразумительно, понятно и изящно (по крайней мере - мне так показалось).
  • Он мало "весит" - около 100 килобайт (драйверы и DLL), не содержит лишнего мусора.
  • Есть примеры для Visual Basic.
  • Есть русская документация (FAQ, описание функций, описание применения).
  • Автор - русский программист, с ним можно связаться по email по-русски, если возникнут вопросы.
   Есть на этом сайте и другой инструмент специально для работы с LPT - TVicLPT. (и еще много других интересных инструментов). Представляет из себя драйвер и OCX - компонент. Однако во-первых он еще не совсем доделан (пока нет секции LPT Communications). Во-вторых в данном случае мне больше нравится работать через DLL - так обеспечивается бОльшая производительность. Возможно я расскажу о нем в другой статье.
   Скачав и установив TVicHW32, я почитал документацию и залез в папку с примерами по VB. Там есть файл TVicLib.bas с объявлениями всех функций, констант, типов. Есть папки с примерами по каждой секции инструмента. Первым делом запустил пример по работе с LPT. Попробовал захватить порт и после этого запустить принтер и сканер, которые у меня были подключены к этому же порту. Оба отвалились с сообщением, что порт недоступен. Затем поробовал наоборот - занять порт принтером (и в следующий раз сканером) и захватить его в TVicHW32. Получил ошибку, что порт уже занят другим приложением. Все работает "по-честному". Можно узнать количество LPT, установленных на машине, выбрать "текущий" LPT, узнать его базовый адрес. Для удобства в TVicHW32 есть функции GetPin и SetPin, которые позволяют прочитать/записать электрический уровень с заданного контакта 25-контактного разъема текущего LPT (естественно на которых это возможно). Можно и просто читать/писать байты в любой регистр LPT, зная его базовый адрес (где поддерживается соответствующая операция). Поигрался немного со своим устройством через эти функции. Мое устройство "зашевелилось". Все сигналы нормально пишутся/читаются. Попробовал перехватить прерывание (для LPT1 это IRQ7). Для этого есть функция UnmaskIRQ, которой нужно передать номер прерывания и с помощью AdressOf указать процедуру-обработчик, находящуюся в стандартном модуле. После этого надо функцией ForceLPTIrq включить поступление прерываний от LPT на контроллер прерываний машины. Кроме того под Windows NT/2000/XP надо в панели управления в свойствах LPT включить обработку прерываний (по умолчанию она выключена). Попробовал - на все сигналы, поступающие от моего устройства по линии Acknowledge (10-я ножка на разъеме LPT) срабатывает установленная мной процедура. В простейшем случае, для пробы, можно просто замыкать например разогнутой скрепкой эту ножку на "земляную" D-образную оболочку разъема (или на ножки с 18-ой по 25-ю). Есть ограничения на частоту следования этих сигналов. В основном это реалии Windows. Подробно об этом можно посмотреть в FAQ. "Цоколевку" разъема LPT (и кучи других разъемов и кабелей) можно посмотреть здесь- http://www.hardwarebook.net/ Кроме этого в TVicHW32 опять же для удобства есть функции для работы с сигналами Centronix. Можно прочитать состояние линий Acknowledge, BUSY, Paper End, Select, ERROR. Можно сформировать короткий импульс (строб) на линиях STROBE и INIT, установить активным или пассивным сигнал AUTOFD, выдать сигнал SLCTIN, выдать на печать один символ. Кроме того можно функцией SetLPTReadMode перевести LPT в режим чтения региста данных (контакты 2-9). Для этого LPT должен быть "двунаправленным" и сконфигурированным в BIOS SETUP как PS/2 compatible или ECP. Перед записью в регистр данных он должен быть переключен обратно в режим записи функцией SetLPTWriteMode. Наконец можно добавить свой "нестандартный" LPT при помощи функции AddNewLPT и работать с ним как с обычным LPT.
   Есть один недостаток. В TVicHW32 отсутствует функция, позволяющая узнать, есть ли у заданного LPT аппаратное прерывание и, если есть - узнать его номер. Как выяснилось, это нетривиальная задача. На этом же сайте есть бесплатный пакет TVicRes. Это исходный код класса, созданного в Delphi и предназначенного для получения информации об аппаратных ресурсах машины. Я портировал его в VB. Получилось это у меня не очень красиво, и я так и не разобрался, как однозначно определить номер IRQ для заданного LPT под разными версиями Windows на разных компьютерах. Но под Windows 98 и XP он вроде выдает IRQ правильно. Скачать переведенный в VB TVicRes можно здесь - http://nikkollo.pisem.net/files/TVicRes_VB.zip
   Ну чтож, все мои потребности в отношении LPT полностью удовлетворены.
   Что еще есть в TVicHW32:

  • Функции общего назначения Можно открыть/закрыть драйвер и проверить открыт ли он. Причем открыт он может быть двумя приложениями одновременно.
  • Функции работы с физической памятью Для того, чтобы получить доступ к памяти, заданной ее физическим адресом, необходимо отобразить этот физический адрес на пространство линейных адресов текущего процесса. TVicHW32 содержит функцию MapPhysToLinear, которая решает эту задачу и возвращает обычный указатель на область памяти, заданную ее физическим адресом и размером. С полученным указателем можно работать непосредственно, а можно и при помощи набора дополнительных функций, которые обеспечивают доступ к физической памяти побайтно, пословно или двойными словами.(Актуально для VB, где непосредственная работа с указателями затруднена).
  • Работа с портами ввода/вывода Набор функций работы с портами ввода/вывода включает две группы функций - для ввода/вывода одиночных байт (слов, двойных слов) и для ввода/вывода массивов данных. Работа с портами возможна в двух режимах - "Soft Mode" и "Hard Mode". "Soft Mode" обеспечивает большее быстродействие, но может дать неверные результаты, если данный порт уже используется другим драйвером. "Hard Mode" работает медленнее, но обеспечивает абсолютно надежный доступ к портам, даже используемым другими драйверами.
  • Обработка аппаратных прерываний Можно запустить/остановить процесс обработки прерываний, указав номер прерывания и установить свою процедуру-обработчик этого прерывания. TVicHW32 позволяет установить несколько обработчиков прерываний или использовать один и тот же обработчик прерываний для нескольких IRQ. Есть ограничения (подробнее см. FAQ):

    • Под всеми версиями Windows нельзя использовать IRQ0 (системный таймер);
    • Под Windows NT/2000 нельзя использовать прерывание от RTC (часы реального времени).
    • Есть расширенные возможности для обработки "Level Sensitive" прерываний.

  • Получение информации о дисках IDE, включая серийный номер TVicHW32 позволяет получить информацию о жестких дисках IDE, установленных на компьютере, включая модель диска, серийный номер, геометрию и другие параметры. Не путать с серийным номером раздела диска, записанным при форматировании и возвращаемым функцией GetVolumeInformation! Информация, считываемая TVicHW32, записывается производителем жестких дисков раз и навсегда и не может быть измененена никаким форматированием. Многие хотят использовать эту информацию для защиты своих программ, хотя автор этого делать не рекомендует (подробнее см. FAQ).
  • Доступ к информации об устройствах PCI Можно получить информацию о всех установленных устройствах на шине PCI (включая AGP и PCMCIA).
  • Работа с клавиатурой TVicHW32 позволяет послать управляющие коды (скэн-коды) непосредственно в контроллер клавиатуры на самом нижнем уровне (аппаратном), имитируя тем самым нажатие/отжатие клавиш. Можно также установить процедуру-перехватчик ("хук"), которая будет перехватывать все нажатия/отжатия клавиш клавиатуры.
  • Выделение памяти под буферы DMA TVicHW32 не реализует какие-либо функции DMA, пользователь может сделать это самостоятельно, используя другие функции. Но TVicHW32 позволяет решить одну из ключевых задач по выделению буфера памяти для операций DMA. К этой памяти выдвигается ряд важных требований. Подробности см. в описании функций.
  • Выполнение пользовательского кода в Ring 0 CPU Функция RunRing0Function позволяет выполнить Вашу процедуру в нулевом кольце защиты процессора (ring 0). Это означает, что в этой функции можно использовать любые привилегированные команды процессора, которые до этого были доступны только в драйверах. Однако ее нет в объявлениях функций для VB, и я не знаю, как ее может использовать VB-программист. Но она есть в драйвере и пользователь сам сможет найти пути ее использования.
   Стоит этот инструмент (персональная лицензия) - 2000 руб. для граждан и предприятий России.

   А теперь ВНИМАНИЕ!
   Я связался с автором - Виктором Ижикеевым и он любезно согласился сделать скидку для всех читателей этой статьи. Теперь Вы можете приобрести его за 1000 руб.
   Для этого нужно отправить почтовым переводом 1000 руб. по адресу:

450005, Уфа
а/я 94
Ижикееву Виктору Ивановичу

   После этого отправить E-mail по адресу nikkollo@mail.ru в котором нужно указать следующие данные:

Предмет покупки - TVicHW32.
Фамилия, Имя, Отчество полностью.
Номер квитанции почтового перевода.

   В ответ на это письмо Вы получите по E-mail в течении нескольких дней зарегистрированную версию TVicHW32. Предложение действительно только для частных лиц - граждан России, любая перепродажа или дарение за рубеж - запрещается.
   Техническая поддержка TVicHW32 для VB-программистов - nikkollo@mail.ru.
   Желаю всем удачи в непростом деле работы с аппаратурой в Visual Basic.
   Здесь Вы можете скачать переведенный в VB из Delphi класс TVicRes.

   Права на все упомянутые здесь торговые марки принадлежат их законным владельцам.

Николай Андреев.
nikkollo@mail.ru
Февраль 2003 г.

 
     

   
   
     
  VBNet рекомендует