A Microchip TCP IP Stack implementációjának alkalmazása a … · 2014. 12. 25. · A Microchip...

61
A Microchip TCP/IP Stack implementációjának alkalmazása a gyakorlatban Ivanov Péter 2004. május 18.

Transcript of A Microchip TCP IP Stack implementációjának alkalmazása a … · 2014. 12. 25. · A Microchip...

  • A Microchip TCP/IP Stack implementációjánakalkalmazása a gyakorlatban

    Ivanov Péter

    2004. május 18.

  • i

    Tartalomjegyzék

    1. Bevezető 11.1. Köszönetnyilvánítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    2. Soros vonal 3

    3. A TCP/IP Stack felépítése 43.1. A Stack rétegei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

    4. User Datagram Protocol (UDP) 7

    5. A TCP/IP Stack konfigurálása 9

    6. A TCP/IP Stack moduljai 136.1. Address Resolution Protocol modul . . . . . . . . . . . . . . . . . . . 14

    6.1.1. ARP funkciók . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146.1.2. ARPTask funkciók . . . . . . . . . . . . . . . . . . . . . . . . . 16

    6.2. User Datagram Protocol (UDP) modul . . . . . . . . . . . . . . . . . . 176.3. Stack Manager modul . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.4. A soros-UDP átalakító modul . . . . . . . . . . . . . . . . . . . . . . . 276.5. HTTP szerver modul . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

    6.5.1. Dinamikus honlap generálás . . . . . . . . . . . . . . . . . . . 356.5.2. HTTP CGI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

    6.6. Microchip fájlrendszer (MPFS) . . . . . . . . . . . . . . . . . . . . . . 396.6.1. MPFS kép készítése . . . . . . . . . . . . . . . . . . . . . . . . . 406.6.2. MPFS könyvtár . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

    6.7. FTP szerver modul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416.7.1. MPFS kép feltöltése FTP kliens segítségével . . . . . . . . . . . 42

    7. Hardver 447.1. Alkatrészek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

    7.1.1. PIC18F452 mikrovezérlő . . . . . . . . . . . . . . . . . . . . . . 447.1.2. RTL8019AS ethernet vezérlő . . . . . . . . . . . . . . . . . . . 487.1.3. 24LC256 típusú soros EEPROM . . . . . . . . . . . . . . . . . . 487.1.4. MAX232A soros vonali illesztő . . . . . . . . . . . . . . . . . . 49

  • ii

    8. Az eszköz használata és tesztelése 508.1. Az eszköz használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508.2. Konfigurálás böngészőprogrammal . . . . . . . . . . . . . . . . . . . . 51

    8.2.1. Hálózat beállítása . . . . . . . . . . . . . . . . . . . . . . . . . . 518.2.2. Soros vonal beállítása . . . . . . . . . . . . . . . . . . . . . . . 538.2.3. Statisztika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

    8.3. Az eszköz tesztelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

  • iii

    Ábrák jegyzéke

    1.1. A rendszer blokkvázlata . . . . . . . . . . . . . . . . . . . . . . . . . . 1

    2.1. Egy bájt átvitele soros vonalon . . . . . . . . . . . . . . . . . . . . . . 3

    3.1. A TCP/IP referencia modell rétegei . . . . . . . . . . . . . . . . . . . . 43.2. A referencia modell és a Microchip TCP/IP Stack rétegei . . . . . . . . 5

    4.1. UDP csomag felépítése . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.2. Az elő-fejléc felépítése . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    6.1. A Stack Manager algoritmusának folyamatábrája . . . . . . . . . . . . 286.2. A Serial2UDP_GetSerialData függvény folyamatábrája . . . . . . . . 316.3. A Serial2UDP_ProcessUDPData függvény folyamatábrája . . . . . . 326.4. Űrlapok kezelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386.5. MPFS képfájl felépítése . . . . . . . . . . . . . . . . . . . . . . . . . . . 396.6. MPFS FAT bejegyzés felépítése . . . . . . . . . . . . . . . . . . . . . . 406.7. MPFS adatblokk felépítése . . . . . . . . . . . . . . . . . . . . . . . . . 406.8. MPFS képfájl feltöltése FTP kliens segítségével . . . . . . . . . . . . . 43

    7.1. Soros vonali illesztő és tápfeszültség stabilizátor kapcsolási rajza . . 457.2. A PIC18F452 típusú mikrovezérlő lábkiosztása . . . . . . . . . . . . . 467.3. A 24LC256 típusú soros EEPROM lábkiosztása . . . . . . . . . . . . . 497.4. A MAX232 típusú soros vonali illesztő lábkiosztása . . . . . . . . . . 49

    8.1. A doboz oldal- és elölnézete . . . . . . . . . . . . . . . . . . . . . . . . 508.2. Az eszköz használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518.3. Konfigurálás böngészőprogrammal: index . . . . . . . . . . . . . . . . 528.4. Hálózat beállítása böngészőprogrammal . . . . . . . . . . . . . . . . . 528.5. Soros vonal beállítása böngészőprogrammal . . . . . . . . . . . . . . 538.6. Statisztika megtekintése böngészőprogrammal . . . . . . . . . . . . . 548.7. Az eszköz tesztelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548.8. Az UDP test program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

  • iv

    Táblázatok jegyzéke

    5.1 Konfigurációs definíciók ill. változók . . . . . . . . . . . . . . . . . . . 12

    6.1 TCP/IP Stack moduljai . . . . . . . . . . . . . . . . . . . . . . . . . . . 146.2. A soros-UDP átalakító modul konfigurációs változói . . . . . . . . . 296.3. A soros-UDP átalakító modul belső változói . . . . . . . . . . . . . . 296.4. A soros-UDP modul átalakító állapotai . . . . . . . . . . . . . . . . . . 33

  • 1

    1. fejezet

    Bevezető

    Manapság az ethernet hálózat elterjedését láthatjuk a hétköznapi használatban ésaz iparban egyaránt. A csavart érpáros kábelek nagy távolságra vezethetők, olcsók,könnyen szerelhetők és az árnyékolatlan kábelek (UTP) is relatíve érzéketlenek azelektromos zavarokra, de ipari alkalmazásban általában árnyékolt kábeleket (STP)használnak.

    A most bemutatásra kerülő rendszerrel egyszerűen és gyorsan képessé tehetjükPIC mikrokontrolleres alkalmazásunkat, hogy kommunikáljon az intraneten vagyinterneten. E szakdolgozatban egy a valóságban is felhasználható alkalmazást mu-tatok be, hogyan illeszthetjük a soros vonalon kommunikáló régebbi fejlesztésűeszközünket ethernet hálózathoz. A rendszer leegyszerűsített blokkvázlata az 1.1.ábrán látható.

    1.1. ábra. A rendszer blokkvázlata

    A Microchip kifejlesztette a PIC18-as mikrokontroller családhoz a TCP/IP Stack-etés egy komplett web szervert. Fejlesztéseit szabadon hozzáférhetővé tette és letölt-hető az internetről. Ezeket a forráskódokat használtam fel.

    A programcsomaggal egy HTTP szervert építhetünk, aminek honlapját FTP-nfrissíthetjük. Szükség van egy PIC 18-as mikrovezérlőre, egy NIC-re (például Realtek8019AS). Kell még egy C fordító, a program lefordításához. Én a PIC C18 demó verzi-óját használtam. Érdemes letölteni az MPLAB legfrissebb verzióját. Ez egy integrált

  • 2

    fejlesztői környezet (IDE) amiben szerkeszthetjük a forrásfájlokat, lefordíthatjuk aprogramot és fel is tölthetjük a mikrovezérlőbe. Kell még egy PIC programozó is. Énaz ICD2 nevezetű programozó és nyomkövető eszközt használtam.

    A szögletes zárójelben levő számokkal mindig az irodalomjegyzékben szereplődokumentumokra hivatkozok.

    1.1. Köszönetnyilvánítás

    Ezúton szeretném megköszönni Dr. Kónya László tanár úrnak és KolingerAttilának a segítséget és a fejlesztéshez nélkülözhetetlen eszközöket.

  • 3

    2. fejezet

    Soros vonal

    Elsősorban az RS-232C szabványról lesz szó ebben a fejezetben. Ez az adatátviteliforma széles körben elterjedt és még most is nagyon sok eszköz használja az iparbanés a számítástechnikában ezt a módszert.

    Az RS232 hátrányai közé tartozik, hogy „aszimetrikus”, tehát közös a föld, ezértzaj érzékeny és csak kis távolságra vezethető. Nagyobb távolságok áthidalására azRS-422 ill. RS-485 szabványú adatátvitel használható.

    Az átvitel aszinkron, full duplex és a bájtok átvitele mindig egy start bit elküldé-sével kezdődik, ezt követi 5–9 darab adatbit végül egy, másfél vagy kettő stop bit. Akilencedik bit lehet paritás bit is vagy a cél eszköz megcímzésére használhatjuk. Akilencedik bitet alapesetben RS-232C kapcsolatnál címzésre használni nem lehet (delehet például az RS-422-nél és RS-485-nél).

    A legelterjedtebb a „8n1” típusú átvitel, ahol 8 adatbit egy stop bit küldéseill. fogadása lehetséges, paritás nélkül. Az általam elkészített program is ebben aformátumban kezeli az adatokat.

    Az adatátviteli sebesség 75, 150, . . . , 2400, 4800, 9600, 19200, 38400, 57600,. . . baud lehet. A baud az átvitt jel értékében történő változások száma egy má-sodperc alatt. Tehát a sebesség megadásánál a baud mértékegység nem egyezik mega bit/másodperccel, mert az utóbbiba nem értendő bele a start-, stop- és paritás bitekátvitele.

    Egy bájt (0xC8) átvitele látható a 2.1. ábrán (TTL szintűek a jelek).

    2.1. ábra. Egy bájt átvitele soros vonalon

  • 4

    3. fejezet

    A TCP/IP Stack felépítése

    Számos TCP/IP implementáció követi a „TCP/IP referencia modell” nevű szoft-ver architektúrát. Azok a programok, amik erre a modellre alapulnak több rétegrevannak osztva, ezek a rétegek egymásra épülnek1 és minden réteg egy vagy többalatta lévő réteggel kommunikál. A TCP/IP referencia modell a 3.1. ábrán látható.

    3.1. ábra. A TCP/IP referencia modell rétegei

    A TCP/IP rétegek „aktívak”, vagyis nem csak akkor működnek, ha kérés érkezikegy szolgáltatáshoz, hanem akkor is, időtúllépés történt vagy egy új csomag érkezett.

    Egy olyan rendszer, ahol sok adat- és programmemória áll rendelkezésre könnyenteljesíti a kéréseket. Egy multitaszkos operációs rendszer extra képességei lehetővéteszik, hogy az implementáció moduláris legyen. A program viszont bonyolult lesz,ha csak egy 8 bites mikrovezérlő áll rendelkezésre néhány száz bájt RAM-mal és kor-látozott programmemóriával. Továbbá, egy multitaszkos operációs rendszer nélkülsok időt kell arra fordítani a programozás során, hogy a Stack független maradjon afő alkalmazástól.

    Relatíve könnyű elkészíteni és helytakarékos az a TCP/IP Stack, amely bele vanintegrálva a fő alkalmazásba. De sok probléma léphet fel, amikor újabb funkciókatszeretnénk a programhoz hozzáadni.

    1Az egymásra épülést angolul a „stacked” szóval fejezik ki, ezért hívják TCP/IP Stack-nek.

  • 5

    Ez a TCP/IP Stack moduláris, C programozási nyelven íródott és a Microchip C18és a HiTech PICC 18 fordítókkal is lefordítható. A forrásfájl automatikusan eldönti,hogy milyen fordítóval szeretnénk fordítani. A két fordító közötti különbségekbőleredő problémákat a compiler.h fájlban levő definíciókkal küszöböljük ki. Ez aTCP/IP Stack csak PIC 18-as mikrovezérlőkön fut.

    3.1. A Stack rétegei

    A 3.2 ábrán is látható, hogy a Microchip TCP/IP Stack is különböző rétegekre vanosztva. A kód úgy lett megírva, hogy minden réteg külön forrásfájlban van, míg azAPI2 külön fejlécfájlban van.

    3.2. ábra. A TCP/IP referencia modell és a Microchip TCP/IP Stack rétegeinek össze-hasonlítása

    Ellentétben a referencia modellel, a Microchip TCP/IP Stack-ben egyes rétegeknem csak a közvetlenül alatta levő réteget érik el. A legnagyobb különbség a hagyo-mányos TCP/IP Stack implementációtól két új modul: StackTask és az ARPTask. AStackTask vezérli a Stack összes moduljának működését az ARPTask pedig az ARPréteg szolgáltatásait valósítja meg.

    Ez a Stack az általánosan ismert kooperatív multitaszk technikát alkalmazza,hogy független legyen a fő alkalmazástól. Egy kooperatív multitaszkos rendszer-ben több taszk működik, minden taszk végrehajt egy feladatrészt, majd a vezérléstvisszaadja és a következő taszk fut. Ebben az értelmezésben a StackTask és az ARP-Task egy-egy kooperatív taszk. A főprogramba vagy az operációs rendszerbe is lehetimplementálni a kooperatív – vagy más típusú – multitaszkot megvalósító kódot.

    A Stack úgy lett megtervezve, hogy független legyen bármilyen operációs rend-szertől, vagyis saját kooperatív multitaszk rendszere van. Ennek eredményekénthasználható bármilyen rendszerben függetlenül attól, hogy használ-e multitaszkosoperációs rendszert vagy sem. Azonban, ha a saját alkalmazásunk használja ezt a

    2Application Programming Interfaces, vagyis a felhasználói program interfész.

  • 6

    TCP/IP Stack-et, alkalmaznunk kell a kooperatív multitaszk technikát a saját taszk-jaink megírásakor. Ez elérhető úgy is, hogy a feladatot több taszkra osztjuk vagy afeladatot egy FSM-nek (Finite State Machine, Véges Állapotú Automata) továbbítjukami a feladatot sok kis részfeladatra bontja és egymás után futtatja le őket. A HTTPszerver az utóbbi megoldást használja.

    Jegyezzük meg, hogy ebben a TCP/IP Stack-ben nincs implementálva az összesolyan modul, ami egy átlagos TCP/IP Stack-ben implementálva van, de ha szük-ség van egy olyan funkcióra, ami nincs implementálva, bármikor megírható különtaszkként vagy modulként.

  • 7

    4. fejezet

    User Datagram Protocol (UDP)

    Az RFC 768-as [2] dokumentumban található az UDP protokoll leírása. Ez aprotokoll az Internet Protocol-ra (IP) épül. Előnye, hogy a programok nagyon egy-szerűen küldhetnek és fogadhatnak üzeneteket, de nincs garantálva, hogy az üzenetnem veszik el ill. nem duplázódik. Azok az alkalmazások amelyeknél adatfolyamokmegbízható továbbítására van szükség, a Transmission Control Protocol-t (TCP)használják.

    4.1. ábra. UDP csomag felépítése

    Az UDP csomagok felépítése a 4.1. ábrán látható.A forrás port opcionális mező, akkor érdemes használni, ha a csomagot küldő

    folyamat választ vár. Ha nincs használva, nullát kell a helyére írni.A cél port a cél címen belül egy folyamatot vagy programrészt jelent, de lehet más

    jelentése is.A hossz a csomag oktetjeinek számát mutatja meg, beleértve a fejlécet és az ada-

    tokat is. Tehát a legkisebb érték, amit felvehet: nyolc.Az ellenőrző összeg az IP fejlécből készült „elő-fejléc”, az UDP fejléc és az adat egyes

    komplemense 16 bitre kiegészítve. Azért hívják elő-fejlécnek, mert az IP fejlécbőlmásolódnak az adatok.

    Az elő-fejléc (4.2. ábra) az UDP fejléc előtt van és tartalmazza a forrás- és célcímet,protokoll típusát és az UDP csomag hosszát. Ez az információ véd az eltévedt cso-magok ellen. Az ellenőrző összeg számítása hasonlít a TCP-ben használt ellenőrzőösszeg számításhoz.

    Ha a kiszámított ellenőrző összeg nulla, akkor az összeg egyes komplemense leszelküldve (FFFFh). Ha az ellenőrző összegként nullát küld a forrás, az azt jelenti, hogy

  • 8

    4.2. ábra. Az elő-fejléc felépítése

    a küldő nem számolt összeget. Nyomkövetéskor alkalmazható vagy, ha a felsőbbszintű protokollok nem használják ezt az összeget. Ebben a TCP/IP Stack-ben azellenőrző összeg számítás nincs implementálva.

    Az UDP modulnak ismernie kell a forrás és cél internet címét és a protokolltípusát.

    Ezt a protokollt használják az internetes név szerverek (DNS) és Trivial FileTransfer Protocol (TFTP).

    Ha az Internet Protocol-on belül használjuk az UDP-t, akkor az a 17-es (oktálisan21) számú protokoll.

  • 9

    5. fejezet

    A TCP/IP Stack konfigurálása

    Ez a kooperatív multitaszk rendszer lehetővé teszi, hogy a felhasználói alkalma-zás saját taszkokat futtasson. Eközben a TCP/IP Stack-kel nem is kell foglalkoznia.Ehhez természetesen az kell, hogy a felhasználó úgy írja meg programját, hogy akooperatív multitaszkos rendszerben működjön. Az egyszerű konfigurálás érde-kében a program C definíciókat használ. A legtöbb paraméter engedélyezése, tiltásavagy beállítása a StackTsk.h fejléc fájlban lehetséges. Azok a paraméterek, amelyekmás fájlban találhatóak, azoknak zárójelben megadom a fájl nevét. Ha valamelyikparamétert változtattuk, a projektet – vagy egyes részeit – újra kell fordítani1.

    Azonosító Értékek Használ MegjegyzésCLOCK_FREQ (compiler.h) Órajel

    frekv.(Hz)

    Tick.c Definiálja a rendszer óra-jel frekvenciáját, hogyki lehessen számolni azidőzítő számláló értékét.

    TICKS_PER_SECONDS 10-255 Tick.c Egy másodperc hánytaktusból áll.

    TICK_PRESCALE_VALUE 2, 4, 8,16, 32, 64,128, 256

    Tick.c Időzítéshez milyen elő-osztó legyen beállítva.

    MPFS_USE_PGRM - MPFS.c Ha a programmemóriátakarjuk használni adat-tárolásra.

    MPFS_USE_EEPROM - MPFS.c Ha külső sorosEEPROM-ot akarunkadattárolásra használni.

    MPFS_RESERVE_BLOCK 0-255 MPFS.c Az MPFS fájlrendszerelőtt fenntartott bájtokszáma.

    EEPROM_CONTROL Külsőmem.kódja

    MPFS.c Hogy meg tudjuk cí-mezni a külső EEPROM-ot.

    1Az MPLAB fejlesztői környezet érzékeli a változtatásokat és kezeli a függőségeket, csak aztfordítja le, ami szükséges.

  • 10

    Azonosító Értékek Használ MegjegyzésSTACK_USE_ICMP - StackTsk.c Ha nincs szükség

    ICMP-re, ne definiáljuk.STACK_USE_SLIP - SLIP.c Ha nincs szükség SLIP-

    re ne definiáljuk.STACK_USE_IP_GLEANING - StackTsk.c Ha nincs szükség IP

    Gleaning-re ne definiál-juk.

    STACK_USE_DHCP - DHCP.c,StackTsk.c

    Ha nincs szükség DHCP-re ne definiáljuk.

    STACK_USE_FTP_SERVER - FTP.c Ha nincs szükség FTPszerverre ne definiáljuk.

    STACK_USE_TCP - TCP.c,StackTsk.c

    Ha nincs szükség TCP-re ne definiáljuk. Auto-matikusan engedélyezi,ha valamelyik modulnakszüksége van TCP-re.

    STACK_USE_UDP - UDP.c,StackTsk.c

    Ha nincs szükség UDP-re ne definiáljuk. Auto-matikusan engedélyezi,ha valamelyik modulnakszüksége van UDP-re.

    STACK_CLIENT_MODE - ARP.c,TCP.c

    Ha definiáljuk a kliensmódú függvények enge-délyeződnek.

    TCP_NO_WAIT_FOR_ACK - TCP.c A TCP várjon vagy ne azACK-re a következő cso-mag küldése előtt.

    MY_DEFAULT_IP_ADDR_BYTE? 0-255 felh. alk. Alap IP: 10.10.5.15MY_DEFAULT_MASK_BYTE? 0-255 felh. alk. Alap netmaszk:

    255.255.255.0MY_DEFAULT_GATE_BYTE? 0-255 felh. alk. Alap átjáró: 10.10.5.15MY_DEFAULT_MAC_BYTE? 0-255 felh. alk. Alap MAC:

    00:04:163:00:00:00MY_IP_BYTE? 0-255 felh. alk. Aktuális IP. Ha DHCP

    engedélyezett akkor aszerver által adott konfi-guráció.

    MY_MASK_BYTE? 0-255 felh. alk. Aktuális netmaszk.MY_GATE_BYTE? 0-255 felh. alk. Aktuális átjáró.MY_MAC_BYTE? 0-255 felh. alk. Aktuális MAC.

  • 11

    Azonosító Értékek Használ MegjegyzésMAX_SOCKETS 1-253 TCP.c Definiálja, hogy hány

    TCP socket használható(a RAM mennyiségétőlfügg). Fordítás köz-ben ellenőrzi, hogyelegendő-e a TCP mo-duloknak a megadottérték.

    MAX_UDP_SOCKETS 1-254 UDP.c Definiálja, hogy hányUDP socket használható(a RAM mennyiségétőlfügg). Fordítás köz-ben ellenőrzi, hogyelegendő-e a UDP mo-duloknak a megadottérték.

    MAC_TX_BUFFER_SIZE 201-1500 TCP.c,MAC.c

    Definiálja a küldő pufferméretét.

    MAX_TX_BUFFER_COUNT 1-255 MAC.c Definiálja a küldő puffe-rek számát.

    MAX_HTTP_CONNECTIONS 1-255 HTTP.c Definiálja az egyszerrefenntartható HTTP kap-csolatok számát.

    MPFS_WRITE_PAGE_SIZE

    (MPFS.h)1-255 MPFS.c Definiálja a lapméretet

    az MPFS fájlrendszer-hez.

    FTP_USER_NAME_LEN (FTP.h) 1-31 FTP.c Definiálja az FTP fel-használónév maximálishosszát.

    MAX_HTTP_ARGS (HTTP.c) 1-31 HTTP.c Definiálja az űrlapok me-zőinek maximális szá-mát, beleértve a mező ne-vét is.

    MAX_HTML_CMD_LEN (HTTP.c) 1-128 HTTP.c Definiálja az űrlappal át-adható sztring maximá-lis hosszát.

    STACK_USE_SER2UDP - ser2udp.c Ha nincs szükség asoros-UDP átalakító mo-dulra ne definiáljuk.

    TARGET_DEFAULT_

    IP_ADDR_BYTE? (ser2udp.h0-255 ser2udp.c Alap cél IP cím: 10.10.5.5.

    DEFAULT_TARGET_PORT

    (ser2udp.h1-65535 ser2udp.c Alap cél port: 2222.

  • 12

    Azonosító Értékek Használ MegjegyzésDEFAULT_LOCAL_PORT

    (ser2udp.h1-65535 ser2udp.c Alap forrás port: 2221.

    INITWAIT_SEC (ser2udp.h 0-42949672

    ser2udp.c ARP kérés előtti várako-zás ideje másodpercben.Alap: 4.

    TIMEOUT_SEC (ser2udp.h 0-42949672

    ser2udp.c ARP kérés után hánymásodpercig vár a vá-laszra. Alap: 4.

    SER2UDP_USE_INTERRUPT

    (ser2udp.h- ser2udp.c A soros adatok vételé-

    hez használjon-e meg-szakítást a modul.

    5.1. táblázat: Konfigurációs definíciók ill. változók

    A fejlesztés során egy projektet érdemes használni. Projekt fájlból is van előreelkészített a programcsomagban. Én az MPNICEE.pjt fájlt használtam. Ezt a fájltakkor érdemes használni, ha a Microchip C18 fordítót Realtek NIC-et és külső sorosEEPROM-ot használunk, továbbá szükségünk van HTTP, FTP szerverre és ICMP-re.Ugyanis ezeket tudja alapból az a program, amit ezzel a projekt fájllal fordítunk.Fontos megjegyezni, hogy a projekt fájlokban is lehet definíciókat megadni.

  • 13

    6. fejezet

    A TCP/IP Stack moduljai

    A moduláris felépítés miatt könnyen beállíthajuk, hogy milyen szolgáltatásokravan szükségünk. Egy modul letiltása csak annyiból áll, hogy a megfelelő definíció eléegy megjegyzés jelet teszünk és a forrásfájlokat eltávolítjuk a projektből. A TCP/IPStack moduljainak rövid áttekintése:

    Modul Fájl szükséges LeírásMAC MAC.c, Delay.c Közeghozzáférési rétegSLIP SLIP.c Közeghozzáférési réteg SLIP-

    hezARP ARP.c, ARPTsk.c, MAC.c

    vagy SLIP.c, Helpers.cAddress Resolution Protocol

    IP IP.c, MAC.c vagy SLIP.c,Helpers.c

    Internet Protocol

    ICMP ICMP.c, StackTsk.c,IP.c, MAC.c vagy SLIP.c,Helpers.c

    Internet Control Message Pro-tocol

    TCP StackTsk.c, TCP.c IP.c,MAC.c vagy SLIP.c,Helpers.c, Tick.c

    Transmission Control Protocol

    UDP StackTsk.c, UDP.c, IP.c,MAC.c vagy SLIP.c,Helpers.c

    User Datagram Protocol

    Stack Manager StackTsk.c, TCP.c, IP.c,ICMP.c, ARPTsk.c, ARP.c,

    MAC.c vagy SLIP.c, Tick.c,Helpers.c

    Stack Manager (StackTask), amivezérli a TCP/IP Stack modul-jait.

    HTTP Server HTTP.c, TCP.c, IP.c,MAC.c vagy SLIP.c,Helpers.c, Tick.c,

    MPFS.c, XEEPROM.c

    HyperText Transfer Protocolszerver

    DHCP Client DHCP.c, UDP.c, IP.c,MAC.c, Helpers.c, Tick.c

    Dynamic Host ConfigurationProtocol

  • 14

    Modul Fájl szükséges LeírásIP Gleaning StackTsk.c, ARP.c,

    ARPTsk.c, ICMP.c, MAC.c

    vagy SLIP.c

    IP cím konfiguráláshoz

    FTP Server FTP.c, TCP.c, IP.c,MAC.c vagy SLIP.c

    File Transfer Protocol szerver

    Serial2UDP ARP.c, UDP.c, MAC.c vagySLIP.c

    Soros-UDP átalakító

    6.1. táblázat: TCP/IP Stack moduljai

    Most a soros-UDP átalakító modul által használt modulok részletes leírása kö-vetkezik. Az itt nem tárgyalt modulok (MAC, SLIP, IP, ICMP, TCP, DHCP) angolnyelvű leírása az AN833-as [1] dokumentumban található.

    6.1. Address Resolution Protocol modul

    Az ARP modul gondoskodik arról, hogy az IP címekből megtudjuk, hogy milyenhardveres cím (MAC cím) tartozik hozzá és hogy más eszközök az IP címünkettudva, megkapják a MAC címünket.

    Az Microchip TCP/IP Stack-jének ARP rétege két modulból áll: ARP.c és ARP-Task.c. Az ARP modulban (ARP.c) az ARP alapvető függvényeit definiálja. Az ARP-Task – ami az ARPTsk.c fájlban található – ezeket a függvényeket felhasználva va-lósítja meg az ARP szolgáltatást. Az ARPTask válaszol az ARP kérésekre és egyegyszintű tárban tárolja a más hosztok ARP válaszát. Az ARPTask modulban nincsmegvalósítva az időtúllépés kezelése, ezt a felsőbb szintű modulokban kell megol-dani.

    Az ARPTask kétféle módban működhet: szerver illetve szerver/kliens. A szer-ver/kliens módban lehetséges ARP kérések generálása. Szerver módban ez a kódrésznincs befordítva. Általában az alkalmazások szerver módban futnak és érdemes isszerver módba fordítani, a kód méretének csökkentése érdekében. Továbbá szervermódban nem kerül lefoglalásra az egyszintű tár és ezzel RAM területet takaríthatunkmeg. Ha a STACK_CLIENT_MODE definiálva van szerver/kliens módban fog működniaz ARPTask modul. A soros-UDP konverter szerver/kliens módban használja azARP modult.

    6.1.1. ARP funkciók

    ARPIsTxReady

    Ez egy makró ami megállapítja, hogy adatok küldése lehetséges-e.Szintaxis: ARPIsTXReady()Paraméter: NincsVisszatérési érték: IGAZ: Ha legalább egy küldő puffer üres. HAMIS: Nincs üresküldő puffer.Előfeltétel: Nincs

  • 15

    Mellékhatás: NincsMegjegyzés: Ez csak egy makródefiníció a MACIsTxReady függvényre.Példa:

    // Ha a küldő puffer üres, elküldünk egy ARP csomagot

    if ( ARPIsTxReady() )

    {

    // ARP csomag küldése

    ARPPut(&RemoteNode, ARP_REPLY);

    }

    ARPGet

    Ez a funkció beolvas egy ARP csomagot és visszatéréskor megadja a szükségesinformációkat a csomagról.Szintaxis: BOOL ARPGet(NODE_INFO *remote, BYTE *opCode)Paraméter: remote [kimenő] A távoli eszközhöz tartozó információk, a MAC és az IPcím.opCode [kimenő] ARP kód. A paraméter lehetséges értékei a következők:ARP_REPLY Egy ARP válasz csomag érkezettARP_REQUEST Egy ARP kérés csomag érkezettARP_UNKNOWN Egy ismeretlen ARP csomag érkezett

    Visszatérési érték: IGAZ: Ha egy érvényes ARP csomag érkezett és az a mi eszkö-zünknek van címezve. HAMIS: Ha ismeretlen ARP kódja van a csomagnak vagynem nekünk van címezve a csomag.Előfeltétel: MACGetHeader már meg volt hívva és a kapott MAC csomag típusaMAC_ARP

    Mellékhatás: NincsMegjegyzés: Ez a funkció azt feltételezi, hogy az aktív pufferben van egy ARP cso-mag és a hozzáférési mutató az ARP csomag elejére mutat. Általában a magasabbszintű rétegek ellenőrzik a MAC puffert és csak akkor hívják ezt a függvényt, ha ARPcsomagot érzékeltek. Ez a funkció beolvassa az egész ARP csomagot és felszabadítjaaz aktív puffert.Példa:

    // Ha MAC csomag érkezett...

    if ( MACGetHeader(\&RemoteNode, \&PacketType) )

    \{

    // Ha ez egy ARP csomag, beolvassuk

    if ( PacketType == MAC\_ARP )

    \{

    // Ez egy ARP csomag

    ARPGet(\&RemoteNode, \&ARPCode);

    ...

  • 16

    ARPPut

    Ez a funkció feltölti a MAC puffert egy érvényes ARP csomaggal.Szintaxis: void ARPPut(NODE_INFO *remote, BYTE opCode)Paraméter: remote [bemenő] A távoli eszköz adatai, mint a MAC és az IP címopCode [bemenő] ARP kód. Lehetséges értékei a következők:ARP_REPLY ARP válaszként küldi el a csomagotARP_REQUEST ARP kérésként küldi el a csomagot

    Visszatérési érték: NincsElőfeltétel: ARPIsTxReady == TRUEMellékhatás: NincsMegjegyzés: Felépíti az ARP csomagot és elküldi.Példa:

    // Megnézzük, hogy küldő puffer elérhető-e

    if ( ARPIsTxReady() )

    {

    // Igen, elküldjük

    ARPPut(&RemoteNode, ARP_REQUEST);

    ...

    }

    6.1.2. ARPTask funkciók

    ARPInit

    Ez a funkció inicializálja az ARPTask modult és előkészíti az ARP kérések küldé-sére és megválaszolására.Szintaxis: void ARPInit()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: NincsMellékhatás: NincsMegjegyzés: Szerver/kliens módban ez a funkció inicializálja az egyszintű tárolót.Példa:

    // Initialize ARPTask

    ARPInit();

    ...

    ARPResolve

    Ez a funkció egy ARP kérést küld egy távoli eszköznek.Szintaxis: void ARPResolve(IP_ADDR *IPAddr)Paraméter: IPAddr [bemenő] A távoli eszköz IP címe, aminek a MAC címét szeret-nénk tudni.Visszatérési érték: NincsElőfeltétel: ARPIsTxReady == TRUE

  • 17

    Mellékhatás: NincsMegjegyzés: Ez a funkció csak szerver/kliens módban elérhető.Példa:

    // Ellenőrizzük, hogy a küldő puffer elérhető-e

    if ( ARPIsTxReady() )

    {

    // ARP kérés küldése

    ARPResolve(\&RemoteNodeIP);

    ...

    }

    ARPIsResolved

    Ez a funkció ellenőrzi a belső tárolót és visszatérési értékként megadja a cél hosztMAC címét.Szintaxis: BOOL ARPIsResolved(IP_ADDR *IPAddr, MAC_ADDR *MACAddr)Paraméter: IPAddr [bemenő] A távoli eszköz IP címe, aminek a MAC címét szeret-nénk tudni.MACAddr [kimenő] A puffer ami a távoli hoszt MAC címét fogja tárolni.Visszatérési érték: IGAZ: Ha egyező IP cím van a belső tárolóban és az átmásolódotta MACAddr változóba. HAMIS: Ha nincs egyező IP cím a belső tárolóban. Ilyenkora MACAddr értéke nem változik.Előfeltétel: NincsMellékhatás: A belső tárolóból az átmásolt adatok eltávolításra kerülnek.Megjegyzés: Az ARPTask csak egyszintű tárolóval dolgozik, ezért a felsőbb réteg-nek kell arról gondoskodnia, hogy másik ARP kérést ne küldjön, míg az előzőre nemérkezett válasz. Ez a funkció csak szerver/kliens módban elérhető.Példa:

    // Ellenőrizzük, hogy érkezett-e válasz

    if ( ARPIsResolved(&RemoteIPAddr, &RemoteMACAddr) )

    {

    // MAC cím megvan. Más feladat következhet...

    ...

    }

    else

    {

    // Még nincs meg a MAC. Várunk...

    ...

    }

    6.2. User Datagram Protocol (UDP) modul

    Az UDP réteg az UDP.c fájlban van implementálva. A fejléc fájlban (UDP.h) van-nak definiálva a réteg szolgáltatásai. Ebben a Stack architektúrában az UDP egy aktív

  • 18

    réteg. Veszi az UDP csomagot és a megfelelő UDP socket-et értesíti az adat érkezé-séről. Az UDP modul kooperatív taszkként van implementálva és automatikusanműködik a fő alkalmazástól függetlenül.

    A réteg legfeljebb 254 UDP socket-et használhat. Ez az érték csak az elérhetőmemóriától és a fordítótól függ. Több socket használatával több szimultán UDPkapcsolat használható. Fontos megjegyezni, hogy minden socket körülbelül 19 bytememóriát használ (érdemes ellenőrizni az UDP.h fájlt) és minden socket növeli azUDP csomagok feldolgozásának idejét.

    Ellentétben a többi socket implementációtól, a Microchip TCP/IP Stack-ben min-den socket egy küldő puffert használ. Ez csökkenti a RAM szükségletet, de problémátokozhat, ha néhány socket nem szabadítja fel a küldő puffert. Ebben az esetben atávoli hosztok és/vagy helyi alkalmazások nem tudnak kapcsolatba lépni az eszköz-zel. Ennek elkerülése érdekében a felhasználónak gondoskodnia kell arról, hogy azösszes socket számára elegendően nagy puffer álljon rendelkezésre. A vételi oldalonis csak egy puffer van, ezért ha adatot olvasunk, az összes adatot be kell olvasni egytaszkban és üríteni a puffert, hogy a többi socket is tudja olvasni az adatát. Nem lehetazt tenni, hogy a taszk csak a puffer egy részét olvassa be és majd egy következőhívás esetén dolgozza fel a maradékot.

    A Microchip TCP/IP Stack-ben nincs implementálva az UDP ellenőrző összegképzés. Az ellenőrző összeg helyére mindig nulla érték kerül. Ezért minden UDP-thasználó modulnak magának kell gondoskodnia az adatok integritásáról.

    UDPInit

    Ez a funkció inicializálja az UDP modult és előkészíti a többszálú UDP kapcso-latokra.Szintaxis: void UDPInit()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: NincsMellékhatás: NincsMegjegyzés: Ezt a függvényt csak egyszer kell meghívni.Példa:

    // Initialize UDP

    UDPInit();

    ...

    UDPOpen

    Ez a funkció előkészíti egy UDP socket-et, hogy a megadott porton adatokattudjon továbbítani.Szintaxis: UDP_SOCKET UDPOpen(UDP_PORT localPort, NODE_INFO *remoteNode,TCP_PORT remotePort)

    Paraméter: localPort [bemenő] A helyi UDP port, ahonnan az adat jön.remoteNode [bemenő] A távoli hoszt, ahova az adatokat küldjük.remotePort [bemenő] A távoli hoszt egy UDP portja, ahova az adatokat küldjük.

  • 19

    Visszatérési érték: Egy érvényes socket azonosító, ha volt szabad socket vagyINVALID_UDP_SOCKET, ha nem volt szabad socket.Előfeltétel: NincsMellékhatás: NincsMegjegyzés: Ez a funkció egyszerre használható helyi ill. távoli kezdeményezésűadattovábbításra. Nincs konkrét kapcsolódási séma az UDP-ben. Ha egy UDP socket-et megnyitottak, akkor az kész az adatok küldésére és fogadására is, egészen addig,amíg be nem zárják a socket-et.Példa:

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    // Egy DHCP üzenet elküldése

    break;

    ...

    UDPClose

    Bezártja a megadott UDP socket-et és szabadnak jelöli.Szintaxis: void UDPClose(UDP_SOCKET socket)Paraméter: socket [bemenő] A bezárandó socket azonosítója.Visszatérési érték: NincsElőfeltétel: NincsMellékhatás: NincsMegjegyzés: Ezt a függvényt csak egyszer kell meghívni.Példa:

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

  • 20

    {

    // Egy DHCP üzenet elküldése

    ...

    // Socket bezárása

    UDPClose (DHCPSocket);

    }

    break;

    ...

    UDPIsPutReady

    Ez a makró állapítja meg, hogy a megadott socket kész-e az adatok küldésére.A socket akkor kész adatküldésre, ha legalább egy MAC küldő puffer üres. Amikorezt a makrót meghívjuk, automatikusan aktív socket-té válik.Szintaxis: BOOL UDPIsPutReady(UDP_SOCKET socket)Paraméter: socket [bemenő] Az ellenőrizendő socket azonosítója.Visszatérési érték: IGAZ: Ha a megadott socket kész az adatok küldésére. HAMIS:Ha nincs szabad küldő puffer.Előfeltétel: NincsMellékhatás: NincsMegjegyzés: Egy socket mindig kész az adatküldésre, amíg van üres MAC küldőpuffer. Amikor ellenőrizzük a socket-et, az aktívvá válik és a többi UDP funkció isműködőképes lesz: UDPGet, UDPFlush és UDPDiscard.Példa:

    ...

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    {

    // Egy DHCP üzenet elküldése

    smState = SM_BROADCAST;

    break;

    }

    case SM_BROADCAST:

    if ( UDPIsPutReady(DHCPSocket) )

    {

    // A socket kész az adatküldésre...

    ...

  • 21

    }

    break;

    ...

    UDPPut

    Az aktív socket küldő pufferébe egy bájt adatot helyez.Szintaxis: BOOL UDPPut(BYTE byte)Paraméter: byte [bemenő] Az adat, amit a küldő pufferbe akarunk tenni.Visszatérési érték: IGAZ: Ha a megadott adatot sikerült a pufferbe tölteni és mégvan hely több adatnak. HAMIS: Ha az adatot sikerült a pufferbe tölteni, de nincshely több adatnak.Előfeltétel: UDPIsPutReady == TRUEMellékhatás: NincsMegjegyzés: Ha egy socket küldésre kész, akkor összes adatot be kell töltenünkvagy addig tölthetjük fel amíg teljesen tele nem lesz a socket puffere. A felhasználónem töltheti az adat egyik felét egy socket-be a másik felét egy másik socket-be.Fontos megjegyezni, hogy amikor betöltjük az adatokat, akkor az adatok küldésenem történik meg. Kivéve akkor, ha a puffer megtelik, ekkor a funkció automatikusanelkezdi az adatok küldését és HAMIS értékkel tér vissza. A felhasználói programkésőbb próbálhat adatot betölteni. Ha az elküldendő adat kevesebb, mint a küldőpuffer, a felhasználói programnak kell kezdeményezni a puffer ürítését az UDPFlushfunkció hívásával. Általában, érdemes a puffert üríteni, ha egy egységnyi adatotbetöltöttünk a pufferbe, attól függetlenül, hogy a puffer még nincs tele.Példa:

    ...

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    {

    // Egy DHCP üzenet elküldése

    smState = SM_BROADCAST;

    break;

    }

    case SM_BROADCAST:

    if ( UDPIsPutReady(DHCPSocket) )

    {

    // A socket kész az adatküldésre...

  • 22

    // Az UDPPut közvetlenül nem kapja meg az DHCPSocket paramétert

    // Az UDPPut az aktív socket-et használja,

    // amit az UDPIsPutReady() állít be, ez a DHCPSocket.

    UDPPut(0x55);

    ...

    }

    break;

    ...

    UDPFlush

    Az aktív socket küldő puffert küldésre késznek állítja be.Szintaxis: void UDPFlush()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: Az UDPPut() függvény már meg volt hívva és a socket aktív, vagyis márfuttattuk a UDPIsPutReady() függvényt.Mellékhatás: NincsMegjegyzés: Ez a funkció küldésre késznek állítja a küldő puffert, de a küldés nemindul el egyből. A felhasználónak nem kell ellenőriznie a küldési folyamat állapotát.A NIC 15-ször próbálja meg a elküldeni az adatot (legalábbis a RTL8019AS, más NICesetén a NIC adatlapjában található ez az információ). Ha a socket puffer egyszermár ürítve volt és üres, a további UDPFlush hívásokat a program figyelmen kívülhagyja.Példa:

    ...

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    {

    // Egy DHCP üzenet elküldése

    smState = SM_BROADCAST;

    break;

    }

    case SM_BROADCAST:

    if ( UDPIsPutReady(DHCPSocket) )

    {

    // A socket kész az adatküldésre...

  • 23

    // Az UDPPut közvetlenül nem kapja meg az DHCPSocket

    // paramétert. Az UDPPut az aktív socket-et használja,

    // amit az UDPIsPutReady() állít be, ez a DHCPSocket.

    UDPPut(0x55);

    ...

    // Most elküldjük

    UDPFlush();

    }

    break;

    ...

    UDPIsGetReady

    Ez a funkció megállapítja, hogy a megadott socket tartalmaz-e vett adatokat és asocket-et aktívnak jelöli ki.Szintaxis: BOOL UDPIsGetReady(UDP_SOCKET socket)Paraméter: socket [bemenő] A socket azonosítójaVisszatérési érték: IGAZ: Ha a megadott socket tartalmaz vett adatokat. HAMIS:Ha a megadott socket nem tartalmaz vett adatokat.Előfeltétel: Az UDPOpen() függvény már meg volt hívva.Mellékhatás: NincsMegjegyzés: NincsPélda:

    ...

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    // A DHCP szervertől választ várunk

    smState = SM_WAIT_FOR_DATA;

    break;

    case SM_WAIT_FOR_DATA:

    if ( UDPIsGetReady(DHCPSocket) )

    {

    // Adatokat olvashatók a socket-ből. Kiolvassuk és

    // feldolgozzuk...

    ...

    }

    break;

  • 24

    ...

    UDPGet

    Az aktív socket vételi pufferéből egy bájt adatot olvas ki.Szintaxis: BOOL UDPGet(BYTE *byte)Paraméter: byte [kimenő] A beolvasott adatbájt.Visszatérési érték: IGAZ: Ha sikerült egy bájtot beolvasni. HAMIS: Ha nem sikerültaz adat beolvasása.Előfeltétel: UDPIsGetReady == TRUEMellékhatás: NincsMegjegyzés: Ha a socket-ben adatok vannak, a felhasználói programnak be kellolvasnia egy vagy több bájtot egy taszk ideje alatt és a socket puffert felszabadítani.Más socket-ből adatot kiolvasni addig nem szabad, amíg az előző puffer nem lettfelszabadítva.Példa:

    ...

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    // A DHCP szervertől választ várunk

    smState = SM_WAIT_FOR_DATA;

    break;

    case SM_WAIT_FOR_DATA:

    if ( UDPIsGetReady(DHCPSocket) )

    {

    // Adatokat olvashatók a socket-ből. Kiolvassuk és

    // feldolgozzuk...

    // A buffer egy BYTE mutató

    while( UDPGet(buffer) )

    buffer++;

    // Feldolgozzuk...

    ...

    // Socket puffer ürítése

    ...

    }

    break;

    ...

  • 25

    UDPDiscard

    Az aktív socket vételi pufferét felszabadítja.Szintaxis: BOOL UDPDiscard()Paraméter: NincsVisszatérési érték: IGAZ: Ha a vételi puffert sikerült felszabadítani. HAMIS: Ha avételi puffer egyszer már fel lett szabadítva.Előfeltétel: NincsMellékhatás: NincsMegjegyzés: NincsPélda:

    ...

    switch(smState)

    {

    case SM_OPEN:

    // Megpróbálunk egy DHCP szerverhez kapcsolódni

    DHCPSocket = UDPOpen(68, &DHCPServerNode, 67);

    if ( DHCPSocket == INVALID_UDP_SOCKET )

    {

    // Nincs szabad socket

    // Hiba kiírása

    }

    else

    // A DHCP szervertől választ várunk

    smState = SM_WAIT_FOR_DATA;

    break;

    case SM_WAIT_FOR_DATA:

    if ( UDPIsGetReady(DHCPSocket) )

    {

    // Adatokat olvashatók a socket-ből. Kiolvassuk és

    // feldolgozzuk...

    // A buffer egy BYTE mutató

    while( UDPGet(buffer) )

    buffer++;

    // Feldolgozzuk...

    ...

    // Socket puffer ürítése

    UDPDiscard();

    }

    break;

    ...

    UDPProcess

    Ez a funkció egy taszkként működik. Egy beérkezett UDP csomagról megálla-pítja, hogy melyik UDP socket-hez tartozik. Ezt a funkciót csak akkor kell meghívni,

  • 26

    ha egy UDP csomag érkezett.Szintaxis: BOOL UDPProcess(NODE_INFO *remote, WORD len)Paraméter: remote [bemenő] A távoli eszköz adatai, ahonnan az UDP csomag érke-zettlen [bemenő] Az UDP csomag teljes hossza a fejlécet is beleszámítvaVisszatérési érték: IGAZ: Ha a taszknak sikerült teljesen feldolgoznia a megadottcsomagot. HAMIS: Ha a taszknak csak részben sikerült feldolgoznia a megadottcsomagot.Előfeltétel: IPGetHeader == TRUE és IPProtocol = IP_PRO_UDPMellékhatás: NincsMegjegyzés: Ahogy fentebb is megjegyeztük, ez a funkció valósítja meg az UDPtaszk funkciót. Akkor kell meghívni, ha egy UDP csomag érkezett ez a funkció beol-vassa és feldolgozza azt. A funkció visszatérési értéke mutatja meg a hívónak, hogya StackTask állapotjelzőjét meg kell-e változtatni. Ebben a implementációban mindigIGAZ értékkel tér vissza a funkció.

    További információért a Stack Manager forráskódját érdemes megnézni, ami aStackTsk.c fájlban található. Fontos észben tartani, hogy ezzel a funkcióval nemkell törődni, ha a StackTask funkciót használjuk.Példa:

    ...

    switch(smState)

    {

    case SM_STACK_IDLE:

    if ( MACGetHeader(&RemoveMAC, &MACFrameType) )

    {

    if ( MACFrameType == MAC_IP )

    smState = SM_STACK_IP;

    ...

    return;

    case SM_STACK_IP:

    if ( IPGetHeader(&RemoteNode, &IPFrameType, &IPDataCount) )

    {

    if ( IPFrameType == IP_PROT_UDP )

    smState = SM_STACK_UDP;

    ...

    return;

    case SM_STACK_UDP:

    if ( UDPProcess(&RemoteNode, IPDataCount) )

    smState = SM_STACK_IDLE;

    return;

    ...

  • 27

    6.3. Stack Manager modul

    Ahogy már korábban is említettem, ez a Stack különböző modulok gyűjteménye.Néhány modult (mint az IP, TCP, UDP és ICMP), akkor kell meghívni, ha olyan cso-mag érkezett. Annak az alkalmazásnak, ami a Microchip TCP/IP Stack-et használja,gondoskodnia kell arról, hogy ezek a modulok megfelelő időközönként fussanak. AStack Manager modul csak a TCP/IP Stack moduljait vezérli.

    A fő alkalmazásban nem kell foglalkoznunk a különböző modulok meghívásával,csak a StackTask nevű taszkot kell meghívnunk. Ez a modul egy külön réteg – aStackTask réteg – aminek a forrása a StackTask.c fájlban található. Amikor ez a taszkfut, megkérdezi a hálózatelérési réteget, hogy érkezett-e valamilyen csomag. Haérkezett, akkor megnézi a fejlécét és a megfelelő modulnak átadja további feldolgozáscéljából.

    Mielőtt a Stack Manager-t munkára fognánk, meg kell hívni a StackInit() funk-ciót, ami inicializálja a modult. Ha ez megtörtént a StackTask() függvényt kellperiodikusan meghívni, hogy a beérkező csomagokat időben elirányítsuk és eköz-ben az idő túllépést és hibákat is kezelni tudjuk. A StackTask pontos működésénekalgoritmusa a 6.1. ábrán látható.

    6.4. A soros-UDP átalakító modul

    Mivel ezt a modult írtam én, ezért részletesen leírom a belső működését. A modulhasználatához két darab UDP socket-re van szükség.

    A soros vonalon érkező adatokat megszakítással és polling eljárással is vételez-hetjük. Természetesen érdemes a megszakítás használatát engedélyezni a ser2udp.hfájlban. A soros vonalról érkező adatok egy alapból 50 bájtos pufferbe kerülnek. Hamegtelik vagy enter (0xA, 0xD) karakter érkezik, akkor azonnal felépítjük és elküld-jük az UDP csomagot.

    A soros adatok küldésekor sajnos nem lehet megszakítást használni, mert haaz UDP csomagot megkaptuk azt fel kell dolgozni és fel kell szabadítani a puffertugyanabban a taszkban, ahol érzékeltük, hogy UDP csomag érkezett. Ha lenne ele-gendő memóriánk, akkor az adatokat átmásolva megoldható lenne a megszakításosadatküldés.

    Az AppConfig struktúrájába került új változók listája a 6.2. táblázatban látható.A 6.2. táblázatban látható változók a websrvr.c fájlban az InitAppConfig függ-

    vényben kapnak egy kezdeti értéket, ill. ha létezik elmentett beállítás a külső sorosEEPROM-ban, akkor az értékük onnan töltődik be. Jelenleg sem soros adatfolyam-szabályozás sem paritás ellenőrzés nincs implementálva.

    A 6.3. táblázatban levő belső változókat a modul függvényei használják.

    Serial2UDP_Init

    A modul inicializálását ez a függvény végzi el.Szintaxis: Serial2UDP_InitParaméter: NincsVisszatérési érték: Nincs

  • 28

    6.1. ábra. A Stack Manager algoritmusának folyamatábrája

  • 29

    NODE_INFO target A céleszköz adatai: IP cím és MAC cím.WORD target_port A cél port száma.WORD local_port A helyi port száma.BYTE refresh A statisztikák megtekintésekor a frissítések közötti idő

    másodpercben.BYTE baud Az baud-dal arányos kiszámított érték, ami az SPBRG

    változóba kerül.BYTE FlowCtrl Értéke lehet 0: nincs szabályozás, 1: szoftveres szabá-

    lyozás, 2: hardveres adatfolyam szabályozás. (Jelenlegnincs használva, későbbi fejlesztéshez fenntartva.)

    BYTE Parity Értéke lehet 0: nincs paritás ellenőrzés, 1: páratlan pa-ritás, 2: páros paritás ellenőrzés. (Jelenleg nincs hasz-nálva, későbbi fejlesztéshez fenntartva.)

    6.2. táblázat. A soros-UDP átalakító modul konfigurációs változói

    static UDP_SOCKET UDPSocket Az adatok továbbításához használt socket.BYTE status A modul állapotát tároló változó. További

    információk a 6.4. táblázatban.DWORD rxbytes, txbytes A fogadott és elküldött oktetek száma.static WORD count A bemeneti soros pufferben elküldésre vá-

    rakozó bájtok száma.static BYTE buf[BUF_SIZE] A bemeneti soros puffer. Alapesetben 64

    bájt méretű.static BYTE buf_end Az adatok száma a soros pufferben.static BYTE_VAL misc Egyes bitjei más-más jelentéssel bírnak. A 0.

    bit: A SendSerialData függvény legköze-lebbi futásakor megpróbáljuk-e elküldeniaz adatokat.

    6.3. táblázat. A soros-UDP átalakító modul belső változói

    Előfeltétel: NincsMellékhatás: A modul inicializálása legalább 4 másodpercig (INITWAIT_SEC) tart.Megjegyzés: Először vár 4 másodpercet. Ennyi idő elég, hogy feléledjen a NIC ésérzékelje, hogy a kapcsolat él. (A későbbiekben érdemes lenne kódot átírni úgy,hogy a NIC interfészén keresztül kérdezze le, hogy él-e a kapcsolat.) Utána elküldegy ARP kérés csomagot, hogy megtudja a cél IP címhez tartozó MAC címet. Mégnégy másodpercig vár (TIMEOUT_SEC) utána „Hiba: MAC cím lekérdezése közbenidőtúllépés történt” hibaállapotba lép. Ha sikerült a MAC lekérdezése megpróbálegy UDP socket-et megnyitni. Ennek sikertelensége esetén „Hiba: Nincs szabad UDPsocket”, ellenkező esetben „Rendben” állapotba kerül. A függvényt csak egyszer kellmeghívni.Példa:

    ...

    Serial2UDP_Init ();

  • 30

    ...

    Serial2UDP_GetSerialData

    Beolvassa a soros vonalról jövő adatot és elhelyezi a buf pufferben, ha lehetséges.Ha a puffer megtelt vagy soremelés (0xD), kocsi vissza (0xA) karakter érkezett, akkora flush vátozót igaz értékre állítja. Ha a soros vonali adatok vételénél keret hibatörtént a modul „Hiba: RS-232 keret hiba” állapotba kerül. Ha az adatok vételekora vételi puffer felülírása következett be, akkor a „Hiba: Az RS-232 puffer felülírás”állapot áll be. A függvény folyamatábrája a 6.2. ábrán látható. Az ábrán a szaggatottvonal akkor érvényes, ha ezt a függvényt a Serial2UDP függvény hívja meg és nemmegszakítással működik.Szintaxis: void Serial2UDP_GetSerialData ()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: NincsMellékhatás: NincsMegjegyzés: Megszakításos módban és a pollingolásnál is ez a függvény működik.Pollingnál a Serial2UDP függvény hívja meg ezt a függvényt.Példa: Nincs

    Serial2UDP_SendSerialData

    Ha a buf puffer tele van (a flush bit 1 értékű), akkor elkészít egy UDP csomagotés elküldi a beállított IP címnek.Szintaxis: void Serial2UDP_SendSerialData ()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: NincsMellékhatás: NincsMegjegyzés: A Serial2UDP függvény hívja meg ezt a függvényt.Példa: Nincs

    Serial2UDP_ProcessUDPData

    A fogadott UDP csomagot azonnal elküldi a soros vonalon keresztül. Folyama-tábrája a 6.3. ábrán látható.Szintaxis: void Serial2UDP_ProcessUDPData ()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: NincsMellékhatás: NincsMegjegyzés: A Serial2UDP függvény hívja meg ezt a függvényt.Példa: Nincs

  • 31

    6.2. ábra. A Serial2UDP_GetSerialData függvény folyamatábrája

    Serial2UDP

    Ez egy kooperatív taszk, amit a fő ciklusban kell meghívni.Szintaxis: void Serial2UDP ()Paraméter: NincsVisszatérési érték: NincsElőfeltétel: Inicializálás megtörtént.Mellékhatás: NincsMegjegyzés: A soros vonalon beérkező adatokat a buf pufferben tárolja aSerial2UDP_GetSerialData () függvény segítségével (csak polling módszernél).

  • 32

    6.3. ábra. A Serial2UDP_ProcessUDPData függvény folyamatábrája

    A SendSerialData () eljárással küldi el a buf pufferben tárolt adatokat a sorosvonalon és a ProcessUDPData () függvénnyel a megadott portra érkező UDP cso-magokat egyből kiírja a soros vonalra.Példa:

    ...

    StackTask();

    HTTPServer();

    Serial2UDP();

    ...

    Serial2UDP_ReInit

    A konfiguráció megváltozásakor kell meghívni.Szintaxis: void Serial2UDP_ReInit ()Paraméter: NincsVisszatérési érték: Nincs

  • 33

    Előfeltétel: NincsMellékhatás: NincsMegjegyzés: Szinte teljesen megegyezik az Serial2UDP_Init funkcióval, de az ARPkérés kiküldése előtt nincs 4 másodperces várakozás.Példa:

    Serial2UDP_GetStatusString

    A modul állapotára vonatkozó stringre mutató mutatót ad vissza.Szintaxis: char *Serial2UDP_GetStatusString (void)Paraméter: NincsVisszatérési érték: Egy sztring mutató, ami megegyezik aSerial2UDP_StatusString változóban levő értékkel.Előfeltétel: NincsMellékhatás: NincsMegjegyzés: A sztring HTML kódokat tartalmaz, 0 kódú karakterrel van lezárvaés a programmemóriában van. A lehetséges állapotok szövegei a 6.4. táblázatbanláthatók.

    Sorszám Angolul Magyarul0 Unknown Ismeretlen1 Ok Rendben2 Error: UDP socket not available Hiba: Nincs szabad UDP socket3 Error: Can’t resolve MAC add-

    ress, time outHiba: MAC cím lekérdezése köz-ben időtúllépés történt

    4 Error: Buffer is full Hiba: A puffer tele van5 Error: RS-232 Framing error Hiba: RS-232 keret hiba6 Error: RS-232 Overrun error Hiba: RS-232 puffer felülírás

    6.4. táblázat. A soros-UDP modul átalakító állapotai

    Példa:

    ...

    WORD HTTPGetVar(BYTE var, WORD ref, BYTE* val)

    {

    switch(var)

    {

    case VAR_DEVSTATUS:

    if (ref == HTTP_START_OF_VAR)

    {

    Serial2UDP_GetStatusString ();

    ref = (BYTE)0;

    }

    *val = Serial2UDP_StatusString[(BYTE)ref];

    if (Serial2UDP_StatusString[(BYTE)ref + 1] == ’\0’)

    return HTTP_END_OF_VAR;

  • 34

    (BYTE)ref++;

    return ref;

    ...

    6.5. HTTP szerver modul

    Ez a HTTP szerver kooperatív taszkként fut, amit a fő alkalmazásból kell meg-hívni. A szerver a HTTP.c forrásfájlban van implementálva és a felhasználói pro-gramban két segédrutint (angolul callback function) használhatunk. Az bemutatóalkalmazás forrásfájlját – a websrvr.c fájlt – használtam fel a saját programomírásához. Ez a HTTP szerver egy csökkentett tudású program, direkt beágyazottrendszerekhez íródott. A szerver tulajdonságai:

    • Többszálú HTTP kapcsolatok

    • Egy egyszerű fájlrendszert támogat (MPFS)

    • A honlapokat a belső programmemóriában és külső EEPROM-ban is tárolhat-juk

    • Tartalmaz egy PC-s programot MPFS képfájl létrehozásához

    • A HTTP GET metódust támogatja (más metódusok könnyen hozzáadhatók)

    • Egy módosított Common Gateway Interface-t (CGI) támogat

    • Dinamikusan generálható a honlapok tartalma.

    A HTTP szerver használatbavételéhez a következő lépéseket kell végrehajtani:

    1. A StackTsk.h fájlban vagy a projekt beállításnál definiálni kell aSTACK_USE_HTTP_SERVER definíciót.

    2. A StackTsk.h fájlban be kell állítani a MAX_HTTP_CONNECTIONS értékét.

    3. A http.c és mpfs.c fájlokat hozzá kell adni a projekthez.

    4. Attól függően, hogy hol szeretnénk a weblapokat tárolni, definiálni kell azMPFS_USE_PGRM vagy az MPFS_USE_EEPROM kulcsszavakat. Ha külső EEPROM-ot használunk tárolóelemnek az xeeprom.c fájlt is hozzá kell adni a projekthez.

    5. A main() függvényt módosítani kell, hogy a HTTP szerver működjön.

    Az összes weblapot egy MPFS (Microchip File System) fájlrendszerbe kell kon-vertálni. Ha az MPFS képfájlt külső EEPROM-ban tároljuk, akkor a felhasználóiprogramba implementálni kell az adatok rögzítéséhez szükséges függvényt.

    A HTTP szerver alap honlapként az index.htm fájlt használja. Ha például egyböngésző a HTTP szerverhez fordul úgy hogy csak az IP címet adták meg a bön-gészőnek az index.htm fájlt kapja meg a böngésző. Tehát minden MPFS képfájlbanlennie kell egy index.htm fájlnak. Ha szükséges az alap fájlnév megváltoztatható,ha a http.c forrásban a HTTP_DEFAULT_FILE_STRING definíciót átírjuk. Fontos, hogya weblap fájlok nevei ne tartalmazzák a következő karaktereket:

  • 35

    • aposztróf és idézőjel (’ és ")

    • kisebb-nagyobb jelek (< és >)

    • kettős kereszt jel (#)

    • százalék jel (%)

    • szögletes és kapcsos zárójelek ([, }, [, {)

    • szűrő jel (|)

    • vissza perjel (\)

    • kalap jel

    Ha egy fájl neve tartalmaz ezek közül egy karaktert, akkor az a honlap nem leszelérhető. A HTTP szerveren van egy lista a támogatott fájl típusokkal. Ezt az in-formációt a böngésző használja fel; ebből állapítja meg, hogy hogyan értelmezzea kapott adatokat. A fájlok azonosítása a hárombetűs kiterjesztés alapján történik.Alapból a HTTP szerver a következő fájltípusokat támogatja: .txt, .htm, .gif,.cgi, .jpg, .cla, .wav. Ha egy alkalmazásban olyan fájltípust akarunk hasz-nálni, ami nincs a listában, akkor a http.c fájlban httpFiles táblázatot kell módo-sítani utána a httpContents felsorolást. Az ismert fájltípusok listáját a stíluslapoktípussal bővítettem (.css).

    6.5.1. Dinamikus honlap generálás

    A HTTP szerver dinamikusan meg tudja változtatni a honlapok tartalmát. A CGI(.cgi kiterjesztésű legyen) fájlokban a %xx kulcsszó helyére tetszőleges adat helyet-tesíthető. A % jel egy vezérlő karakter. Az xx egy kétjegyű azonosító, hexadecimálisformában. Ügyeljünk arra, hogy az A-F karakterek nagy betűvel legyenek írva! Így256 féle változót használhatunk. Ha % jelet szeretnénk kiírni, írjunk egymás után kétszázalék jelet: %%.

    Az eredeti Microchip megoldásban nem teljes értékű hexadecimális számok vol-tak megadhatók. A % jel után két darab decimális számot kellett írni, amit a pro-gramban hexadecimális számként kellet feldolgozni. Így 00-99 változó megadásalehetséges. Én írtam egy egyszerű konvertert, ami a hexadecimális stringet átalakítjaegy bájttá. Így 00-tól FF-ig adhatók meg az azonosítók.

    HTTPGetVar

    Ez a funkció egy segédfüggvény (callback function) a HTTP-hez. Ha HTTP szer-ver egy %xx szöveget talál egy CGI lapon, akkor meghívja ezt a funkciót. Ezt afunkciót a felhasználói programban kell megírni és különböző változó adatokat tu-dunk vele továbbítani.Szintaxis: WORD HTTPGetVar(BYTE var, WORD ref, BYTE *val)Paraméter: var [bemenő] A változó azonosítója, aminek az állapotát akarjuk lekér-dezni.

  • 36

    ref [bemenő] Ez az érték jelzi, hogy ha ez az első függvényhívás. Ekkor a változóértéke HTTP_START_OF_VAR. Ez első hívás után már ez a változó a felhasználói alkal-mazásé. Egyszerre csak egy bájt átvitele lehetséges. Ez a változó teszi lehetővé, hogytöbb bájt átvitele esetén a HTTP szerver nyomon kövesse az adatok átvitelét úgy,hogy ebben a változóban az átvitt adat indexét kell tenni és visszatéréskor is ezt aváltozót kell átadni. Az utolsó bájt átvitelekor HTTP_END_OF_VAR értéket kell vissza-térési értéknek megadni. A HTTP szerver egészen addig meghívja ezt a funkciót,amíg nem kap egy HTTP_END_OF_VAR értéket.val [kimenő] Egy bájt adat, amit küldeni szeretnénk.Visszatérési érték: A ref változó új értéke, amit a felhasználói alkalmazás állapítmeg. Ha HTTP_END_OF_VAR értéket ad vissza, legközelebb csak akkor hívódik meg,ha megint szükség van a változó értékére.Előfeltétel: NincsMellékhatás: NincsMegjegyzés: Ez a függvény egy változót kér a felhasználói alkalmazástól, de annaknem feltétlenül kell értékeket adni. Az hogy milyen információt ad át a függvény, aza hozzárendelt weblaptól függ.Példa: A soros-UDP átalakítóhoz készítettem a stats.cgi fájlt, ebben a következőolvasható:

    Device status%01

    Amikor a HTTP szerver a fájl feldolgozása során a %01 szöveghez ér, meghívja akövetkező funkciót: HTTPGetVar(1, HTTP_START_OF_VAR, &value). A felhasználóialkalmazásban levő websrvr.c fájlban van ez a funkció és ehhez hasonlóan néz ki:

    WORD HTTPGetVar(BYTE var, WORD ref, BYTE* val)

    {

    switch(var)

    {

    ...

    case VAR_RXBYTES:

    if (ref == HTTP_START_OF_VAR)

    {

    ltoa (rxbytes, TmpString);

    ref = (BYTE)0;

    }

    *val = TmpString[(BYTE)ref];

    if (TmpString[(BYTE)ref + 1] == ’\0’)

    return HTTP_END_OF_VAR;

    (BYTE)ref++;

    return ref;

    ...

    6.5.2. HTTP CGI

    A CGI-nek egy módosított verziója használható ebben az implementációban.Ezzel az interfésszel a HTTP kliens egy funkciót tud meghívni a felhasználói alkal-

  • 37

    mazásban a HTML GET módszerével. További információk az RFC1866-os doku-mentumban [5] találhatók.

    A HTTP szerver nem dekódolja az átadott URL-t. Ez azt jelenti, hogy ha az átadottűrlapok mezője speciális karaktereket tartalmaz (, %, ékezetes karakterek, stb.),akkor a funkciónak átadott paraméter %xx formátumú sztringeket fog tartalmazni,ahol a xx az ASCII karakter hexadecimális kódja. Az űrlapokat tartalmazó oldalakat.cgi kiterjesztéssel kell ellátni.

    Fontos észben tartani, hogy amikor jelszavakat továbbítunk CGI segítségével, ajelszavakat kódolatlanul továbbítjuk, tehát azok „lehallgathatók”.

    HTTPExecCmd

    Ez egy segédfüggvény (callback function). Ha a HTTP szerver a GET módszerreltörténő lekérdezésnél több mint egy paramétert kap, akkor hívja meg ezt a funkciót.Ezt a funkciót a felhasználói alkalmazásnak kell tartalmaznia.Szintaxis: void HTTPExecCmd(BYTE **argv, BYTE argc)Paraméter: argv [bemenő] Ez egy sztring tömb. Az első sztring (argv[0]) az űrlapaction mezőjének tartalma, a többi (argv[1..n]) a paraméterek.argc [bemenő] A paraméterek száma, beleszámítva az action mezőt is.Visszatérési érték: A felhasználói alkalmazásnak be kell állítania az argv[0] válto-zót egy érvényes honlapnévre, ami a visszatérési eredményt tartalmazza.Előfeltétel: NincsMellékhatás: NincsMegjegyzés: Ezt a függvényt a HTTP szerver hívja meg. A felhasználói alkalma-zásnak ki kell tudnia szolgálnia az egymás utáni hívásokat. Alapesetben az argu-mentumok száma maximum 5 és az argumantumsztringek hossza legfeljebb 80lehet. Ha egy alkalmazásnak ennél több argumentum vagy hosszabb sztring kell,a MAX_HTTP_ARGS vagy a MAX_HTML_CMD_LEN definíciót kell megváltoztatni. Ezek ahttp.c fájlban találhatók.Példa: A setup.cgi fájlt is a soros-UDP átalakítóhoz készítettem. Ebben olvashatóa következő:

    Local IP

    Local Port

    Netmask

    Gateway

    Target IP

    Target Port

    Refresh rate

  • 38

    sec

    Ennek a táblázatnak a második oszlopaiban adhatunk meg különféle szöveg for-mátumú adatokat. A képernyőn látható kép a 6.4. ábrán van. Az utolsó sorban egygomb látható „Save” felirattal. Ha rákattintunk erre a gombra, akkor az űrlapot a„GET” módszerrel elküldi a böngésző.

    6.4. ábra. Űrlapok kezelése

    A HTTP kérés ez lesz: setup.cgi?0=10.10.5.15&1=2221&2=255.255.255.0&3=10.10.5.15&4=10.10.5.5&5=2222&6=5&7=SaveEnnek hatására HTTP szerver pe-dig a következő paraméterekkel meghívja a HTTPExecCmd függvényt:argc = 17 argv[0] = "setup.cgi"

    argv[1] = "0" argv[2] = "10.10.5.15"

    argv[3] = "1" argv[4] = "2221"

    argv[5] = "2" argv[6] = "255.255.255.0"

    argv[7] = "3" argv[8] = "10.10.5.15"

    argv[9] = "4" argv[10] = "10.10.5.5"

    argv[11] = "5" argv[12] = "2222"

    argv[13] = "6" argv[14] = "5"

    argv[15] = "7" argv[16] = "Save"

    Ehhez természetesen MAX_HTTP_ARGS és a MAX_HTML_CMD_LEN értékét is meg kellnövelni. Az adatokat feldolgozó függvény pedig így néz ki:

    void HTTPExecCmd(BYTE** argv, BYTE argc)

    {

    BYTE i;

    BYTE var;

    for (i = 1; i < argc; i += 2)

    {

    switch(argv[i][0] - ’0’)

    {

    case CGI_CMD_LOCALIP:

    StringToIPAddress (argv[i + 1], &AppConfig.MyIPAddr);

  • 39

    break;

    case CGI_CMD_LOCALPORT:

    AppConfig.local_port = atoi (argv[i + 1]);

    break;

    ...

    case CGI_CMD_BUTTON:

    // Ez a parameter adodik at utolsonak...

    Serial2UDP_ReInit ();

    SaveAppConfig ();

    break;

    }

    ...

    }

    Az egy karakterből álló azonosítók használata leegyszerűsíti a program kódját, ezértérdemes alkalmazni.

    6.6. Microchip fájlrendszer (MPFS)

    A HTTP szerver egy egyszerű fájlrendszert használ a honlapok tárolására. Afájlrendszer képe a mikrovezérlő memóriájában és egy külső soros EEPROM-ban istárolható. A fájlrendszer formátuma a 6.5. ábrán látható.

    6.5. ábra. MPFS képfájl felépítése

    A fenntartott terület mérete az MPFS_RESERVE_BLOCK definícióban van megadva.A fenntartott területet a felhasználói alkalmazás használhatja a konfigurációs értékektárolására. Egy MPFS tároló egy vagy több MPFS FAT (Fájl Elhelyezkedési Tábla,File Allocation Table) bejegyzést tartalmaz, amit egy vagy több adatblokk követ. AFAT bejegyzés határozza meg a fájl nevét, pozícióját a memóriában és a fájl állapotát.A FAT bejegyzés formátuma a 6.6. ábrán van.

  • 40

    Az állapotjelző mutatja meg, hogy a bejegyzés használatban van, törölve van ill.a FAT végét is jelezheti. Minden FAT bejegyzés tartalmaz egy 16 vagy 24 bites címet.A cím hossza a felhasznált memória típusától függ.

    Ha a belső programmemóriát használjuk „kis” (small) memóriamodellel, akkor16 bites címeket fog használni. Ha a belső programmemóriát használjuk viszont„nagy” (large) memóriamodellel, akkor 24 bites címeket fog használni. A külsőEEPROM eszközöknél mindig 16 bites címzési módszert használunk, függetlenül amemóriamodelltől.

    Ebben a fájlrendszerben a fájlnevek 8+3 bájt hosszúak. A fájl neve 8 bájtos és akiterjesztés további 3 bájt hosszúságú. A 16 bites cím megadja az első adatblokkot.Minden fájlnév nagybetűkkel szerepel a könnyebb névkezelés érdekében.

    Az adatblokk formátuma a 6.7. ábrán szerepel. A blokk végét egy speciális karak-ter jelzi; az EOF (End Of File), amit 0xFFFF (16 bites címzésnél) vagy 0xFFFFFF (24bites címzésnél) követ. Ha a fájl tartalmazza az EOF karaktert, akkor egy DLE (DataLink Escape) karakterrel jelezzük, hogy ez a fájl része. Ha a DLE karakter szerepelaz adatblokkban, akkor két DLE karakter jelzi, hogy az a fájl része.

    6.6.1. MPFS kép készítése

    A csomag része egy PC-s program (MPFS.exe), amivel MPFS képfájlokat hozha-tunk létre. A program képes bináris és C nyelvű adatok létrehozására is.

    Az MPFS.exe használata: mpfs [/?] [/c] [/b] [/r] [bemenet][kimenet], ahol

    • /? hatására segítséget ír ki,

    • /c paraméter segítségével C kódot kérhetünk,

    • /b paraméterrel bináris kódot készít (ez az alapbeállítás),

    • /r paraméterrel megadhatjuk hány bájtot szeretnénk fenntartani saját haszná-latra, (ez csak bináris módban működik, alap: 32 bájt),

    • bemenet a bemenő adatokat tartalmazó könyvtár,

    6.6. ábra. MPFS FAT bejegyzés felépítése

    6.7. ábra. MPFS adatblokk felépítése

  • 41

    • kimenet az MPFS képet tartalmazó fájl.

    Például: mpfs /c Honlap honlap.c Így egy C fájlt kapunk benne a Honlapkönyvtárban lévő fájlok adatai. Bináris fájlt kapunk az mpfs Honlap honlap.binparancs hatására. A bináris fájl elején 32 bájt fenntartott. Ha megváltoztatjuk a fenn-tartott terület méretét ne felejtsük el a StackTsk.h fájlban a MPFS_RESERVE_BLOCKdefiníciót megváltoztatni.

    Mielőtt a képfájlt létrehozzuk az összes honlapot egy könyvtárba kell másolni.Ha egy fájl kiterjesztése .htm, akkor a program az összes kocsi vissza, új sor karakterttörli, hogy csökkentse a képfájl méretét. Ha az MPFS képfájlt C adatként használjuk,akkor a projektünkhöz hozzá kell adni a C fájlt. Ha a képfájlt külső soros EEPROM-ban tároljuk, a bináris fájlt fel kell tölteni a memóriába. További információ a 41.oldalon az „FTP szerver modul” résznél.

    Az MPFS képkészítő program nem ellenőrzi az elkészült fájl méretét. Bináris adatkészítése esetén ellenőrizni kell az adat méretét.

    6.6.2. MPFS könyvtár

    Az MPFS fájlrendszer eléréséhez szükséges könyvtár az MPFS.c fájlban van imp-lementálva. Az MPFS könyvtárat a HTTP és az FTP szerver használja a felhasználóialkalmazástól függetlenül. Az MPFS könyvtár jelenlegi verziójával nem lehet egy lé-tező fájlrendszerhez új fájlokat adni ill. törölni. Bármilyen változás esetén egy újabbképfájlt kell létrehozni.

    Ha a belső programmemóriát használjuk a tárolásra, az MPFS_USE_PGRM szót defi-niálni kell. Ha viszont külső EEPROM-ot használunk, a MPFS_USE_EEPROM kulcsszótkell definiálni. Egyszerre csak egyik definíció szerepelhet a StackTsk.h fájlban; en-nek ellenőrzésére a futásidő alatt egy ellenőrzőkód fut le.

    A memória típusától függően különböző lappuffer méretet kell beállítani. Az alapméret (amit az MPFS_WRITE_PAGE_SIZE határoz meg) 64 bájt. Ha más pufferméretrevan szükség az MPFS_WRITE_PAGE_SIZE definíciót kell megváltoztatni.

    Az MPFS könyvtárnak ez a verziója az xeeprom.c fájlt használja a külső EEPROMeléréséhez. Miközben egy fájlt olvas vagy ír kizárólagosan az MPFS irányítja az I2Cbuszt és nem engedélyezi más I2C eszközöknek – legyen az szolga vagy mester– a hozzáférést. Ha több I2C eszközt használunk, akkor a felhasználói alkalmazásírásakor ezt figyelembe kell venni.

    6.7. FTP szerver modul

    Ez a modul is egy kooperatív taszkként funkcionál és az FTP.c fájlban van aszerver forráskódja. Ez az FTP szerver nem tudja az összes szolgáltatást, ami az RFC 959-ben [6] le van leírva, mivel direkt beágyazott rendszerekhez lett tervezve, minimálisa mérete és a tudása. A modul jellemzői:

    • Egy szálú FTP kapcsolat. A felhasználó azonosítása az alkalmazás feladata,

    • Automatikusan kezeli az MPFS fájlrendszert,

  • 42

    • A „PUT” paranccsal egy új MPFS kép tölthető fel,

    • A fájlok egyenkénti feltöltése nem lehetséges.

    A modul két részből áll: maga az FTP szerver és a felhasználó azonosító függvény,ami a felhasználói alkalmazásnak kell tartalmaznia. Egy FTPVerify függvényt kellírnia a felhasználónak, ami ellenőrzi az FTP felhasználót és a jelszót.

    Itt is megjegyzem, hogy a jelszót kódolatlanul küldi el a számítógép, tehát azoka megfelelő eszközökkel „lehallgathatók”.

    Az FTP szerver használatához a következőket kell megtettünk:

    1. A STACK_USE_FTP_SERVER-t definiálni kell. A komment jelet el kell távolítani aStackTsk.h fájlban a definíció elől.

    2. A definiált socket-ek számát növelni kell kettővel ugyancsak a StackTsk.hfájlban.

    3. Az FTP.c és az mpfs.c fájlokat hozzá kell adni a projektünkhöz.

    4. Vagy az MPFS_USE_PGRM MPFS_USE_EEPROM definíciót be kell állítani, attólfüggően, hogy milyen tárolóelemet használunk. Ha külső EEPROM-ot, azxeeprom.c fájlt is adjuk hozzá a projektünkhöz.

    5. Módosítsuk a main() függvényt, hogy az FTP szerver inicializáló függvényeés taszkja fusson.

    Az FTP szerver 180 másodperc után jelez időtúllépést feltöltésnél és letöltésnélegyaránt. Ha egy kapcsolat 180 másodpercnél tovább van „IDLE” (tétlen) állapotban,akkor automatikusan megszakítja a szerver a kapcsolatot. Így a bennragadt klienseknem gátolhatják meg a további FTP műveleteket.

    6.7.1. MPFS kép feltöltése FTP kliens segítségével

    Az FTP szerver fő feladata ebben a Stack-ben, hogy távolról lehessen frissíteniaz MPFS képfájlt. A jelenlegi verzió csak akkor működik, ha külső EEPROM-othasználunk adattárolásra.

    Egy képfájl feltöltése látható a 6.8. ábrán. A vastagon szedett betűk a felhasználóáltal beírt adatokat jelzi. A jelszó természetesen nem látszódik a képernyőn.

    FTPVerify

    Ez egy segédfüggvény (callback function), amit az FTP szerver akkor hív meg,ha kérést vesz a kapcsolat felépítésére. Ezt a funkciót a felhasználói alkalmazásnakkell tartalmaznia.Szintaxis: BOOL FTPVerify(char *login, char *password)Paraméter: login [bemenő] Egy sztring, ami tartalmazza a felhasználó nevét.password [bemenő] Sztring, ami a jelszót tartalmazza.Visszatérési érték: IGAZ: Ha a felhasználói név és a jelszó érvényes. HAMIS: Havagy a felhasználó neve, vagy a jelszó érvénytelen.

  • 43

    c:\> ftp 10.10.5.15

    220 ready

    User (10.10.5.15: (none)): ftp

    331 Password required

    Password: microchip

    230 Logged in

    ftp> put mpfsimg.bin

    200 ok

    150 Transferring data...

    226 Transfer Complete

    16212 bytes transferred in 0.01Seconds 16212000.00Kbytes/sec.

    ftp> quit

    221 Bye

    6.8. ábra. MPFS képfájl feltöltése FTP kliens segítségével

    Előfeltétel: NincsMellékhatás: NincsMegjegyzés: A felhasználónév hossza nullától kilencig változhat. Ha hosszabb fel-használónévre van szükség az FTP_USER_NAME_LEN definíciót kell megváltoztatni azftp.h fájlban.

    A jelszó és az FTP utasítások hossza legfeljebb 31 karakter hosszú lehet. Hahosszabb jelszó és/vagy parancs szükséges, akkor a MAX_FTP_CMD_STRING_LEN defi-níciót kell megváltoztatni az FTP.c fájlban.Példa:

    ROM char FTP_USER_NAME[] = "ftp";

    #define FTP_USER_NAME_LEN (sizeof(FTP_USER_NAME)-1)

    ROM char FTP_USER_PASS[] = "microchip";

    #define FTP_USER_PASS_LEN (sizeof(FTP_USER_PASS)-1)

    BOOL FTPVerify(char *login, char *password)

    {

    if ( !memcmppgm2ram(login, (ROM void*)FTP_USER_NAME,

    FTP_USER_NAME_LEN) )

    {

    if ( !memcmppgm2ram(password, (ROM void*)FTP_USER_PASS,

    FTP_USER_PASS_LEN) )

    return TRUE;

    }

    return FALSE;

    }

  • 44

    7. fejezet

    Hardver

    A „PIConNET” kártya kapcsolási rajzát és a nyomtatott áramkört a ChipCadKft. készítette. A kapcsolási rajz az 1. számú mellékleten látható. A rajzon látható93LC46B típusú soros EEPROM nem lett beforrasztva.

    A kártyához készítettem egy soros vonali illesztőt és egy egyszerű tápfeszült-ségstabilizátort, ami a 7.1. ábrán látható. A soros vonal illesztését egy MAX232Atípusú integrált áramkör valósítja meg. A rajzon MAX232 IC szerepel, a két IC kö-zött annyi a különbség, hogy a MAX232 mellé 1 µF-os kondenzátorokat kell tenni,míg a MAX232A megelégszik 100 nF-os kondenzátorokkal. A tápfeszültség stabili-zálását pedig egy 78L05 IC végzi el.

    7.1. Alkatrészek

    7.1.1. PIC18F452 mikrovezérlő

    Ez egy FLASH programmemóriával rendelkező RISC mikrokontroller10 MIPS tel-jesítményre képes és maximum 40 MHz-en működhet. 32 kilobájt FLASH építettekbe a programmemóriának, 1536 bájt RAM és 256 bájt EEPROM van benne. Utasítás-készlete 75 utasításból áll és úgy optimalizálták, hogy a C programnyelven történőfejlesztést megkönnyítse. 31 szintű verem van beépítve, ami ha szükséges szoftvere-sen bővíthető. A nyomtatott áramköri lapon felhasznált TQFP tok rajza a 7.2. ábránlátható. Az IC részletes leírása az angol nyelvű adatlapon [7] van.

    Perifériák jellemzői:

    • A lábak áramleadása vagy -felvétele 25 mA lehet.

    • Három külső megszakítást generáló láb áll rendelkezésre.

    • Timer0 modul: 8 bit ill. 16 bites időzítő/számláló 8 bites programozható előosz-tóval.

    • Timer1 modul: 16 bites időzítő/számláló.

    • Timer2 modul: 8 bites időzítő/számláló 8 bites periódus regiszterrel (időalap aPWM-hez).

  • 45

    7.1. ábra. Soros vonali illesztő és tápfeszültség stabilizátor kapcsolási rajza

  • 46

    7.2. ábra. A PIC18F452 típusú mikrovezérlő lábkiosztása

    • Timer3 modul: 16 bites időzítő/számláló.

    • Opcionális másodlagos oszcillátor Timer1-es és Timer3-as modulokhoz.

    • Két Capture/Compare/PWM modul. A modul háromféleképpen konfigurál-ható:

    – Capture (mintavételező) bemenetként (16 bites, maximum felbontás6, 25ns = TCY/16),

    – Compare (összehasonlító) bemenetként (16 bites, maximum felbontás100ns = TCY),

    – PWM kimenetként (felbontás 1 bittől 10 bitig változtatható, 8 bites felbon-tásnál fmax = 156kHz, 10 bites felbontásnál fmax = 39kHz).

    • Szinkron soros port (Master Synchronous Serial Port, MSSP) modul. Hárommódban működhet:

    – 3 vezetékes SPI módban (mind a négyfajta SPI módban működik),

    – I2C mester módban,

    – I2C szolga módban.

  • 47

    – Címezhető USART modul. RS-232 és RS-485 módot is támogatja.– Párhuzamos szolga port (PSP).

    Analóg paraméterek:

    • 10 bites AD konverter jellemzői:

    – Gyors mintavételező képesség,– Működik szundi (SLEEP) módban,– Linearitás ≤ 1 Lsb.

    • Programozható feszültségesés jelzés (Programmable Low Voltage Detection,PLVD): megszakítás kérhető, ha leesik a feszültség.

    • Tápfeszültség-kiesés esetén beállítható reset folyamat (Brown-out Reset, BOR).

    Speciális jellemzők:

    • Tipikusan százezerszer törölhető/írható a FLASH programmemória.

    • Tipikusan egy milliószor törölhető/írható az adat EEPROM.

    • A FLASH és az adat EEPROM legalább 40 évig megtartja tartalmát.

    • A szoftverből lehet írni/olvasni a programmemóriát.

    • Fejlett beépített reset áramkör: Power-on Reset (POR), Power-up Timer(PWRT), Oscillator Start-up Timer (OST).

    • Watchdog időzítő (WDT) saját RC oszcillátorral.

    • Programozható kódvédelem.

    • Tápegységkímélő szundi (SLEEP) mód.

    • Változtatható oszcillátorbeállítások:

    – az elsődleges oszcillátor négyszerezése (PLL használatával),– másodlagos órajel engedélyezése/tiltása.

    • Soros programozás két lábon keresztül (In-Circuit Serial Programming, ICSP).

    • Nyomkövetés két lábon keresztül (In-Circuit Debugging, ICD).

    CMOS technológia előnyei:

    • Alacsony teljesítményű, nagy sebességű FLASH/EEPROM technológia

    • Széles tápfeszültség-tartomány (2.0–5.5V)

    • Ipari- és kiterjesztett hőmérsékleti tartományok

    • Alacsony teljesítményigény:

    – kisebb, mint 1,6 mA, ha 5V a tápfeszültség és 4 MHz a frekvencia– 25 µA, ha 3V a tápfeszültség és 32 kHz a frekvencia– kisebb, mint 0,2 µA szundi üzemmódban

  • 48

    7.1.2. RTL8019AS ethernet vezérlő

    Ez az IC valósítja meg a fizikai kapcsolatot az ethernet hálózattal. A régebbi ver-ziójú RTL8019-et továbbfejlesztették és 16 kilobájt SRAM-ot építettek be egy tokba.Full-duplex-es és 10 Mbit/s sebesség érhető el. Csavart érpáros (10baseT) és koaxiáliskábellel (10base5, 10base2) is használható, továbbá a már igen elavult AUI csatlako-zást is használhatunk. A PIConNET kártyán egy RJ45-ös csatlakozó lett kialakítva acsavart érpáros kapcsolathoz, továbbá van négy LED, amely a kapcsolat létrejöttétill. a hálózati forgalmat jelzi. További információ az IC adatlapján [8] található.

    Ez az integrált áramkör a beépített SRAM-ot pufferként felhasználva ethernetkereteket küld ill. fogad manchester kódolással és kezeli az ütközéseket. Az OSI/ISOmodellben gyakorlatilag a fizikai- és adatkapcsolati réteget valósítja meg.

    7.1.3. 24LC256 típusú soros EEPROM

    Ebben a memóriában 32 kilobájt méretű EEPROM található és I2C buszon keresz-tül kommunikál a mikrokontrollerrel. Egy speciális formátumba csomagolva FTP-nkeresztül tölthetjük fel honlapunkat a memóriába, továbbá ebben az EEPROM-bantároljuk az alkalmazás beállításait. További információ az angol nyelvű adatlapon[11] van. A 7.3. ábrán látható a tok lábkiosztása.

    A tok jellemzői a következők:

    • Kis fogyasztású CMOS technológiával készül:

    – Az íráskor felvett áram 3 mA 5.5V-os tápfeszültségnél.

    – Az olvasáskor felvett áram maximum 400 µA 5.5V-os tápfeszültségnél.

    – Nyugalmi áram átlagosan 100 nA 5.5V-os tápfeszültségnél.

    • Két vezetékes I2C kompatibilis soros busz.

    • Kaszkádba köthető maximum 8 eszköz.

    • Belső időzítésű írási- és olvasási ciklusok.

    • 64 bájt méretű lapok írása támogatott.

    • Maximális írási idő 5 ms.

    • Hardveres írás védelem.

    • Schmitt Trigger-es bemenetek.

    • Egymillió törlés/írás ciklus.

    • Minimum 4 kV-os elektrosztatikus kisülés ellen védett.

    • Adatmegtartási idő legalább 200 év.

    • 8 érintkezős PDIP, SOIC, TSSOP, MSOP, DFN és 14 érintkezős TSSOP tokkal isgyártják.

  • 49

    7.3. ábra. A 24LC256 típusú soros EEPROM lábkiosztása

    7.1.4. MAX232A soros vonali illesztő

    A soros vonal illesztését végzi ez az integrált áramkör (lábkiosztása a a 7.4. ábránlátható). Az 5V-os TTL szintű jeleket ±12V-os szintre alakítja, ehhez négy darab100 nF-os kondenzátorra van szükség. Két darab bemenetet és két darab kimenetetkezel, ebből csak egyet-egyet használtam fel. Az IC részletes leírása az adatlapján[10] olvasható.

    7.4. ábra. A MAX232 típusú soros vonali illesztő lábkiosztása

  • 50

    8. fejezet

    Az eszköz használata és tesztelése

    8.1. Az eszköz használata

    A kész eszközön három csatlakozó és öt LED található(8.1. ábra).

    8.1. ábra. A doboz oldal- és elölnézete

    Jelmagyarázat:

    1. Soros vonal: egy DSUB9-es csatlakozó található a dobozon. Ezen keresztültörténik az RS-232 szabvány szerinti kommunikáció.

    2. Ethernet: egy RJ45-ös foglalat van a csavart érpáros kábelnek.

    3. Tápfeszültség: a protokollkonverternek 5-15V egyenfeszültségre van szüksége.

    4. Link LED (sárga): Ha világít, a kapcsolat létrejött a két ethernet-es készülékközött.

    5. RX LED (zöld): Ha villog, adatok érkeznek az ethernet hálózaton az eszközfelé.

    6. TX LED (zöld): Ha villog, az eszköz adatokat küld az ethernet hálózaton.

    7. OK LED (zöld): Ha világít, akkor az eszköz megfelelően működik.

    8. ERROR LED (piros): Ha világít, akkor az eszköz működése során hiba lépettfel.

  • 51

    Az eszköz használata a 8.2. ábrán látható. Az ethernet hálózat kialakítására szám-talan lehetőség van: lehet csak csavart érpáros technológiát használni vagy csavartérpáros kábeleket és optikai vagy mikrohullámú átvitelt is. Az áthidalható távolságakár több kilométer is lehet.

    8.2. ábra. Az eszköz használata

    8.2. Konfigurálás böngészőprogrammal

    Az eszköz konfigurálását bármilyen böngészőprogrammal elvégezhetjük. Ala-pesetben az eszköz IP címe 10.10.5.15 hálózati maszkja 255.255.0.0. A http://10.10.5.15címet beírva a böngészőbe a 8.3. ábrán látható képet kell látnunk. A „Help” linkrekattintva ennek a fejezetnek a kivonatos verzióját olvashatjuk el.

    Az egyes linkekre kattintva beállíthatjuk a soros vonalat, a hálózatot ill. megte-kinthetjük a statisztikákat.

    8.2.1. Hálózat beállítása

    A „Network setup” linkre kattintva a 8.4. ábrán látható oldalon a következőketállíthatjuk be:

    • Local IP: az eszköz IP címe (alap: 10.10.5.15).

    • Local Port: az eszköz ezen a porton várja az adatokat (alap: 2221).

    • Netmask: hálózati maszk (alap: 255.255.0.0).

    • Gateway: ha a cél IP címe másik tartományba esik meg kell adni az átjárót (alap:10.10.5.15). Ha ugyanabban a hálózatban van, akkor az átjáró megegyezik azeszköz IP címével.

    • Target IP: a soros vonalról érkező adatokat ennek az IP címnek fogja továbbítani(alap: 10.10.5.5).

    • Target Port: a soros vonalról érkező adatokat a megadott portra küldi (alap:2222).

  • 52

    8.3. ábra. Konfigurálás böngészőprogrammal: index

    8.4. ábra. Hálózat beállítása böngészőprogrammal

  • 53

    • Refresh rate: A statisztika megtekintésekor ennyi másodpercenként fog fris-sülni a lap (alap: 10).

    A „Save” gombra kattintva az adatokat eltárolja a I2C buszos EEPROM-ba és azeszköz lekérdezi a megadott cél IP cím MAC címét.

    8.2.2. Soros vonal beállítása

    A „Serial port setup” oldalon (8.5. ábra) a soros vonal sebességét lehet beállítani.A sebesség 2400-tól 57600 baud-ig állítható. A „Save” gombra kattintva a beállításazonnal érvényes lesz és az értéket elmenti az EEPROM-ba.

    8.5. ábra. Soros vonal beállítása böngészőprogrammal

    8.2.3. Statisztika

    A statisztikákat tartalmazó oldalon (a 8.6. ábra) láthatjuk az eszköz állapotát(rendben van ill. valamilyen hiba történt), a beállított paramétereket és az eddigátvitt adatok számát bájtban. Ez a HTML oldal automatikusan frissül alapesetben 10másodpercenként. Ez frissítési érték (Refresh rate) a hálózati beállításokat tartalmazólapon átállítható tetszőleges értékre.

  • 54

    8.6. ábra. Statisztika megtekintése böngészőprogrammal

    8.3. Az eszköz tesztelése

    Mivel csak egy eszközt készült el, ezért a teszteléshez számítógépen egy program-mal (UDP test) szimuláltam a másik eszközt és egy egyszerű terminálprogrammalküldtem és fogadtam a soros vonali adatokat. A 8.7. ábrán látható az eszköz és aszámítógép összekötése.

    8.7. ábra. Az eszköz tesztelése

    Az UDP test (8.8. ábra) nevű programot C++ nyelven írtam direkt azért, hogya készüléket tesztelni tudjam. A program egy fő ablakból áll, ami két részre vanosztva.

  • 55

    8.8. ábra. Az UDP test program

    A bal oldalon található egy UDP kliens: a megadott IP címre és annak megadottportjára elküldi a szövegdobozban található szöveget.

    A jobb oldalon az UDP szerver vezérelhetjük, ami a program futtatásakor au-tomatikusan elindul. A szerver megadott portjára érkező adatokat a program egyszövegdobozban jeleníti meg.

    A program működését egyszerűen ki lehet próbálni: a szerver címének a loopbackeszköz címét kell megadni (például 127.0.0.1). Majd a kliensnek is ezt a címet és aszerver portját adjuk meg. Ha az elküld gombra kattintunk az üzenetnek meg kelljelennie a jobb oldali szövegdobozban.

  • 56

    Irodalomjegyzék

    [1] Nilesh Rajbharti. The Microchip TCP/IP Stack, 2002.Fájl: tcpipstack/an833.pdf

    [2] J. Postel. User Datagram Protocol, RFC 768, 1980.Fájl: rfc/rfc768.txt.pdf

    [3] T. Bradley, C. Brown, A. Malis. Inverse Address Resolution Protocol, RFC 2390,1998.Fájl: rfc/rfc2390.txt.pdf

    [4] David C. Plummer. An Etherne