Sign in Join
Wiki copytemporary

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

OldNewLine
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).*

Back to history