Hardware Access/hu: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Hardware Access/hu
| Old | New | Line | |
|---|---|---|---|
| 1 | + | # Hardver hozzáférés | |
| 2 | + | ||
| 3 | + | ## Áttekintés | |
| 4 | + | ||
| 5 | + | Ezen az oldalon a hardverek Lazarus által megvalósítható eléréséről olvashatsz. Ezek az eszközök a következők: ISA, PCI, USB, párhuzamos port, soros port, stb. | |
| 6 | + | ||
| 7 | + | Egységes több-platformos elérés a hardver eszközökhöz nincs kidolgozva a Free Pascal Runtime Library-ban vagy az LCL-ben. Ezért ez az oldal megpróbálja összefoglalni a hardverek elérésének módjait különböző platformokon. A kód lefordítható különböző környezetekben a feltételes fordítási lehetőséget használva, így: | |
| 8 | + | ||
| 9 | + | ``` pascal | |
| 10 | + | uses | |
| 11 | + | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, | |
| 12 | + | {$IFDEF WIN32} | |
| 13 | + | Windows; | |
| 14 | + | {$ENDIF} | |
| 15 | + | {$IFDEF Unix} | |
| 16 | + | ports; | |
| 17 | + | {$ENDIF} | |
| 18 | + | ``` | |
| 19 | + | ||
| 20 | + | Jelenleg nem ismert hogy a macOS/x86 engedi-e a hardverek elérését. Mivel megakadályozhatja, ezért javaslom olyan driver-ek használatát mint az io.dll. | |
| 21 | + | ||
| 22 | + | ## Párhuzamos és Soros kommunikáció összehasonlítása | |
| 23 | + | ||
| 24 | + | Az ISA kártyák, a PCI kártyák és a Parallel Port a számítógéppel **párhuzamos** protokollal kommunikál. A Serial Port és az USB eszközök **soros** protokolt használnak. Mivel a processzor és így a programozási nyelvek is az adatok elérésének párhuzamos módját alkalmazzák, ezért e protokolok használata jóval egyszerűbb a szoftverekben. Amikor egy Integer típusú változót kezelsz, annak értékét egyetlen utasítással elérheted. A soros protokollal azonban egyszerre csak egy bitet szerezhetsz meg, és ezt követően össze kell fűznöd azokat hogy megismerd a tényleges adatot. | |
| 25 | + | ||
| 26 | + | A soros kommunikációt bonyolultabb kidolgozni, de viszonylag egyszerű ha egy előre elkészített komponenst használsz. A hardver oldalán is nehéz a megvalósítás, ezért sok hardver speciális integrált áramköröket vagy mikrokontrollereket tartalmaz erre a célra. | |
| 27 | + | ||
| 28 | + | Íme egy összefoglaló táblázat a hardver hozzáférési protokolokról: | |
| 29 | + | ||
| 30 | + | | | Sebesség | Hardver kialakítás nehézsége | | |
| 31 | + | |---------------|----------------------------|------------------------------| | |
| 32 | + | | Serial Port | Nagyon lassú (\< E5 bit/s) | Közepes | | |
| 33 | + | | Parallel Port | Lassú (~ E6 bit/s) | Könnyű | | |
| 34 | + | | ISA Card | Közepes (~ E7 bit/s) | Közepes | | |
| 35 | + | | USB | Közepes (~ E7 bit/s) | Nehéz | | |
| 36 | + | | PCI Card | Nagyon gyors (\> E9 bit/s) | Nagyon nehéz | | |
| 37 | + | ||
| 38 | + | ## Párhuzamos kommunikáció | |
| 39 | + | ||
| 40 | + | ### Az inpout32.dll használata Windows-on | |
| 41 | + | ||
| 42 | + | Windows 9x és NT kiadásaiban különböző módok léteznek a hardverek eléréséhez. A 9x sorozatban (95, 98, ME) a programok közvetlenül hozzáférhetnek a hardverekhez, mint a DOS esetén tehették. Az NT sorozatban (Windows NT és XP) azonban ez nem lehetséges. Ezeken a rendszereken minden kommunikációt a hardverekkel eszközmeghajtókkal kell megvalósítani. Ez biztonsági szempontból jó, de eszköz-meghajtó programokat fejleszteni sok idejébe és pénzébe kerülhet a kis vállalkozásoknak. | |
| 43 | + | ||
| 44 | + | Szerencsére van egy függvénytár ami megoldja ezt a problémát. Ha Windows NT rendszert érzékel kicsomagolja a HWInterface.sys kernel szintű eszközmeghajtót és telepíti azt. Ha Windows 9x rendszert érzékel akkor egyszerűen gépi kódú utasításokat használ a hardver eléréséhez. | |
| 45 | + | ||
| 46 | + | Hogyan használható a függvénytár? Egyszerűen! Csak két eljárás van: Inp32 és Out32, használatuk pedig magától értetődő. | |
| 47 | + | ||
| 48 | + | Dinamikusan lesz betöltve a függvénytár, ezért először definiálni kell mindkét funkciót: | |
| 49 | + | ||
| 50 | + | ``` pascal | |
| 51 | + | type | |
| 52 | + | TInp32 = function(Address: SmallInt): SmallInt; stdcall; | |
| 53 | + | TOut32 = procedure(Address: SmallInt; Data: SmallInt); stdcall; | |
| 54 | + | ``` | |
| 55 | + | ||
| 56 | + | - Address mutatja a port címét amit el akarsz érni | |
| 57 | + | - Out32 elküldi Data tartalmát az Address által mutatott portra | |
| 58 | + | - Inp32 kiolvas egy bájtot az Address által mutatott portról | |
| 59 | + | ||
| 60 | + | Most betöltheted a függvénytárat. Ezt megteheted ott ahol a programod főablakának OnCreate metódusát deklarálod: | |
| 61 | + | ||
| 62 | + | ``` pascal | |
| 63 | + | type | |
| 64 | + | TMyForm = class(TForm) | |
| 65 | + | ......... | |
| 66 | + | private | |
| 67 | + | { private declarations } | |
| 68 | + | Inpout32: THandle; | |
| 69 | + | Inp32: TInp32; | |
| 70 | + | Out32: TOut32; | |
| 71 | + | ......... | |
| 72 | + | implementation | |
| 73 | + | ......... | |
| 74 | + | procedure TMyForm.FormCreate(Sender: TObject); | |
| 75 | + | begin | |
| 76 | + | {$IFDEF WIN32} | |
| 77 | + | Inpout32 := LoadLibrary('inpout32.dll'); | |
| 78 | + | if (Inpout32 <> 0) then | |
| 79 | + | begin | |
| 80 | + | // needs overtyping, plain Delphi's @Inp32 = GetProc... leads to compile errors | |
| 81 | + | Inp32 := TInp32(GetProcAddress(Inpout32, 'Inp32')); | |
| 82 | + | if (@Inp32 = nil) then Caption := 'Error'; | |
| 83 | + | Out32 := TOut32(GetProcAddress(Inpout32, 'Out32')); | |
| 84 | + | if (@Out32 = nil) then Caption := 'Error'; | |
| 85 | + | end | |
| 86 | + | else Caption := 'Error'; | |
| 87 | + | {$ENDIF} | |
| 88 | + | end; | |
| 89 | + | ``` | |
| 90 | + | ||
| 91 | + | Ha a függvénytárat az OnCreate-ben töltöd be akkor ne felejtsd el befejezni a használatát az OnDestroy-ban: | |
| 92 | + | ||
| 93 | + | ``` pascal | |
| 94 | + | procedure TMyForm.FormDestroy(Sender: TObject); | |
| 95 | + | begin | |
| 96 | + | {$IFDEF WIN32} | |
| 97 | + | FreeLibrary(Inpout32); | |
| 98 | + | {$ENDIF} | |
| 99 | + | end; | |
| 100 | + | ``` | |
| 101 | + | ||
| 102 | + | Itt egy egyszerű példa az Inp32 funkció használatára: | |
| 103 | + | ||
| 104 | + | ``` pascal | |
| 105 | + | {$IFDEF WIN32} | |
| 106 | + | myLabel.Caption := IntToStr(Inp32($0220)); | |
| 107 | + | {$ENDIF} | |
| 108 | + | ``` | |
| 109 | + | ||
| 110 | + | Ez a kód egy ISA kártyával lett tesztelve a \$0220-as porton, Lazarus 0.9.10 használatával Windows XP rendszeren. Természetesen a Windows unit-nak a uses részben szerepelnie kell hogy futtthasd ezt a kódot. Használatához az "inpout32.dll" állományt ugyanabba a könyvtárba kell telepíteni ahol az alkalmazásod található. | |
| 111 | + | ||
| 112 | + | A függvénytár honlapja itt található: [www.logix4u.net/inpout32.htm](http://www.logix4u.net/inpout32.htm) *lásd: discussion* | |
| 113 | + | ||
| 114 | + | ### Assembler használata Windows 9x rendszeren | |
| 115 | + | ||
| 116 | + | Windows 9x rendszeren használhatsz assembler kódot is. Tegyük fel hogy a \$320-as portra a \$CC értéket akarod írni. A következő kód ezt teszi:: | |
| 117 | + | ||
| 118 | + | ``` pascal | |
| 119 | + | {$ASMMODE ATT} | |
| 120 | + | ... | |
| 121 | + | asm | |
| 122 | + | movl $0x320, %edx | |
| 123 | + | movb $0xCC, %al | |
| 124 | + | outb %al, %dx | |
| 125 | + | end ['EAX','EDX']; | |
| 126 | + | ``` | |
| 127 | + | ||
| 128 | + | ### Hibaelhárítás Windows-on | |
| 129 | + | ||
| 130 | + | Egy léehetséges hibaforrás hogy olyan párhuzamos hardvert használsz amely nem támogatja a "Plug And Play" rendszert Windows-on és így annak portjait a Windows egy másik eszközhöz kapcsolja. A következő hivatkozáson információkat találsz arról hogy miként utasíthatod a Windows-t arra hogy ne használja a hardvered portjait "Plug And Play" eszközökhöz: | |
| 131 | + | ||
| 132 | + | <http://support.microsoft.com/kb/135168> | |
| 133 | + | ||
| 134 | + | Folyamatban... | |
| 135 | + | ||
| 136 | + | ### Az IOPerm használata portok eléréséhez Linuxon | |
| 137 | + | ||
| 138 | + | A hardverek elérésének legjobb módja Linux-on az eszközmeghajtók használata, azonban a meghajtókészítés folyamatának bonyolultsága miatt néha egy gyorsabb megoldás kézenfekvőbb. Ahhoz hogy a "[[doc:rtl/ports|ports]]" unit-ot használhasd Linux-on a programodat rendszergazdaként kell futtatni, és az IOPerm segítségével a port eléréséhez megfelelő jogosultságokat kell beállítani.. A "[[doc:rtl/ports|ports]]" unit dokumentációját [itt](http://www.freepascal.org/docs-html/rtl/ports/index.html) találod. | |
| 139 | + | ||
| 140 | + | Az első teendő a Libc linkelése és azIOPerm meghívása. Van egy unit a free pascalban ami linkeli a meglévő (g) libc-t, azonban ez hibát okoz ha közvetlenül hívjuk meg az alkalmazásból és statikusan kerül felhasználásra, mivel a verziók közötti változások kompatibilitási problémákat okozhatnak. A függvények mint az ioperm valószínűleg nem változnak. | |
| 141 | + | ||
| 142 | + | ``` pascal | |
| 143 | + | {$IFDEF Linux} | |
| 144 | + | function ioperm(from: Cardinal; num: Cardinal; turn_on: Integer): Integer; cdecl; external 'libc'; | |
| 145 | + | {$ENDIF} | |
| 146 | + | ``` | |
| 147 | + | ||
| 148 | + | - "from" az első port amelyet el akarsz érni. | |
| 149 | + | - "num" a portok száma az elsőtől amelyeket el akarsz érni, az IOPerm(\$220, 8, 1) hozzáférést biztosít a program számára az összes porthoz beleértve a \$220 és \$227 portokat is. | |
| 150 | + | ||
| 151 | + | Az IOPerm meghívása után a port\[\<cím\>\] forma használható. | |
| 152 | + | ||
| 153 | + | ``` pascal | |
| 154 | + | {$IFDEF Linux} | |
| 155 | + | i := ioperm($220, 8, 1); | |
| 156 | + | port[$220] := $00; | |
| 157 | + | myLabel.Caption := 'ioperm: ' + IntToStr(i); | |
| 158 | + | i := Integer(port[$220]); | |
| 159 | + | myOtherLabel.Caption := 'response: ' + IntToStr(i); | |
| 160 | + | {$ENDIF} | |
| 161 | + | ``` | |
| 162 | + | ||
| 163 | + | Ez a kód egy általános ISA kártya \$0220-as portján lett kipróbálva, a Lazarus 0.9.10 változatával Mandriva Linux 2005 és Damn Small Linux 1.5 rendszereken. | |
| 164 | + | ||
| 165 | + | ### Általános UNIX Hardver Elérés | |
| 166 | + | ||
| 167 | + | ``` pascal | |
| 168 | + | {$IFDEF Unix} | |
| 169 | + | Uses Clib; // kinyeri a libc könyvtár nevét | |
| 170 | + | {$ENDIF} | |
| 171 | + | ||
| 172 | + | {$IFDEF Unix} | |
| 173 | + | function ioperm(from: Cardinal; num: Cardinal; turn_on: Integer): Integer; cdecl; external clib; | |
| 174 | + | {$ENDIF} | |
| 175 | + | ``` | |
| 176 | + | ||
| 177 | + | Az FPC egy absztrakt hívással az "fpioperm" -el éri el az ioperm-t ez a [[doc:rtl/x86/index.html|x86 unit]]-ban található, és szintén definiálja az fpIOPL-t és az out-/inport függvényeket. Ezek a függvények állnak rendelkezésre jelenleg a Linux/x86 és a FreeBSD/x86 rendszerben. | |
| 178 | + | ||
| 179 | + | Ennek a linkelése nem ajánlott a libc-hez csak ha a telepítés és a hordozhatóság megvalósítható. | |
| 180 | + | ||
| 181 | + | A libc kézi linkelése (pl a libc függvényeinek ad-hoc deklarásával amelyek valahol fellelhetőek) szintén kerülendő (illetve a libc import sor szükségszerűen hibát dob, mivel a standard C lib nem hívja meg a libc-t, továbbá pl. a libroot a BEos vagy más platformokon nem szabványos C szimbólumokat használ). Egyszóval kompatibilitási hibákat okoz. | |
| 182 | + | ||
| 183 | + | **Megjegyzés:** A libc unit használata semmilyen körülmények között nem ajánlott, kivétel a Kylix kompatibilitás. Lásd: [[libc unit]] | |
| 184 | + | ||
| 185 | + | ## Soros kommunikáció | |
| 186 | + | ||
| 187 | + | Soros kommunikációt végző szoftver építése nagyon egyszerű a [Synaser függvénytár](http://synapse.ararat.cz/doku.php) használatával. A példa együtt áttekintve a [Synaser dokumentációjával](http://synapse.ararat.cz/doc/help/synaser.html) könnyen érthető. A leglényegesebb rész a TBlockSerial.Config mellyel beállítható a sebesség (bitek száma másodpercenként), valamint az adat bitek, az ellenörző (parity) bitek, vezérlő (stop) bitek és kapcsolódási (handshake) protokol, ha van. A következő kód egy COM 1-re sorosan csatlakozó egérrel lett tesztelve. | |
| 188 | + | ||
| 189 | + | ``` pascal | |
| 190 | + | program comm; | |
| 191 | + | ||
| 192 | + | {$apptype console} | |
| 193 | + | ||
| 194 | + | uses | |
| 195 | + | Classes, SysUtils, Synaser; | |
| 196 | + | ||
| 197 | + | var | |
| 198 | + | ser: TBlockSerial; | |
| 199 | + | begin | |
| 200 | + | ser:=TBlockSerial.Create; | |
| 201 | + | try | |
| 202 | + | ser.Connect('COM1'); | |
| 203 | + | ser.config(1200, 7, 'N', SB1, False, False); | |
| 204 | + | while True do | |
| 205 | + | Write(IntToHex(ser.RecvByte(10000), 2), ' '); | |
| 206 | + | finally | |
| 207 | + | ser.free; | |
| 208 | + | end; | |
| 209 | + | end. | |
| 210 | + | ``` | |
| 211 | + | ||
| 212 | + | A következő kód a fentebbi példa egy másik változata. A fentebbi példa alapvetően hibásnak tűnik a "while true do..." ciklus használata miatt. A teszteléshez használt rendszeren (Asus A6T Laptop, Digitus USB-RS232 Adapterrel, Ubuntu 8.04.1), ez a rész a következő hibát okozta: Az alkalmazás munkamenetenként csak egyszer futott hibátlanul, amikor az alkalmazás újra lett indítva, már nem tudott csatlakozni a soros porthoz. Így a rendszer újraindítására volt szükség minden alkalommal amikor a felhasználó az alkalmazást újra használni akarta, ez pedig nagyon zavaró hiba. | |
| 213 | + | ||
| 214 | + | ``` pascal | |
| 215 | + | ||
| 216 | + | program serialtest; | |
| 217 | + | ||
| 218 | + | {$mode objfpc}{$H+} | |
| 219 | + | ||
| 220 | + | uses | |
| 221 | + | {$IFDEF UNIX}{$IFDEF UseCThreads} | |
| 222 | + | cthreads, | |
| 223 | + | {$ENDIF}{$ENDIF} | |
| 224 | + | Classes,SysUtils,Synaser,Crt | |
| 225 | + | { ez után jöhetnek a unit-ok }; | |
| 226 | + | ||
| 227 | + | var l:boolean; | |
| 228 | + | ||
| 229 | + | function check_affirmation():boolean; | |
| 230 | + | var k:string; | |
| 231 | + | begin | |
| 232 | + | Writeln('A kilépéshez NE használd a CTRL-C gombokat, inkább valamelyik másik gombbal állítsd le az alkalmazást! '+ | |
| 233 | + | 'Válassz a lehetőségek közül! '+ | |
| 234 | + | '[0]=Kilépés, [1]=Rendben, folytatás! '); | |
| 235 | + | Writeln('Választás: '); | |
| 236 | + | Read(k); | |
| 237 | + | if StrtoInt(k) = 1 then | |
| 238 | + | begin | |
| 239 | + | check_affirmation:=true; | |
| 240 | + | Writeln('OK, az alkalmazás tovább fut ...'); | |
| 241 | + | end | |
| 242 | + | else | |
| 243 | + | begin | |
| 244 | + | check_affirmation:=false; | |
| 245 | + | Writeln('Kilépés'); | |
| 246 | + | end | |
| 247 | + | end; | |
| 248 | + | ||
| 249 | + | procedure RS232_connect; | |
| 250 | + | var | |
| 251 | + | ser: TBlockSerial; | |
| 252 | + | begin | |
| 253 | + | ser:=TBlockSerial.Create; | |
| 254 | + | try | |
| 255 | + | ser.Connect('/dev/ttyUSB0'); //ComPort | |
| 256 | + | Sleep(1000); | |
| 257 | + | ser.config(1200, 7, 'N', SB1, False, False); | |
| 258 | + | Write('Eszköz: ' + ser.Device + ' Állapot: ' + ser.LastErrorDesc +' '+ | |
| 259 | + | Inttostr(ser.LastError)); | |
| 260 | + | Sleep(1000); | |
| 261 | + | repeat | |
| 262 | + | Write(IntToHex(ser.RecvByte(10000), 2), ' '); | |
| 263 | + | until keypressed; //Important!!! | |
| 264 | + | finally | |
| 265 | + | Writeln('A soros port fel lesz szabadítva...'); | |
| 266 | + | ser.free; | |
| 267 | + | Writeln('A soros port sikeresen fel lett szabadítva!'); | |
| 268 | + | end; | |
| 269 | + | end; | |
| 270 | + | ||
| 271 | + | begin | |
| 272 | + | l:=check_affirmation(); | |
| 273 | + | if l=true then | |
| 274 | + | RS232_connect() | |
| 275 | + | else | |
| 276 | + | Writeln('Kilépés a programból! '); | |
| 277 | + | end. | |
| 278 | + | ``` | |
| 279 | + | ||
| 280 | + | A [[Hardware Access/hu|külső hivatkozások]] részben UNIX és Windows soros port kezeléssel foglalkozó írások címei találhatók. | |
| 281 | + | ||
| 282 | + | ## USB | |
| 283 | + | ||
| 284 | + | ### libusb | |
| 285 | + | ||
| 286 | + | Egy keresztplatformos lehetőség Linux, BSD és macOS rendszerekhez a [libusb](http://libusb.sourceforge.net/). | |
| 287 | + | ||
| 288 | + | A fejlécek megtalálhatók a <http://www.freepascal.org/contrib/db.php3?category=Miscellaneous> címen: | |
| 289 | + | ||
| 290 | + | | név | szerző | változat | dátum | link | megjegyzés | | |
| 291 | + | |----|----|----|----|----|----| | |
| 292 | + | | libusb.pp | nowrap \| Uwe Zimmermann | 0.1.12 | nowrap \| 2006-06-29 | <http://www.sciencetronics.com/download/fpc_libusb.tgz> | | | |
| 293 | + | | libusb.pas | Johann Glaser | | nowrap \| 2005-01-14 | <http://www.johann-glaser.at/projects/libusb.pas> | | | |
| 294 | + | | fpcusb | Joe Jared | 0.11-14 | nowrap \| 2006-02-02 | <http://relays.osirusoft.com/fpcusb.tgz> | nowrap \| hibás letöltési cím | | |
| 295 | + | ||
| 296 | + | ### FTDI | |
| 297 | + | ||
| 298 | + | Az [FTDI](http://www.ftdichip.com/) chip-jeinek kezeléshez használhatod az általuk kiadott pascal fejléceket a dll függvénytáruk eljárásainak hívására. | |
| 299 | + | ||
| 300 | + | ## Külső hivatkozások | |
| 301 | + | ||
| 302 | + | Kommunikációs Protokolok sebességének összehasonlítása: | |
| 303 | + | ||
| 304 | + | 1. <http://en.wikipedia.org/wiki/Serial_port#Speed> | |
| 305 | + | 2. <http://www.lvr.com/jansfaq.htm> - Jan Axelson's Parallel Port FAQ | |
| 306 | + | 3. <http://en.wikipedia.org/wiki/USB#Transfer_Speed> | |
| 307 | + | 4. <http://en.wikipedia.org/wiki/PCI#Conventional_PCI_bus_specifications> | |
| 308 | + | ||
| 309 | + | Soros Kommunikációval kapcsolatos hivatkozások: | |
| 310 | + | ||
| 311 | + | 1. UNIX-on: [1](http://www.easysw.com/~mike/serial/serial.html) | |
| 312 | + | 2. Windows-on: <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp> | |
| 313 | + | 3. Synaser komponens: <http://synapse.ararat.cz/> | |
| 314 | + | 4. Comport Delphi csomag: <http://sourceforge.net/projects/comport/> | |
| 315 | + | ||
| 316 | + | ISA Digital Oscilloscope - Egy példa a hardverelérésre teljes forráskóddal: [<http://eletronicalivre.incubadora.fapesp.br/portal/english/oscilloscope/>](http://eletronicalivre.incubadora.fapesp.br/portal/english/oscilloscope/) | |
| 317 | + | ||
| 318 | + | --- | |
| 319 | + | *From the Free Pascal wiki, page "Hardware Access/hu", 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).* |
