Доступ из программы на языке Ада к портам ввода/вывода PC x86 в ОС Linux.

V-1.0 (C) А.Гавва


Зачем это нужно?

Как правило, при подключении к компьютеру какого-либо нестандартного и/или самодельного оборудования (например, программатор, регулятор освещения, сигнализация...) возникает проблема организации простейшего программного управления этим оборудованием через обращения программы к аппаратным портам ввода/вывода PC x86.

Как это осуществить?

Вообще, тема программирования портов ввода/вывода в Linux более детально описана в "Linux I/O port programming mini-HOWTO" (есть перевод на русский язык).

Пакет "pc_ports_io" содержит подпрограммы, которые обеспечивают возможность непосредственного доступа к портам ввода/вывода PC в OS Linux из программы написанной на языке Ада. Эти подпрограммы полностью аналогичны подпрограмм доступа к портам ввода/вывода для языка C, которые описаны в файле "/usr/include/sys/io.h".

Перед осуществлением ввода/вывода в какой-либо аппаратный порт программе необходимо предоставить право на это. Это осуществляется с помощью вызова функции:

   function ioperm
     (uu_from : unsigned_long;
      uu_num : unsigned_long;
      uu_turn_on : int) return int;

где "uu_from" - это первый порт, а "uu_num" - это число подряд идущих портов к которым необходимо предоставить право доступа; значение параметра "uu_turn_on" равное 1 - указывает на предоставление права доступа, а равное 0 - на запрет доступа.

Для вызова "ioperm" необходимо иметь права root. Таким образом, либо программа должна быть запущена пользователем root, либо на исполняемом файле владельцем которого является root должен быть установлен флаг suid.

После завершения работы программы очистка прав доступа к портам происходит автоматически, поэтому вызов "ioperm (..., ..., 0)" не является обязательным.

Функция "ioperm" способна предоставить доступ только к портам с 16#0000# до 16#03FF#, поэтому для портов ввода/вывода, которые расположены в другом диапазоне, необходимо использовать функцию "iopl", которая предоставляет доступ ко всем портам сразу. Чтобы обеспечить доступ программы ко всем портам сразу следует использовать уровень 3 ("iopl (3)"). Для обращения к функции "iopl" также как и в случае с "ioperm" необходимо иметь права root.

Непосредственный ввод/вывод 8-битных байтов, 16-битных и 32-битных слов осуществляется соответствующими in/out подпрограммами.

Подпрограммы имя которых содержит суффикс "_p" добавляют короткую задержку (~1мкс) после доступа к порту за счет вывода байта в порт 16#80#, поэтому перед использованием этих подпрограмм необходимо обеспечить программе право доступа к порту 16#80# (вывод в порт 16#80# никак не влияет на систему).

Примеры

Файлы "io_example_0.adb", "io_example_1.adb" и "io_example_2.adb" содержат простые примеры программ доступа к порту LPT к которому для индикации подключены 12 светодиодов. Схема подключения светодиодов - максимально приметивна и представлена в файле "db25m_leds.png" (сопротивление резисторов 360 Ом).

graphics/db25m_leds.png

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ

Автор этого творенья не несёт никакой ответственности за последствия использования представленного материала и программного обеспечения.

Архив: pc_ports_io.tar.gz