Hardware Access/sk
│
Deutsch (de) │
English (en) │
español (es) │
français (fr) │
magyar (hu) │
日本語 (ja) │
한국어 (ko) │
polski (pl) │
português (pt) │
русский (ru) │
slovenčina (sk) │
中文(中国大陆) (zh_CN) │
O čom je článok
Táto stránka je začiatkom tutoriálu venovanom prístupe k hardwarovým zariadeniam v Lazare. Medzi tieto zariadenia patria (ale nie sú jediné): ISA, PCI, paralelný sériový port.
Platformovo nezávislý prístup k zariadeniam nie je implementovaný ani freepascalovskou RTL (Runtime Library) ani LCL, takže tento článok sa venuje metódam prístupu k hardvérovým zariadeniam na rozličných platformách. Zdrojový kód však môže byť pri používaní podmienenej kompilácie preložený na rozličných systémoch. Príklad podmienenej kompilácie:
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
{$IFDEF WIN32}
Windows;
{$ENDIF}
{$IFDEF Linux}
ports;
{$ENDIF}
Pomoc je vítaná, hlavne pre MacOS.
Používanie inpout32.dll na Windows
Windows používa rozličné spôsoby prístupu k hardvérovým zariadeniam na systémoch skupiny 9x a iný v skupine NT. Toto môže pôsobiť skutočne problematicky. Windows 9x (95, 98, Me) umožňujú programovať pristupovať na porty priamo, podobne ako to bolo v DOSe. Avšak Windows NT už toto vôbec nedovolí a k portom treba pristupovať cez ovládače zariadení. Je to bezpečnostný mechanizmus, ale môže byť dosť otravné, keď je ovládač zariadenia príliš komplexný pre malý projket, ktorý potrebuje pristupovať k paralelnému portu.
Našťastie existuje knižnica, ktorá v sebe nesie ovládače zariadení. Ak detekuje Windows z rodiny NT, dekomprimuje ovládač a nainštaluje pre jadro ovládač Hwinterface.sys. Keď zdetekuje Windows rodiny 9x, jednoducho použije na prístup k zariadeniam assembler.
A ako používať knižnicu? jednoducho! Pozná iba dve funkcie: Inp32 a Out32. Ich použitie je celkom intuitívne.
Knižnicu budeme načítavať dynamicky, takže najskôr potrebujeme definovať obe funkcie:
type
TInp32 = function(Address: ShortInt): ShortInt; stdcall;
TOut32 = procedure(Address: ShortInt; Data: ShortInt); stdcall;
- Address reprezentuje adresu portu, ku ktorému chcete pristupovať.
- Out32 odosiela dáta špecifikované v Data na port určený v Address.
- Inp32 vracia jeden bajt z portu, ktorý ste zadali.
Teraz môžeme načítať knižnicu. Môžete to implementovať napríklad v metóde OnCreate vášho hlavného formulára.
type
TMyForm = class(TForm)
.........
private
{ private declarations }
Inpout32: THandle;
Inp32: TInp32;
Out32: TOut32;
.........
implementation
.........
procedure TMyForm.FormCreate(Sender: TObject);
begin
{$IFDEF WIN32}
Inpout32 := LoadLibrary('inpout32.dll');
if (Inpout32 <> 0) then
begin
@Inp32 := GetProcAddress(Inpout32, 'Inp32');
if (@Inp32 = nil) then Caption := 'Error';
@Out32 := GetProcAddress(Inpout32, 'Out32');
if (@Out32 = nil) then Caption := 'Error';
end
else Caption := 'Error';
{$ENDIF}
end;
Ak ste knižnicu načítavali pri OnCreate, nezabudnite ju pri OnDestroy aj uvoľniť z pamäte:
procedure TMyForm.FormDestroy(Sender: TObject);
begin
{$IFDEF WIN32}
FreeLibrary(Inpout32);
{$ENDIF}
end;
Toto je jednoduchý príklad, ako používať funkciu Inp32:
{$IFDEF WIN32}
myLabel.Caption := IntToStr(Inp32($0220));
{$ENDIF}
Tento kód bol testovaný s vlastnou ISA kartou na porte $0220, Lazarom verzie 0.9.10 na Windows XP. Pre správny beh programu budete, samozrejme, potrebovať mať vo svojej uses klauzule uvedené "windows". Súbor "inpout.dll" by mal byť umiestnený v rovnakom adresári, ako vaša aplikácia.
Domovskú stránku knižnice nájdete tu: www.logix4u.net/inpout32.htm
Použitie ioperm na prístup k portom na Linuxe
Najlepší spôsob pristupovania k hardvéru na Linuxe vedie cez ovládače zariadení. Avšak, vďaka komplexnosti úloh spojených s vytváraním ovládača, bývajú rýchlejšie metódy občas veľmi užitočné.
Aby ste na LInuxe mohli používať unit "ports", váš program musí byť spustený s právami užívateľa root a pre nastavenie príslušných orpávnení prístupu k portom musí byť volaný IOPerm. Dokumentáciu vzťahujúcu sa k unitu "ports" môžete nájsť tu.
Prvá vec, ktorú musíte urobiť, je zlikovať váš program s glibc a zavolať IOPerm. Vo FreePascale existuje unit, ktorý dynamicky linkuje celé glibc; avšak sú s ním problémy, keď je používaný priamo aplikáciou. A linkovať staticky celú glibc knižnicu nie je veľmi dobrá myšlienka pre multiplatfomovú aplikáciu, pretože používanie platformovo špecifických riešení by malo byť minimálne.
{$IFDEF Linux}
function ioperm(from: Cardinal; num: Cardinal; turn_on: Integer): Integer; cdecl; external 'libc';
{$ENDIF}
- "from" repezentuje prvý port, ktorý sa má sprístupniť, "num" je počet
- portov, na ktoré sa ma pristupovať po prvom, takže ioperm($220, 8,
- 1) sprístupní pre náš program všetky porty od $220 do $227 (vrátane oboch).
Po sprístupnení OIPerm môžete na porty pristupovať cez port[<adresa>].
{$IFDEF Linux}
i := ioperm($220, 8, 1);
port[$220] := $00;
myLabel.Caption := 'ioperm: ' + IntToStr(i);
i := Integer(port[$220]);
myOtherLabel.Caption := 'response: ' + IntToStr(i);
{$ENDIF}
Tento kód bol testovaný s vlastnou ISA kartou na porte $0220, použijúc Lazarus 0.9.10 na systémoch Mandriva Linux 2005 a Damn Small Linux 1.5