Hardware Access/ru: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Hardware Access/ru
| Old | New | Line | |
|---|---|---|---|
| 1 | + | ## Обзор | |
| 2 | + | ||
| 3 | + | Данная страница является началом руководства по доступу к аппаратным устройствам в Lazarus. Эти устройства включают в себя: ISA, PCI, USB, параллельный порт, последовательный порт. | |
| 4 | + | ||
| 5 | + | Мультиплатформенный подход для доступ к устройствам не реализован в Free Pascal Runtime Library или через LCL, поэтому это руководство кратко описывает способы доступа к аппаратным устройствам для различных платформ. Код может быть откомпилирован для различных сред при помощи директив компилятора, например: | |
| 6 | + | ||
| 7 | + | ``` pascal | |
| 8 | + | uses | |
| 9 | + | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, | |
| 10 | + | {$IFDEF WIN32} | |
| 11 | + | Windows; | |
| 12 | + | {$ENDIF} | |
| 13 | + | {$IFDEF Unix} | |
| 14 | + | ports; | |
| 15 | + | {$ENDIF} | |
| 16 | + | ``` | |
| 17 | + | ||
| 18 | + | В настоящее время неизвестно, допустим ли доступ к аппаратным устройствам в macOS/x86. Эта система может не допускать такого доступа. В таком случае, со временем должен появится драйвер наподобие io.dll. | |
| 19 | + | ||
| 20 | + | ## Сравнение параллельного и последовательного протоколов | |
| 21 | + | ||
| 22 | + | Устройства ISA, PCI и Параллельный Порт взаимодействуют с компьютером посредством **параллельного** протокола. Последовательный порт и устройства USB используют **последовательный** протокол. Поскольку процессор и, соответственно, языки програмирования работают с параллельным доступом к данным, работу с таким протоколом легче реализовать на стороне программного обеспечения. Например, когда Вы обращаетесь к целочисленной переменной, Вы можете получить ее значение при помощи одной комманды. В то же время, при использовании последовательного протокола, Вы можете узнать только один бит в каждый момент времени, и Вам будет необходимо соединить все биты вместе для получения значения. | |
| 23 | + | ||
| 24 | + | Последовательное соединение тяжело реализовать напрямую, но может быть реализовано посредством специальных компонент. Реализация последовательного протокола также сложна и на стороне аппаратного обеспечения - для этой цели используются специализированные интегральные схемы и микроконтроллеры. | |
| 25 | + | ||
| 26 | + | Краткое сравнение протоколов: | |
| 27 | + | ||
| 28 | + | | | Скорость | Сложность аппаратной реализации | | |
| 29 | + | |----|----|----| | |
| 30 | + | | Последовательный порт | Очень низкая (\< E5 бит/с) | Средняя | | |
| 31 | + | | Параллельный порт | Низкая (~ E6 бит/с) | Низкая | | |
| 32 | + | | Устройство ISA | Средняя (~ E7 бит/с) | Средняя | | |
| 33 | + | | USB | Средняя (~ E7 бит/с) | Высокая | | |
| 34 | + | | Устройство PCI | Очень высокая (\> E9 бит/с) | Очень высокая | | |
| 35 | + | ||
| 36 | + | ## Параллельное соединение | |
| 37 | + | ||
| 38 | + | ### Использование inpout32.dll в ОС Windows | |
| 39 | + | ||
| 40 | + | Существуют различные пути доступа к аппаратному обеспечению в Windows 9x и NT. В 9x (95, 98, Me) программа может обращаться к аппаратному обеспечению напрямую, как и в DOS. В NT (Windows NT и XP) такой доступ невозможен. Архитектурой NT подразумевается что взаимодействие с аппаратными портами должно производиться через драйвер устройстав. Этот подход реализован из соображений безопасности, однако разработка драйвера может стоить слишком больших денег и времени для небольших проектов. | |
| 41 | + | ||
| 42 | + | К счастью, существует библиотека, решающую данную проблему. В случае, если обнаружена Windows NT, она извлекает и устанавливает в систему драйвер устройства HWInterface.sys. В случае Windows 9x она просто использует ассемблер для доступа к оборудованию. | |
| 43 | + | ||
| 44 | + | Но как использовать эту библиотеку? Очень просто! Она содержит только двее функции: Inp32 и Out32, назначение которых интуитивно понятно. | |
| 45 | + | ||
| 46 | + | Мы загрузим библиотеку динамически, поэтому сначала определим обе функции: | |
| 47 | + | ||
| 48 | + | ``` pascal | |
| 49 | + | type | |
| 50 | + | TInp32 = function(Address: SmallInt): SmallInt; stdcall; | |
| 51 | + | TOut32 = procedure(Address: SmallInt; Data: SmallInt); stdcall; | |
| 52 | + | ``` | |
| 53 | + | ||
| 54 | + | - Address является адресом порта, к которому необходимо получить доступ | |
| 55 | + | - Out32 отправляет данные **Data** в порту, указанный параметром **Address** | |
| 56 | + | - Inp32 возвращает байт из порта, указанного параметром **Address** | |
| 57 | + | ||
| 58 | + | Теперь можно загружать библиотеку. Это можно реализовать, например в методе OnCreate главной формы программы: | |
| 59 | + | ||
| 60 | + | ``` pascal | |
| 61 | + | type | |
| 62 | + | TMyForm = class(TForm) | |
| 63 | + | ......... | |
| 64 | + | private | |
| 65 | + | { private declarations } | |
| 66 | + | Inpout32: THandle; | |
| 67 | + | Inp32: TInp32; | |
| 68 | + | Out32: TOut32; | |
| 69 | + | ......... | |
| 70 | + | implementation | |
| 71 | + | ......... | |
| 72 | + | procedure TMyForm.FormCreate(Sender: TObject); | |
| 73 | + | begin | |
| 74 | + | {$IFDEF WIN32} | |
| 75 | + | Inpout32 := LoadLibrary('inpout32.dll'); | |
| 76 | + | if (Inpout32 <> 0) then | |
| 77 | + | begin | |
| 78 | + | // обычное @Inp32 = GetProc... как в Delphi приводит к ошибкам компиляции | |
| 79 | + | Inp32 := TInp32(GetProcAddress(Inpout32, 'Inp32')); | |
| 80 | + | if (@Inp32 = nil) then Caption := 'Error'; | |
| 81 | + | Out32 := TOut32(GetProcAddress(Inpout32, 'Out32')); | |
| 82 | + | if (@Out32 = nil) then Caption := 'Error'; | |
| 83 | + | end | |
| 84 | + | else Caption := 'Error'; | |
| 85 | + | {$ENDIF} | |
| 86 | + | end; | |
| 87 | + | ``` | |
| 88 | + | ||
| 89 | + | Если Вы загрузили библиотеку в методе OnCreate, не забудьте выгрузить ее в методе OnDestroy: | |
| 90 | + | ||
| 91 | + | ``` pascal | |
| 92 | + | procedure TMyForm.FormDestroy(Sender: TObject); | |
| 93 | + | begin | |
| 94 | + | {$IFDEF WIN32} | |
| 95 | + | FreeLibrary(Inpout32); | |
| 96 | + | {$ENDIF} | |
| 97 | + | end; | |
| 98 | + | ``` | |
| 99 | + | ||
| 100 | + | Пример использования функции Inp32: | |
| 101 | + | ||
| 102 | + | ``` pascal | |
| 103 | + | {$IFDEF WIN32} | |
| 104 | + | myLabel.Caption := IntToStr(Inp32($0220)); | |
| 105 | + | {$ENDIF} | |
| 106 | + | ``` | |
| 107 | + | ||
| 108 | + | Код был проверен с собственным устройством ISA на порте \$0220, используя Lazarus 0.9.10 в ОС Windows XP. Вам потребуется подключить модуль Windows в разделе uses для запуска приложения. Для развертывания Вам потребуется библиотека "inpout32.dll" в одном каталоге с приложением. | |
| 109 | + | ||
| 110 | + | Домашняя страница приложения: [www.logix4u.net/inpout32.htm](http://www.logix4u.net/inpout32.htm) *См. обсуждение* | |
| 111 | + | ||
| 112 | + | ### Использование ассемблера в ОС Windows 9x | |
| 113 | + | ||
| 114 | + | В Windows 9x Вы также можете использовать код на ассемблере. Например, Вы хотите записать значение \$CC в порт \$320. Вот как будет выглядеть код: | |
| 115 | + | ||
| 116 | + | ``` pascal | |
| 117 | + | {$ASMMODE ATT} | |
| 118 | + | ... | |
| 119 | + | asm | |
| 120 | + | movl $0x320, %edx | |
| 121 | + | movb $0xCC, %al | |
| 122 | + | outb %al, %dx | |
| 123 | + | end ['EAX','EDX']; | |
| 124 | + | ``` | |
| 125 | + | ||
| 126 | + | ### Проблемы в ОС Windows | |
| 127 | + | ||
| 128 | + | Одна из возможных проблем, возникающих при использовании доступа к параллельным устройствам не поддерживающим Plug And Play, заключается в том, что Windows может присвоить порт, используемый Вашим оборудованием другому устройству. Инструкции, как заставить Windows не присваивать адрес вашего устройства устройствам Plug And Play можно найти по ссылке ниже: | |
| 129 | + | ||
| 130 | + | <http://support.microsoft.com/kb/135168> | |
| 131 | + | ||
| 132 | + | ### Использование ioperm для доступа к портам в Linux | |
| 133 | + | ||
| 134 | + | Наилучшим способом доступа к аппаратуре в Linux является использование драйверов устройств, но, всвязи со сложностью создания драйвера, иногда может быть полезен быстрый способ. | |
| 135 | + | ||
| 136 | + | Для использования модуля "[[doc:rtl/ports|ports]]" в Linux, программа должна быть запущена от имени пользователя root и должен быть вызван IOPerm для установки разрешений для доступа к порту. Вы можете найти документацию по модулю "[[doc:rtl/ports|ports]]" [здесь](http://www.freepascal.org/docs-html/rtl/ports/index.html). | |
| 137 | + | ||
| 138 | + | Первое, что необходимо сделать, это соединиться с (g)libc и вызвать IOPerm. Модуль, позволяющий соединиться с (g)libc существует в free pascal, но этот модуль создает проблемы при использовании напрямую из приложения и статическом подключении библиотеки (g)libc. Это не очень хорошее решение, поскольку она часто изменяется от версии к версии несовместимым образом. Однако такие функции как ioperm, вряд ли будут изменяться. | |
| 139 | + | ||
| 140 | + | ``` pascal | |
| 141 | + | {$IFDEF Linux} | |
| 142 | + | function ioperm(from: Cardinal; num: Cardinal; turn_on: Integer): Integer; cdecl; external 'libc'; | |
| 143 | + | {$ENDIF} | |
| 144 | + | ``` | |
| 145 | + | ||
| 146 | + | - "from" обозначает первый порт, к которому будет осуществлен доступ. | |
| 147 | + | - "num" означает количество портов, идущих после первого, к которым будет осуществлен доступ; таким образом ioperm(\$220, 8, 1) разрешает доступ из программы ко всем портам в диапазоне от \$220 до \$227. | |
| 148 | + | ||
| 149 | + | После вызова IOPerm Вы можете использовать port\[\<Адрес\>\] для доступа к портам. | |
| 150 | + | ||
| 151 | + | ``` pascal | |
| 152 | + | {$IFDEF Linux} | |
| 153 | + | i := ioperm($220, 8, 1); | |
| 154 | + | port[$220] := $00; | |
| 155 | + | myLabel.Caption := 'ioperm: ' + IntToStr(i); | |
| 156 | + | i := Integer(port[$220]); | |
| 157 | + | myOtherLabel.Caption := 'response: ' + IntToStr(i); | |
| 158 | + | {$ENDIF} | |
| 159 | + | ``` | |
| 160 | + | ||
| 161 | + | Этот код был тестирован на собственном устройстве ISA на порте \$0220, используя Lazarus 0.9.10 на Mandriva Linux 2005 и Damn Small Linux 1.5 | |
| 162 | + | ||
| 163 | + | ### Общий аппаратный доступ в ОС UNIX | |
| 164 | + | ||
| 165 | + | ``` pascal | |
| 166 | + | {$IFDEF Unix} | |
| 167 | + | Uses Clib; // retrieve libc library name. | |
| 168 | + | {$ENDIF} | |
| 169 | + | ||
| 170 | + | {$IFDEF Unix} | |
| 171 | + | function ioperm(from: Cardinal; num: Cardinal; turn_on: Integer): Integer; cdecl; external clib; | |
| 172 | + | {$ENDIF} | |
| 173 | + | ``` | |
| 174 | + | ||
| 175 | + | **Замечание** FPC предоставляет абстракцию ioperm, названную "fpioperm" в [[doc:rtl/x86/index.html|модуле x86]], и также определяет функции out и inport. Эти функции в настоящее время реализованы для ОС Linux/x86 и FreeBSD/x86. | |
| 176 | + | ||
| 177 | + | Не рекомендуется подключение к libc кроме крайней необходимости всвязи с функциями развертывания и совместимости. Также, ручное подключение libc (объявляя специальные функции libc, доступные в других местах), как сделано выше не рекомендуется (например в ОС, где стандартная библиотека C назывется не libc, как, например, libroot в BeOS). | |
| 178 | + | ||
| 179 | + | **Замечание 2** Использование _модуля_ libc не рекомендуется ни при каких обстоятельствах, кроме как для совместимости с Kylix. Это вызвано тем, что модуль относительно непереносимый и должен быть модифицирован как можно меньше в связи с вопросам совместимости с Kylix. | |
| 180 | + | ||
| 181 | + | ## Последовательное соединение | |
| 182 | + | ||
| 183 | + | Раздел [[Hardware Access|Внешние ссылки]] содержит руководства по последовательным портам для UNIX и Windows. | |
| 184 | + | ||
| 185 | + | ## USB | |
| 186 | + | ||
| 187 | + | ### libusb | |
| 188 | + | ||
| 189 | + | Кросплатформенная реализация для Linux, BSDs и macOS: [libusb](http://libusb.sourceforge.net/). | |
| 190 | + | ||
| 191 | + | Заголовки перечислены на <http://www.freepascal.org/contrib/db.php3?category=Miscellaneous>: | |
| 192 | + | ||
| 193 | + | | название | автор | версия | дата | ссылка | отметки | | |
| 194 | + | |----|----|----|----|----|----| | |
| 195 | + | | libusb.pp | nowrap \| Uwe Zimmermann | 0.1.12 | nowrap \| 2006-06-29 | <http://www.sciencetronics.com/download/fpc_libusb.tgz> | | | |
| 196 | + | | libusb.pas | Johann Glaser | | nowrap \| 2005-01-14 | <http://www.johann-glaser.at/projects/libusb.pas> | | | |
| 197 | + | | fpcusb | Joe Jared | 0.11-14 | nowrap \| 2006-02-02 | <http://relays.osirusoft.com/fpcusb.tgz> | nowrap \| ссылка для загрузки не работает | | |
| 198 | + | ||
| 199 | + | ### FTDI | |
| 200 | + | ||
| 201 | + | Если вы используете микросехему от [FTDI](http://www.ftdichip.com/), Вы можете использовать паскалевские заголовки для их интерфейсной dll. | |
| 202 | + | ||
| 203 | + | ## Внешние ссылки | |
| 204 | + | ||
| 205 | + | Сравнение скорости коммуникационных протоколов: | |
| 206 | + | ||
| 207 | + | 1. <http://en.wikipedia.org/wiki/Serial_port#Speed> | |
| 208 | + | 2. <http://www.lvr.com/jansfaq.htm> - Jan Axelson's Parallel Port FAQ | |
| 209 | + | 3. <http://en.wikipedia.org/wiki/USB#Transfer_Speed> | |
| 210 | + | 4. <http://en.wikipedia.org/wiki/PCI#Conventional_PCI_bus_specifications> | |
| 211 | + | ||
| 212 | + | Ссылки по последовательному протоколу: | |
| 213 | + | ||
| 214 | + | 1. On UNIX: [1](http://www.easysw.com/~mike/serial/serial.html) | |
| 215 | + | 2. On Windows: <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp> | |
| 216 | + | 3. Synaser component: <http://synapse.ararat.cz/> | |
| 217 | + | 4. Comport Delphi package: <http://sourceforge.net/projects/comport/> | |
| 218 | + | ||
| 219 | + | Цифровой осцилоскоп ISA - Пример аппаратного доступа с исходными текстами: | |
| 220 | + | ||
| 221 | + | [2](http://eletronicalivre.incubadora.fapesp.br/portal/english/oscilloscope/) | |
| 222 | + | ||
| 223 | + | --- | |
| 224 | + | *From the Free Pascal wiki, page "Hardware Access/ru", as it stood on 2020-02-16 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
