Тема: Com-порт
Показать сообщение отдельно
  #16  
Старый 04.10.2011, 23:54
Lucky192 Lucky192 вне форума
Прохожий
 
Регистрация: 04.10.2011
Сообщения: 28
Репутация: 1351
По умолчанию

Цитата:
Сообщение от chainik
Привожу драйвер ком- порта для Win95/Win98
К сожалению в WinXP этот трюк уже не работает. Система не допускает прямого обращения к портам ввода/вывода. Это элемент защиты.
У меня на предприятии есть стенды с такой системой. Заменить уже не на что...
Управление аппаратными ресурсами - это основная задача всех многозадачных операционных систем. Неотъемлемой частью такого управления является изоляция программ пользовательского режима от аппаратуры (система не допускает прямого обращения к аппаратной части). Если хотите прямой доступ к аппаратным портам, к памяти, к процессору - становитесь частью ОС, пишите драйвер. Иначе из процессора вытеснят, память кусками выгрузят на диск, а к порту доступа не дадут, т.к. кто-то его уже занял...

Однако не все так плохо, и подобный трюк все-таки работает под XP. Дело в том, что привилегии для кода выполняемого в пользовательском режиме гибко настраиваются. Привилегии процесса задаются табличным способом. К каждому процессу привязан набор таблиц, отвечающих за привилегии, виртуальную память и т.д. В том числе есть и таблица, отвечающая за доступ к портам ввода-вывода (I/O Permission Map). Естественно, что по умолчанию доступ ко всей аппаратуре для приложений закрыт. Также пользовательским приложениям запрещена работа с таблицами привелегий. Но разрешена для драйверов. К счастью, такие драйвера уже давно написаны. Самый простой - это giveio.sys, он дает открывшему его приложению доступ ко всему диапазону портов ввода вывода.

Принцип работы giveio.sys простой:
1. Сначала нужно установить драйвер в систему. Это можно сделать многими способами. Например специальной утилитой (LoadDrv.exe). Еще можно загрузить драйвер прямо из программы, воспользовавшись функциями API. Это достаточно сделать один раз, в дальнейшем драйвер будет загружаться вместе с системой.
2. Нужно подключиться к драйверу giveio.sys. Драйвер обнаружит это подключение и автоматически разрешит доступ ко всем портам для вызывающего процесса. Подключение к драйверу выполняется через функцию CreateFile. В качестве имени файла нужно передать строку '\\.\giveio';
3. Все. Доступ к портам для данного процесса открыт. Можно закрывать хэндл драйвера - доступ сохраниться вплоть до завершения работы процесса.

Есть и другие подобные драйверы. С их помощью, например, можно открыть доступ не ко всем портам, а лишь к определенному диапазону. Или открыть доступ для другого процесса.

Цитата:
Сообщение от chainik
Обрати внимание насколько здесь все проще.
Чтобы отослать байт ты просто отправляешь его в порт
(команды IN/OUT)
Это обманчивая простота. Вот примеры вызова функций WinAPI для замены всех функций модуля Port95:
Код:
ReadFile(h,ByteValue,1,tmp,nil);  // function PortReadByte(Addr:Word):Byte;             
ReadFile(h,WordValue,2,tmp,nil);  // function PortReadWord(Addr:Word)	 : Word;
ReadFile(h,WordValue,2,tmp,nil);  // function PortReadWordLS(Addr:Word) : Word;
WriteFile(h,ByteValue,1,tmp,nil); // procedure PortWriteByte(Addr:Word; Value:Byte);
WriteFile(h,WordValue,2,tmp,nil); // procedure PortWriteWord(Addr:Word; Value:Word);
WriteFile(h,WordValue,2,tmp,nil); // procedure PortWriteWordLS(Addr:Word; Value:Word)
 
ReadFile(h,IntValue,4,tmp,nil);   // А такую функцию в Port95 еще добавлять надо ;)
WriteFile(h,IntValue,4,tmp,nil);  // также как и эту
Конечно, нужно еще где-то взять дескриптор h. Но и для Port95 нужно где-то взять адрес порта. Казалось бы чего уж проще - 378h, 278h - вот они (а при использовании WinAPI нужно еще CreateFile с кучей параметров вызывать, ошибки обрабатывать... фу-фу-фу!!!). Ан нет. Вот нужно нам 4 порта использовать. Есть 2 штатных (повезло - а то на новых ведь может и не быть) + ISA карта на 2 порта. Все еще просто? Усложним задачу: [в кабинете начальника] "...а еще чтоб с разными картами работало" (а вдруг карта сгорит а другой такой нет, но есть очень-очень похожая). Еще усложним: [в магазине] "Какие еще ISA-карты? Нету их в продаже и не будет, но в наличии есть PCI ( берите - последняя осталась! ) или PCIExpress или переходник USB-COM. Что будете брать?" (А в WinAPI - вот он я - уже ставлю драйвер для купленного чего-то там, меняю строчку 'COM1' на 'COM18', дописываю еще 10 строк сложного, лишнего, страшного своей бесполезностью кода... Вот-вот завершу переделки! -[ехидно потирает ручки]- )

Еще осталась неохваченной настройка COM-порта. Ее нужно писать самому, в Port95.pas этого нет. Не надеяться же на то, что порт до нас уже кто-то настроил. Какой-то особенной простоты настройки при прямом доступе к портам нет. Будем считать ничья.

Ну и конечно же, мое самое любимое: СКОРОСТЬ!!! Казалось бы - ассемблерные функции. Да там тормозить просто нечему!!! Ан нет и тут засада... Есть такая инструкция OUT. Она-то нам всю малину и испортила. Больно уж долго выполняется (быстрее скорости порта не разгонишься, а это очень медленно даже для систем 20-летней давности). А дальше оптимизировать уже некуда - и так две инструкции. Еще момент: [ситуация] оборудование попалось настырное - шлет и шлет данные непрерывным потоком на полной скорости. Скорость приема байт хоть и небольшая (каких-то 10 кГц всего), но и квант времени в системе немаленький - 18 миллисекунд. Кто-то процессор занял чуть дольше положенного - и PortReadByte не выполнялся в течении 10 мс. Хорошо что есть буфер FIFO! Целых 16 байт. На 16 мс. Мда, уже не хватает - могут быть потери данных (вот она проклятая многозадачность где боком вылезла) - надо что-то думать... А в WinAPI - дописал 100 строк сложного кода и у тебя как-то все само-собой в буфере появляется - успевай только обрабатывать.
Ответить с цитированием