STM32 I i s i@ o Ethernet w p Marcin Peczarski v z y k Z a à a c k Spis treści 3 Przedmowa....................................................................................................................7 1. 2. Podstawy......................................................................................................................11 1.1. M ikrokontroler S T M 3 2 F 1 0 7 ..............................................................................................12 1.2. Struktura p rzy k ład ó w ........................................................................................................... 13 1.3. Przykład I a - m iganie diodam i św ie c ą c y m i..................................................................15 1.3.1. Plik ex_ied.c.......................................................................................................................16 1.3.2. Pliki util_delay.h i util_delay.c.........................................................................................17 1.3.3. Pliki board_led.it i board_led.c........................................................................................17 1.3.4. Pliki stni32fi0x_gpio.lt i slin32fl0x_rcc.lt...................................................................... 18 1.3.5. Pliki stni32fl0x.lt, system_stm32fi0x.h i core_an3.h....................................................19 1.3.6. Plik Iibstiii32fi0x.a............................................................................................................ 19 1.3.7. Plik stm32f KLconf.h........................................................................................................ 20 1.3.8. Pliki board_def.lt i board_defs.lt..................................................................................... 21 1.3.9. Plik stdiiit.h........................................................................................................................ 22 1.3.10. Plik startup_stm32_cld.c.................................................................................................. 22 1.4. K om pilow anie p rz y k ła d ó w ................................................................................................ 23 1.5. W ejścia i w yjścia b in arn e....................................................................................................26 1.6. W yśw ietlacz c ie k ło k ry staliczn y ........................................................................................30 1.7. Przykład lb - test w yśw ietlacza ciek ło k ry staliczn eg o ...............................................33 1.7.1. Pliki board_lcd.lt i board_lcd_ksO108.c.........................................................................34 1.7.2. Pliki fotil5x8.lt \font5x8.c.................................................................................................37 1.7.3. Pliki ntil_lcd.lt i a liljc d .c ................................................................................................37 1.7.4. Plik ex_lcd.c...................................................................................................................... 38 1.8. O rganizacja pam ięci p ro g ra m u ..........................................................................................38 1.8.1. Sekcje..................................................................................................................................38 1.8.2. Procedura startowa............................................................................................................42 1.8.3. Skrypt konsolidatora.........................................................................................................45 1.9. Styl pisania i kom entow ania tekstu źró d ło w eg o ..........................................................49 Intersieci......................................................................................................................51 2.1. M odel w a rstw o w y ................................................................................................................52 2.2. E th ern et....................................................................................................................................54 2.3. IP - protokół in tersieci........................................................................................................ 60 2.4. A R P - tłum aczenie adresów sieciow ych na adresy sp rzęto w e................................ 66 2.5. Sieć testow a............................................................................................................................ 67 2.6. Przykład 2 - m onitor s ie c i..................................................................................................69 2.6.1. Pliki board_init.lt i b o a rd jn it.c ......................................................................................70 2.6.2. Pliki util_led.h i util_led.c............................................................................................... 79 2.6.3. Plik ex_eth.c...................................................................................................................... 80 Spis treści 4.2.3. 4.2.4. 4.2.5. 4.2.6. 4.2.7. 3. Stos TCP/IP................................................................................................................83 3.1. Przegląd im p lem en tacji....................................................................................................... 84 3.2. B iblioteka Iw IP ...................................................................................................................... 86 3.2.1. Dopasowanie do architektury mikrokontrolera - plik conex-in3.li..............................86 3.2.2. 3.2.3. 3.2.4. 3.2.5. Parametry konfiguracyjne - plik Iwipopts.h.................................................................. 93 Kompilowanie - plik liblwipd.ci..................................................................................... I^0 Kody błędów.................................................................................................................... I01 Struktura p b u f ................................................................................................................. 101 3.2.6. Struktura n e t i f .........................................................................................................................104 3.3. 4.4. 5. 3.7. Testy stero w n ik ó w .............................................................................................................. 136 3.8. 1CMP - kom unikaty kontrolne i kom unikaty o b łę d a c h .......................................... 137 3.8.1. Sprawdzanie osiągalności odbiorcy...............................................................................138 3.8.2. Powiadamianie o nieosiągalności odbiorcy..................................................................139 3.8.3. Kontrola przepływu.........................................................................................................139 3.8.4. Przekroczenie czasu.........................................................................................................140 3.8.5. Problem z parametrem..................................................................................................... 140 3.9. D H C P - konfigurow anie ustaw ień sieciow ych w ę z ła .............................................. 141 4. Programowanie w modelu klient-serwer 4.1. 143 N um er p o rtu .......................................................................................................................... 145 4.2. T C P .......................................................................................................................................... 146 4.2.1. Podstawowe własności.................................................................................................... 146 4.2.2. Nagłówek.......................................................................................................................... 147 U wagi k o ń co w e ..................................................................................................................166 Serwer TCP.............................................................................................................. 169 5.1. Protokół w arstw y ap lik acji............................................................................................... 170 5.1.1. Projekt protokołu............................................................................................................. 170 5.1.2. Projekt implementacji protokołu.................................................................................. 172 5.2. Przykład 5a - pierw sza w ersja serw era T C P ............................................................... 178 5.2.1. Pliki tcp_server.h i tcp_server.c..................................................................................... 178 5.2.2. Plik ex_tcpd.c...................................................................................................................185 5.2.3. Testowanie przykładu..................................................................................................... 186 3.5. Przykład 3b - sterow nik E thernetu bez k opiow ania................................................. 127 3.5.1. Plik util_eth_nc.c - inicjowanie interfejsu sieciowego............................................... 127 3.5.2. Plik util_eth_nc.c - wysyłanie ramek ethernetowych................................................130 3.5.3. Plik util_eth_nc.c - odbieranie ramek ethernetowych............................................... 130 3.6. Przykład 3c - eksperym entalny sterow nik E thernetu bez k opiow ania............... 132 3.6.1. Plik util_eth_zc.c - inicjowanie interfejsu sieciowego................................................133 3.6.2. Plik util_etli_zc.c - wysyłanie ramek ethernetowych.................................................. 134 Otwieranie połączenia.....................................................................................................149 Przesyłanie danych...........................................................................................................152 Zamykanie połączenia.....................................................................................................153 Funkcje biblioteczne........................................................................................................154 Funkcje zw rotne...............................................................................................................160 4.3. U D P ........................................................................................................................................162 4.3.1. Podstawowe własności....................................................................................................162 4.3.2. Nagłówek..........................................................................................................................162 4.3.3. Inicjowanie klienta i serw era..........................................................................................163 4.3.4. Przesyłanie danych.......................................................................................................... 163 4.3.5. Funkcje biblioteczne........................................................................................................164 4.3.6. Funkcja zw rotna.............................................................................................................. 166 D M A ....................................................................................................................................... 1°6 3.4. P rzykład 3a - p ierw sza w ersja sterow nika E th ern e tu ............................................... 109 3.4.1. Pliki util_liine.li i utU_time.c...........................................................................................109 3.4.2. Pliki util_eth.li i util_eth.c - inicjowanie interfejsu sieciowego.................................. 112 3.4.3. Plik ulil_eth.c - wysyłanie ramek ethernetowych.........................................................117 3.4.4. Plik utU_eth.c - odbieranie ramek ethernetowych........................................................118 3.4.5. Pliki utiijw ip.h i utiljw ip .c - inicjowanie interfejsu sieciowego.............................. 120 3.4.6. Pliki util_lwip.h i utiljw ip .c - budziki..........................................................................122 3.4.7. Pliki board_conf.li i boardjconf.c................................................................................. 124 3.4.8. Pliki util_lcd_ex.h i util_lcd_ex.c.................................................................................. 125 3.4.9. Plik ex_ip.c.......................................................................................................................125 5 5.3. Przykład 5b - serw er T C P z n a d z o rc ą ........................................................................ 188 5.3.1. Pliki util_wdg.h i util_wdg.c.......................................................................................... 189 5.3.2. Plik ex_tcpd_wdg.c......................................................................................................... 190 5.3.3. Testowanie przykładu..................................................................................................... 191 6. Klient T C P ............................................................................................................... 193 6.1. Projekt protokołu............................................................................................................... 194 6.2. Przykład 6a - pierw sza w ersja klienta T C P ...............................................................197 6.2.1. 6.2.2. 6.2.3. 6.2.4. 6.2.5. 6.2.6. Tryby o obniżonym poborzem ocy............................................................................... 198 Pliki util_rtc.h i ulil_rtc.c...............................................................................................198 Pliki tcp_client.h i tcp_client.c..................................................................................... 202 Plik util_error.h............................................................................................................... 210 Plik ex_tcp_client.c.........................................................................................................211 Testowanie przykładu.................................................................................................... 212 6.3. Przykład 6b - klient T C P z obsługą rejestrów z a p aso w y ch ..................................214 6.3.1. Pliki util_bkp.h i util_bkp.c...........................................................................................2 14 6.3.2. Plik lcp_client_bkp.c.......................................................................................................216 6.3.3. Plik ex_tcp_clnt_bkp.c....................................................................................................217 6.3.4. Testowanie przykładu.................................................................................................... 217 Spis treści 6 7. Serwer li DI»..............................................................................................................219 7.1. Projekt p rotokołu.............................................................................................................. 220 7.2. Przykład 7 - prosty serw er U D P .................................................................................221 7.2.1. Pliki udp_server.h i udp_server.c................................................................................ 221 7.2.2. Plik ex_udpd.c................................................................................................................ 224 7.2.3. Testowanie przykładu................................................................................................... 225 8. Klient UDP................................................................................................................227 8.1. D N S ...................................................................................................................................... 228 8.2. S N T P ................................................................................................................................... 229 8.3. Przykład 8 - autom atyczna synchronizacja zegara czasu rzeczy w isteg o 232 8.3.1. Pliki sntpjciient.h i sntp_client.c.................................................................................232 8.3.2. Plik ex_sntp.c................................................................................................................. 238 8.3.3. Testowanie przykładu....................................................................................................240 8.3.4. Uwagi końcowe............................................................................................................. 241 9. Rozgłaszanie UDP................................................................................................... 243 9.1. Przykład 9a - rozgłaszanie dalagram ów U D P ..........................................................244 9.1.1. Plik ex_send_bcast.c......................................................................................................244 9.1.2. Testowanie przykładu....................................................................................................247 9.2. Przedmowa Proponując C zytelnikow i kolejną na naszym rynku książkę o m ikrokontrolerach, pow inienem na w stępie udzielić odpow iedzi na dw a istotne pytania. O czym je s t ta książka? Do kogo je s t skierow ana? Na pierw sze pytanie najkrócej m ógłbym odpow iedzieć, że książka traktuje o im ple­ m entow aniu protokołów i tw orzeniu aplikacji sieciow ych na m ikrokontrolery, które są w yposażone w interfejs E thernet. W ydajność obliczeniow a m ikrokontrolerów sta­ le rośnie (przy zachow aniu poboru m ocy w granicach rozsądnych dla lego rodzaju układów ). U m ożliw ia to zaim plem entow anie stosu protokołów sieciow ych TCP/IP, dotychczas dostępnego tylko na dużych m aszynach i kom puterach osobistych. M oim zdaniem spow oduje to rew olucję zastosow ań m ikrokontrolerów , podobną do tej, jak ą spow odow ało kilkadziesiąt lat tem u łączenie kom puterów osobistych w sieci lokalne (ang. local area netw orks) i intersieci (ang. internets). U rządzenia sterow ane m ikrokontroleram i m ogą stać się częs'cią Internetu, co stw arza zupełnie now e m ożliw ości. Specyfika urządzeń sterow anych m ikrokontroleram i polega m iędzy innym i na ko­ nieczności reagow ania na w iele zdarzeń zew nętrznych i sterow ania w ielom a p e­ ryferiam i. C zasy reakcji pow inny być na tyle krótkie, aby spraw iać w rażenie, że w szystko dzieje się niejako rów nolegle. Stosow ane są tu dw a podejścia: - cala aplikacja napisana jest w postaci jed n eg o program u, m ającego dostęp do całości zasobów sprzętow ych, bezpośrednio obsługującego układy peryferyjne i w ykorzystującego intensyw nie system przerw ań - działaniem m ikrokontrolera steruje system operacyjny, ukryw ający obsługę sprzętu i przerw ań w sterow nikach urządzeń, a aplikacja jest podzielona na za­ dania, procesy lub w ątki w ykonyw ane w spółbieżnie pod kontrolą tego system u operacyjnego. Przykład 9b - odbieranie datagram ów U D P 9.2.1. 9.2.2. ................................................. 247 Plik ex_recv_bcast.c...................................................................................................... 248 Testowanie przykładu....................................................................................................249 10. Serwis W W W ...........................................................................................................251 łO .I. K om unikacja m iędzy klientem a serw erem W W W .................................................252 10.1.1. URI.................................................................................................................................. 252 10.1.2. H TTP...............................................................................................................................253 10.1.3. HTML.............................................................................................................................. 256 10.2. Przykład 10 - prosty serw is W W W .............................................................................259 10.2.1. Pliki httpjm rser.h i http_jmrser.c................................................................................ 259 10.2.2. Pliki http_server.h, littp.lt i http_applicatian.h........................................................... 265 10.2.3. Plik http_server.c - obsługa H TTP.............................................................................. 266 10.2.4. Plik lutp_server.c - obsługa połączenia TCP.............................................................. 271 10.2.5. Plik littp_(ipplication.c.................................................................................................. 273 10.2.6. Plik stm32_logo.h........................................................................................................... 277 10.2.7. Plik exjittpd.c.................................................................................................................278 10.2.8. Testowanie przykładu............................................................................................. 278 Dodatek. Narzędzia G NU............................................................................................. 281 Literatura......................................................................................................................... 286 W niniejszej książce prezentuję pierw sze podejście, które sprzyja zm niejszaniu rozm iaru pam ięci zajm ow anej przez aplikację, co byw a nadal istotne w system ach w budow anych. K siążka ta m a w założeniu być podręcznikiem i przew odnikiem . C hcąc zrealizow ać zasadę, że najlepiej uczyć się na przykładach, stanąłem przed koniecznością w ybo­ ru platform y sprzętow ej i środow iska program istycznego. Prezentow ane w książ­ ce zagadnienia ilustruję przykładam i napisanym i na m ikrokontroler STM 32F107 z rdzeniem A R M C ortex-M 3 firm y ST M icroeleclronics. Do ich przetestow ania uży­ łem zestaw u Z L29A R M z m odułem ethernetow ym ZL3E T H oraz w yśw ietlaczem ciekłokrystalicznym W G 12864A . Przykłady napisane są w języ k u C, w którym obecnie najczęściej program uje się m ikrokontrolery. K om pilow ałem je za pom ocą G C C w w ersji 4.4.3, z w ykorzystaniem G N U B inutils w wersji 2.20.1 i N ew iib w w ersji 1.18. U żyłem w nich publicznie dostępnej im plem entacji stosu T C P/IP - biblioteki lw IP w w ersji 1.3.2. S korzystałem też z bibliotek dostarczanych przez S T M icroeleclronics: C M SIS (C ortex M icrocontroller Softw are Interface Standard) w w ersji 1.30, ST M 32F10x Standard P eripherals Library w wersji 3.3.0 i ST M 32 E TH F irm w are Library w w ersji 1.1.0. 8 Przedmowa Św iadom ie zrezygnow ałem z pisania przykładów w języku C++, który zyskuje ostat­ nio coraz w iększą popularność w s'wiecie m ikrokontrolerów . C ++ ujaw nia sw oje za­ lety przy dużych program ach, zw łaszcza gdy intensyw nie korzysta się ze standardo­ wej biblioteki w zorców STL (ang. Standard Template Library). Nie m a co ukrywać, że C ++ je st bardzo trudnym językiem . C hcę, aby książka była w pełni dostępna dla C zytelnika nieznającego C++. U żyw ając pełnej siły wyrazu C++, ryzykow ałbym nie­ zrozum ienie przykładów, a nie ma tu m iejsca na szczegółow e objaśnianie zaaw anso­ w anych konstrukcji tego języka. N atom iast pisanie przykładów w jakiejś' okrojonej w ersji C ++ byłoby tylko niepotrzebnym dodaw aniem lukru obiektow ości. C zytelnik znający C ++ bez problem u przełoży na ten języ k przykłady napisane w C. Przykłady starałem się pisać w sposób ogólny, aby m ogły być łatw o przeniesione na inne m ikrokontrolery. Jedynym rzeczyw iście specyficznym i m ocno zależnym od sprzętu fragm entem kodu jest sterow nik (ang. driver) pośredniczący m iędzy bi­ blioteką lw IP a m ikrokontrolerem . Szczegółow o w yjaśniam , ja k napisać taki ste­ row nik i ja k dopasow ać bibliotekę lw iP do architektury konkretnego m ikrokontro­ lera. Pozostała część prezentow anego przeze m nie oprogram ow ania w cale lub tylko w bardzo niew ielkim stopniu zależy od architektury sprzętu i daje się łatw o zaadap­ tow ać na dow olny m ikrokontroler. Postaram się teraz odpow iedzieć na drugie z postaw ionych na początku pytań. K siążka przeznaczona jest dla osób, które ju ż m ają jak ieś dośw iadczenie w pro­ gram ow aniu m ikrokontrolerów. Zakładam , że C zytelnik um ie program ow ać w C. C hcącym poszerzyć sw oją w iedzę o tym języ k u polecam klasyczną książkę Język A N SI C, napisaną przez je g o tw órców , K ernighana i R itchiego [2J. N ie je st potrzebna znajom ość A sem blera ARM . O czekuję co najm niej podstaw ow ej w iedzy z zakresu elektroniki, tak aby na podstaw ie opisów i schem atów zam ieszczonych w książce oraz danych katalogow ych um ieć sam odzielnie zm ontow ać układ prototypow y lub w ykonać niezbędne połączenia w jak im ś zestaw ie uruchom ieniow ym , których wiele jest dostępnych na rynku. Nie oczekuję natom iast żadnej w iedzy o sieciach kom pu­ terow ych czy protokołach sieciow ych - staram się w yjaśniać w szystko od podstaw. Z akładam też, że C zytelnik m a w ystarczające obycie inform atyczne, aby sam odziel­ nie zainstalow ać środow isko program istyczne (edytor, kom pilator itd.) i zapoznać się ze szczegółam i je g o obsługi. M am nadzieję, że książka będzie ciekaw ą lekturą zarów no dla profesjonalisty, zaw odow o projektującego układy z m ikrokontroleram i, ja k i hobbysty zajm ującego się tym tylko dla w łasnej satysfakcji. M oże też zaintere­ sow ać osoby, które nigdy dotąd nie program ow ały m ikrokontrolerów , a chciałyby się dow iedzieć, ja k im plem entuje się protokoły sieciow e na taki komputer. W ydaje mi się, że dodatkow ym atutem książki jest zaprezentow anie Czytelnikow i przedstaw iciela now oczesnej rodziny m ikrokontrolerów STM 32. Jest to niew ątpli­ wie rodzina układów, które m ają szansę odnieść rynkow y sukces w najbliższej przy­ szłości. W ybrany do napisania przykładów m ikrokontroler STM 32F107 należy do linii zorientow anej na kom unikację (ang. connectivity line). O prócz zw ykle spotyka­ nych w m ikrokontrolerach interfejsów I2C, SPI i US ART, w yposażony jest w CAN, Ethernet, I2S i U SB. Interfejs Ethernet może pracow ać z przepływ nością 10 M b/s lub 100 M b/s w trybie dw ukierunkow ym naprzem iennym (ang. half-duplex) lub dw ukierunkow ym jednoczesnym (ang. full-duplex). Interfejs USB m oże pracow ać Przedmowa 9 z przepływ nością 12 M b/s (ang. fu ll speed) jako urządzenie (ang. device) oraz z prze­ pływ nością 1,5 M b/s (ang. low speed) lub 12 M b/s jako host. Ponadto STM 32F107 zaw iera dość typow e układy licznikow e oraz przetworniki analogow o-cyfrowe i cy­ frowo-analogowe. Skonstruow any jest w oparciu o 32-bitowy rdzeń ARM Cortex-M 3, który można taktować m aksym alnie z częstotliw ością 72 M Hz. Rdzeń ten za­ projektow ano specjalnie do sterow ania system am i głęboko w budowanym i (ang. de­ eply em bedded). O feruje rozbudow any system przerwań z krótkim i przewidywalnym czasem rozpoczęcia obsługi oraz typow e dla tego segm entu układów tryby oszczędza­ nia energii. Rdzeń obsługuje tylko zestaw instrukcji Thum b-2, rozszerzający zestaw instrukcji T hum b o kodach 16-bitowych o instrukcje o kodach 32-bitowych. Thum b-2 je st reklam ow any jak o osiągający w ydajność tylko nieznacznie mniejszą od zestawu instrukcji A RM o kodach 32-bitow ych przy zm niejszeniu o około 25% zapotrzebo­ w ania na pam ięć program u, co je st porów nyw alne z gęstością kodu osiąganą przy zastosow aniu okrojonego zestawu instrukcji Thum b, który jednak cechuje się istotnie m niejszą w ydajnością od pełnego zestawu instrukcji ARM . U kład książki jest następujący. R ozdział 1 pełni funkcję rozbudow anego wstępu. Poruszam w nim zagadnienia niezw iązane bezpośrednio z tytułem książki, ale po­ trzebne w dalszej jej części. O pisuję obsługę w ejść i w yjść ogólnego przeznaczenia (ang. general purpose input-output) na przykładzie diod św iecących i w yśw ietla­ cza ciekłokrystalicznego. W yjaśniam strukturę archiw um z przykładam i i param etry kom pilacji. Omawiam, też organizację pam ięci program u oraz działanie procedury startow ej (ang. startup code) i skryptu konsolidatora (ang. linker script). Rozdział 2 zaczynam od przedstaw ienia m odelu w arstw ow ego intersieci. N astępnie opisuję technologię Ethernet, ale skupiam się tylko na jej w ariantach i trybach pracy ob­ sługiw anych przez m ikrokontroler. Przedstaw iam budow ę ramki i rodzaje adresów ethernetow ych. N astępnie w yjaśniam , ja k ram ki podstaw ow ego protokołu intersie­ ci, czyli IP (ang. Internet Protocol), są przesyłane w ram kach Ethernet. O pisują też działanie A R P (ang. A ddress Resolution Protocol), czyli protokołu tłum aczącego ad­ resy IP na adresy ethernelow e. Rozdział ten kończę przykładem prostego m onitora sieci. W rozdziałach 3 i 4 om aw iam bibliotekę lw iP im plem entującą stos protokołów TCP/IP. W rozdziale 3 zajm uję się w spółpracą tej biblioteki ze sprzętem - pokazuję trzy w ersje sterow nika Ethernetu. Poszczególne sterow niki różnią się trybem pracy D M A (ang. D irect M em ory A ccess) oraz sposobem obsługi buforów odbiorczych i nadaw czych. Pokazuję w ersję z kopiow aniem zaw artości buforów i bez kopiow a­ nia ich zaw artości (ang. zero copy). N a końcu tego rozdziału przedstaw iam nieco inform acji o protokołach IC M P (ang. Internet C ontrol M essage Protocol) i DHCP (ang. D ynam ie H ost Configuration Protocol). W rozdziale 4 zajm uję się interfejsem program istycznym API (ang. application program m ing interface) m iędzy bibliote­ ką lw iP a aplikacją. O pisuję podstaw ow y interfejs udostępniany przez tę bibliotekę, czyli interfejs surow y (ang. raw). Pokazuję, jak w ykorzystać ten interfejs do tw orze­ nia aplikacji w m odelu klient-serw er. W rozdziale tym przedstaw iam też niezbędne inform acje o protokołach T C P (ang. Transmission Control Protocol) i U DP (ang. U ser D atagram Protocol). Rozdział 4 jest jedynym w książce niezakończonym żadnym przykładem , gdyż w łaściw ie kolejne rozdziały do końca książki zaw ierają przykłady korzystające z w iadom ości przedstaw ionych w tym rozdziale. W rozdziale 5 opisuję dw a przykłady serw erów TCP, czyli podstaw ow ego strum ieniow ego pro- 10 Przedmowa tokołu w arstwy transportow ej intersieci. W drugim z tych serw erów urucham iam układ nadzorcy (ang. w atchdog) w celu zopobieżenia trw ałem u zaw ieszeniu się program u. W rozdziale 6 om aw iam dw a przykłady klientów TCP. K orzystają one z w budow anego w m ikrokontroler zegara czasu rzeczyw istego RTC (ang. R eal Time C lock), w celu urucham iania się w zadanych odstępach czasu. Ponadto korzystają leż z trybu czuw ania (ang. standby), aby zm niejszyć pobór prądu zasilania m iędzy ko­ lejnymi uruchom ieniam i. D rugi z klientów dodatkow o używ a rejestrów zapasow ych (ang. backup registers) m ikrokontrolera STM 32F107, aby m iędzy kolejnym i urucho­ m ieniam i przechow ać w nich dane aplikacji. W rozdziale 7 zam ieszczani przykład prostego serw era UDP, czyli podstaw ow ego pakietow ego protokołu w arstw y trans­ portow ej intersieci. S erw er ten pozw ala zdalnie sterow ać portam i w ejścia-w yjścia m ikrokontrolera. W rozdziale 8 opisuję przykład klientów dw óch protokołów bazu­ jących na UDP, a m ianow icie DNS (ang. D om ain N am e System ) i S N T P (ang. Sim ple N etw ork Time Protocol). S N T P służy do synchronizacji czasu w sieci i um ożliw ia zsynchronizow anie zegara czasu rzeczyw istego m ikrokontrolera z jak im ś dostępnym w Internecie atom ow ym w zorcem czasu. W rozdziale 9 zajm uję się rozgłaszaniem (ang. broadcast) w UDP. W rozdziale 10 pokazuję, ja k skom unikow ać się z m ikro­ kontrolerem za pom ocą przeglądarki internetow ej i opisuję im plem entację prostego serw isu W W W (ang. World Wide Web). Listę książek i dokum entów , z którym i w ar­ to się zapoznać, zam ieszczam w spisie literatury. W dodatku opisuję narzędzia G NU , których użyłem do skom pilow ania przykładów. D uża część książki, począw szy od rozdziału 4, zaw iera szczegółow e opisy, jak im plem entuje się w łasne protokoły i tw orzy aplikacje korzystające bezpośrednio z protokołów transportow ych T C P i UDP. W szystkie przykłady używ ają interfejsu surow ego, który pozw ala na lepszą integrację aplikacji ze stosem TCP/IP. Interfejs surow y jest preferow any w sy stem ach w budow anych, gdyż ma m ale w ym agania pam ięciow e i nie potrzebuje dużej m ocy obliczeniow ej - nie m a w ątków ani p ro ­ cesów , nie trzeba zm ieniać kontekstu. P rzykładow e program y są sterow ane zdarze­ niami (ang. event based) za pom ocą funkcji zw rotnych (ang. callback functions). Ź ródłem zdarzeń są przerw ania. Przykłady konstruuję przyrostow o - kolejne korzy­ stają z m odułów zaprogram ow anych na potrzeby poprzednich przykładów . W szystkie pliki źródłow e przykładów , łącznie ze źródłam i biblioteki lw IP oraz źródłam i specyficznych dla m ikrokontrolerów S T M 32 bibliotek dostarczanych przez ST M icroelectronics, dostępne są w postaci skom presow anego archiw um , k tó ­ re m ożna ściągnąć ze strony W ydaw nictw a BTC http://w w w .btc.pl lub strony d o m o ­ wej A utora h ttp://w w w .m iinuw .edu.pl/~ nw rpe/book. C hcę w yraźnie zaznaczyć, że książka nie je st instrukcją obsługi narzędzi progra­ m istycznych ani nie stanow i w yczerpującej dokum entacji sprzętu użytego do prze­ testow ania zam ieszczonych przykładów . C zytelnik z łatw ością znajdzie potrzebną dokum entację na stronach internetow ych odpow iednich producentów . Staram się prom ow ać polską term inologię. D la w ygody C zytelnika, zw ykle zm u­ szonego korzystać z dokum entacji w języku angielskim , przy pierw szym , a czasem i przy kolejnym , użyciu term inu, który nie je s t pow szechnie znany, um ieszczam w naw iasach je g o angielski odpow iednik. M arcin P eczarski, W arszaw a 2011 Podstawy 12 I. Podstawy W tym rozdziale poruszam zagadnienia niezw iązane bezpośrednio z tytułem książki. Z apoznanie się z w iększością tego m ateriału uw ażam jed n ak za potrzebne do zro ­ zum ienia przykładów zam ieszczonych w następnych rozdziałacłi. Ponadto niektóre z tych zagadnień nie są, m oim zdaniem , dostatecznie obszernie opisane w literatu­ rze pośw ięconej m ikrokontrolerom , a w ydają mi się w ażne i ciekaw e. Staram się tu przedstaw ić tylko niezbędne podstaw y, ujęte w takiej kolejności, aby C zytelnik m ógł ja k najszybciej zacząć urucham iać program y. C zytelnik czujący, że przedsta­ w ione w tym rozdziale tem aty są m u dobrze znane, m oże go szybko przekartkow ać lub przejść od razu do następnego rozdziału, czyli do zasadniczej części książki. 1.1. Mikrokontroler STM32F107 W szystkie prezentow ane w lej książce przykłady napisałem w języ k u C na m ikro­ kontroler ST M 32F107, który w yposażony jest w 32-bitow y rdzeń A RM C ortexM 3. Ponadto m ikrokontroler ten m a w iele układów peryferyjnych, m.in. interfejs E thernet, który um ożliw ia podłączenie go do sieci lokalnej, a za je j pośrednictw em do Internetu. U ktad S T M 32F107 je s t dostępny w kilku w ersjach różniących się w ielkościam i pam ięci i liczbą w yprow adzeń. Z estaw iono je w tabeli 1.1. S krót KiB oznacza niedaw no w prow adzoną do inform atyki now ą jed n o stk ę rozm iaru pam ięci - kibibajt (kilobinarybajt), czyli d okładnie 1024 bajty, w odróżnieniu od kilobajta (skrót kB), który form alnie pow inien m ieć 1000 bajtów. O bsługa E thernetu i stosu T C P /IP je st bardzo „pam ięciożerna” , m im o to w szystkie zam ieszczone w tej książ­ ce przykłady m ożna uruchom ić na najskrom niejszym m odelu. W tabeli 1.2 przestaw iono podstaw ow e typy C obsługiw ane sprzętow o przez rdzeń C ortex-M 3. W celu w ykonania operacji arytm etycznych na innych typach, w szcze­ gólności na 64-bitow ym typie całkow itym ł o n g l o n g i typach zm iennoprzecinko­ w ych, w yw oływ ane są funkcje biblioteczne. D latego ze w zględów w ydajnościo- Tab. 1.1. Dostępne wersje mikrokontrolera STM32F107 Model Flash SRAM STM 32F107R B 12 8 KiB 48 KiB LQFP64 STM 32F107R C 25 6 KiB 64 KiB LQFP64 STM 32F107VB 128 KiB 4 8 KiB LQFP100 lub LFBGA100 STM 32F107VC 2 5 6 KiB 64 KiB LQFP100 lub LFBGA100 a tires, void*, char* itd. R ozm iar 8 bitów 16 bitów 32 bity 32 bity 32 bity 13 w ych, jeśli jest to m ożliw e, należy unikać stosow ania typu long long, a przede w szystkim typów zm iennoprzecinkow ych f l o a t , d o u b le i long double. W m ikrokontrolerach STM 32 rdzeń C ortex-M 3 je st skonfigurow any na stale w try­ bie cienkokońców kow ym (ang. little-enclian). Z atem zm ienna w ielobajtow a prze­ chow yw ana jest w pam ięci od najm niej do najbardziej znaczącego bajtu. Ilustruje to poniższy fragm ent program u w języku C. union { unsigned short s; unsigned char c [2); } a; a.s = 0xla2b; if (a.c[0) == Qx2b 66 a.cli] == Qxla) /* Jestem cienkokońcówkowy (ang. little-endian). */ else if (a.cfO] == Gxla 66 a.c[l] == 0x2b) /* Jestem grubokońcówkowy (ang. big-endian). */ C ortex-M 3 m a typow y dla architektury A RM zestaw rejestrów: - RO do R12 - rejestry ogólnego przeznaczenia (ang. general purpose registers), SP (R13) - w skaźnik stosu (ang. stack pointer), LR (R 14)- adresu pow rotu (ang. link register), PC (R15) - licznik program u (ang. program counter), PSR - rejestr znaczników (ang. program status register), PRIMASK, FAULTMAyJK, BASEPRI - rejestry m askujące przerw ania (ang. exception m ask registers) - w dokum entacji przerw ania nazyw ane są w yjątkam i, - CONTROL - rejestr sterujący trybam i pracy rdzenia. O bszerniejszy opis architektury m ikrokontrolera STM 32F107 znajduje się w kolej­ nych rozdziałach, gdzie będzie potrzebny w prezentow anych przykładach. Czytelnik zainteresow any szczegółam i m oże też zaw sze sięgnąć do dokum entacji dostępnej w Internecie. O gólny przegląd architektury i param etry elektryczne zam ieszczone są w [9]. N iezbędne dla program istów inform acje o rdzeniu m ożna znaleźć w |7], a w szystkie układy peryferyjne są opisane szczegółow o w [8]. Obudowa Tab. 1.2. Podstawowe typy języka C i ich rozmiary w architekturze Cortex-M3 Typ char signed char unsigned char short unsigned short int unsigned long unsigned long 1.2. Struktura przykładów Struktura przykładów Integralną częścią książki są teksty źródłow e przykładów . Skom presow ane archi­ w um zaw ierające aktualną ich w ersję m ożna ściągnąć ze strony W ydaw nictw a B TC http://w w w .btc.pl lub ze strony dom ow ej A utora htip://www.minutw.echt. p t/~m a rpe/book. Spora część tekstów źródłow ych m a charakter dość standardo­ wy, bardzo techniczny i ich dokładne poznanie je st zbędne do zrozum ienia dzia­ łania program u. Ponadto przeglądanie długich w ydruków program ów byw a nu­ żące. N atom iast przestudiow anie całości teksów źródłow ych staje się oczyw iście konieczne, gdy chcem y je zm odyfikow ać. D latego w książce zam ieszczam tylko kluczow e fragm enty tekstów źródłow ych, a chcących poznać całość odsyłam do archiw um w w ersji elektronicznej. A rchiw um to zaw iera strukturę katalogów po­ k azaną na rysunku 1.1. Ż eby zachow ać przejrzystość, niektóre podkatalogi - nie­ istotne z punktu w idzenia zrozum ienia treści książki - na tym rysunku pom inięto. Ścieżki w tym archiw um podaję w konw encji uniksow ej z ukośnikiem w praw ą 14 ■exam ples - stronę. Jeśli nazw a ścieżki rozpoczyna się od kropki, to je s t to ścieżka w zględem katalogu, w którym rozpakow ano archiw um z przykładam i. Jestem przekonany, że taka konw encja pozw oli C zytelnikow i łatw o odnajdow ać p otrzebne katalogi i pliki w system ie, którego używ a. K atalog ./exam ples zaw iera teksty źródłow e w szystkich przykładów opisanych w tej książce. Podkatalog ./exam ples/src zaw iera pliki z im plem entacją. P odkatalog ./exam ples/include zaw iera pliki nagłów kow e. Jego podkatalogi butterfly, p ro to ty­ p e, z,l29ann+z.l3eth zaw ierają pliki nagłów kow e definiujące k onfigurację sprzętu. P odkatalog ./exam ples/scripts zaw iera skrypty konsolidatora (ang. lin ker scripts). W nazw ach plików stosuję następ u jącą konw encję. Pliki, których nazw a zaczyna się od przedrostka board, zaw ierają tekst źródłow y zależny od użytego zestaw u uruchom ieniow ego, czyli od schem atu elektrycznego k onstruow anego urządzenia. Pliki, których nazw a zaczyna się od przedrostka util, zaw ierają funkcje użyteczne w w ielu przykładach i niezależne od schem atu elektrycznego, ale być m oże nadal zależne od architektury m ikrokontrolera. N azw y głów nych plików poszczeg ó l­ nych przykładów , zaw ierających funkcję m ain, zaczynają się od przedrostka ex. P ozostałe pliki nie zależą w cale lub zależą w niew ielkim stopniu od arch itek tu ­ ry m ikrokontrolera, a tym bardziej nie zależą od schem atu elektrycznego. N azw a pliku, który im plem entuje protokół sieciow y, zaw iera skrót nazw y tego protokołu (np. tcp, udp, snip, http) o raz pełn io n ą w tym protokole funkcję (np. client, se­ rver). Poszczególne pliki źródłow e, um ieszczone w katalogu ./exam ples, opisuję sukcesyw nie w rozdziałach dotyczący ch odpow iednich przykładów , w których są w ykorzystyw ane. i W katalogu ./lw ip-1.3.2 znajdują się źródła biblioteki iw IP im plem entującej stos protokołów TCP/IP. Do napisania przykładów prezentow anych w tej książce w yko­ rzystałem jej w ersję 1.3.2. K atalog ./excim ples/include/arcli zaw iera pliki nagłów ­ kow e specyficzne dla architektury C ortex-M 3 i potrzebne do skom pilow ania tej biblioteki. Ponadto w katalogu ./exam ples/include znajduje się plik nagłów kow y lw ipopts.li, za pom ocą którego konfiguruje się opcje stosu TCP/IP. B ibliotekę IwIP i w szystkie te pliki nagłów kow e opisuję szczegółow o w rozdziale 3. W katalogu Jst/L ibraries um ieszczone są źródła bibliotek dostarczanych przez ST M icroelectronics. Są to C M SIS (C ortex M icrocontroller Softw are Interface Standard) w wersji 1.30, S T M 32FIO x Standard P eripherals L ibrary w wersji 3.3.0 [6] i ST M 32 ETH F irm w are L ibrary, przez producenta określana też ja k o STM 32 ETH Driver, w wersji 1.1.0 patrz rów nież [3], W szystkie razem nazyw am dalej skrótow o biblioteką STM 32. Sposób skom pilow ania biblioteki STM 32 opisuję w rozdziale 1.4. U dostępniane przez nią struktury i funkcje, które w ykorzystuję, om aw iam przy odpow iednich przykładach. W katalogu ,/st znajdują się też dw a pli­ ki w form acie chm. Jeden zaw iera d o kum entację S T M 32F10x Standard P eripherals Library, a drugi - opis S T M 32F 107 L w lP D em onstration Package w raz z doku­ m entacją ETH Firm w are Library. W katalogu ./st/L ibraries/C M SIS/D ocum entation znajduje się dokum entacja C M SIS w form acie htm l. K atalog ./m ake zaw iera skrypty dla program u m ake. O pisuję je w dodatku. K atalog ten zaw iera rów nież program y pom ocne przy urucham ianiu niektórych przykładów. Przedstaw iam je w odpow iednich m iejscach, gdzie są w ykorzystyw ane. 15 1.3. Przykład la - miganie diodami świecącym i I. Podstawy -s rc - Include - arch - butterfly - prototype - zl29arm +zl3eth — scripts -s rc — - lw lp -1 .3 .2 - -Ip v4 - n etif - include I - s t — L ib ra rie s- ipv4 -S T M 3 2 F 1 O x_S tdP eriph_D river-S T M 3 2 ETH D riv e r --------------- CM SIS - ■make n src inc - C M 3 —i— C oreSupport '— D evice S u pp o rt- -S T - -STM 32F10X Rys. 1.1. Struktura katalogów archiwum z przyktadami 1.3. Przykład 1a - miganie diodami świecącymi W w ielu książkach uczących program ow ania pierw szym prezentow anym przykła­ dem je s t zw ykle program typu W itaj Św iecie. W św iecie m ikrokontrolerów oznacza to zam iganie diodą św iecącą. N ie je ste m oryginalny i leż w pierw szym przykła­ dzie m igam diodam i. Posłuży mi to jed n ak do czegoś w ięcej, do opisania kolejnych składników architektury m ikrokontrolera, zależności m iędzy plikam i nagłów kow y­ mi, sposobu konfigurow ania zestaw u uruchom ieniow ego oraz kom pilow ania cało­ ści. Przykłady, które prezentuję w kolejnych rozdziałach, są coraz bardziej skom ­ plikow ane, składają się czasem naw et z kilkudziesięciu plików źródłow ych, ale ich struktura je s t analogiczna do struktury pierw szego przykładu. Poznanie tej struktury na prostym przykładzie um ożliw i później skupienie się na m erytorycznej zaw ar­ tości przykładów , bez potrzeby opisyw ania za każdym razem , gdzie w archiw um znajdują się potrzebne pliki, ja k dopasow ać przykład do innego schem atu elektrycz­ nego, ja k go skom pilow ać itd. W zestaw ie Z L29A R M do m ikrokontrolera podłączone są dw ie diody św iecące. Załóżm y, że je d n a je s t czerw ona, a druga zielona. W pierw szym przykładzie m iga­ ją one w nieskończonej sekw encji: św ieci czerw ona, św iecą obie, św ieci zielona, obie nie św iecą. W ta b e li 1.3 zestaw iono nazw y plików źródłow ych i bibliotecz­ nych, które trzeba w yspecyfikow ać kom pilatorow i, aby skom pilow ać ten przykład. Tab. 1.3. Pliki przykładu 1a Źródłowe I biblioteczne e x je d .c startup _stm 32_cld. c boardJ e d .c util_delay.c Iibstm 32/10x.a Nagłówkowe board_def.h board_defs.li board led.h utH_delay.h Stm32t10x_conf,h 16 17 1.3. Przykład la - miganie diodami świecącymi 1. Podstawy 1.3.2. Pliki util_delay.h i util_delay.c Plik util_delay.h znajduje się w katalogu ./exam ples/include, a plik util_delay.c w ka­ talogu ./exam ples/src. Pierw szy z tych plików deklaruje sygnaturę funkcji opóźnia­ jącej, a drugi zaw iera jej im plem entację. F unkcja ta je st bardzo prosta: void Delay(volatile unsigned count) ( while(count— ); I U zyskanie w ym aganego opóźnienia w ym aga eksperym entalnego skalibrow ania w artości argum entu, gdyż czas opóźnienia zależy od częstotliw ości taktow ania i ustaw ienia opcji kom pilatora. Ponadto w szelkie przerw ania obsługiw ane w trak­ cie w ykonyw ania tej funkcji w ydłużają opóźnienie. Precyzyjne odm ierzanie cza­ su m ożna uzyskać, w ykorzystując układy licznikow e, co jednak w ym aga znacznie w ięcej pracy program istycznej. Jednak w wielu zastosow aniach taka prosta funkcja jest w ystarczająca i będziem y z niej korzystać w kolejnych przykładach. Rys. 1.2. Pliki nagłówkowe przykładu 1a Ponadto zaw iera ona nazw y plików nagłów kow ych w ykorzystyw anych w tym przykładzie i znajdujących się w podkatalogu ./exam ples/include. Pliki nagłów ­ kow e bibliotek nie są w ym ienione. N a rysunku 1.2 zobrazow ano g raf zależności w łączania plików nagłów kow ych z uw zględnieniem plików nagłów kow ych biblio­ tek. W kolejnych podrozdziałach opisuję szczegółow o zaw artość poszczególnych plików. O opcjach kom pilacji piszę w rozdziale 1.4. U staw ienia zw orek zestaw u Z L29A R M w tym przykładzie nie m ają istotnego znaczenia. N ależy tylko w ybrać sposób zasilania płytki zw orką PW R SE T (U SB lub E X T - zew nętrzny zasilacz) i zw orkam i BOOTO i BOOT1 m iejsce, skąd startuje program . Ja ustaw iam BOOTO w pozycji 0, aby program startow ał z pam ięci Flash. W tym przypadku ustaw ienie BOOT1 nie m a znaczenia. 1.3.1. 1.3.3. Pliki boardJ e d .h i boardJ e d .c P lik boardJ e d .li znajduje się w katalogu ./exam ples/include, a plik b o a r d je d .c w katalogu ./exam ples/src. W pierw szym z tych plików deklarujem y sygnatury funk­ cji obsługujących diody św iecące, a w drugim um ieszczam y ich im plem entacje. N ajpierw uzależniam y tekst źródłow y program u od połączeń w zestaw ie urucho­ m ieniow ym . D eklarujem y, że diody św iecące podłączone są do portu E (G PIO E, ang. g eneral purposeńnput-output E), czerw ona dioda do w yprow adzenia 15, a zie­ lona - do w yprow adzenia 14. D o w yprow adzeń podłączone są katody diod, zatem następnie definiujem y, że dioda św ieci, gdy na w yprow adzeniu je st stan niski (stała Bit_RESET), a nie św ieci w stanie w ysokim (stała Bit_SET). O dpow iedni fragment program u w ygląda następująco: Plik e x je d .c ((include <board_def,h> Plik e x j e d .c znajduje się w katalogu ./exam ples/src i zaw iera funkcję main przy­ kładu. W funkcji main najpierw w yw ołujem y funkcję LED configure konfigurującą w yprow adzenia, do których podłączone są diody św iecące, a następnie w nieskoń­ czonej pętli w yw ołujem y funkcje w łączające lub w yłączające odpow iednią diodę św iecącą, poprzedzielane w yw ołaniem funkcji opóźniającej D elay. Funkcje te o p i­ suję w następnych podrozdziałach. lifndef BOARD_TYPE lerror BOARD_TYPE undefined (fendif int main(void) | static const unsigned delay_time = 2000000; LEDconfigure(); for (;;) { RedLEDonO; Delay(deiay_time); GreenLEDonO ; Delay (delay_tiine); RedLEDoff(); Delay(delay_time); GreenLEDoff(); Delay(delay_time); ) ) łif BOARD_TYPE ==* PROTOTYPE i | \ BOARD_TYPE == BUTTERFLY !! \ BOARD_TYPE == ZL29ARM (¡define GPIO_LED (¡define REDDLED fdefine GREEN_LED idefine RCC_APB2Periph_GPIO_LED ¡(define LED_ON Idefine LED_OFF (¡else terror Undefined BOARD_TYPE fendif GPIOE GPIO_Pin_15 GPIO_Pin_14 RCC_APB2Periph_GPIOE BitJtESET Bit SET W t-U .J . S tała BOARD_TYPE musi być zdefiniow ana w pliku board_def.li. W artości, do których porów nyw ana je st ta stała, zdefiniow ane są w pliku board_defs.Ii. Pliki board_def.lt i board_defs.h opisuję w jednym z następnych podrozdziałów . W m ikrokontrolerach ST M 32 przed użyciem jakiegokolw iek układu peryferyjne­ go m usim y w łączyć taktow anie tego układu. D om yślnie, po w yzerow aniu m ikro­ kontrolera, w szystkie sygnały taktujące peryferie są w yłączone. Jest to rozsądne, 18 I. Podstawy gdyż oszczędza energię - nieużyw ane układy nie pobierają niepotrzebnie prądu. Z atem w funkcji konfigurującej diody św iecące najpierw m usim y uaktyw nić tak­ tow anie portu, do którego są one podłączone. N astępnie, przed w łaściw ym skon­ figurow aniem , ustaw iam y tak port w yjściow y, aby diody były początkow o w yłą­ czone. W yprow adzenia konfigurujem y w trybie w yjściow ym przeciw sobnym (ang. push-pull output). Poniew aż sterow anie diodam i św iecącym i nie w ym aga strom ych zboczy sygnału, ustaw iam y najm niejszą (z trzech m ożliw ych: 2 M H z, 10 M H z lub 50 M H z) szybkość zm ian sygnału na tych w yprow adzeniach. C ała funkcja konfigu­ rująca diody św iecące w ygląda tak: 1.3. Przykład la - miganie diodami świecącym i 3.5. ffdefine __10 volatile typedef struct f _ I 0 uint32_t CRŁ; 10 uint32_t CRH; 10 uint32_t IDR; 10 uint32_t ODR; _ X 0 uint32__t BSRR; 10 uint32_t BRR; _ I 0 uint32__t LCKR; ) GPIOJTypeDef; ffdefine PERIPH_BASE ifdefine APB2PERIPHJ3ASE ffdefine GPIOE_BASE ffdefine GPIOE RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_LED, ENABLE); GPIOJiriteBit(GPIO_LED, RSD_LED | GREEN_LED, LEDJ3FF); GPIO~StructInit{&GPIO_InitStruct}; GPIO_InitStruct.GPI0_Pin * GREEN_LED j RED_LED; GPI(f InitStruct.GPIOJfode = GPIO_Mode_Out_PP; GPIO_InitSŁruct.GPIO_Speed = GPI0_Speed_2MHz; GPX0 Init (GPI0_LED, &GPIO_InitStruct:); } Dla każdej z diod św iecących definiujem y trzy funkcje: w łączającą, w yłączającą oraz zw racającą stan diody, czyli 1, gdy dioda św ieci, a 0 w przeciw nym przypad­ ku. Funkcje te obudow ują w yw ołania funkcji z biblioteki ST M 32. D la czerw onej diody w yglądają one następująco: j } ' “ {(uint32_t) 0x40000000) (PERIPHJBASE + 0x10000) (APB2PERIPH_BASE + 0x1800} ((GPIOJTypeDef *) GPIOE_BASE) Pow yższe definicje spraw iają, że np. do rejestru w yjściow ego ODR (ang. output data register) portu E m ożem y się odw ołać, pisząc: GPIOE->ODR void RedLEDoff (void) { GPIO WriteBit(GPICJLED, RED_LED, LED OFF) ; Taki bezpośredni sposób odw oływ ania się do rejestrów w ejścia-w yjścia będziem y jeszcze w ykorzystyw ać w dalszej części lego rozdziału. Innym przykładem są, zde­ finiow ane w pliku core_cm 3.h, funkcje w łączające i w yłączające przerw ania: ) int RedLEDstate(void) ( return GPIOJleadOutputDataBit(GPI0_LED, RED_LED) == LED_0M; 1.3.4. Pliki stm 32f10x.h, system_stm32f10x.h i core_cm3.h Pliki stm 3 2 fl0 x.h i system _ stm 3 2 fl0 x.h znajdują się w katalogu Jst/L ib ra ries/ C M SIS/C M 3/D eviceSupport/ST /STM 32F ]0x, a plik core_cm 3.h w katalogu J s t/ L ibraries/C M SlS/C M 3/C oreSupport. Są one częścią biblioteki STM 32. W plikach tych zdefiniow ane są adresy rejestrów w przestrzeni w ejścia-w yjścia, m akra obu­ dow ujące instrukcje A sem blera, num ery przerw ań i przeróżne stale potrzebne, aby program ow anie było w ygodniejsze. Przykładow o, użyty w yżej port E i rejestry, za pom ocą których funkcje biblioteczne odw ołują się do niego, są zdefiniow ane na­ stępująco: void LEDconfigure(void) { GPICJInitTypeDef GPIO_InitStruct; void RedLEDon(void) ( GPIOJłriteBit(GPIO_LED, RED_L£D, LED O N ) ; 1 static inline void static inline void Funkcje obsługujące zieloną diodę są analogiczne. Te i inne podobne m akra pojaw ią się w rozdziale 3. Pliki s tm 32f10xjjp io .h i stm 32f10x_rcc.h Pliki stm 32fl0x_ g p io .il i stm 3 2 fI0x_rcc.li znajdują się w katalogu J st/L ib ra ries/ STM 32F 10x_StdP eripli_D river/inc. Pliki te są częścią biblioteki ST M 32. W pli­ ku stm 3 2 f¡0x_gpio.lt zdefiniow ane są struktury, stałe i funkcje obsługujące p or­ ty w ejścia-w yjścia, a w pliku stm 3 2 fl0 x _ rc c.h - obsługujące zerow anie układów m ikrokontrolera i dystrybucję sygnałów zegarow ych do układów peryferyjnych. Identyfikatory (funkcji, stałych, typów ) zdefiniow ane w pliku stm 3 2 fl 0x_gpio.lt m ają prefiks G PIO (ang. G eneral P urpose Input-O utput), a te w pliku stm 3 2 fl0 x _ rec.h - prefiks RCC (ang. Reset a n d d o c k Control). W katalogu J st/L ib ra ries/ ST M 32F 10x_StdP eriph_D river/src znajdują się odpow iednie pliki stm 32fW x_gpio. c i stm32j'10x_rcc.c z im plem entacją. D o każdego układu peryferyjnego m ikrokon­ trolera biblioteka STM 32 dostarcza odpow iednią parę plików, np. dla układów licz­ nikow ych są to pliki stm 3 2 fl0 x _ tim .h i stm 32fJ0x_tim .c. 19 3.6. enable_irq() ( asm volatile ("cpsie i");) disable_irq() { asm volatile ("cpsid i");) Plik Iibstm 32f10x.a Do każdego przykładu m usim y dołączyć w łaściw e pliki biblioteczne - ten przykład w ym aga plików stm 3 2 fl0 x_ g p io .c i stm 32fl0x_rcc.c. Z astanaw ianie się, które pliki są niezbędne w konkretnym program ie i dołączanie do każdego projektu innego zestaw u plików bibliotecznych je s t czasochłonne i nużące. Lepszym rozw iązaniem je st skom pilow anie raz w szystkich dostarczonych plików źródłow ych biblioteki ST M 32 i zebranie ich w jed n y m binarnym pliku bibliotecznym , który potem tyl­ ko konsolidujem y z plikam i przykładu. D odatkow ym zyskiem je s t skrócenie czasu rekom pilacji, jeśli m odyfikujem y przykład - pliki biblioteczne nie są rekom pilow ane. Plik U bsim 32f]0x.a zaw iera w łaśnie skom pilow aną bibliotekę ST M 32, którą m ożem y konsolidow ać z plikam i przykładów . Plik U bstm 32fl0x.a m usim y utw o­ rzyć sam i - pow staje on przez skom pilow anie w szystkich plików z rozszerzeniem c z następujących katalogów : 20 I. Podstawy - ./'st/U braries/ST M 32F I0x_StdP eriph_D river/src, - ./st/Libraries/STM 32_ETJ-J_D river/src, - Jst/Libraries/C M SlS/C M 3/C oreSupport, - Jst/L ibraries/C M SIS/C M 3/D eviceSttpport/ST /ST M 3 2 F 1Ox. Pliki nagłów kow e biblioteki znajdują się w katalogach: - Jst/L ibraries/S I'M 3 2 F JO x_StdPeriph_D river/inc, - ./.st/Libntries/ST M 32_E T JJ_D river/inc, - ./.sl/L ibraries/C M SIS/C M 3/C oreSupport, - Jst/L ibraries/C M SIS/C M 3/D eviceSupport/SIZ ST M 32F 10x. Ponadto potrzebny je st jeszcze plik nagłów kow y stm 32flO x_conf.li, który je s t w ka­ talogu ./exam ples/include. Przydatne opcje kom pilatora opisuję szczegółow o w ro z­ dziale 1.4. 1.3.7. Plik stm32f10_conf.h Plik stm 3 2 f]0 _ c o iifh zn ajduje się w katalogu ./exam ples/include. W zam yśle tw órców biblioteki S T M 32 m a on być cen tralnym m iejscem konfigurow ania opcji projektu. Z aleca się, aby w nim um ieszczać dyrektyw y # in c lu d e w szyst­ kich używ anych plików stm32J'10x_*.h o raz definicje zw iązane z konfiguracją sprzętu, zestaw u uruchom ieniow ego itp., czyli definicje zależne od schem atu elek ­ trycznego. N iestety takie rozw iązanie się nie spraw dza. Jak w idać na rysunku 1.2, każdy z plików stm 32flO x_*.h w łącza p lik stm 3 2 fI0 _ co n f.h - pośrednio poprzez plik stm 32j'I0x.h. Z atem w łączanie plików stm 3 2 fI0 x_ * .h w pliku stm 3 2 fl O_conf. h pow oduje pow stanie cykli w łączeń plików nagłów kow ych. K om pilator sobie z nim i radzi. Jednak przy tw orzeniu w iększych projektów , w celu skrócenia cza­ su rekom pilacji, stosujem y zw ykle narzędzia, które w ykryw ają zależności m iędzy plikam i. D zięki tem u po edycji plików źródłow ych w ykonyw ana je s t rekom pila­ cja przyrostow a - kom pilow ane są ty lk o zm ienione pliki i pliki od nich zależne. W ystępow anie cyklu w łączeń plików nagłów kow ych je s t błędem , gdyż w prow adza zbędne zależności m iędzy plikam i i m oże pow odow ać niepotrzebne kom pilow anie wielu plików. Ponadto zależność plików nagłów kow ych biblioteki S T M 32 od p li­ ku sttn 3 2 fJO_conf.lt spraw ia, że jak ak o lw iek zm iana w nim w ym aga p rzekom pi­ low ania tej biblioteki, co je s t n ieuzasadnione - biblioteka nie pow inna zależeć od plików nagłów kow ych projektu. B łędem je s t też w łączanie w szędzie w szystkich m ożliw ych plików nagłów kow ych, g d y ż niepotrzebnie w ydłuża czas kom pilow a­ nia projektu. Z w yżej om ów ionych pow odów zrezygnow ałem w tej książce z w ykorzystyw ania pliku stin32fJ0_conf.h. Stosuję tradycyjne podejście i w każdej jed n o stce translacji (dla języ k a C je st to zw ykle pojedynczy plik źródłow y z rozszerzeniem c) w łączam tylko te pliki, które są tam niezbędne. N iestety pliku stm 3 2 f 10_conf.lt nie m ożna się pozbyć całkow icie i trzeba go dostarczyć, gdyż zaw iera definicję m akra a s s e r t _ param, które je st używ ane przez b ibliotekę STM 32. M akro to służy do spraw dzania popraw ności argum entów w funkcjach bibliotecznych. M oże to być w ykorzystane na etapie urucham iania program u, ale w wersji ostatecznej takie spraw dzanie raczej 1.3. Przykład Ja - miganie diodami iw iecqcym i 21 należy w yłączyć, gdyż zw iększa rozm iar kodu w ynikow ego i w ydłuża czas w y­ konyw ania program u. N a potrzeby tej książki plik stm 32fJ O_conf.il zaw iera tylko puste makro: idefine assert_param(expr) 1.3.8. ((void)0) Pliki board_def.li i board_defs.h Pliki bounl_def.h i boayd_defs.h są m oją propozycją rozw iązania problem u konfi­ gurow ania elem entów projektu zależnych od schem atu elektrycznego. Plik bottrd_ defs.li znajduje się w katalogu ./exam ples/include i zaw iera definicje stałych dla poszczególnych w ariantów sprzętu: idefine idefine idefine Idefine idefine BUTTERFLY PROTOTYPE ZL29ARM STE100P ZL3ETH 10700 10701 10729 100 300 Plik baaixl_defs.liym l w łączany przez plik bocird_def.li, który definiuje używ any w pro­ jekcie w ariant sprzętu. Przykładow o w katalogu ./exaniples/incliide/zl29ann+zl3elli jest plik b o a n l_ d e fh określający, że chcem y użyć zestaw u ZL29A R M z m odułem ethernetow ym ZL3ETH . Z aw iera on definicje: Idefine B O A R D T Y P E ZL29ARM Idefine ETI1__B0ARD ZL3ETH Plik b o a rd _ d efh je st .włączany każdorazow o, gdy w którym ś pliku źródłow ym trze­ ba uzależnić jak ieś definicje od w ariantu sprzętu, ja k to pokazałem w rozdziale 1.3.3. M am y dw ie m ożliw ości użycia tego pliku. Po pierw sze, m ożem y podać kom ­ pilatorow i, żeby poszukiw ał plików nagłów kow ych m .in. w katalogu ./exam ples/ inclttde/zl29ann+ zl3eth. Dla każdego projektu m ożem y indyw idualnie ustawić tę ścieżkę. D la każdego w ariantu sprzętu tw orzym y osobny podkatalog z inną w ersją pliku board_def.h. Po drugie, m ożem y po prostu um ieszczać w bieżącym katalogu projektu w łaściw y plik b oard_defli. T rzeba w tedy pam iętać, żeby przy w łączaniu ujm ow ać jeg o nazw ę w cudzysłow y, co w ym usza poszukiw anie pliku nagłów ko­ w ego najpierw w katalogu bieżącym . W łaściw a dyrektyw a preprocesora pow inna zatem w yglądać lak: iinclude "board_def.h" K olejnym zadaniem pliku board_def.hJ e s t w eryfikacja spójności definicji w ym aga­ nych przez bibliotekę STM 32. U życie tej biblioteki w ym aga zdefiniow ania trzech stałych preprocesora języka C. Pierw sza z nich to stała USE_STDPERIPH_DRIVER oznaczająca w łaśnie, że chcem y korzystać ze Standard Peripherals Library, któ­ ra je st częścią biblioteki STM 32. D ruga stała definiuje m odel m ikrokontrolera. ST M 32F107 należy do linii zorientow anej na kom unikację (ang. connectivity line) i odpow iednia stała to STM32F10X_CL - dw ie ostanie litery nazw y są skrótem angiel­ skiej nazw y tej linii m ikrokontrolerów . T rzecia stała HSE_VALUE definiuje częstotli­ wość w hercach kw arcu, którym taktujem y m ikrokontroler. D efinicje tych trzech stałych m uszą być w idoczne we w szystkich plikach nagłów kow ych i źródłow ych biblioteki STM 32 oraz w plikach źródłow ych projektu, w których w łączane są pliki nagłów kow e tej biblioteki. Ponadto definicje te m uszą być w szędzie jednakow e. N ajw łaściw szym rozw iązaniem byłoby zdefiniow anie tych stałych w jakim ś pli­ 22 ku nagłów kow ym . Z oczyw istego pow odu nie m oże to być board_def.h, bo nie je st on w łączany przez pliki biblioteki STM 32. M ógłby to być plik stm 3 2 fl()_ c o n f h, ale niestety je g o w łączenie je s t uzależnione od w cześniejszego zdefiniow ania stałej USE_STDPERIPH_DRIVER, a p o nadto pozostałe dw ie stale są używ ane w pli­ ku slm 3 2 fl0 x.h jeszcze przed w łączeniem w nim pliku stm 3 2 fl0 _ c o n fh . Jedynym rozw iązaniem je st zdefiniow anie tych trzech stałych ja k o argum entów kom pilatora, ja k opisuję to w rozdziale 1.4. Ż eby je d n ak uniknąć niespójności w ich definicji, co m oże pow odow ać błędne działanie program u, dobrze je st zw eryfikow ać te definicje w pliku board_def.lv. łifndef USE_STDPERIPH_DRIVER łerror USE_STDPERIPH_DRIVER not defined ffendif iifndef STM32F10X_CL fierror STM32F10X_CL not defined ffendif Iifndef HSE_VALUE fierror HSE_VALUE not defined ffendif ffif HSE_VALUE != 10000000 terror ZL29ARM board uses 10 MHz external quarz, tendif N a koniec należy zw rócić uw agę, że w w ersjach Standard Peripherals Library star­ szych niż 3.2.0 stała HSE_VALUE nazyw ała się HSE_Value. T rzeba w tedy za pom ocą argum entu kom pilatora zdefiniow ać w artość stałej HSE_Value, a przed pierw szym użyciem HSE_VALUE dodać definicję: łdefine HSE_VALUE HSE_Value 1.3.9. ! Plik s tdinth Plik stdint.h jest częścią standardow ej biblioteki języ k a C i znajduje się w k atalo ­ gu ze standardow ym i plikam i nagłów kow ym i. Standardow a biblioteka jest zw ykle dostarczana razem z zestaw em narzędzi (ang. toolchain) lub środow iskiem progra­ m istycznym (IDE, ang. integrated d evelopm ent environm ent). W tej książce uży­ wam biblioteki N ew lib - popularnej im plem entacji standardow ej biblioteki C na m ikrokontrolery. Plik stdint.h definiuje m.in. typy calkow itoliczbow e uniezależnia­ jące im plem entację od architektury procesora, np. typy: in t 8 _ t , u in t 8 _ t, i n t l 6 _ t , u i n t l 6 _ t , in t 3 2 _ t, u in t3 2 _ t. D efiniuje też m akra do obsługi tych typów. Potrzeba takich definicji w ynika z tego, że ję z y k C pozostaw ia pew ną sw obodę je g o im plem entatorom co do rozm iarów poszczególnych typów. P rzykładow o typ i n t w archi­ tekturach 16-bitowych ma zw ykle 16 bitów, a w architekturach 32- i 64-bitow ych - 32 bity. Z kolei typ lo n g w architekturach 16- i 32-bitow ych m a zw ykle 32 bity, a w architekturach 64-bitow ych - 64 bity. 1.3.10. Plik startup_stm32_cld.c Plik startup_stm 32_cld.c znajduje się w katalogu ./exam ples/src i zaw iera definicję w ektora przerw ań oraz przykładow ą procedurę startow ą, w ykonyw aną przed w y­ w ołaniem funkcji main program u. N ajpraw dopodobniej najlepszym rozw iązaniem je st dołączenie do projektu pliku startow ego dostarczonego w raz z używ anym ze­ staw em narzędzi. Plik ten m a zw ykle nazw ę podobną do tej w tytule podrozdziału. 23 1.4. Kompilowanie przykładów I. Podstawy Przykłady plików startow ych dla różnych kom pilatorów , napisane w A sem blerze, znajdują się w archiw um w katalogu Jst/L ibraries/C M SlS/C M 3/D eviceSupport/ST / STM 32F 10x/startup. W ażne jest, aby użyć pliku w łaściw ego do zastosow anego m i­ krokontrolera. Pliki startow e dla ST M 32F107 m ają w końców ce nazw y litery cl (ang. connectivity line). Poznanie zaw artości pliku z procedurą startow ą nie jest konieczne do zrozum ienia zaw artości książki. Tym bardziej nie je s t w ym agana też um iejętność pisania procedury startow ej. D la zainteresow anych opisuję te zagadnie­ nia w rozdziale 1.8. 1.4. Kompilowanie przykładów Zakładam , że C zytelnik m a ju ż ja k ie ś dośw iadczenie w program ow aniu m ikrokon­ trolerów A R M w języku C, m a zainstalow ane jak ieś ulubione środow isko progra­ m istyczne i um ie w nim skonfigurow ać projekt. D latego nie będę rozw odził się na tem at instalow ania narzędzi program istycznych i ograniczę się do w yjaśnienia ustaw ień kom pilatora i konsolidatora. W szystkie darm ow e zestaw y narzędzi i w iele kom ercyjnych w ykorzystuje oprogram ow anie stw orzone w ram ach projektu G N U , czyli kom pilator C /C ++ z pakietu G C C (ang. G N U C om piler C ollection) oraz pa­ kiet G N U B inary U tilities, w skrócie nazyw any B inutils, zaw ierający konsolidalor Id oraz inne pom ocnicze program y do m anipulow ania plikam i binarnym i, ja k np. ar, objcopy, objdum p itd. D o kom pilow ania opisyw anych w tej książce przykładów używ ałem w łaśnie tych narzędzi i dlatego ograniczam się tylko do opisu ich opcji. Inne narzędzia m ają bardzo podobny zestaw opcji i C zytelnik z łatw ością dobierze odpow iednie ustaw ienia. D la zw olenników program u m ake i kom pilow ania z linii poleceń zam ieszczam w archiw um w katalogu ./m ake zestaw plików m akefile - za­ w artość tego katalogu opisuję w dodatku. W środow isku program istycznym trzeba ustaw ić katalog ./exam ples/src jak o m iej­ sce, gdzie kom pilator m a szukać plików źródłow ych. Przypom inam , że je s t to ścieżka w zględem m iejsca, gdzie zostało rozpakow ane archiw um z przykładam i. Tę i w szystkie kolejne ścieżki trzeba dopasow ać do konkretnego system u. P odstaw ow e opcje kom pilatora zam ieszczone są w tabeli 1.4. K ażdy plik źródłow y języ k a C (jednostka translacji) kom pilujem y do binarnego pliku pośredniego, który ma tę sam ą nazw ę, co odpow iedni plik źródłow y, a tylko rozszerzenie zm ienione z c na o. Z pew nością w arto w łączyć w ypisyw anie przez kom pilator w szystkich ostrzeżeń, no i oczyw iście należy czytać te ostrzeżenia. Sam fakt, że program się skom pilow ał, nie daje żadnej gw arancji je g o popraw ności. U w ażna analiza każdego ostrzeżenia i zastanow ienie się nad przyczyną, dla której kom pilator je w ypisał, m oże uchronić przed w ielogodzinnym poszukiw aniem błędu w program ie. D obry styl program ow ania to m iędzy innym i dbanie o to, aby w raporcie kom pilacji nie Tab. 1.4. Podstawowe opcje kompilatora Znaczenie Opcja -c Tylko kompilacja do pliku pośredniego (z rozszerzeniem o) -Wa 1.1 Włączenie generowania wszystkich ostrzeżeń -g Włączenie informacji dla debuggera -mcpu=cortex-m3 W ybór architektury mikrokontrolera, rdzeń Cortex-M3 -mthumb Zestaw instrukcji Thumb lub Thum b-2 24 1. Podstawy Tab. 1.6. Miejsca poszukiwania plików nagłówkowych Tab. 1.5. Opcje kompilatora sterujące optymalizacją Znaczenie Opcja -oo 25 1.4. Kompilowanie przykładów Wyłączenie wszelkich optymalizacji -Os Minimalizacja rozmiaru kodu wykonywalnego oi io i o Maksymalizacja szybkości wykonywania kodu, większe wartości oznaczają bardziej agresywną optymalizację -ffunction-sections Każda funkcja w osobnej sekcji -fdata-sections Każda zmienna globalna i statyczna w osobnej sekcji pojaw iały się żadne ostrzeżenia, oczyw iście nie przez w yłączenie ich w ypisyw ania. K ażdy program da się tak napisać, aby kom pilator nie zgłaszał żadnych ostrzeżeń. C o do pozostałych opcji, to z kodu w ynikow ego nie m usim y usuw ać inform acji dla debuggera, bo nie są one zapisyw ane w pam ięci program u m ikrokontrolera - debugger je s t urucham iany na kom puterze, z którego w ykonuje się program ow anie m ikrokontrolera. N iezbędne je s t w ybranie włas!ciw ej architektury m ikrokontrolera i obsługiw anego zestaw u instrukcji. M ikrokontrolery z rdzeniem C ortex-M 3 w yko­ nują tyiko zestaw instrukcji T hum b-2. B ardzo w ażne je s t w ybranie pożądanego poziom u optym alizacji kodu w ynikow ego. K om pilator m a bardzo dużo szczegółow ych opcji sterujących procesem optym aliza­ cji. Z w ykle w ystarczy jed n ak w ybrać m iędzy m inim alizacją rozm iaru kodu w yko­ nyw alnego a szybkością je g o w ykonyw ania za pom ocą opcji z tabeli 1.5. Panuje dość pow szechne przekonanie, że program ując m ikrokontrolery, należy pre­ ferow ać m inim alizację rozm iaru kodu w ynikow ego. T rzeba jednak pam iętać, że p o ­ szczególne w arianty optym alizacji nie są całkiem niezależne. M niejszy kod na ogól w ykonuje się szybciej, dlatego zastosow anie opcji -Os w pływ a też na przyspiesze­ nie w ykonyw ania program u. Z drugiej strony, ustaw ienie jed n ej z opcji -0 1 , -02 lub -03 w łącza rów nież te optym alizacje, które zm niejszają rozm iar kodu w ynikow ego i nie spow alniają w ykonyw ania program u, zatem m oże rów nież przyczynić się do zm niejszenia rozm iaru kodu w ynikow ego. C hoć oczyw iście niektóre optym aliza­ cje, takie ja k um ieszczanie ciała funkcji w m iejscu jej w yw ołania (ang. inline) czy rozw ijanie pętli, istotnie zw iększają rozm iar kodu w ynikow ego. U w ażam , że d o p ó ­ ki rozm iar dostępnej pam ięci na to pozw ala, pow inniśm y optym alizow ać szybkość w ykonyw ania program u. M inim alizow anie rozm iaru kodu jest uzasadnione, jeśli pozw oli zastosow ać tańszy m odel m ikrokontrolera - z m niejszą pam ięcią lub jeśli bez takiej m inim alizacji program nie m ieści się w najw iększej dostępnej w danej rodzinie m ikrokontrolerów pam ięci. Z apew ne jed n ak najw ięcej pam ięci m ożna za­ oszczędzić przez w łaściw y do b ó r stru ktu r danych i algorytm ów . Istotną redukcję rozm iaru kodu w ynikow ego m ożna też stosunkow o prosto osiąg­ nąć, nie rezygnując z optym alizacji szybkości w ykonyw ania. O kazuje się, że sporo m iejsca w pam ięci program u zajm uje kod dołączanych bibliotek. K ażda biblioteka zaw iera bardzo w iele użytecznych funkcji i zm iennych globalnych, z których nasz program zw ykle w ykorzystuje tylko niew ielką część. Sam i piszem y też w łasne b i­ blioteki i nie zaw sze w yw ołujem y w szystkie zaim plem entow ane funkcje w każdym projekcie. A by pozbyć się tego nieużyw anego kodu, m ożem y ustaw ić dw ie ostat­ nie opcje w ym ienione w tabeli 1.5, a następnie w fazie konsolidow ania program u ustaw ić opcję odśm iecania (ang. garbage collector) - patrz tabela 1.9. U staw ienia ________________________ Param elry kompilatora _______ __ -I./examples/include -I ./examples/include/zl29arm+zl3eth - I ./st/Libraries/STM32F10x_StdPeriph_Driver/inc - I ./st/Librari.es/STM32_ETH__Driver/inc - I ./st/Libraries/CMSIS/CM3/CoreSupport - I ./st/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - I ./lwip-1.3,2/src/.tnclude -I ./lwip-1.3.2/src/include/ipv'l________________________ Tab. 1.7. Stale konfigurujące bibliotekę STM32 Param etr kompilatora -DUSE STDPERIPH DRIVER Znaczenie Użyj Standard Peripherals Library -DSTM32F10X CL Kompiluj dla STM 32F105 lub STM 32F107 (ang. connectivity line device) -DIISE VALUE=10000000 Zainstalowany jest kwarc 10 MHz te spraw iają, że kom pilator um ieści każdą funkcję i zm ienną globalną lub statyczną w osobnej sekcji, a konsolidator spraw dzi, do których funkcji i zm iennych są odw yw ołania w tekście źródłow ym i pozostaw i w kodzie w ynikow ym tylko te funkcje i zm ienne, które są rzeczyw iście w ykorzystyw ane. N ależy zaznaczyć, że uzyskanie zadow alającego rezultatu w ym aga, aby w szystkie pliki źródłow e poddać tej opty­ m alizacji. D otyczy to rów nież bibliotek. S ą to, oprócz biblioteki STM 32, przede w szystkim libc, czyliistandardow a biblioteka C oraz libm , czyli standardow a biblio­ teka funkcji m atem atycznych. Ponadto należy zadbać o zoptym alizow anie, dostar­ czanej w raz z G CC , niskopoziom ow ej biblioteki czasu w ykonania libgcc (ang. Iow level runtim e library). W libgcc im plem entuje się konstrukcje języ k a C niew spierane bezpośrednio przez sprzęt - dla C ortex-M 3 jest to np. arytm etyka na typach, które nie są w ym ienione w tabeli 1.2. N ieco w ięcej o kom pilow aniu tych bibliotek piszę w dodatku. Przykłady zam ieszczone w tej książce i w szystkie biblioteki kom ­ pilow ałem z następującym i opcjam i optym alizacji: -02 -ffunction-sections -fdata-sections W tabeli 1.6 zam ieszczone są param etry kom pilatora ustaw iające nazwy katalogów, w których należy poszukiw ać plików nagłów kow ych. Pierw szy w iersz konfiguruje ścieżkę do katalogu, w którym znajduje się w iększość plików nagłów kow ych przy­ kładów . D rugi w iersz w tej tabeli to ścieżka do pliku bo a rd _ d efh . Jak napisałem wyżej, przy om aw ianiu tego pliku, ścieżka ta m oże być inna i w skazyw ać na inny plik b oard_def.h, konfigurujący inny w ariant sprzętu. K olejne cztery wiersze zaw ie­ rają ścieżki do plików nagłów kow ych biblioteki STM 32. O statnie dw a w iersze to ścieżki do plików nagłów kow ych biblioteki lwIP. O m aw iam tę bibliotekę dopiero w rozdziale 3, ale w arto m ieć zaw czasu ustaw ione w szystkie potrzebne ścieżki. W rozdziale 1.3.8 napisałem , że biblioteka STM 32 w ym aga zdefiniow ania trzech stałych preprocesora. O dpow iednie param etry kom pilatora, definiujące te stale, są w ym ienione w tabeli 1.7. Param etry te m uszą być rów nież ustaw ione podczas kom ­ pilow ania plików źródłow ych w łączających plik board_ d e fh . N ajlepiej jest ustawić je dla w szystkich plików źródłow ych przykładów , czyli w szystkich plików z kata­ logu Jexam ples/src. 26 I. Podstawy Tab. 1.8. Katalogi z plikami źródłowymi biblioteki STIVI32 Jst/Ubraries/STM32F10x_StdPeriph_Driver/src ./stlLibrarieslSTM 32JTH_Driver/src Jst/Libraries/CMSIS/CM3/CoreSupport Jst/LibraneslCIVISIS/Cl/l3/DeviceSupport/ST/STM32F10x Tab. 1.9. Opcje konsolidatora Znaczenie Opcja -mcpu-cortex-m3 -mthumb W ybór architektury mikrokontrolera -nostartfiles Wyłączenie domyślnego pliku z procedurą startową -L./make/lib/7.129arm+zi3eth Miejsce poszukiwania plików bibliotecznych -L./examples/scripts Miejsce poszukiwania skryptu konsolidatora -Tstm32f107vc.Ids Nazwa skryptu sterującego procesem konsolidacji -Wl,— gc-secfcions Uaktywnienie odśmiecania - usuwanie zbędnego kodu A by utw orzyć bibliotekę Iib stm 3 2 fl0 x.a , trzeba skom pilow ać do odpow iednich plików pośrednich z rozszerzeniem o w szystkie pliki źródłow e z rozszerzeniem c z katalogów w ym ienionych w tabeli 1.8, a następnie połączyć je w jed en plik b i­ blioteczny. K ażde Środowisko program istyczne m ożna tak ustaw ić, aby w ynikiem kom pilacji zam iast pliku w ykonyw alnego była biblioteka. M ożna to też zrobić z li­ nii poleceń za pom ocą program u ar, przykładow o: arm-elf-ar -rcs Iibstm32fł0x.a *.o O statnim etapem tw orzenia program u je s t konsolidacja. W tabeli 1.9 zaw arto opcje w ykorzystyw ane przy łączeniu (konsolidow aniu, linjkowaniu) plików pośrednich i bibliotek do pliku w ykonyw alnego. Zakładam , że konsolidalor nie je s t urucham ia­ ny bezpośrednio za pom ocą np. polecenia a nn-elf-ld, a poprzez kom pilator polece­ niem arm -elf-gcc. Taki sposób urucham iania konsolidatora je st w ygodniejszy, gdyż jest w tedy autom atycznie dołączana standardow a biblioteka języ k a C. Podobnie ja k podczas kom pilacji, trzeba w yspecyfikow ać architekturę m ikrokontrolera. Jeśli d o ­ łączam y nasz plik z procedurą startow ą, to trzeba w yłączyć dołączanie dom yślnej procedury startow ej. M ożna też ustaw ić ścieżkę do m iejsca, gdzie poszukiw ane m ają być nasze biblioteki, jeśli nie znajdują się w katalogu bieżącym . N a razie m am y tylko jedną bibliotekę, czyli Iibstin32fl0x.a, ale w rozdziale 3 utw orzym y drugą z im ple­ m entacją stosu TCP/IP. K onsolidatorow i trzeba też podać nazw ę skryptu sterującego procesem konsolidacji i ścieżkę do katalogu, gdzie m a poszukiw ać tego skryptu. Najpraw dopodobniej najlepiej jest zdać się na skrypt konsolidatora dostarczony wraz ze środow iskiem program istycznym . D la zainteresow anych zrozum ieniem , ja k dzia­ ła konsolidator, opisuję w rozdziale 1.8.3 prosty skrypt do architektury C ortex-M 3. Aby skutecznie m inim alizow ać rozm iar generow anego program u, bardzo w ażne jest też uaktyw nienie opcji odśm iecania w fazie konsolidacji. 1.5. Wejścia i wyjścia binarne M ikrokontroler S T M 32F 107 m a pięć, oznaczonych literam i od A do E, 16-bitow ych portów w ejścia-w yjścia. Jak w każdym m ikrokontrolerze, ich k o n fig u ro w a­ nie i dostęp do nich odbyw a się za pom ocą rejestrów w przestrzeni adresow ej w ejść-w yjść. Jest to o pisane szczeg ó ło w o w [8 |. N ajw ażniejsze rejestry, z któ- 27 1.5. Wejścia i wyjścia binarne rych będziem y korzystać, przestaw ione są na rysunku 1.3. D ane z wejść czyta się z rejestru ID R (ang. input data register), który je s t rejestrem tylko do odczytu. Stan w ejść znajduje się w m łodszych 16 bitach tego rejestru. Pozostałe bity nie są używ ane. D ane w yjściow e zapisuje się do rejestru ODR (ang. output data regi­ ster). D ane zapisane do tego rejestru m ogą być rów nież odczytyw ane. K orzysta się przy tym tylko z m łodszych 16 bitów rejestru. P ozostałe bity są zarezerw ow ane. A tom ow e, nieprzeryw ane obsługą przerw ań, operacje na poszczególnych bitach m ożna w ykonać za pom ocą rejestrów BRR (ang. bit reset register) i BS R R (ang. bit set/reset register), które są rejestram i tylko do zapisu. Starszych 16 bitów rejestru BRR nie używ a się. Z apisanie jed y n k i na bicie B R x rejestru BRR zeruje odpow ied­ ni bit O D R x w rejestrze O DR . Z apisanie jed y n k i na bicie B S x rejestru B S R R ustaw ia odpow iedni bit O D R x w rejestrze O D R. Z apisanie jed y n k i na bicie B R x rejestru BSRR zeruje odpow iedni bit O D R x w rejestrze O D R. Z apisyw anie zera na bitach B S x i B R x nie zm ienia w artości bitów rejestru ODR. Jeśli w rejestrze B S R R oba bity B S x i B R x są jed n o cz eśn ie zapisyw ane w artością 1, to pierw szeństw o m a bit B S x - odpow iedni bit O D R x zostaje ustaw iony. Tryb pracy portów w ejścia-w yjścia konfiguruje się za pom ocą rejestrów CRL (ang. configuration register Iow) i CRH (ang. configuration register high). K ażde w ypro­ w adzenie m ożna skonfigurow ać indyw idualnie. D la każdego w yprow adzenia prze­ w idziano po cztery bity konfiguracyjne: CNFxl, CNFxO, MODExl, MODExO. R ejestr CRL konfiguruje w yprow adzenia 0 ...7 , a CRH - w yprow adzenia 8 ...1 5 . D ostępne tryby pracy portów w ejścia-w yjścia i odpow iadające im ustaw ienia bitów konfiguracyj­ nych zam ieszczone są w tabeli 1.10. N ależy zw rócić uw agę, że rezystory podciąga­ ją c e do zasilania i ściągające do m asy są ustaw iane za pom ocą rejestru ODR. W przy­ padku ustaw ienia funkcji alternatyw nej w yprow adzenie m oże być też dw ukierunko­ we (ang. bidirectional) - w tedy kierunkiem w yprow adzenia steruje w łaściw y uktad peryferyjny. G dy w yprow adzenie je st ustaw ione w trybie w yjściow ym , bity MODExl i MODExO określają m aksym alną częstotliw ość sygnału na w yjściu, przy obciążeniu 50 p F i założeniach, że w spółczynnik w ypełnienia sygnału w ynosi 4 5 -5 5 % , a cza­ sy narastania i opadania (m ierzone standardow o ja k o zm iana m iędzy 10% a 90% poziom u w ysokiego) nie przekraczają w sum ie 2/3 okresu sygnału. U staw ienia tych bitów podane są w tabeli 1.11. Tab. 1.10. Tryby pracy portów wejścia-wyjścia , Tryb pracy ;jtópExif MODExO . CNFxl CNFxO 0 0 0 0 Nieistotne floating input 0 0 0 1 Nieistotne pull-down input 0 0 1 0 0 pull-up input 0 0 1 0 1 0 0 0 lub 1 Nazwa anglelska Wejście analogowe analog input Wejście pływające (stan po resecie) Wejście ściągane do masy Wejście podciągane do zasilania Wyjście przeciwsobne Wyjście z otwartym drenem push-pull output open-drain output Funkcja alternatywna, wyjście przeciwsobne alternate lunction pushpull output Funkcja alternatywna, wyjście z otwartym drenem alternate function open-drain output 01 10 11 (patrz tabela 1.11) ODRx , 0 1 0 lub 1 1 0 Nieistotne 1 1 Nieistotne I. Podstawy 28 30 31 2Q 29 26 27 25 24 23 22 21 20 19 18 17 16 Zarezerw ow ane 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 IDR15 IDR14 IDR13 IDR12 IDR11 IDR10 IDR9 !DR8 IDR7 IDR6 !DR5 IDR4 IDR3 IDR2 IDR1 IDRO r r Tab. 1.11. Maksymalna częstotliwość sygnału wyjściowego M0DExl 15 MODExO 1 30 31 28 29 26 27 24 25 23 22 20 21 19 18 17 16 Zarezerw ow ane 14 15 13 12 10 11 BRR 8 7 6 5 4 3 2 ODR8 O DR7 ODR6 O DR5 ODR4 O DR3 ODR2 ODR1 ODRO 9 ODR15 ODR14 ODR13 ODR12 ODR11 ODR10 ODR9 0 rw rw rw rw rw rw rw rw rw rw rw rw rw rw rw rw 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 BR15 BR14 BR13 BR 12 BR11 BR10 BR9 BR8 BR7 BR6 BR5 BR4 BR3 BR2 BR1 BR0 w w w w w w w w w w w w w w w W Z a rezerw ow ane 0 Częstotliwość 10 MHz 0 r r 29 1.5. Wejścia i wyjścia binarne 0 2 MHz 1 50 MHz Z w ykle dużo w ygodniejsze je s t konfigurow anie portów w ejścia-w yjścia za pom ocą funkcji bibliotecznej niż operow anie bezpośrednio na rejestrach C R L i CRH. W celu w ygodnego konfigurow ania portów biblioteka STM 32 dostarcza strukturę typu G P IO _InitT ypeD ef. typedef struct { uintl6_t GPIG^Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIOJtode; ) GPIO_IniŁTypeDef; Jak o w artość składow ej GPI0_Pin podaje się m askę bitow ą w yprow adzeń, które są konfigurow ane. N ajlepiej je s t używ ać alternatyw y następujących stałych, zdefinio­ w anych w bibliotece STM 32. idefine GPIO_Pin_0 idefine GPIO_Pin__l idefine GPI0_Pin_2 (£uintl6_t)0x0001) ((uintl6_t) 0x0002) £ (uin 1 16__t) 0x0004) Idefine GPI0_Pin_15 £ (Uintl6_t) 0x8000) idefine GPIO_Pin_All ((uintl6_t) 0xFFFF) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 BR15 BR14 BR13 BR12 BR11 BR10 BR9 BR8 BR7 BR6 BR5 BR4 BR3 BR2 BR1 BR0 W w w w w w w w w w w w w w w w 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 BS15 BS14 BS13 BS12 BS11 BS10 BS9 BS8 BS7 BS6 BS5 BS4 BS3 BS2 BS1 BSO w w w w w w w w w w w w w w w W 31 30 CNF7[1:0| rw rw 14 15 CNF3|1:0] CRH rw rw 31 30 CNF15£1:0j rw [ 15 rw 14 CNF11[1 :QJ rw | rw 28 29 MODE7(1:0] 26 27 CNF6(1:0j rw rw rw 12 13 MODE3[1:0] 11 10 rw rw rw rw 29 26 27 26 rw MODE15[1:Oj rw 13 | rw 12 MODE11[1:0J rw rw CNF2[1:0] CNF14£1:0] rw 11 j rw 8 9 MODE2(1:0] rw rw 25 24 MODE14[1:0] rw 10 9 rw 24 rw rw CNF10£1:0] rw 25 MODE6[1:0] i Rys. 1.3. Podstawowe rejestry portów wejścia-wyjścia 20 21 MODE5[1:0j 19 18 CNF4[1:0] rw rw rw rw rw rw 7 6 5 4 3 2 CNF1(1:0] rw rw 23 22 CNF 13f 1:0] rw 8 7 rw 22 CNF5{1:0! rw MODE10[1:0J rw 23 I rw rw 21 20 MODE13f1:QJ rw rw 6 5 CNF9(1:0J rw MODE1[1:0| rw | rw rw 19 18 CNF12]1:0] rw rw 4 3 MODE9{1:OJ rw CNF0(1:0) rw | rw rw rw rw 17 16 MODE12[1;0] rw 2 1 rw rw 0 MODE0{1;0] rw CNF8[1;0] 16 17 MODE4(1:0} | rw typedef enum { GPIO_Speed_10MHz - 1, GPIO_Speed_2MHz, GPIO~Speed_50MHz } GPIOSpeed_TypeDef; Składow a GPIO_Mode określa tryb pracy w yprow adzenia. Stale reprezentujące po­ szczególne tryby pracy zdefiniow ano w bibliotece ST M 32 jak o typ w yliczeniow y GPIOMode_TypeDef. N azw y poszczególnych trybów jednoznacznie je identyfikują, a dodatkow o dla klarow ności kolejność definicji na poniższym w ydruku odpow iada kolejności opisów w tabeli 1.10. typedef enum { GPIO__Mode_AIN GPIO_Mode_IN_FŁOATING GprO_Mode_IPD GPIO_Mode_IPU GPI0J4ode_0ut_PP GPI0_Mode_0ut_0D G PI0~Mode_AF_P P GPI0J4ode_AF_0D GPIOMode_TypeDef; 0x0, 0x04, 0x28, 0x48, 0x10, 0x14, = 0x18, “ 0xlC = = = = 0 MODE8[1:0] rw Składow a GPIO_Speed określa m aksym alną „prędkość” pracy wyprowadzenia. D opuszczalne wartości zdefiniow ane są jako typ w yliczeniow y GPIOSpeed_TypeDef. j rw A by skonfigurow ać w yprow adzenia portu, należy zainicjow ać strukturę typu GPIOMode_TypeDef i w yw ołać funkcję G P I0 _ In it, przekazując jak o jej param etry nazw ę portu i adres tej struktury, ja k przedstaw iono to w rozdziale 1.3.3. Do zmie- 1. Podstawy 30 niania stanu w yjść oraz czytania stanu w ejść i w yjść biblioteka S T M 32 udostępnia następujące funkcje. uintl6_t uint8__t uintl6_Ł uint8_t void void void void GPIO_ReadInputData(GPIO_TypeDef *GPI0x); GPIO_ReadInputDataBit(GPIG_TypeDe£ *GPI0x, uintl6_t GPI0_Pirt); GPIO_ReadOutputData{GPIO_TypeDef *GPI0x); GPIO_ReadOutputDataBit(GPIO_TypeDef *GPI0x, uintl6_t GPI0_Pin); GPIO_ResetBits(GPIOJTypeDef *GPlOx, uint!6_t GPIO_Pin}; GPIO_SetBits(GPIOJTypeDef *GPX0xf uintl6_t GPIO_Pin); GPIO_Wrifce(GPIOJTypeDef *GPI0x, uint!6_t PortVai); GPI0_WriteBit(GPIOJTypeDef *GPlOx, uintl6_t GPICJPin, BitAction BitVal); N azw y tych funkcji są sam otłum aczące się. P aram etr GPIOx musi w skazyw ać port w ejścia-w yjścia i przyjm uje je d n ą z w artości GPIOA, GPIOB, GPI0C itd. P aram etr GPI0_Pin to m aska bitow a określająca w yprow adzenia - najlepiej je s t stosow ać alternatyw ę opisanych w yżej stałych G PI0_Pin_x, gdzie x je st num erem w yprow a­ dzenia. Funkcje G P IO _R eadInputD ataB it i G PIO _R eadO utputD ataBit zw racają 1, gdy odpow iednio co najm niej jed n o z w yspecyfikow anych w ejść lub w yjść ma stan w ysoki. Funkcja GPIO__WriteBit pow inna w łaściw ie nazyw ać się GPIO_Wri.teBi.ts, gdyż um ożliw ia jed n o czesn e w yzerow anie lub ustaw ienie w szystkich bitów w yspe­ cyfikow anych za pom ocą param etru G PI0_Pin. P aram etr B itV a l przyjm uje w artość Bit_RESET lub Bi.t_SET, ja k to ju ż w idzieliśm y w rozdziale 1.3.3. B iblioteka ST M 32 nie dostarcza niestety atom ow ej (niepodzielnej) operacji, pozw alającej jed n o cześn ie na w yzerow anie pew nych bitów i ustaw ianie innych. Taka operacja będzie nam potrzebna w następnym przykładzie i tam opiszę jej im plem entację. 1.6. Wyświetlacz ciekłokrystaliczny W kilku przykładach w ykorzystuję w yśw ietlacz ciekłokrystaliczny (L C D , ang. liq­ uid crystal display). Z astosow ałem w yśw ietlacz graficzny typu W G 12864A z m a­ trycą m onochrom atyczną szerokości 128 i w ysokości 64 pikseli. W yśw ietlacz ten zbudow any je s t w oparciu o dw a sterow niki kom patybilne z układem K S0108. Pojedynczy sterow nik obsługuje połów kę w yśw ietlacza, czyli fragm ent obrazu 64 na 64 piksele. O rganizację je g o pam ięci obrazu pokazano na rysunku 1.4. Pam ięć obrazu je s t podzielona na 8 bloków po 64 bajty każdy. W dokum entacji w yśw ietla­ cza bloki nazyw ane są stronam i (ang. pa g e), co w odniesieniu do w yśw ietlaczy w y­ daje mi się bardzo m ylące. Każdy blok odpow iada za w yśw ietlanie jed n eg o w iersza składającego się z 8 linii. Pojedynczy bajt w bloku steruje w yśw ietlaniem kolum ny składającej się z 8 pikseli. Jeśli bit je s t ustaw iony, to piksel je s t ciem ny, a w prze­ ciw nym przypadku - jasny. Są też produkow ane m odele w yśw ietlaczy, w których je s t odw rotnie - obraz jest w yśw ietlany w negatyw ie. N ajm niej znaczący bit odpo­ w iada pikselow i w górnej linii w iersza, a najbardziej znaczący - dolnej. S terow nik przechow uje trzy zm ienne (adresy). X je st adresem (num erem ) bieżącego wiersza. Y je s t adresem (num erem ) kolum ny. Z je st num erem linii (a nie w iersza), która je s t w yśw ietlana ja k o pierw sza na g órze ekranu. Z m ienna Z um ożliw ia realizację przew ijania obrazu, ale nie będziem y z tego korzystać w przykładach. Z apis i o d ­ czyt pam ięci obrazu zaw sze dotyczy bajtu w skazyw anego przez zm ienne X i Y. Po zapisie lub odczycie adres Y je s t autom atycznie zw iększany o jeden. 31 1.6. Wyświetlacz ciekłokrystaliczny - adres bloku (wiersza) i— Num er bitu Z - adres pierwszej wyświetlanej llnll — Y - adres k o lu m n y ____ * 0 1 63 ’ LSB 0 — 1 2 3 4 5 Blok 0 6 .M SB 7 ’ LSB 0 1 2 3 4 5 6 .M SB 7 Blok 1 _ 15 • LSB 0 1 2 3 4 5 Blok 7 6 63 .M SB 7 Rys. 1.4. Organizacja pamięci obrazu LCD W yśw ietlacz W G 12864A podłącza się w zestaw ie Z L29A R M do złącza 20-stykow ego. T rzeba też pam iętać o przestaw ieniu zw orki D ISPLAY w pozycję G R A PII. Schem at pokazujący podłączenie poszczególnych w yprow adzeń w yśw ietlacza do w yprow adzeń m ikrokontrolera je s t przedstaw iony na rysunku 1.5. W yśw ietlacz S TM 32F107V C PEO PE1 Y:PE 2 ÍÍÍP É 3 Y PE4 n:P E 5 PE6 PE7 PE8 Y PE9 PE10 PE11 PE12 nRST LCD 98 1 2 3 4 5 38 0 9 10 11 12 13 14 DO D1 D2 D3 D4 D5 D6 D7 39 40 41 42 43 14 . 4 6 5 15 16 17 RS E R /ffl CS1 CS2 - Rys. 1.5. Schemat podłączenia LCD 2' VEE R5T -0 + 5 V 18 LEDA LEDK D IS P L A Y JP 3 □ | VO ^ RESET i VSS VDD 10k GRAPH CHAR /. Podstawy 32 Tab. 1.12. Polecenia sterownika KS0108 s 1000 ms £ 450 ms RS ^ 450 ms 0 J S 140 ms > 10 ms R /W W i D6 0 D5 D4 D3 1 1 1 1 1 1 D2 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 B 0 1 0 zapisywany bajt 1 1 odczytany bajt DO D1 1 1 C Y Ustaw adres bloku, numer wiersza X Ustaw numer początkowej linii Z Z ”\ r D 0-7 Rys. 1.6. Cykl zapisu LCD ___________ a 1000 ms_____________ R 0 0 0 0 Czytaj status: B = 0 - gotowy, B = 1 - zajęty, C = 0 - wyświetlanie włączone, C = 1 - wyłączone, R = 0 - aktywny, R = 1 - w trakcie zerowania Zapisz bajt do pamięci obrazu Czytaj bajt z pamięci obrazu W tabeli 1.12 zestaw ione są polecenia w ykonyw ane przez sterow nik w yśw ietlacza. Pierw sze polecenie w łącza i w yłącza w yśw ietlanie. D ane z pam ięci obrazu są prze­ syłane na ekran dopiero po w łączeniu w yśw ietlania. K olejne trzy polecenia usta­ w iają w artości adresów X, Y i Z. P rzedostatnie polecenie zapisuje dane do pam ięci obrazu. O statnie polecenie odczytuje dane z pam ięci obrazu. Po w ydaniu każdego z w ym ienionych w yżej poleceń sterow nik zm ienia status na zajęty. Przed w ysia­ niem kolejnego z tych poleceń trzeba poczekać, aż sterow nik pow róci do stanu gotowy. Stan sterow nika spraw dza się za pom ocą polecenia Czytaj status. Podczas operacji zapisu (bit R /W w yzerow any) linie danych D 0 ...D 7 po stronie m ikrokon­ trolera m uszą być ustaw ione jak o w yjścia, a podczas odczytu (bit R/W ustaw iony) - ja k o wejścia. DL W G 12864A kom unikuje się z m ikrokontrolerem za pom ocą interfejsu rów noleg­ łego, który m a osiem dw ukierunkow ych linii danych D 0 ...D 7 , linię RS w yboru m iędzy transm isją danych a w ysyłaniem kom endy lub odczytem statusu, linię w y­ boru zapisu lub odczytu R /W , linię zezw olenia E (ang. enable) oraz linię zerow ania R ST. Zaw iera też linie w yboru sterow nika CS1 i C S2 (ang. chip select), na których stanem aktyw nym je s t stan w ysoki. N a rysunku 1.6 pokazano cykl zapisu oraz zależności czasow e podane w nocie katalogow ej sterow nika K S0108, a na rysu n ­ ku 1.7 - cykl odczytu. C Opis C = 0 - wyłącz wyświetlanie, C = 1 - włącz wyświetlanie Ustaw adres kolumny Y X R/W CS1, CS2 r RS 33 1.7. Przykład Ib - test wyświetlacza ciekłokrystalicznego 1.7. Przykład 1 b - test wyświetlacza ciekłokrystalicznego a 450 ms > 140 ms a 10 ms R/W Przykład ten dem onstruje użycie opisanego w poprzednim podrozdziale graficzne­ go w yśw ietlacza ciekłokrystalicznego. W tabeli 1.13 zaw arto nazw y plików, które należy podać kom pilatorow i jak o pliki źródłow e tego przykładu. Ponadto zaw iera nazw y tych plików nagłów kow ych w ykorzystyw anych w tym przykładzie, które znajdują się w podkatalogu ./exam ples/include. W kolejnych podrozdziałach opisuję zaw artość poszczególnych plików. Z arów no w tym , jaki i w kolejnych przykładach nie opisuję plików, które opisałem ju ż poprzednio. Tab. 1.13. Pliki przykładu 1b CS1, CS2 ' RS ł Źródłowe I biblioteczne _ A _ ,a 20 ms e x jc d .c fonl5x8.c startup _ s tm 3 2 jtld .c board_lcd_ks0108.c Sont5x8.h b o a rd jle ł.h board_defs.h board Icd.h u tiljlelay .c utilJod . c Ilbstm32f10x.a Nagłówkowe D 0-7 Rys. 1.7. Cykl odczytu LCD -v/— uliljdelay.h u liljc d .li stm 32HOx_conl.h I. Podstawy 34 1.7. Przykład Ib - test wyświetlacza ciekłokrystalicznego Pliki boardJ c d .h i board_lcd_ks0108.c szego w yprow adzenia definiujem y jak o stałą D 0 _ S H IF T . O dpow iednie definicje dla Z L 29A R M są następujące: Plik boctrdJlcd.h znajduje się w katalogu ./exam ples/include. D efiniuje on prosty interfejs program istyczny do obsługi w yśw ietlacza w trybie tekstow ym . Interfejs len z założenia m a być niezależny od zastosow anego w yśw ietlacza i każdy typ w y­ św ietlacza pow inien bez problem u m óc go zrealizow ać. O czyw iście poszczególne typy w yśw ietlaczy będą różnić się liczbą w ypisyw anych w ierszy tekstu i liczbą zna­ ków w w ierszu. N a opisanym w ro zdziale 1.6 w yśw ietlaczu będziem y w ypisyw ać 8 w ierszy tekstu po 21 znaków w w ierszu. Interfejs, zdefiniow any w pliku board J c d . /?, udostępnia tylko bardzo skrom ny zestaw funkcji: void void void void void łdefine DATA_PORT GPIOE łdefine D0_D7 (GPIO_Pin_0 | GPIO_Pin_l | GPI0_Pin_2 | \ GPI0_Pin_3 | GPIcfpinj! | GPI0_Pln_5 | \ GPI0_Pin_6 | GPI0J>in_7) łdefine D0_SHIFT 0 O dczytyw anie danych nie nastręcza żadnych problem ów . Im plem entujem y prostą funkcję, korzystającą z rejestru ID R (ang. input data register): static uint8_t Dataln(void) | return (DATA_PORT->IDR s D0_D7) » D0_SHIFT; 1 LCDconfigure(void); LCDciear(void); LCDgoto{int textLine, int charPos); LCDputchar(char c); LCDputcharWrap(char c ) ; U życie rejestru ODR (ang. output data register) w celu zapisyw ania danych w yda­ je się naturalnym pom ysłem . S ytuacja nie je s t jed n ak tak prosta, ja k przy odczy­ cie. M odyfikujem y tyiko 8 bitów portu, a pozostałe m ogą być używ ane przez inne urządzenia. N ajpierw należy odczytać aktualną zaw artość rejestru ODR, a następnie zm odyfikow ać w łaściw e bity i zapisać now ą w artość. Z auw ażm y jednak, że taka sekw encja nie jest atom ow a. Potencjalnie m iędzy odczytem w artości ODR a zapi­ sem now ej m oże zostać zgłoszone przerw anie. Jeśli w trakcie je g o obsługi m ody­ fikow ane są inne bity rejestru ODR tego sam ego portu, to m am y pow ażny problem - nasz program nadpisze m odyfikacje w ykonane w procedurze obsługi przerw ania. R ozw iązaniem je s t w ykorzystanie rejestru B S R R (ang. b it set/reset register), który zapew ni atom ow ość operacji m odyfikow ania bitów. F unkcja zapisująca dane w y­ gląda następująco: Jak nazw a w skazuje, funkcja LC D configure inicjuje w yśw ietlacz. M usi ona zostać w yw ołana, zanim zostanie w yw ołana jak ak o lw iek inna funkcja odw ołująca się do w yśw ietlacza. Funkcja LCDciear czyści (zeruje) zaw artość pam ięci obrazu. Funkcja LCDgoto ustaw ia bieżącą pozycję znaku (kursora), ale żaden znak kursora nie je st w yśw ietlany. Funkcje LCDputchar i LCDputcharWrap w ypisują w pozycji kursora znak o podanym kodzie A SCII i przesuw ają kursor o jed en znak w praw o. R óżnią się tym , że jeśli znak nie m ieści się ju ż w w ierszu, to funkcja LCDputcharWrap prze­ suw a kursor na początek kolejnego w iersza (zaw ija w iersz) i tam w ypisuje podany znak. N atom iast funkcja LCDputchar traktuje wienjz, jak b y byl bardzo długi, ale tekst niem ieszczący się w w ierszu je s t ignorowany. łdefine SET_BITS!x) łdefine CLR_BITS(x) P lik boardJ c d J c s O l 0 8 .c zn a jd u je się w k atalo g u ./exa m p le s/src. Z aw iera on im p lem en tację p rzed sta w io n y ch w yżej funkcji d la w y św ietlaczy ze ste ro w n i­ kam i k o m p aty b iln y m i z u k ład em K S 0108 i u k ry w a w szy stk ie sz czeg ó ły im ­ p lem en tacji sp ec y fic z n e d la teg o stero w n ik a. D zięki tak iem u p o d ejściu , chcąc zastosow ać inny typ w y św ie tla cz a , nie trzeb a m o d y fik o w ać w ielu plik ó w p ro ­ gram u - w y starczy tylk o z m o d y fik o w a ć ten p lik lub p o d m ien ić go na inny, im ­ p lem en tu jący taki sam in terfe js d la p o siad an eg o typu w y św ie tla c z a. D lateg o nie o p isu ję w szy stk ich szczeg ó łó w im p le m e n ta cji, z w łaszcza że o b słu g a w y św ie tla ­ cza nie je s t g łó w n y m tem atem tej k siążk i. S k u p iam się tylk o na ty m , co w yd aje mi się ciekaw e, a C zy teln ik z aw sz e m o że zajrze ć d o arch iw u m , g d z ie z n ajd u je się pełny tekst źró d ło w y tego p rz y k ła d u i g d zie zam ie śc iłe m też d o d atk o w e k o ­ m entarze. B iblioteka ST M 32 nie dostarcza w ygodnych funkcji do operow ania na dw ukierunkow ych liniach danych. W szczególności struktura G PIO _InitTypeD ef i funkcja G P IO _Init są co praw da bardzo w ygodne do konfigurow ania w yprow adzeń, ale ta w ygoda okupiona je s t dodatkow ym narzutem czasow ym - aby obsłużyć w szystkie przypadki, im plem entacja tej funkcji je s t stosunkow o skom plikow ana. Przy pew ­ nych założeniach upraszczających m ożna to zrobić bardziej efektyw nie. Załóżm y, że w yprow adzenia danych w yśw ietlacza rozm ieszczone są po kolei na w spólnym porcie. D efiniujem y identyfikator portu DATA_PORT, do którego podłączone są linie danych w yśw ietlacza, i m askę bitow ą D0 D7 dla tych w yprow adzeń. Pozycję pierw ­ 35 ((uint32_t)(x)) ((uint32_t)(x) « 16) static void DataOut(uint8_t x) ( DATA_PORT->BSRR = CLRJ3ITS (~ ( (ulnt32_t) X « SET~BITS( {(uint32_t)X « D0_SIIIFT) S D0_D7) | D0_SHIFT) « D0_D7); ) Pozostało jeszcze zaim plem entow anie operacji zm iany kierunku w yprow adzeń. Tu niestety nie uda się zapew nić alom ow ości tej operacji i trzeba uw ażać, aby uniknąć konkurencyjnych zm ian, skutkujących niedeterm inislycznym zachow aniem się pro­ gram u. D odatkow y problem przy rekonfiguracji portu spraw ia konieczność odw o­ ływ ania się do dw óch rejestrów , a m ianow icie do C R L (ang. configuration register Iow) i CRH (ang. configuration register high). F unkcje przełączające w yprow adzenia danych w tryb w ejściow y i w yjściow y w yglądają tak: !s k i ¡j: static void DataLinesIn(void) ( uint32_t r; DATA_PORT->BSRR = SET_BXTS(DQ_D7); lif D0_SHIFT < 8 r - DATA__PORT->CRL; r &= ~(OxffffffffU « (4 * D0_SHIFT)); r i= 0x88888888U « (4 * D0_SHIFT); DATA_PORT->CRL = r; lehdif fif D0_SHIFT > 0 r = DATA PORT->CRH; I. Podstawy 36 r &= ~(Oxff£f£fffU » r (= 0x88888S88U » DATA_PORT->CRH “ r; łendi£ (32 - 4 * DO_SHIFT)); (32 - 4 * DO_SHIFT); static void DataLinesOut(void) uint32_t r; #i£ D0_SHIFT < 8 r = DATA_PORT->CRL; r s= ~(0xf££££f££U « r |= OxlinilllU « DATA_PORT->CRL = r; iendif łif D0_SHIFT > 0 r = DATA_PORT->CRH; r s= ~(0xff£ff££fU » r |= OxlllllillU » DATA_PORT->CRH = r; iendif 1.7. Przykład Ib - test wyświetlacza ciekłokrystalicznego P odobną staranność należy też w ykazać podczas konfigurow ania wyjść. Początkow y stan w yprow adzenia m ożna ustaw ić, zanim to w yprow adzenie zostanie ustaw ione w tryb w yjściowy. W ięcej o tym m ożna przeczytać w kom entarzach w pliku b o ­ ard _lcd_ksOJ 08. c. Z apew ne w arto byłoby rozszerzyć przedstaw iony w tym podrozdziale interfejs pro­ gram istyczny w yśw ietlacza np, o funkcje udostępniające inform acje, ile wierszy i ile znaków w w ierszu m oże być w yśw ietlonych. Taką rozbudow ę pozostaw iam C zytelnikow i jak o ćw iczenie. ( (4 * D0_SHIFT)); (4 * D0_SHIFT); 1.7.2. (łdefine FIRST_CIIAR 32 łdefine LAST_CHAR 126 łdefine CHAR_WIDTH 5 extern const char £ont5x8(LAST_CHAR - FIRST_CHAR + 1 1 (CHAR_WIDTH]; ) Z rozum ienie pow yższego fragm entu program u w ym aga ponow nego spojrzenia na rysunek 1.3 oraz tabele 1.10 i 1.11. Stała 0x88888888U oznacza ustaw ienie w ypro­ w adzeń w trybie w ejściow ym z rezystorem podciągającym do zasilania lub ścią­ gającym do masy. Przed przełączeniem w yprow adzeń w tryb w ejściow y, ustaw ia­ my je w stan w ysoki (za pom ocą B S R R ), co spraw ia, że po przełączeniu będą ustaw ione rezystory podciągające. D zięki tem u unikam y stanów nieustalonych na w yprow adzeniach. Stała O x l l l l l i l l U oznacza ustaw ienie w yprow adzeń w trybie w yjściow ym przeciw sobnym 10 M H z. Przy przełączaniu kierunku w yprow adzeń pew nej uw agi w ym aga też w łaściw a kolejność zm ian kierunku i sygnału na linii R /W , którą sterujem y za pom ocą poniższej funkcji: Plik fo n t5 x 8 .c znajduje się w katalogu Jexam ples/src i zaw iera definicje wzorów bitow ych poszczególnych znaków. Pojedynczy bajt definiuje jedną kolum nę znaku. N ajbardziej znaczący bit je st na dole, a najm niej znaczący - na górze. K olejne bajty definiują kolum ny od lewej do praw ej. const char font5x8[LAST_CHAR - FIRST_CHAR + 1 ] [CHARJIIDTHI = ( (0x00, 0x00, 0x00, 0x00, 0x00], /* spacja */ (0x00, 0x00, Qx5F, 0x00, 0x00}, /* ! */ (0x00, 0x07, 0x00, 0x07, 0x00}, /* " */ (0x10, R W (0); /* Najpierw wystaw sygnał WRITE. */ DataLinesOut(); /* Potem ustaw jako wyjścia. */ /* ~ */ N iew ątpliw ie w arto byłoby mieć m ożliw ość w yśw ietlania polskich liter ze znakam i diakrytycznym i, czyli ą, ę, ć itd. N ajprościej jest uzupełnić pow yższą tablicę o zna­ ki kodow ane zgodnie z norm ą ISO /IEC 8859-2. Jak w poprzednim podrozdziale, takie rozszerzenie zbioru w yśw ietlanych znaków pozostaw iam C zytelnikow i jak o ćw iczenie. static void RW(int x) ( if (x) CTRL_P0RT->BSRR = RW_LINE; else CTRL_P0RT->BRR = RW_LINE; /* Najpierw ustaw jako wejścia. */ /* Potem wystaw sygnał READ. */ 0x08, 0x08, 0x10, 0x08} }; łdefine CTM,_P0RT GPI0E łdefine RW_LINE GPIO_Pin_10 DataLinesIn(); RW(1); Pliki font5x8.h i font5x8.c W yśw ietlacz W G 12864A nie m a w budow anego generatora znaków. Trzeba je ge­ nerow ać program ow o. Plik fo n t5 x8 .h znajduje się w katalogu ./exam ples/include. D eklaruje on tablicę fo n t5 x 8 w zorów bitow ych znaków o kodach A SC II od FIRST_ CHAR (spacja) do LAST_CHAR (tylda). W zory znaków m ają w ysokość 8 pikseli i sze­ rokość CHAR_WIDTH pikseli. (32 - 4 * D0_SHIFT)); (32 - 4 * D0_SHIFT); I W arto zaznaczyć, że dobry ko m p ilato r potrafi rozw inąć funkcję RW w m iejscu jej w yw ołania i zoptym alizow ać instrukcje w arunkow e, jeśli argum ent tej funkcji je st stalą. K olejność zm ian kierunku w yprow adzeń i sygnału R /W pow inna uniem oż­ liwić sytuację, gdy linie danych są ustaw ione w tryb w yjściow y jednocześnie w w ięcej niż jed n y m układzie do nich podłączonym . W łaściw e sekw encje przełączeń są następujące: 37 .7.3. Pliki u tiljc d .h i u tiljc d .c Plik u ti lj c d .c znajduje się w katalogu ./exam ples/src, a odpow iadający mu plik nagłów kow y u tiljc d .h - w katalogu ./exam ples/include. Pliki te udostępniają cztery przydatne w ysokopoziom ow e funkcje ogólnego przeznaczenia: void void void void LCDwrite(const char *s); LCDwriteWrap(const char *s); LCDwriteLen(const char *s, unsigned n); LCDwriteLenWrap(const char *s, unsigned n); F unkcje te korzystają z niskopoziom ow ego interfejsu zdefiniow anego w pliku b o­ a r d J e d .h , dzięki czem u ich im plem entacja nie zależy od konkretnego m odelu w y­ św ietlacza. Pierw sze dw ie funkcje w ypisują ciąg znaków zakończony term inalnym I. Podstawy 38 1.8. Organizacja pam ięci programu 39 FLASH zerem (tak zw ykle kończą się napisy w C), z tym że druga zaw ija tekst, jeśli nie mieści się w w ierszu. K olejne dw ie funkcje służą do w ypisyw ania ciągu znaków niezakończonych term inalnym zerem . T rzeba w tedy jak o drugi argum ent podać liczbę znaków do w ypisania. A nalogicznie druga z tych funkcji zaw ija zbyt długi tekst. Jeśli, ja k to zaproponow ałem w poprzednim podrozdziale, utw orzym y tablicę zna­ ków w edług norm y 1SO/IEC 8859-2, to przedstaw ione w tym podrozdziale funkcje bez żadnych m odyfikacji będą m ogły ich używ ać. N ieco bardziej am bitnym ćw i­ czeniem je s t dodanie, choćby w ograniczonym zakresie, w ypisyw ania ciągu zna­ ków w kodow aniu UTF-8. sidata = etext 1.7.4. Plik e x jc d .c Plik e x j c d .c znajduje się w katalogu ./exam ples/src. D em onstruje on użycie niektó­ rych z w yżej opisanych funkcji. W nieskończonej pętli w yśw ietlane są na przem ian dw a testy. Pierw szy test w ypisuje m .in. w szystkie znaki zdefiniow ane w pliku fo n t5x8.c. Drugi testuje przem ieszczanie kursora po ekranie i zaw ijanie tekstu. 1.8. Organizacja pamięci programu W tym podrozdziale opisuję, ja k w pam ięci m ikrokontrolera rozm ieszcza się kod program u i je g o zm ienne, co dzieje się zanim zostanie w yw ołana funkcja main, jak w yw oływ ane są procedury obsługi przerw ań oraz ja k to kontrolow ać i m ody­ fikować. O pis dotyczy języ k a C, architektury C ortex-M 3 i narzędzi G N U (GCC i B inutils), ale w innych języ k ach program ow ania i ińnyeh architekturach w szystko dzieje się bardzo podobnie. Z akładani też, że program ładow any je st do pam ięci Flash. 1.8.1. Sekcje Kod program u oraz dane, na których on operuje, są w pam ięci zblokow ane w sek­ cjach. Na ry s u n k u 1.8 przedstaw iono typow e rozm ieszczenie sekcji w pam ięci m i­ krokontrolera. Sekcja , i s r _ v e c t o r je s t specyficzna dla architektury C orlex-M 3. Z aw iera tablicę adresów procedur obsługi przerw ań, a ponadto początkow ą w artość w skaźnika sto­ su oraz adres, od którego zaczyna się w ykonyw anie program u. W ięcej o tym piszę w następnych podrozdziałach. Sekcja . t e x t zaw iera kod w ykonyw alny, czyli skom pilow ane w szystkie funkcje naszego program u oraz w szystkie funkcje biblioteczne, które do niego dołączam y. Sekcja .r o d a t a zaw iera dane tylko do odczytu. Są to te zm ienne, któ re zostały zadeklarow an e ja k o stale z uży ciem słow a k luczow ego c o n s t i nie zostały zo p ­ tym alizow ane. K o m p ilato r nie m usi alokow ać p am ięci dla zm iennej, która nie zm ienia sw ojej w artości i je j zak res w ido czn o ści je s t o g ran iczo n y do je d n e g o blo ­ ku, je d n ej funkcji lub jed n o stk i translacji. Z op ty m alizo w an a m oże być zm ienna lokalna (zad ek laro w an a w ew n ątrz bloku instrukcji o to czo n eg o naw iasam i k lam ­ row ym i lub w ew nątrz funkcji) w y sp ecy fik o w an a ja k o c o n s t lub s t a t i c c o n s t albo zm ienn a glob aln a w y sp ecy fik o w an a ja k o s t a t i c c o n s t. Z m ienna globalna 0x08000000 Rys. 1.8. Typowa organizacja pamięci programu w ysp ecy fikow ana tylko ja k o c o n s t nie m oże być zoptym alizow ana, gdyż je j na­ zw a je s t w idoczna na zew nątrz jed n o stk i translacji i potencjalnie m ożna odw ołać się do niej z innych je d n o stek translacji, a standardow y proces kom pilow ania ję ­ zyka C nie przew iduje optym alizacji p om iędzy jed n o stk am i translacji. W sekcji . r o d a ta um ieszczane są też stale napisow e, n iezależnie od tego, czy m ają jaw n ie zd efin io w aną nazw ę. Sekcja .d a ta zaw iera zm ienne globalne i statyczne, które są inicjow ane w artościa­ mi niezerow ym i. W artość zerow a to taka, której binarna reprezentacja ma w szystkie bity w yzerow ane. W artość niezerow a to w artość, która nie je s t zerow a, czyli jej reprezentacja binarna m a co najm niej jed en bit różny od zera. W tej sekcji znajdują się tylko zm ienne zadeklarow ane bez kw alifikatora c o n s t. Są to w szystkie takie zm ienne globalne oraz te lokalne, które są dodatkow o opatrzone słow em kluczo­ w ym s t a t i c . Sekcja .b s s zaw iera dokładnie te sam e kategorie zm iennych co sekcja .d a ta , ale są to te zm ienne, które są inicjow ane w artościam i zerow ym i lub nie podano żadnej w artości inicjującej. Z m ienna, dla której nie podano w artości inicjującej, je s t (zw y­ kle) dom yślnie inicjow ana w artością zerow ą. S ekcja heap to sterta przydzielona program ow i. Na stercie zm ienne są alokow ane za pom ocą funkcji bibliotecznych przydzielających pam ięć, takich ja k np. raallo c. 1. Podstawy 40 Sekcja s t a c k zaw iera stos program u. N a stosie um ieszczane są zm ienne lokalne (autom atyczne). N azw a zm ienna autom atyczna oznacza, że zm ienna laka znika au­ tom atycznie, gdy sterow anie program u w ychodzi poza zakres jej w idoczności. N a stosie odkładane są też w artości argum entów aktualnych w yw ołania funkcji, czyli w artości tych argum entów , które zostały przekazane funkcji w aktualnym jej w yw o­ łaniu. Z m ienne autom atyczne i argum enty funkcji są najczęściej optym alizow ane przez kom pilator i o ile je st to tylko m ożliw e, nie są przechow yw ane na stosie, a w rejestrach procesora. N a stosie odkładane m ogą też być adres pow rotu z funkcji oraz w artości rejestrów , których funkcja używ a i których w artości musi odtw orzyć przed pow rotem . W architekturze A R M nie odkłada się adresu pow rotu na stos bezpośrednio - je st on trzym any w rejestrze procesora LR. Jeśli LR je s t potrzebny do zagnieżdżonego w yw ołania funkcji, to dopiero w tedy jeg o w artość jest odkładana na stos. W ątpliw ości, co do um ieszczania zm iennych globalnych w poszczególnych sek­ cjach, pow inny w yjaśnić poniższe przykłady. Z m ienne a, b, c zostaną um ieszczone w sekcji .r o d a ta : 1.8. Organizacja pam ięci programu N apis zostanie um ieszczony w sekcji .r o d a t a , ale w skaźnik s8 w sekcji .d a ta : const char * s8 = "Ala ma kota."; N apis będzie um ieszczony w sekcji .d a ta , a w skaźnik s9 w sekcji .r o d a ta lub zostanie zoptym alizow any: char * const s9 = "Ala ma kota."; N apis i w skaźnik slO zostaną um ieszczone w sekcji .r o d a ta , w skaźnik może zo­ stać zoptym alizow any: const char * const slO = "Ala ma kota."; W skaźniki s i l , s ł 2 zostaną um ieszczone w sekcji .b s s : char * sil; char * sł2 = NULL; K olejny przykład pokazuje sposób przydziału pntięci dla zm iennych lokalnych. void funkcja(char *p, int n) { /* p - stos lub rejestr */ /* n - stos lub rejestr */ const int a ~ 5; const: int b = 0/ const int c; int i; char q f 10]; static char x; static char y = 'a'; const char z = 'b'; Z m ienne d, e, f zostaną um ieszczone w sekcji .r o d a t a lub zoptym alizow ane: /* stos lub rejestr */ /* /* /* /* stos */ .bss */ .data */ .rodata łub optymalizacja */ static const int d = 5; static const int e = 0; static const int f; /* alokacja n bajtów na stercie */ p = malloc(n); Z m ienne g, j zostaną um ieszczone w sekcji .d a ta , a zm ienne h, i , k, m w sekcji .b s s : /* napis w .rodata */ strcpy(p, "Ala ma kota."); int g = 5/ int h = G; int i; static int j = 5; static ,i.nt k = 0; static int m; for (i = 0; i < n; -Hi) ( char s; /* stos lub rejestr */ static char t; / * .bss */ static char u = ,c'; /* .data */ const char w = ’ d'; /* .rodata lub optymalizacja */ Sytuacja nieco bardziej się kom plikuje, gdy używ am y globalnych tablic lub w skaź­ ników, gdyż kw alifikator c o n s t m oże dotyczyć sam ego w skaźnika lub w artości, na którą w skazuje, co d em onstrują następujące przykłady. Tablice s l , s2 zostaną um ieszczone w sekcji .r o d a ta : static const char sl{} = "Ala ma kota."; const char s2[) = "To jest kot Ali."; T ablice s3, s4 będą um ieszczone w sekcji .d a ta : static char s3|j = "Ala ina kota."; char s4[] = "To jest kot Ali."; Tablice s5, s6 zostaną um ieszczone w sekcji .b ss : static char s5(10]; char S6110]; N apis i w skaźnik s7 będą um ieszczone w sekcji .d a ta : char * s7 = "Ala ma kota."; 41 i 1 Sekcje . isr_ _ v ecto r, . t e x t i .r o d a t a zaw ierają dane tylko do odczytu i dlatego m ogą być um ieszczone w pam ięci Flash. M ożna je też um ieścić wRAM - m ikro­ kontrolery A RM m ogą w ykonyw ać kod z RAM . Sekcje .b s s , heap is ta c k za­ wierają dane, które m ogą być m odyfikow ane przez program i dlatego muszą być um ieszczone w RAM . Zauw ażm y, że są dw ie sekcje .d a ta , jedna w Flash, a druga w RAM . Sekcja .d a ta zaw iera dane, które z jednej strony m ają nadane jak ieś niezerow e w artości początkow e, a z drugiej strony m ogą być m odyfikow ane przez program . Sekcja .d a ta um ieszczona w pam ięci Flash przechow uje w artości począt­ kow e, które są przepisyw ane do RAM przed rozpoczęciem w ykonyw ania progra­ mu. Ponadto przed rozpoczęciem w ykonyw ania program u trzeba w yzerow ać sekcję .b s s , gdyż zaw artość RAM po w yzerow aniu m ikrokontrolera je st niezdefiniow ana. Zatem sekcje .d a ta i .b s s w ym agają program ow ego inicjow ania. Z ajm uje się tym procedura startow a, o której piszę w następnym podrozdziale. 42 1.8.2. I. Podstawy Procedura startowa Procedura startow a zależy od architektury procesora i używ anego kom pilatora, gdyż z reguły je s t pisana w A sem blerze konkretnego procesora. Tu przedstaw iam m ini­ malną, ale w pełni funkcjonalną i w w iększości przypadków zupełnie w ystarczającą, procedurę startow ą dla architektury C ortex-M 3 i kom pilatora C z pakietu G CC. Na jej podstaw ie C zytelnik m oże stw orzyć w łasną, bardziej rozbudow aną i dostosow a­ ną do sw oich potrzeb. R ozszerzenia dodane do języ k a C przez G N U C um ożliw ia­ ją napisanie procedury startow ej b ez użycia A sem blera. Pełny tekst źródłow y dla m ikrokontrolera ST M 32F107, opatrzony kom entarzam i, znajduje się w archiw um z przykładam i w pliku startup_ stm 3 2 _ cld .c, który je st w katalogu ./exatnples/src. W tym m iejscu opisuję tylko kluczow e fragm enty procedury startow ej. Z aczynam y od z ad ek laro w an ia p seu d o zm ien n y ch , któ re w sk azu ją g ran ice sekcji. D eklarujem y je ja k o e x te r n , g dy ż są d efin io w an e p rze z k o n so lid ato r, co zo b a­ czym y w następnym p o d ro zd ziale. P o p atrzm y na ry su n ek 1.8. Z m ien n a s i d a t a zachow uje się tak, ja k b y b y ła u m ieszczo n a w pierw szy ch czte rech bajtach sekcji .d a t a w pam ięci F lash — je j ad res je s t ad resem p o czątku tej sekcji w Flash. U w aga, lokacja zm iennej _ s i d a t a i p o zo stały ch p seu d o zm ien n y ch p o k ry w a się w pam ięci z p raw d ziw y m i zm ien n y m i naszeg o pro g ram u . Te p seu d o zm ien n e służą tylko do o k reślen ia adresów , gdzie zaczy n ają się i ko ń czą p o szczeg ó ln e sekcje, Z m ien n a _ s d a ta je s t p o ło żo n a w czterech pierw szy ch bajtach dan y ch in i­ cjow anych w R A M , a zm ien n a __edata zajm u je cztery bajty tu ż za dan y m i in i­ cjow any m i, czyli adres zm iennej __sdata w sk azu je i p ierw szy ad res sekcji .d a ta w R A M , adres zm iennej _ e d a ta - pierw szy adres ża tą sekcją. Z m ien n a _ s b s s zajm uje p oczątk o w e czte ry bajty d an y ch zero w an y ch , a zm ien n a _ e b s s - cztery bajty tuż za tym i d an ym i, czyli ad res zm iennej s b s s w sk azu je pierw szy ad ­ res sekcji .b s s , a ad res zm iennej _ e d a ta - pierw szy adres za tą sekcją. A dres zm iennej e s t a c k w sk azu je p ierw szy adres za pam ięcią R A M , czyli początkow y w ierzchołek stosu. extern extern extern extern extern extern unsigned long unsigned long unsigned long unsigned long unsigned long void _estack; _sidata; __sdata; _edata; _sbss; _ebss; N astępnie pow inniśm y zadeklarow ać sygnaturę głów nej funkcji, od której rozpo­ czyna się w ykonyw anie program u i która zw yczajow o nazyw a się main. Funkcja ta musi być zdefiniow ana (zaim plem entow ana) w jak iejś jed n o stce translacji. N asza funkcja main nie przyjm uje żadnych argum entów , choć nic nie stoi na przeszkodzie, aby takie argum enty zadeklarow ać, jeśli znajdziem y po tem u sensow ny pow ód. K onw encja nakazuje, aby funkcja m ain była typu i n t , choć nie będziem y w yko­ rzystyw ać zw racanej w artości - w św iecie m ikrokontrolerów funkcja ta nigdy nie kończy działania. Jednak kom pilatory traktują ją specjalnie i w ypisują ostrzeżenie, jeśli dostarczym y jej im plem entację innego typu. int main(void); 1.8 . Organizacja pam ięci programu 43 D efiniujem y dom yślną procedurę obsługi przerw ania D e f a u l t j ł a n d l e r - nieocze­ kiw ane przerw anie zaw iesza m ikrokontroler. M ożna oczyw iście, jeśli potrzebujem y, zaim plem entow ać bardziej w yrafinow aną obsługę. static void Defaultjłandler(void) ( for (;;); 1 M usim y koniecznie napisać procedurę R e se t_ H a n d le r w yw oływ aną po w yzero­ w aniu m ikrokontrolera. M inim alna im plem entacja lej procedury rozpoczyna się od dw óch pętli. Pierw sza pętla kopiuje sekcję .d a ta z Flash do R A M , a druga - zeruje sekcję .b s s . Po tym m ożna ju ż rozpocząć w ykonyw anie program u - w yw ołujem y funkcję main. Funkcja ta zw ykle nigdy się nie kończy, ale gdyby jed n ak nastąpił z niej pow rót, zapętiam y się w nieskończoność. static void Reset_Handler(void) { unsigned long *src, *dst; for (dst *dst = for (dst *dst = main (); for = &_sdata, src = &_sidata; dst < &_edata; ++dst, -i+src) *src; = &_sbss; dst < &_ebss; ++dst) 0; 1 Kolej na deklaracje procedur obsługi przerw ań - dla każdego przerw ania trzeba dostarczyć bezparam etrow ą funkcję typu v o id . Funkcje te deklarujem y z atry­ butem weak, co w yjaśniam w dalszej części tego podrozdziału. M ikrokontroler ST M 32F107 m oże zgłaszać kilkadziesiąt przerw ań. Poniższy w ydruk obejm uje tyl­ ko fragm ent ich listy. Idefine WEAK attribute ((weak)) void WEAK NMIJ-Iandler (void) ; void WEAK HardFault_Handler(void); void WEAK MemManage_Handler(void); void WEAK BusFault_Handler(void); void WEAK UsageEault_Handler(void)/ void WEAK SVCJIandler (void); void WEAK DebugMon_Handler(void); void WEAK PendSV_Handler(void); void WEAK SysTick_Handler(void); void WEAK WWDG_IRQHandler(void); void WEAK PVD_IRQHandler(void); void WEAK TAMPER_IRQHandler(void); void WEAK RTC_IRQHandler(void); void WEAK RTCAlarm_IRQ!Iandler (void); void WEAK ETH_IRQHandler(void); void WEAK OTGJf’ SJRQHandler(void); Tablicę przerw ań um ieszczam y w specjalnie dla niej przeznaczonej sekcji , i s r _ v e c to r . Jest ona zadeklarow ana ja k o tablica stałych w skaźników do bezparam etrow ych funkcji typu v o id . D la ST M 32F107 tablica ta m a 84 elem enty, ale nie w szystkie są obecnie używ ane - część je s t zarezerw ow ana do przyszłego w yko­ 44 1. Podstawy rzystania. Pierw szy elem ent (o indeksie 0) tablicy przerw ań zaw iera początkow ą w artość w skaźnika stosu, ładow aną do rejestru SP po w yzerow aniu m ikrokontrole­ ra, Drugi elem ent (o indeksie 1) w skazuje na procedurę w yw oływ aną po w yzero­ waniu. K olejne 14 elem entów to adresy obsługi procedur przerw ań zdefiniow anych w architekturze C ortex-M 3. Pozostałe 68 elem entów to adresy obsługi przerw ań układów peryferyjnych, specyficznych dla ST M 32F107. Z arezerw ow ane elem enty tablicy przerw ań są inicjow ane zeram i. attribute ((section(".isr_vector"))) void (* const g pfnVectors(])(void) = { &_estack, Resetjlandler, /* Przerwania Cortex-M3 */ MMIJiandler, HardFault_Handler, MemManage_Handler, BusFault_Handler, UsageFault_Handler, 0, 0, 0, 0, SVCJiandler, DebugMonJlandler, 0, PendSV_Handier, SysTick__Handler, /* Przerwania układów peryferyjnych */ WWDG_IRQHandler, PVDJRQHandler, TAMPER_IRQHandler, RTC_IRQHandler, 45 1.8. Organizacja pam ięci programu m ultiple dęfinition). Z kolei brak im plem entacji dom yślnej w ym agałby dostarcze­ nia im plem entacji procedur obsługi w szystkich przerw ań, gdyż inaczej konsolidator zgłosiłby bkjd odw yw ołania do niezdefiniow anej nazw y (ang. w u lefm ed rejerence). fpragma weak NMI_Handler = Default_Hancłler fpragma weak HardFaułt_Handler = Defaultjiandler fpragma weak MemManage_ilandler = Defaułt_Handłer fpragma weak OTG_FS_IRQHandier = Default_Handler Pow yższe instrukcje spraw iają, że nazw y procedur obsługi przerw ań są słabymi aliasam i nazw y dom yślnej procedury obsługi. Jeśli konsolidator nie znajdzie de­ finicji jak iejś procedury, to użyje aliasu, czyli w stawi do tablicy przerw ań adres procedury dom yślnej. Skrypt konsolidatora W w yniku kom pilacji, na podstaw ie każdej jednostki translacji, tw orzony jest odpo­ w iadający jej plik pośredni, zaw ierający w szystkie sekcje, których w ygenerow anie było niezbędne dla tej jednostki translacji. Jest to plik relokow alny, co oznacza, że każda sekcja m oże być um ieszczona pod dow olnym adresem w pam ięci procesora. Pliki pośrednie m ogą być łączone w w iększe pliki, tw orząc biblioteki. Aby po­ wstał program w ykonyw alny, trzeba połączyć w łaściw e pliki pośrednie i biblioteki. W tym procesie łączenia scalane są w je d n ą sekcję w szystkie sekcje pełniące tę sam ą funkcję ze w szystkich plików poddanych łączeniu. Łączeniem plików pośred­ nich i rozm ieszczaniem poszczególnych sekcji w pam ięci zajm uje się konsolidator. W przypadku konsolidatora Id z pakietu B inutils przebiegiem konsolidacji steruje skrypt, co um ożliw ia bardzo elastyczne sterow ania tym procesem . ETH_IRQHandler, W katalogu Jcza tn p les/scn p ts znajdują się skrypty w ym ienione w tabeli 1.14. D la każdego m odelu m ikrokontrolera S T M 32F107 je st tam um ieszczony osobny skrypt. Są one jed n ak bardzo podobne, dlatego tu zam ieszczam tylko w ydruk pliku stm 3 2 fl 07vc. Ids: OTG_FS_IRQHandler MEMORY RTCAiarm_IRQHandler, ); Ż eby tablica przerw ań m ogła być skonsolidow ana z resztą program u, czyli żeby k onsolidator m ógł do niej pow staw iać w łaściw e adresy procedur, to dla każdej w y­ specyfikow anej w tablicy przerw ań nazw y procedury musi być dostarczona je j im ­ plem entacja. Procedury obsługi przerw ań definiujem y zw ykle w różnych je d n o st­ kach translacji. Na ogól jed n ak nie chcem y im plem entow ać procedur dla w szyst­ kich przerw ań, a tylko dla tych używ anych w danym program ie - pozostałym najchętniej przypisalibyśm y adres dom yślnej procedury D e fa u lt_ H a n d le r. D o tego w łaśnie służy, w spom niany w yżej, m echanizm słabego (ang. w e a k ) w iązania nazw. Jeśli konsolidator znajdzie procedurę, której nazw a została um ieszczona w tablicy przerw ań, to w staw i do tej tablicy jej adres. Jeśli jed n ak takiej procedury nie znaj­ dzie, to w staw i adres procedury dom yślnej. B ez m ożliw ości słabego w iązania nie udałoby się tego zrobić elegancko. Z aim plem entow anie dom yślnego zachow ania w e w szystkich procedurach i próba dostarczenia później w łaściw ej im plem entacji spow odow ałaby błąd konsolidacji - dw ukrotnie zdefiniow ana ta sam a nazw a (ang. ( FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 256K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 6<1K I _mininuim_stack_and_heap_size = 8192; INCLUDE cortex-m3.1ds Z a pom ocą instrukcji MEMORY deklarujem y dostępne obszary pam ięci, ich atrybuty (r - upraw nienie do odczytu, w - m ożliw ość zapisu, x - zezw olenie na w ykony­ w anie kodu z tej pam ięci), adres początku i rozm iar. N ależy podkreślić, że alryTab. 1.14. Skrypty konsolidatora dla STM32F107 Skrypt Opis cortex-m3.lds Część wspólna dla architektury Cortex-M3 stm 32H07rb.lds Część specyliczna dla STM 32F107RB stm 32H 07rc.lds Część specyficzna dla STM 32F107RC stm 32l107vb.lds Część specyficzna dla STM 32F107VB stm 32n07vc.lds Część specyficzna dla STM 32F107VC I. Podstawy 46 buty te są tylko inform acją dla konsolidatora i nie w ym uszają żadnych ograniczeń dostępu do fizycznej pam ięci m ikrokontrolera. N astępnie deklarujem y m inim alny rozm iar pam ięci, która m usi pozostać w olna dla stosu i sterty (sekcje s ta c k i heap). K onsolidator zgłosi błąd, gdy w R A M zostanie za m ało m iejsca. W reszcie na koń­ cu, za pom ocą instrukcji IN C L U D E , przechodzim y do w ykonania głów nego skryptu cortex-m 3.lds, w spólnego dla w szystkich modeli m ikrokontrolera. Jest to m inim al­ ny, ale w pełni funkcjonalny, skrypt dla architektury C orlex-M 3. P oznaw szy jeg o strukturę, C zytelnik m oże stw orzyć w łasny, bardziej rozbudow any i dostosow any do sw oich potrzeb. Skrypt ten w ygląda tak: SECTIONS ( .text : f K E E P (*(.isr_vector)) * E.text) * (.text.*) *{.rodata) * (.rodata.*) . = AL I G N (4); _etext = _sidata = _etext; ) >FLASH =0xf f 1.8. Organizacja pamięci programu 47 osobnych sekcji. Na om aw ianym w ydruku pom inąłem fragm ent tw orzący sekcje dla debuggera, gdyż nie m a to w pływ u na organizację pam ięci program u - zaintere­ sow any C zytelnik m oże po prostu zajrzeć do pliku ./exam ples/scripts/cortex-m 3.lds. Poniżej opisuję szczegółow o poszczególne konstrukcje użyte w tym skrypcie. SECTIONS { 1 Instrukcja S E C T IO N S rozpoczyna głów ną część skryptu definiującą sposób przetw a­ rzania sekcji z plików pośrednich na sekcje w pliku w ynikow ym (w ykonyw alnym ). Z aw iera definicje poszczególnych sekcji w pliku w ynikow ym . W tym konkretnym przypadku są to sekcje . t e x t , .d a ta i .b s s . .text : 1 ) >FLASH =0xff Pow yższa instrukcja tw orzy sekcję . t e x t , która zostanie um ieszczona w pam ięci Flash, a ew entualne puste, nieużyw ane m iejsca zostaną w ypełnione w artościam i 0xf f . .data : AT(_sidata) .data : AT(_sidata) I i . = AL I G N (4); _sdata = M.data) M.data.*) . = AL I G N (4); _edata = ) >RAM =0 ) >RAM =0 i .bss : { . = AL I G N (4) ; _sbss = .; * ( .bss) * {.bss.*) * (COMMON) . = A L I G N (4); _ebss = .; ) >RAM _estack = (ORIGIN(RAM) + LENGTH(RAM)) & OxFFFFFFFC; ASSERT(_ebss + _minimum_stack_and_heap size <= _estack, "There is not enough space in RAM for stack and heap.") PROVIDE(end = _ebss); /* Teraz zostały już tylko informacje dla debuggera. */ ) Pow yższy skrypt tw orzy trzy sekcje: . t e x t , .d a ta i .b s s . W sekcji . te x t są um iesz­ czane w spólnie sekcje ,i s r _ v e c t o r , . t e x t i .r o d a t a - nie m a potrzeby tw orzenia Pow yższa instrukcja tw orzy sekcję .d a ta . A dresy w tej sekcji m ają być tak w ylicza­ ne (relokow ane), jak b y była um ieszczona w R A M , ale zaw artość tej sekcji zostanie fizycznie załadow ana pod adres _ s i d a t a , który je s t pierw szym adresem w pam ięci Flash tuż za sekcją . t e x t (połączonym i sekcjam i . is r _ v e c to r , . t e x t i .ro d a ta ). E w entualne puste, nieużyw ane m iejsca zostaną w ypełnione zeram i. .bss : I | >RAM P ow yższa instrukcja tw orzy sekcję .b s s , która zostanie um ieszczona w RAM . * {. text) *(.text.*) P o w y ższa instrukcja w ybiera o k reślo n e sek cje z w yspecyfikow anych plików. W yrażenie reg u larn e przed n aw iasem je s t w zorcem nazw y pliku - gw iazdka o zn acza w szy stk ie pliki. W yrażenie reg u larn e w n aw iasie je s t w zorcem nazw y sek cji, którą należy w ybrać z tego pliku. G w iazdka zastępuje dow olny ciąg znaków . W ybierane są w szy stk ie sek cje o nazw ach pasujących do w zorca ze w szy stk ich plików o nazw ach pasu jący ch do w zorca. S ekcje, których nazw a ma d o d atk o w y su fik s rozpoczynający się kropką, pow stają, jeśli p odczas kom p ilo ­ w ania ustaw im y op cję um ieszczan ia w szy stk ieg o w osobnych sekcjach (patrz o statn ie dw a w iersze w tabeli 1.5). P rzykładow o funkcja o nazw ie xyz zostanie um ieszczo n a w tedy w sw ojej sekcji o nazw ie .t e x t . x y z . Jeśli opcje te nie z o ­ stan ą u staw ione, to funkcja ta zo stan ie um ieszczo n e w e w spólnej sekcji . t e x t I. Podstawy 48 'S 1.9. Styl pisania i komentowania tekstu źródłowego ASSERT (_ebss + jiunimuni_stack_and_heap_size <= _eatack, w raz z innym i funkcjam i z tej sam ej je d n o stk i tran slacji. P o w y ższe instrukcje p o k ry w ają o b ie sytuacje. "There is not enough space in RAM for stack and heap.") Instrukcja A S S E R T spraw dza popraw ność w arunku. Jeśłi w yrażenie w pierw szym argum encie jest fałszyw e, to konsolidator przeryw a pracę i w ypisuje tekst będący drugim argum entem . Z asady w yliczania w artości w yrażenia w arunkow ego są ana­ logiczne ja k w języ k u C. W tym konkretnym przykładzie konsolidator zgłosi błąd, gdy po scaleniu w szystkich sekcji, które m ają znaleźć się w RAM , zostanie za mało m iejsca na stos i stertę. K E E P (*(.isr_vector)) Pow yższa instrukcja K E E P spraw ia, że sekcja , i s r _ v e c t o r , czyli tablica adresów procedur obsługi przerw ań oraz sam e procedury obsługi przerw ań nie zostaną usunięte z pliku w ynikow ego przez ods'm iecacz (patrz opcja odśm iecania w tabeli 1.9). D o tablicy przerw ań i do procedur przerw ań nie m a zw ykle żadnych odw ołań w tekście źródłow ym - procedur przerw ań raczej nie w yw ołujem y ja w n ie - są na ogól w yw oływ ane przez sprzęt, w ięc odśm iecacz m iałby w szelkie podstaw y, żeby je usunąć z pliku w ynikow ego. PROVIDE (end = __ebss) ; P ow yższa instrukcja P R O V ID E pow oduje, że jeśli w ja k iejś jed n o stce translacji jest o dw yw ołanie do zew nętrznego sym bolu o nazw ie end, a sym bol ten nie został nig­ dzie zdefiniow any, to zostanie on zdefiniow any przez konsolidator i zostanie mu p rzydzielony adres będący w artością w yrażenia um ieszczonego po praw ej stronie operatora przypisania. W tym konkretnym przypadku będzie to pierw szy wolny adres za sekcją .b s s . Z m ienna o nazw ie end je st w ykorzystyw ana przez standardo­ w ą bibliotekę jęz y k a C do w skazania początkow ego końca sterty. M ianow icie ad­ res tej zm iennej je s t używ any do zainicjow ania zm iennej heap_end, która pam ięta pierw szy w olny adres nad stertą, w ięc na początku działania program u sterta ma zerow y rozm iar. Jeśli trzeba przydzielić now ą pam ięć i nie ma m iejsca na stercie, to spraw dza się, czy m ożna rozszerzyć stertę. Sterta je s t rozszerzana, jeśli m iędzy heap_end a w skaźnikiem stosu (rejestr S P ) je s t dostateczna ilość w olnego m iej­ sca. Z m ienna heap_end je s t tylko zw iększana, nigdy zm niejszana. Zarządzaniem rozm iarem sterty zajm uje się funkcja, której nazw a zaw iera zw ykle napis sb rk - w b ibliotece N ew lib dla architektury A RM je s t to funkcja _ sb rk . W niektórych im plem entacjach biblioteki standardow ej zm ienna używ ana do w skazania począt­ kow ego końca sterty nazyw a się _end. T rzeba w tedy odpow iednio zm odyfikow ać instrukcję P R O V ID E . . = ALIGNH); Jeśli nie zdecydujem y inaczej, to konsolidator, analizując skrypt, układa scalane sekcje po kolei. K ropka oznacza adres, pod którym zostanie um ieszczona kolejna scalana sekcja, czyli docelow y adres początku tej sekcji. Z nak rów ności je s t opera­ torem przypisania. Jeśli do kropki przypiszem y w artość, to zm odyfikujem y bieżący adres i następna scalana sekcja zostanie um ieszczona pod tym now ym adresem . O perator ALIGN zw raca najbliższy adres, który je s t w ielokrotnością je g o argum entu i służy do w yrów nyw ania położenia sekcji w pam ięci. A RM je st architekturą 32-bitow ą. A rchitektury 32-bitow e w ym agają zw ykle, aby adresy początków sekcji były w yrów nyw ane do w ielokrotności 4. _etext = .; Pow yższa instrukcja przypisuje sym bolow i __etext bieżący adres. W tekście źród­ łow ym w C ten sym bol będzie w idoczny jak o zm ienna um ieszczona pod tym ad­ resem . _sidata = _etext; Pow yższa instrukcja sym bolow i _ s i d a t a przypisuje w artość w yrażenia po praw ej stronie znaku rów ności. W tym przypadku je st to w artość przypisana poprzednio sym bolow i e te x t . Zauw ażm y, że k onsolidator operuje na adresach, ale defin io ­ w ane sym bole są w tekście źródłow ym w idziane ja k o zm ienne i dla uzyskania ad­ resu trzeba użyć operatora dereferencji &, czyli aby uzyskać adres przypisany przez konsolidator sym bolow i __sidata, trzeba w C użyć w yrażenia & _ sid ata. Po praw ej stronie operatora przypisania m oże pojaw ić się w yrażenie składające się z poprzed­ nio zdefiniow anych sym boli połączonych za pom ocą w iększości operatorów arytm etyczno-logicznych, które są d ostępne w języ k u C, a dla w ym uszenia kolejności działań m ożna użyć naw iasów , ja k w poniższym przykładzie. _estack = (ORIGIN(RAM) I LEHGTH(RAM)) S OxFFFFFFFCj Pow yższa instrukcja definiuje p o czątkow ą w artość rejestru S P , czyli w ierzchołka stosu. R ejestr SP w skazuje na ostatnio odłożoną na stos w artość. W architekturze A RM , jak w w iększości procesorów , stos rośnie w dól, w kierunku m niejszych ad­ resów. Poniew aż je s t to architektura 32-bitow a, na stosie odkładane są w ielokrotno­ ści czterech bajtów, a w artość rejestru SP musi być podzielna przez cztery. Zatem początkow a w artość w ierzchołka stosu pow inna być pierw szym adresem za RAM , a jeśli ten adres nie je s t w ielokrotnością czterech, to należy go zm niejszyć do naj­ bliższego podzielnego przez cztery. 49 1.9. Styl pisania i komentowania tekstu źródłowego Tekst źródłow y program u je s t czytany nie tylko przez kom pilator (lub interpreter), którem u styl program ow ania je s t obojętny. Jest też czytany przez ludzi, którzy chcą lub m uszą go pielęgnow ać i dalej rozw ijać. D obrze napisany program kom puterow y daje się łatw o m odyfikow ać i rozszerzać o now ą funkcjonalność. Program żyje, gdy jest rozw ijany i popraw iany, często przez kolejne pokolenia program istów , którzy w zajem nie się nie znają. Program , którego nie m ożna zm odyfikow ać, m a dużą szan­ sę stać się m artw y i przestać być używany. C ałość lub fragm enty dobrze napisanego program u pow inno dać się w ykorzystać w kolejnych projektach. Jedną z w ażniej­ szych przyczyn trudności m odyfikow ania program u je s t nieczytelnie napisany tekst źródłowy, którego po pew nym czasie naw et autor nie rozum ie. D ołożyłem w szel­ kich starań, aby zam ieszczone w tej książce przykłady były napisane elegancko, w dobrym stylu. Program y kom puterow e m ają jed n ak taką przypadłość, że zaw sze m ożna w nich coś popraw ić i napisać lepiej. W ażnym elem entem popraw iającym czytelność program u są kom entarze. Nie nale­ ży je d n a k przesadzać i kom entow ać każdej linijki - to w brew pozorom m oże u trud- 50 1. Podstawy niać czytanie tekstu źródłow ego. N ależy bezw zględnie kom entow ać te fragmenty, których działanie je st nieoczyw iste albo pow ód ich napisania trudno odgadnąć. K om entarze pow inny być pisane pełnym i zdaniam i i popraw nym językiem . N ie na­ leży um ieszczać kom entarzy tryw ialnych, opisujących to, co w idać w tekście źród­ łow ym program u. Z am iast długich opisów często w ystarczy w łaściw ie dobrać na­ zwy funkcji, ich param etrów i zm iennych. O dpow iednie nazw y spraw iają, że tekst źródłow y sam odokum entuje się, a niew ielka ilość kom entarzy w ystarcza do jego zrozum ienia. Taki sam okom entujący się tekst źródłow y czyta się bardzo przyjem ­ nie. Teksty źródłow e zaw arte w archiw um z przykładam i są skom entow ane, lecz nie przesadnie. Pew nym uspraw iedliw ieniem je st fakt, że cała treść książki je st sw ego rodzaju kom entarzem do tych przykładów . Z oszczędności m iejsca, w głów nym tekście książki, w e fragm entach program ów ilustrujących opisyw ane zagadnienia i przykłady pom ijam w iększość kom entarzy. N ie są one tu potrzebne, g dyż sam tekst książki stanow i dostateczne w yjaśnienie. Intersieci 2.1. M odel warstwowy Intersieć (ang. internet) składa się z w ielu autonom icznych, w spółdziałających sieci lokalnych (LA N, ang. local area netw ork). N ajw iększą intersiecią, ja k ą dotychczas stw orzono, jest Internet. Intersieci zarządzane są w sposób rozproszony - poszczę- * gólne organizacje, firnty nadzorują sw oje fragm enty sieci. Z apew nienie popraw - $ nej w spółpracy w takim środow isku w ym aga standaryzacji. W iększość aspektów ;p działania intersieci je s t opisana w dokum entach R FC (ang. R equest fo r Continents). rj N iektóre z nich uzyskały status o ficjalnego standardu, ale w iększość nie m a charak- g teru norm atyw nego, będąc tylko niezobow iązującym i zaleceniam i albo inform acja-/^, mi, lecz m im o to są pow szechnie stosow ane i przestrzegane przez tw órców opro­ gram ow ania sieciow ego. D okum enty RFC są publikow ane na stronie http://w w w . jrfc-editor.org. .;1| Ten rozdział zaczynam od przedstaw ienia m odelu w arstw ow ego intersieci. N astępnie opisuję zasady działania E thernetu, czyli najpow szechniejszej obecnie technologii budow y przew odow ych sieci lokalnych. Potem w yjaśniam , ja k sieci lokalne oparte na E thernecie łączy się w intersieć. S poro m iejsca pośw ięcam adresow aniu w intersieciach. P odaję tylko niezbędne m inim um inform acji potrzebnych do program ow ania usług sieciow ych, a chcących w iedzieć w ięcej odsyłam do studiow ania RFC. Jako przykład kończący ten rozdział proponuję napisanie prostego m onitora sieci. # 'jjj ';| ;r V ;■ 'jf 'i* Term inem p a kiet nazyw am d o w olną porcję danych w ysyłanych przez dow olny !i. protokół sieciowy. W odniesieniu do poszczególnych protokołów stosuję bardziej precyzyjne nazwy. P akiet m oże w ięc oznaczać ram kę E thernetu, datagram IP, da­ tagram UDP, segm ent TCP, kom unikat jak ieg o ś protokołu pom ocniczego lub apli­ kacyjnego. Ś~ 2.1. Model warstwowy O program ow anie sieciow e tw orzy się w arstw ow o. W arstw a definiuje protokół ko­ m unikacyjny udostępniający pew ną usługę. T ypow e w arstwy, które m ożem y w yod­ rębnić w intersieciach, przedstaw ione są na ry s u n k u 2.1. U m ieściłem na nim też skróty nazw protokołów , które p o jaw iają się w tej książce. P rzyporządkow anie kon­ kretnego protokołu do określonej w arstw y nie zaw sze jest proste i jednoznaczne. W arstw a korzysta z usług w arstw y niższej, znajdującej się w m odelu w arstw ow ym bezpośrednio pod nią, na podobnej zasadzie ja k chcący w ysiać przesyłkę korzy­ sta z firm y kurierskiej. Podział kom unikacji sieciow ej na w arstw y m a szereg za­ let. Poszczególne w arstw y są projektow ane i im plem entow ane niezależnie. Z usług udostępnianych przez daną w arstw ę m ożna korzystać ja k z gotow ego kom ponentu, nie trzeba go sam odzielnie im plem entow ać. W arstw ę m ożna traktow ać ja k czarną skrzynkę - żeby jej używ ać, nie trzeba znać szczegółów w ew nętrznych - w ystar­ czy znać interfejs program istyczny udostępniany przez im plem entację tej warstwy, Im plem entację w arstw y m ożna łatw o zastąpić inną, o ile m a podobny interfejs pro­ gram istyczny. W praktyce pełna separacja i niezależność w arstw nie je st osiągana. w ypełnionego na stronie przez użytkow nika itd. H TT P nie musi nic w iedzieć, jak te dane są przesyłane przez sieć. Tym zajm uje się protokół w arstw y transporto­ wej. P odstaw ow ym i protokołam i transportow ym i w intersieciach są T C P (ang. Transm ission Contro! ProtocoI) i U D P (ang. U ser D atagram Protocol). H TTP akurat korzysta z TCP, który gw arantuje, że jeśli dane dotrą do odbiorcy, to dotrą we w łaściw ej kolejności. Z apew nia też, że dane zostaną w ysiane ponow nie (będą retransm itow ane), gdy ich otrzym anie nie zostanie potw ierdzone w pew nym usta­ lonym czasie. Protokół transportow y z kolei nie musi znać topologii sieci - nie musi w iedzieć, gdzie w sieci znajduje się odbiorca danych. Z najdow aniem drogi do odbiorcy, czyli trasow aniem (ang. routing), zajm uje się w arstwa sieciow a. W in­ tersieciach jest jeden podstaw ow y protokół w tej w arstw ie, m ianow icie IP (ang. Internet P rotocol), który działa niezależnie od zastosow anego m edium transm isyj­ nego - m ożna w tym celu użyć kabli elektrycznych, św iatłow odów , fal radiow ych, a naw et gołębi pocztow ych (patrz R FC 1149). Z a obsługę konkretnego medium odpow iada w arstw a dostępu do sieci. W arstw ę tę zw ykle dzieli się na dw ie podw arstwy. Warstwa łącza zajm uje się kodow aniem liniow ym , synchronizacją odbiornika do nadajnika i kontrolą jakości transm isji. K odow anie liniow e m a na celu dopa­ sow anie sekw encji transm itow anych bitów do w łasności nośnika, np. gdy niepo­ żądane jest w ysyłanie długich ciągów sam ych zer lub jedynek. Warstwa fizyczna definiuje param etry elektryczne nośnika. Z ależnie od użytego m edium są to przy­ kładow o poziom y napięć w kablu, długość fali, rodzaj m odulacji itp. D efiniuje też param etry m echaniczni złączy. W popularnym siedm iow arstw ow ym m odelu OSI (ang. Open System Interconnection Reference M odel), prom ow anym przez ISO (ang. International O rganization fo r Standardization), m iędzy w arstw ą aplikacji a transportow ą w yróżnia się dw ie dodat­ kow e. Warstwa prezentacji m a za zadanie ustalenie jednolitego form atu danych. Są •i1 I Na szczycie m odelu w arstw ow ego znajduje się w arstw a aplikacji. Protokoły tej w arstw y definiują sposób interakcji m iędzy aplikacjam i. Przykładow o H TT P (ang. H ypertext Transfer P rotocol) służy do przesyłania zaw artości stron www. D efiniuje fi. on m iędzy innym i, ja k przeglądarka m a poprosić o zaw artość strony, ja k serw er ■. odsyła odpow iedź z tą zaw artością, ja k przesłać do serw era zaw artość form ularza 53 Rys. 2.1. Model warstwowy intersieci 55 2.2. Ethernet to m iędzy innym i: porządek bajtów (little-endian lub big-endian), kodow anie liczb (uzupełnieniow e do dw ójki, uzupełnieniow e do jed y n ek itp.) i napisów (ASCII, EB C D IC , U TF-8 itp.). Warstwa sesji odpow iada za m ultiplcksow anie danych róż­ nych aplikacji. W tych w arstw ach m oże leż odbyw ać się szyfrow anie danych, czego przykładem st| protokoły SSH (ang. Secure S h ell) i T L S /S S L (ang. Transport Layer Security, Secure Socket Layer). Ethernet E thernet jest jed y n y m przedstaw icielem w arstw y dostępu do sieci rozw ażanym w tej książce. Sieć E thernet m ożna zbudow ać w oparciu o różne rodzaje m edium transm isyjnego. Na początku stosow any był gruby, a potem cienki kabel koncen­ tryczny. O becnie najpow szechniej w ykorzystuje się kable skrętkow e, popularnie nazyw ane skrętką. M ożna też użyć św iatłow odu w ielom odow ego lub jednom odow ego. W spółpracę z w łaściw ym m edium transm isyjnym zapew nia nadajnik-odbiornik (ang. transceiver), obecnie częściej nazyw any zew nętrznym urządzeniem w arstw y fizycznej (ang. external p h ysic a l layer device), a w żargonie skrótow o PHY. O bsługą sam ego protokołu E thernetu zajm uje się układ sterow ania dostępem do m edium M A C (ang. M edia A ccess C ontrol). M A C i P ifY połączone są za po­ mocą ustandaryzow anego interfejsu, np. M II (ang. M edia Independent Interface), RM II (ang. R educed M edia In d ependent Interface) lub G M II (ang. G igabit M edia Independent Interface), co uniezależnia M A C od zastosow anego rodzaju m edium transm isyjnego i gw arantuje popraw ną w spółpracę układów różnych producentów. M ożna pow iedzieć, że M A C realizuje w arstw ę łącza, a PH Y w arstw ę fizyczną. W tab eli 2.1 zestaw ione są w ybrane w arianty E thernetu stosow ane w przeszło­ ści i obecnie. Dla kabli skrętkow ych podano liczbę w ykorzystyw anych par, a dla św iatłow odu najczęściej używ aną długość fali. Podane są też typow e zasięgi dla standardow ego okablow ania - lepszej jak o ści kable lub św iatłow ody um ożliw iają zw iększenie zasięgu. Tab. 2.1. Wybrane warianty Ethernetu Przepływność 10 Mb/s Oznaczenie Gruby kabel koncentryczny 10BASE2 Cienki kabel koncentryczny 10BROAD36 10BASE-T 100 Mb/s 1 Gb/s 10 Gb/s Opis 10BASE5 Kabel współdzielący różne usługi, np. z telewizją kablową Zasięg 185 m 100BASE-T4 Skrętka min. kategorii 3, cztery pary ÏO OrrT 100BASE-TX Skrętka min. kategorii 5, dwie pary 100 m 100BASE-FX Światłowód wielomodowy, 13 10 nm 412 m 1000BASE-T Skrętka min. kategorii 5, cztery pary 100 m 10GBASE-T Skrętka min. kategorii 6, cztery pary Światłowód wielomodowy, 8 5 0 nm 10GBASE-LR Światłowód jednomodowy, 13 10 nm Jako zw ykli użytkow nicy sieci najczęściej spotykam y się z E thernetem w wersji 100B A SE-TX lub 10BASE-T. W szystkie urządzenia obsługujące w ariant 100BA­ SE -T X obsługują też 10BASE-T. U rządzenia obsługujące tylko 10B A SE-T są aktu- 87654321 w m m 22 0 m 5000 m 55 m 82 m 10 0 0 0 m R J-45 Fem ale R J-45 M ale 36 00 m 100 m 10GBASE-SR Przem ysł telekom unikacyjny stosuje ustandaryzow ane oznaczanie przew odów ko­ loram i. Skrętka używ ana w E thernecie m a cztery pary w kolorach biało-niebieskim , biało-pom arańczow ym , biato-zielonym i biało-brązow ym . Pierw szy przew ód w pa­ rze ma izolację w kolorze białym z paskiem lub paskam i w drugim kolorze. Drugi przew ód w parze ma izolację w drugim kolorze z opcjonalnym paskiem lub paska­ mi w kolorze białym . W szystkie kom ponenty sieci E thernet zbudow anej w oparciu 0 skrętkę w yposaża się w złącza R J-45, przedstaw ione na ry s u n k u 2.2. K artę sie­ ciow ą z koncentratorem (ang. hub), przełącznikiem (ang. sw itch) lub gniazdem sieci strukturalnej łączy się za pom ocą kabla prostego (ang. patch cable, patch cord), którego dw a w arianty są zam ieszczone na r y s u n k u 2.3. W arianty te m ają identycz­ ne połączenia elektryczne, różnią się przyporządkow aniem par do poszczególnych końców ek złącza. W szafach krosow niczych sieci strukturalnej też stosuje się kable proste. D o połączenia dw óch kart sieciow ych 10B A SE -T lub 100B A SE-TX trzeba użyć kabla skrzyżow anego (ang. crossover cable) z ry s u n k u 2.4. W 10BASE-T 1 100BASE-TX w ykorzystyw ane są tylko pary biało-pom arańczow a i bialo-zielona oraz styki 1, 2, 3 i 6 złącza RJ-45. 50 0 m Skrętka min. kategorii 3, dwie pary 1000BASE-SX Światłowód wielomodowy, 8 5 0 nm 1000BASE-LX Światłowód jednomodowy, 13 10 nm K ategoria kabla skrętkow ego określa jeg o w łasności elektryczne. O gólnie, czym w yższa je st kategoria, tym szersze pasm o przenoszenia i m niejsze są przesłuchy m iędzy param i. D la 10B A SE-T w ystarczy kabel kategorii 3, przenoszący pasm o 16 M H z. D la 100B A SE-TX potrzebny je s t kabel kategorii co najm niej 5 o paśm ie 100 M H z. W now ych instalacjach stosuje się okablow anie kategorii 5e, 6 lub 6a. K able kategorii 5e m ają zredukow ane przesłuchy w stosunku do kategorii 5. K able kategorii 6 i 6a m ają pasm o przenoszenia odpow iednio 250 M H z i 500 M Hz. Na potrzeby bardzo szybkich sieci zdefiniow ano kategorie 7 i 7a, które m ają pasm o przenoszenia odpow iednio 600 M H z i 1000 M H z. Stosow ane są kable nieekranow ane U TP (ang. unshielded tw isted pair) lub ekranow ane. Ekran m oże być w yko­ nany z oplotu lub folii m etalow ej. Ekran m oże obejm ow ać cały kabel, każdą parę oddzielnie lub jednocześnie każdą parę i cały kabel. K able ekranow ane m ają różne oznaczenia, np.: FT P (ang. fo iled tw isted pair), ST P (ang. shielded tw isted pair), SFT P (ang. screened fu lly shielded tw isted pair). Rys. 2.2. Złącze RJ-45 12345678 □ 12345678 Wersja A ____________________ Blalo-zieiony______________________^ _________________Zletono-blały ______________________ ^ <D- Niebiesko-blaly 0^ -------------------------------^ ---- l-------------------------- ^0 B la ło -n ie b ie s k i ^ ___________________Pomarańczowo-bialy__________________ ^ _____________________ Bialo-brązowy_____________________ Bialo-brązowy q Brązowo-bialy - Wersja B ^ __________________ Błalo-poroarańczowy__________________ ^ ^ __________________ Pomarańczowo-bialy__________________ ^ ©_____________ aatojgto^r----------------------@ _____________________ Nieblesko-bialy____________________ ^ ^ Bialo-niebieski____________ ^ Brązowo-bialy Rys. 2.3. Kabel prosty alnie w zaniku. Jeszcze niedaw no E thernet 1 G b/s stosow any byl przede w szystkim do łączenia urządzeń sieciow ych, które m uszą obsługiw ać duży ruch (przełączni­ ki, rutery, serw ery), ale obecnie co raz częściej w interfejs m ogący pracow ać rów ­ nież ja k o 1000B A SE-T w yposażane są kom putery osobiste. U kład testow y użyty do napisania tej książki, czyli zestaw Z L29A R M z m odułem Z L 3E T H , obsługuje 10B A SE-T i 100BA SE-TX . D alszy opis będzie dotyczył przede w szystkim tych wariantów. Brązowo-bialy Rys. 2.4. Kabel skrzyżowany dla 10BASE-T i 100BASE-TX 6 oktetów 6 oktetów 2 oktety 4 6 do 1 5 0 0 oktetów 4 oktety ADRES ODBIORCY ADRES NADAWCY DŁUGOŚĆ TYP DANE SEKWENCJA KONTROLNA D ane w sieci E thernet są przesyłane w ram kach. Istnieje kilka standardów opisu­ jący c h form at ram ki. Nie w chodząc w niepotrzebne szczegóły, w szystkie one defi­ niują strukturę przedstaw ioną na ry s u n k u 2.5. W term inologii sieciow ej oktet (ang. octet) oznacza 8 kolejnych bitów. Pojęcie to w prow adzono dla odróżnienia od bajlu, który w przeszłości nie zaw sze oznaczał 8 bitów. Przy zapisyw aniu w ysyłanego siecią ciągu oktetów obow iązuje konw encja, że oktety w ysyłane są od lewej do praw ej. Podobnie zapisuje się ciąg bitów przesyłanych siecią. Pierw szy w ysyłany bit je s t zapisyw any po lewej. N atom iast pew nej uwagi w ym aga konw encja, któ­ ra określa, że w E thernecie bity oktetu transm itow ane są od najm niej znaczącego. R am ka zaczyna się od pream buły, która zaw iera na przem ian bity 1 i 0, począw szy od jedynki. W yjątkiem je s t ostatni bit, który też je s t jedynką - pream buła kończy się dw om a jedynkam i. Pream buła w yglądu zatem następująco: 10101010 1 0101010 10101010 10101010 10101010 10101010 10101010 10101011 *' W zapisie szesnastkow ym je st to ciąg ośm iu oktetów: 55 55 55 55 55 55 55 d5. Zielono-bialy ^ ______________________Bialo-brązowy_________________ 8 oktetów PREAMBUŁA Rys. 2.5. Ramka Ethernetu Biało-pomarańczowy © - <D- 57 2.2. Ethernet 2. ¡ntersieci 56 Pream buła w E thernecie łO M b/s zapew nia synchronizację odbiornika do nadajni­ ka. O dbiornik m oże zgubić początkow e bity ram ki, ale w ystarczy, aby popraw nie rozpoznał koniec pream buły. G ubienie początkow ych bitów pream buły niczym nie grozi. W w ariantach E thernetu o w iększej przepływ ności stosuje się bardziej w y­ rafinow ane kodow anie bitów, zapobiegające gubieniu początku ram ki, ale pream ­ buła została zachow ana ze w zględu na kom patybilność. Pream buła je st obsługiw a­ na przez sprzęt. O program ow anie tw orzy ram ki bez pream buły i otrzym uje ramki z usuniętą pream bułą. K olejne dw a pola ram ki to adres odbiorcy i nadawcy. Każdy interfejs w sieci E thernet musi m ieć unikalny adres, który nazyw am y adresem sprzętow ym lub ad­ resem M A C . Jeśli pierw szy bit adresu odbiorcy je s t zerem , to jest to adres pojedyn­ czego interfejsu. Jeżeli pierw szy bit adresu odbiorcy jest jedynką, to je st to adres grupow y (ang. m ulticast). W iele interfejsów m oże m ieć w spólny adres grupowy. W ysianie ram ki na adres grupow y oznacza w ysłanie jej do w szystkich interfejsów w spółdzielących ten adres. A dres odbiorcy składający się z sam ych jedynek, czyli szesnastkow o adres ff ff ff ff ff ff, jest adresem rozgłoszeniow ym (ang. broadcast) i oznacza w szystkie interfejsy w danej sieci lokalnej. Jako adres nadaw cy um iesz­ cza się adres interfejsu, który w ysyła ram kę. A dres nadaw cy nie pow inien być ad­ resem grupow ym ani rozgłoszeniow ym . Jeśli drugi bit adresu je st zerem , to jest to adres adm inistrow any globalnie. W tedy kolejne 22 bity adresu są unikalnym kodem producenta danego urządzenia (karty sieciow ej), a ostatnie 24 bity są unikalnym num erem tego urządzenia nadaw anym przez producenta. W ten sposób zapew nia się, że w jednej sieci nie znajdą się dw a interfejsy o tym sam ym adresie. Jeśli dru­ gi bit adresu je st jedynką, to je s t to adres adm inistrow any lokalnie. W tedy pozo­ stałe 46 bitów adresu m ożem y przydzielić w edług w łasnego uznania, pam iętając, 59 2.2. Ethernet Tab. 2.2. Wybrane wartości pola typ ramki Ethernetu W1 k J 0x0800 IP wersfa 4 0x0806 ARP 0x8100 VLAN 0x86dd IP wers)a 6 W2 I Koncentrator lub przełącznik W4 aby adresy w jed n ej sieci lokalnej się nie pow tarzały. D aw niej adresy sprzętow e j® były zapisyw ane na stale w RO M urządzenia. O becnie najczęściej są zapisyw ane w pam ięci Flash i m ogą być m odyfikow ane program ow o. Pam iętajm y, że w zapisie i szesnastkow ym pierw szy bit adresu to najm łodszy bit pierw szego oktetu. § K olejnym polem ram ki je s t pole D LU G O ŚĆ -T Y P, które m ożna interpretow ać dwojako: jak o długość pola danych lub ja k o typ pola danych. Jeśli w tym polu je s t wartość od 46 do 1500, to należy go interpretow ać ja k o liczbę oktetów w polu danych, Je.śli natom iast je s t tam w artość w iększa lub rów na 1536 (0x0600), to pole to należy interpretow ać ja k o typ pola danych, określający protokół w arstw y w yższej przesylany w tej ram ce. Przykładow e, najczęściej spotykane typy pola danych są zam iesz­ czone w ta b e li 2.2. O protokołach tych piszę w ięcej w dalszej części tego rozdziału. Jeśli pole D L U G O Ś Ć -T Y P je s t interpretow ane jak o długość danych, to typ danych m oże być określony za pom ocą dodatkow ego nagłów ka, um ieszczonego w początku pola danych. W praktyce stosuje się w yłącznie ram ki z polem D LU G O ŚĆ -T Y P interpretow anym ja k o typ. P oniew aż sprzęt je s t w stanie rozpoznać koniec nadaw ania ram ki, to długość pola danych nie musi być przesyłana. Jeśli pole T Y P ma w artość 0x8100, to m am y do czynienia z ram ką sieci wirtualnej (V LA N , ang. virtual local area n etw o rk), przedstaw ioną na ry s u n k u 2.6. Takie ram ki um ożliw iają w ydzielenie w jed n ej sieci fizycznej wielu sieci w irtualnych, rozróżnianych za pom ocą znacznika (ang. ta g ) V LA N . W łaściw e pole D ŁU G O ŚĆ -T Y P je st w tedy um ieszczone za tym znacznikiem . >’ % .■$, :Ę ¡' ,1 ft M T X Pole danych może m ieć zm ienną długość, zależnie od ilości danych, które m ają być przesiane. Pole danych nie m oże być krótsze niż 46 oktetów (42 oktety dla ram ek : j | V LA N ). Jeśli je st mniej danych do przesiania, to pole danych je st uzupełniane zera-.'M mi do m inim alnej długości. M inim alna długość pola danych w ynika z potrzeby za- | j | pew nienia pew nej ustalonej m inim alnej długości ram ki, co je s t potrzebne do prawi- m dlow ego w ykryw ania kolizji, o których poniżej. M aksym alny rozm iar pola danych ( ogranicza ilość danych, które m ożna przesiać w pojedynczej ram ce. M aksym alna długość pola danych nazyw a się M T U (ang. m axim um transm ission unit) sieci. H M TU Ethernetu w ynosi 1500 oktetów . |J O statnim polem ramki je st sekw encja kontrolna (ang. fr a m e check sequence). J e s t;;j j ona liczona za pom ocą algorytm u C R C -32 (ang. cyclic redundancy check) opisanego | j | w norm ie IEEE 802.3 i służy do w eryfikacji integralności ram ki. Sekw encja kontrolna ram ki je st w yliczana przez nadajnik i w eryfikow ana przez odbiornik sprzętow o. ■■ 8 oktetów 6 oktetów 6 oktetów PREAMBUŁA ADRES ODBIORCY ADRES NADAWCY W7 Protokół przesyłany w polu danych W artość w polu TYP 2 oktety 2 oktety 2 oktety 0x8100 ZNACZNIK VLAN "d ł u g o ś ć " TYP Rys. 2.6. Ramka Ethernetu ze znacznikiem VLAN 4 2 do 15 0 0 oktetów 4 oktety DANE SEKWENCJA KONTROLNA 1 W6 ---------- W5 Rys. 2.7. Topologia sieci Ethernet opartej o kabel skrętkowy E thernet oparty na skrętce m a topologię gw iazdy, pokazaną na ry s u n k u 2.7. Każde urządzenie sieciow e m a jed en port (interfejs sieciow y), za pom ocą którego łączy się ze w spólnym centralnym urządzeniem w ieloportow ym , czyli koncentratorem (ang. hub) lub przełącznikiem (ang. sw itch). W celu zbudow ania w iększej sieci koncentra­ tory i przełączniki m ożna łączyć ze sobą hierarchicznie. K oncentrator i przełącznik różnią się zasadą pracy. K oncentrator je st urządzeniem biernym . K ażdą odebraną ram kę retransm ituje do w szystkich sw oich portów , z w yjątkiem oczyw iście portu, z którego ram kę odebrał. Przełącznik natom iast analizuje adresy w nagłów kach ra­ m ek i zapam iętuje adresy sprzętow e (M A C ) urządzeń podłączonych do poszczegól­ nych portów. Jeśli przełącznik w ie, do którego portu je st podłączony adresat ram ki, to w ysyła ją tylko do tego portu. Poniew aż urządzenia m ogą zm ieniać port, do któ­ rego są podłączone, przełączniki nie pam iętają przyporządkow ania adresu do portu w nieskończoność - jeśli urządzenie nie je s t aktyw ne przez pew ien ustalony czas, to inform acja o jeg o adresie je s t zapom inana. Ponow na aktyw ność urządzenia odśw ie­ ża tę inform ację. Przełącznik m ożna zw ykle konfigurow ać, aby filtrow ał i separo­ wał ruch sieciow y m iędzy pew nym i portam i i tw orzyć w ten sposób sieci w irtualne. P rzełączniki, w porów naniu z koncentratoram i, zm niejszają zbędny ruch w sieci. O becnie w now o budow anych sieciach instaluje się w yłącznie przełączniki. R ozw ażm y sytuację, gdy w centrum sieci z rysunku 2.7 je s t koncentrator. K oncentrator retransm ituje natychm iast każdą odebraną ram kę do w szystkich por­ tów, oprócz tego, z którego tę ram kę odebrał. O znacza to, że żaden port nie m oże jed n o cz eśnie nadaw ać i odbierać. Z atem w szystkie interfejsy pracują w trybie na­ przem iennym (ang. half-cluplex). Ponadto w danym m om encie tylko jed n o urządze­ nie podłączone do koncentratora m oże nadaw ać. Jeśli w ięcej niż jed n o urządzenie nadaje, pow staje kolizja i żadna ram ka nie je s t popraw nie odbierana. M usi w ięc istnieć ja k iś sposób spraw iedliw ego rozstrzygania o kolejności nadaw ania ram ek. W E thernecie je s t stosow any rozproszony protokół bazujący na śledzeniu stanu do­ stępności m edium transm isyjnego i w ykryw aniu kolizji (C SM A /C D , ang. C arrier Sense M ultiple A ccess with C ollision D etection). U rządzenie m oże rozpocząć nada­ w anie, gdy ustali, że żadne inne urządzenie nie nadaje przez ustalony w standardzie czas odstępu m iędzyram kow ego (ang. interfram e gap). Jeśli jak ieś urządzenie roz­ pocznie nadaw anie ram ki, pozostałe odbierają ją (koncentrator rozsyła ją do w szyst­ kich) i w strzym ują się z nadaw aniem . Sygnały w sieci nie rozchodzą się jed n ak nie­ skończenie szybko. M oże się w ięc zdarzyć, że dw a urządzenia w ykryją, że m edium je st w olne i rozpoczną nadaw anie praw ie rów nocześnie. Jednak po jak im ś czasie oba stw ierdzą, że w ystąpiła kolizja. W tedy przestają nadaw ać. Po w ykryciu kolizji każde urządzenie odczekuje pseudolosow y czas, zanim znów zacznie testow ać do­ 60 2. Intersieci stępność m edium . Pseudolosow ość zm niejsza szansę w ystąpienia ponow nej kolizji i zapew nia spraw iedliw y dostęp do m edium . Po każdej kolejnej kolizji zw iększa-1 ny je st przedział w artości, z którego losow any je s t czas oczekiw ania na kolejna 5 próbę transm isji. Jeśli w ysianie ram ki nie pow iedzie się kilkanas'cie razy, ramka jest porzucana. A by m echanizm w ykryw ania kolizji działał popraw nie, pierw szy bit 0 ram ki musi dotrzeć do najdalszego zakątka sieci E thernet, zanim zostanie wysiany |" ostatni bit tej ram ki. N ależy przy tym uw zględnić opóźnienia w noszone przez kable 'i i w szystkie interfejsy sieciow e po drodze. D latego w łaśnie w standardzie zdefiniow ano m inim alną długość ram ki. N ajkrótsza ram ka bez pream buły m a 64 oktety. N ależy w yraźnie zaznaczyć, że kolizje nie są niczym negatyw nym , są nieodzowny £ częścią protokołu rozstrzygania o kolejności dostępu do m edium . 2.3. 2.3. IP - protokół intersieci 61 z początkow ych 24 bitów, a sufilcs to końcow e 8 bitów. M aski, podobnie ja k adresy, zapisuje się za pom ocą notacji dziesiętnej z kropkam i. Pow yższa m aska jest więc zapisyw ana jak o 255.255.255.0. K iedyś rozw ażano stosow anie m asek, w których jedynki i zera m ogły się dow olnie przeplatać, ale obecnie takich m asek się nie uży­ wa. Z atem m askę m ożna jednoznacznie zdefiniow ać, podając liczbę od 0 do 32, określającą liczbę jedynek znajdujących się na początku m aski. A dres w raz z m a­ ską zapisuje się alternatyw nie, podając tę liczbę po ukośniku. P rzykładow o napis 192.168.51.84/24 oznacza adres 192.168.51.84 z m aską 255.255.255.0. R ozw ażm y teraz sytuację, gdy w centrum sieci je s t przełącznik. Sieć nadal może \ pracow ać w trybie half-duplex i stosow ać C SM A /C D . Jednak przełącznik umożli- j w ia bardziej efektyw ne w ykorzystanie m edium . N ie rozsyła on każdej odebranei ; ram ki do w szystkich portów. Interfejsy m ogą być teraz skonfigurow ane w trybii jednoczesny m {¡mg. fu ll-d u p lex), czyli m ogą jed n o cześn ie nadaw ać i odbierać ram- ji!' ki. N ie w ystępują kolizje i nie używ a się C SM A /C D . W E thernecie 1 G b/s i 10 Gb/s R? w praktyce stosuje się tylko tryb jednoczesny. Prefiks adresu w raz z m aską w yznacza pulę adresów, do której należą w szystkie adresy m ające ten sam prefiks. Przykładow o 192.168.51.0/24 oznacza przedział ad­ resów od 192.168.51.0 do 192.168.51.255. Pew ne przedziały adresów m ają specjal­ ne znaczenie. A dresy 127.0.0.0/8, czyli adresy od 127.0.0.0 do 127.255.255.255, są zarezerw ow ane dla tzw. pętli zw rotnej. A dresy te nie m ogą pojaw ić się w żadnej sieci fizycznej. Pętla zw rotna jest fikcyjnym interfejsem sieciow ym , dostarczanym przez oprogram ow anie stosu protokołów sieciow ych, stosow anym do testow ania program ów - w szystko w ysłane przez ten interfejs w raca do niego. Z w ykle w tym celu używ a się adresu 127.0.0.1. N astępujące pule adresów są zarezerw ow ane dla intersieci pryw atnych i nie m ogą pojaw iać się w Internecie: Interfejsy ethernetow e um ożliw iają zw ykle negocjow anie trybu pracy. W ybierany je st tryb o najw iększej w spólnie obsługiw anej przepływ ności. Ponadto preferow anj ' jest tryb jednoczesny. - od 10.0.0.0 do 10.255.255.255, - od 172.16.0.0 do 172.31.255.255, - od 192.168.0.0 do 192.168.255.255. IP - protokół intersieci Podstaw ow ym protokołem intersieci je s t IP (ang. Internet Protocol). M im o że daw ­ no tem u opracow ano ju ż je g o w ersję 6, obecnie nadal najpow szechniej używ ana . je st w ersja 4, która je s t opisana w R FC 791 i przyjęto ja k o standard intersieci STD 5. W dalszej części książki pom ijam num er w ersji i jeśli piszę o IP, to należy do­ m niem yw ać w ersję 4. IP definiuje adresy sieciow e, nazyw ane adresam i IP. A dres IP je s t przypisany do interfejsu sieciow ego, a nie do urządzenia. Pojedynczy w ęzeł sieci (ang. nade, host) m oże mieć w iele interfejsów i każdy z nich m a swój unikalny adres IP. Jednem u interfejsow i m ożna przypisać w iele adresów IP. K ojarzenie adresu IP z w ęzłem sieci, spotykane w zw rotach typu „adres IP kom putera” , w ynika stąd, że wiele kom puterów (osobistych) ma tylko jed en interfejs sieciow y i w tedy taki zw rot jesi jednoznaczny. A dres IP je st liczbą 32-bitow ą. Posługiw anie się zapisem dw ójko­ w ym jest niew ygodne, dlatego zw ykle stosuje się notacją dziesiętną z kropkam i 32 bity adresu dzieli się na 4 oktety. Każdy oktet zapisuje się ja k o liczbę dziesiętną. Poszczególne liczby oddziela się kropką. Przykładow o adres 11000000 10101000 00110011 01010100 zapisuje się ja k o 192.168.51.84. A dres IP składa się z prefiksu i sufiksu. Prefiks w yróżnia się za pom ocą maski, która jest, tak ja k adres IP, liczbą 32-bitow ą. Pozycje bitów, na których w m asce jest jedynka, to pozycje bitów adresu należące do prefiksu, a pozycje bitów, na których w m asce jest zero, to pozycje bitów adresu należące do sufiksu. P rzykładow o m a­ ska 11111111 11111111 11111111 00000000 oznacza, że prefiks adresu IP składa się Pula od 169.254.0.0 do 169.254.255.255 je s t przeznaczona na adresy lokalne, które w ęzły m ogą sobie przydzielać autom atycznie, ale są to adresy nierutow alne, czyli nie m ogą pojaw ić się w Internecie. A dresy od 224.0.0.0 do 239.255.255.255 są adresam i grupow ym i (ang. m ulticast). A dres grupow y w skazuje w iele interfejsów sieciow ych. Intersieci buduje się z m niejszych sieci, nazyw anych podsieciam i, sieciam i fizycz­ nymi lub sieciam i lokalnym i. Podsieć m ożna zbudow ać ja k o sieć Ethernet. Podsieć m ożna rów nież utw orzyć jak o sieć w irtualną, stosując technikę V LA N. Podsieci łączy się za pom ocą ruterów. R uter (ang. router) to w ęzeł, który m a w iele interfej­ sów sieciow ych - po jednym w każdej łączonej podsieci. W sieciach w irtualnych interfejsy rutera rów nież m ogą być w irtualne - jeden interfejs fizyczny może być w spółdzielony przez w iele sieci w irtualnych. P rzykładow a intersieć je s t pokazana na ry s u n k u 2.8. W szystkie adresy IP w obrębie jednej podsieci m ają w spólny prefiks. Prefiks adresu IP w yznacza adres tej podsieci. Sufiks adresu IP oznacza unikalny adres w pod­ sieci. Pulę adresów podsieci określa się, podając prefiks adresu IP i m askę, np. 192.168.51.0/24 oznacza adresy od 192.168.51.0 do 192.168.51.255. A dresu z sufiksem składającym się z sam ych zer nie przydziela się ze w zględów historycznych. A dres z sufiksem składającym się z sam ych jed y n ek je s t adresem ukierunkow anego rozgłaszania - adresatam i są w szystkie interfejsy w danej podsieci. Przykładow o dla sieci 192.168.51.0/24 je s t to adres 192.168.51.255. A dres 255.255.255.255 jest adresem rozgłaszania (ang. broadcast) w bieżącej podsieci. A dres, którego prefiks składa się z sam ych zer, je s t zaw sze adresem w bieżącej podsieci, np. adres 0.0.0.84 w podsieci 192.168.51.0/24 w skazuje interfejs o adresie 192.168.51.84. 62 63 2.3. IP - protokół intersieci 2. Intersieci' Tab. 2.3. Tablica tras węzła W1 Adres odbiorcy Interfejs Następny 1 0 .0 .0.0/24 ethO Bezpośrednio Dowolny ethO 10.0.0,1 się w tym celu tablicą tras (ang. routing labie) i w ykonuje algorytm w yznaczania tras, nazyw any też algorytm em trasow ania (ang. routing algorithm ). Szczególną rolę w algorytm ie trasow ania odgryw ają rutery. W niektórych system ach ruter byw a nazyw any bram ą (ang. gatew ay). Przypuśćm y, że węzeł W1 chce w ysiać datagram IP do w ęzła W 2. Posługuje się w tym celu sw oją tablicą tras, przedstaw ioną w tabeli 2.3. O program ow anie trasu­ ją c e p rzegląda pierw szą kolum nę tablicy tras, w iersz po w ierszu, w poszukiw aniu w zorca zgodnego z adresem odbiorcy. W tym przypadku pierw szy w iersz opisuje przedział, do którego należy adres w ęzła W 2. Po znalezieniu zgodności datagram IP jest w ysyłany przez interfejs w ym ieniony w drugiej kolum nie tego w iersza do następnego węzła, którego adres jest um ieszczony w trzeciej kolum nie. W rozw aża­ nym przypadku zostanie użyty jed y n y interfejs w ęzła W l, czyli ethO, a datagram IP zostanie w ysiany bezpośrednio do w ęzła W 2. B ezpośrednie w ysłanie jest m ożliw e, gdyż W l i W 2 są podłączone do w spólnego przełącznika. Pierw szy w iersz tablicy tras w ęzła W l opisuje w łaśnie te węzły, do których W l m oże w ysyłać datagram y IP bezpośrednio. bezpośrednio rutery R1 i R2. A dresy w tej podsieci należą do puli 192.168.1.128/ 30, czyli m ożna w niej rozdzielić tylko dw a adresy: 192.168.1.129 i 192.168.1.130. Pierw szy z nich przydzielono intefrejsow i e lh l rutera R l, a drugi - interfejsow i ethO rutera R2. W tej podsieci adresem rozgłaszania je s t 192.168.1.131, choć m ało praw dopodobne, aby rozgłaszanie było w ykorzystyw ane w sieci dwuwęzlow ej. R uter R l ma jeszcze interfejs eth2, który łączy naszą przykładow ą sieć z Internetem . Po praw ej stronie rysunku w idzim y podsieć 172.19.0.0/20. M ożna w niej przydzielić 4094 adresy: od 172.19.0.1 do 172.19.15.254. A dresem rozgła­ szania jest 172.19.15.255. i? --i . V .• W ęzły końcow e sieci m ają po jed n y m interfejsie sieciow ym . K ażdy ruter m a co najm niej dw a interfejsy. K ażdy interfejs pracujący w w arstw ie sieciow ej (patrz ry- ■ sunek 2.1) m a przypisany adres IP. Interfejsy (porty) przełączników P I i P2 ethernetow yeh nie m ają przypisanych adresów IP, gdyż przełącznik pracuje w warstwie dostępu do sieci. Pora teraz w yjaśnić, ja k IP przesyła dane w intersieciach. D ane do w ysiania pako­ w ane są w datagram y IP i w ysyłane w polu danych ram ki ethernetow ej, której pole / T Y P ma w artość 0x0800 (patrz tabela 2.2). Ten proces nazyw a się kapsulkow aniem (ang. eiicapsulrition). D atagram IP zaw iera w nagłów ku adres odbiorcy, na którego podstaw ie w ęzeł podejm uje decyzję, co zrobić z tym datagram em . W ęzeł posługuje R ozw ażm y teraz sytuację, gdy w ęzeł W l chce w ysłać datagram IP do w ęzła W 4. N ie m oże tego zrobić bezpośrednio, bo w ęzły te są w różnych podsieciach. A dres W 4 pasuje do w zorca adresów w drugim w ierszu tablicy tras w ęzła W l. Z w ykle ostatni w iersz w tablicy tras opisuje dom yślne (ang. clefault) zachow anie algoryt­ mu trasow ania i obejm uje w szystkie adresy, które nie pasują do poprzednich w ier­ szy. W tym przypadku w ęzeł W l w yśle datagram na adres 10.0.0.1, czyli do rutera R l. W datagram ie w ysyłanym do rutera adres odbiorcy to nadal adres docelow ego odbiorcy, a nie rutera. Ruter, otrzym aw szy ten datagram , posłuży się w celu jeg o dostarczenia sw oją tablicą tras, przedstaw ioną w tabeli 2.4. W tej tablicy tras ad­ res w ęzła W 4 pasuje do w zorca w drugim w ierszu i dlatego datagram IP zostanie w ysiany przez interfejs etlil do kolejnego rutera o adresie 192.168.1.130, czyli do rutera R2, który ju ż jest we w spólnej podsieci z w ęzłem W 4 i m oże dostarczyć datagram IP bezpośrednio do odbiorcy. Tablica tras rutera je st zazw yczaj bardziej rozbudow ana niż tablica tras w ęzła koń­ cow ego. W ęzłowi końcow em u w ystarczają zw ykle dw a w pisy - jed en dotyczący podsieci, w której je s t ten w ęzeł, a drugi dom yślny, kierujący w szystkie datagram y do rutera. R uter m a po jed n y m w pisie dla każdej bezpośrednio do niego podtączoTab. 2.4. Tablica tras rutera R1 Adres odbiorcy Interfejs Następny 10 .0 .0.0/24 ethO Bezpośrednio 17 2.1 9 .0 .0 /2 0 ethl 19 2.1 6 8 .1 .1 3 0 1 9 2 .1 6 8 .1 .1 2 8 /3 0 ethl Bezpośrednio eth2 Bezpośrednio eth2 212.85.125.1 . 2 1 2 .8 5 .1 2 5 .0 /2 4 Dowolny 64 2. Intersieći 31 WERSJA [0:3] D L NAGŁ. [4:7] ZNACZNIKI [16:18] IDENTYFIKACJA [0:15] CZAS ŻYCIA [0:7] DŁUGOŚĆ CAŁKOWITA [16:31] TYP OBSŁUGI [8:15] PROTOKÓŁ [8:15] PRZESUNIĘCIE FRAGMENTU [19:31] SUMA KONTROLNA NAGŁÓWKA [16:31[ ADRES IP NADAWCY [0:31] ADRES IP ODBIORCY [0:31] Rys. 2.9. Podstawowy nagłówek datagramu IP nej podsieci oraz po jed n y m w pisie dla każdej podsieci, która nie je s t b ezp o śred n io ’: podłączona, ale ruter zna do niej trasę. R uter m a też zw ykle w pis dom yślny, który kieruje do innego rutera. R uter nie musi znać tras do w szystkich podsieci - data gram y do nieznanych podsieci przesyła tem u dom yślnem u ruterow i w nadziei, że l tam ten zna trasę. W w yżej przedstaw iony sposób rutery przekazują sobie datagram y IP, aż do pom yśl­ nego dostarczenia do odbiorcy lub w ystąpienia błędu - ruter na ścieżce m oże być ; uszkodzony lub przeciążony, ruter m oże nie znaleźć w łaściw ego w pisu w tablicj tras, interfejs m oże być w yłączony lub uszkodzony, dostarczanie na pew ne adresy m oże być zablokow ane adm inistracyjnie itd. IP je s t usługą bezpołączeniow ą - dla każdego datagram u trasa w inlersieci je st w yznaczana indyw idualnie. Teoretycznie datagram y IP m iędzy tą sam ą parą w ęzłów m ogą poruszać się różnym i trasam i. IP je s t usługą zaw odnego d o starczania w ram ach dostępnych m ożliw ości. O znacza to. że oprogram ow anie IP stara się dostarczać datagram y, używ ając w szelkich dostęp­ nych tras, ale datagram y m ogą być gubione i dostarczane w innej kolejności niż zostały w ysiane. T eoretycznie datagram y m ogą też być duplikow ane, czyli odbiorca m oże dostać ten sam datagram w ięcej niż jed en raz. D atagram IP składa się z nagłów ka i przesyłanej po nim zaw artości. Podstaw ow y nagłów ek je s t pokazany na rysunku 2.9. Jest to typow y sposób przedstaw iania struktur danych w intersieeiach, używ any w dokum entach RFC. Każdy w iersz re­ prezentuje kolejne 32 bity, czyli 4 oktety struktury. O ktety są w ysyłane wierszami od góry do dołu, a w w ierszu od lew ej do praw ej. N um eracja bitów je s t od lewej do praw ej - od 0 do 31. Jeśli ja k ie ś pole je s t interpretow ane ja k o liczba dw ójko­ w a, to najbardziej znaczący bit (M SB , ang. m ost significant bit) je s t pierw szy od lew ej, a najm niej znaczący (LSB, ang. least significant b it) - pierw szy od prawej. W ynika z tego, że liczby, których reprezentacja zajm uje w ięcej niż jed en oktet, są w ysyłane w tak zw anym sieciow ym porządku oktetów, tożsam ym z porządkiem grubokońców kow ym (ang. big-endian), czyli ja k o pierw szy jest przesyłany najbar­ dziej znaczący oktet, a ja k o ostatni - najm niej znaczący. Zauw ażm y, że sieciowa kolejność oktetów je st odw rotna do kolejności oktetów stosow anej w kom puterach osobistych o architekturze x86 i m ikrokontrolerach STM 32, które są maszynami ; cienkokońców kow ym i (ang. little-eiulian). W rócę jeszcze do tego przy opisie ada­ ptacji biblioteki lw IP do architektury STM 32. 2.3. IP - protokół inlersieci 65 Pole W E R SJA zajm uje pierw sze 4 bity nagłów ka IP i je st w nim num er wersji, czyli 4. Pole DL. N AG Ł. (ang. internet h eader length) zajm uje kolejne 4 bity i za­ w iera długość nagłów ka w w ielokrotnościach 4 oktetów. Podstaw ow y nagłów ek m a 20 oktetów, więc w tym polu jest zw ykle liczba 5. N agłów ek m oże zaw ierać dodatkow e opcje i być dłuższy, ale zaw sze je g o długość je st uzupełniana do w ie­ lokrotności 4 oktetów. Z atem pierw szy oktet nagłów ka IP zaw iera zw ykle wartość szesnastkow ą 0x45. Pole T Y P O B SŁ U G I (ang. type o f service) określa priorytet datagram u. Pole D ŁU G O ŚĆ C A Ł K O W IT A zaw iera sum aryczną długość nagłów ka i zaw artości datagram u w oktetach. Poniew aż pole to je st 16-bitowe, m aksym alna długość datagram u wynosi 65 535 oktetów , a m aksym alna długość jego zaw artości nie m oże przekroczyć 65 515 oktetów. K olejne trzy pola ID E N T Y FIK A C JA , Z N A C Z N IK I i PR Z E S U N IĘ C IE F R A G ­ M E N T U w ykorzystuje się podczas fragm entow ania i składania datagram ów IP. M im o że datagram m oże m ieć m aksym alnie 65535 oktetów, m aksym alna jeg o długość w konkretnej technologii dostępu do sieci nie m oże przekroczyć MTU tej sieci. Przypom inam , że M T U E thernetu w ynosi zw ykle 1500 oktetów. Jeśli zachodzi potrzeba w ysiania datagram u IP dłuższego niż M TU sieci, to taki data­ gram musi zostać podzielony na fragm enty o rozm iarach nie w iększych niż M TU. S ytuacja taka m oże w ystąpić u pierw otnego nadaw cy datagram u lub w ruterze łą­ czącym sieci o różnych M TU . Po podzieleniu poszczególne fragm enty są przesy­ łane osobno. Składaniem tych części w całość zajm uje się końcow y odbiorca. Jest to m ożliw e, gdyż w szystkie fragm enty datagram u IP m ają tę sam ą w artość w polu ID E N T Y FIK A C JA . Pole P R Z E S U N IĘ C IE FR A G M E N T U (ang. fra g m e n t offset) inform uje o położeniu fragm entu w oryginalnym datagram ie. Pole Z N A C ZN IK I zaw iera dw a znaczniki: - nie fragm entuj - tego datagram u IP nie w olno fragm entow ać; jeśli ten datagram je st za długi, należy go porzucić; - w ięcej fragm entów - inform uje, że to nie je s t ostatni fragm ent, pozw ala rozpo­ znać ostatni fragm ent. P ole C ZA S Ż Y C IA (TTL, ang. tim e to live) określa, ile razy ten datagram IP m oż­ na przesiać przez sieć. K ażdy w ęzeł (zw ykle jest to ruter), przesyłając datagram dalej, zm niejsza w artość tego pola o jed en . Jeśli w artość czasu życia osiągnie zero, to datagram jest usuwany. C hodzi o to, aby datagram y, których nie można dostar­ czyć, nie krążyły w sieci w nieskończoność. D atagram m oże być niedostarczalny np. z pow odu błędu w konfiguracji tablic tras w ruterach, skutkującego pow staniem cyklu. Pole PR O T O K Ó Ł zaw iera num er protokołu kapsulkow anego (przenoszonego) w tym datagram ie IP. N ajczęściej spotykane w artości tego pola są zam ieszczo­ ne w tabeli 2.5. T C P i U D P są protokolarni w arstw y transportow ej. IC M P (ang. Internet C ontrol M essage Protocol) je s t protokołem diagnostycznym w arstwy sie­ ciow ej i transportow ej, um ożliw iającym m iędzy innym i w ykryw anie problem ów z trasow aniem . N a przykład kom unikat IC M P w ysyła się do pierw otnego nadaw cy datagram u IP, jeśli datagram ten usunięto z pow odu upłynięcia jeg o czasu życia - patrz też rozdział 3.8. 2.5. Sieć testowa Tab. 2.5. Wybrane wartości pola PROTOKÓŁ nagłówka IP W artość w polu PROTOKÓŁ Kapsulkowany protokół 1 ICMP 6 TCP 17 UDP w ego w oktetach i dla IP m a w artość 4. Pole O PER A C JA przyjm uje w artość 1 dla prośby o przetłum aczenie adresu, a w artość 2 dla odpow iedzi na tę prośbę. K olejne pola to odpow iednie adresy. D ługości tych pól są określone przez w artości pól DL. A DR. SPR ZĘTÓ W , i DL. A DR. SIECIOW . W ęzeł, chcąc w ysiać datagram IP do odbiorcy, którego adresu ethernetow ego nie zna, rozgłasza do w szystkich w ęzłów w sw ojej podsieci prośbę A R P (w artość 1 w polu O PE R A C JA ). Prośba je s t w ysyłana za pom ocą sprzętow ego m echanizm u rozgłaszania na adres elhernetow y ff ff ff ff ff ff. N adaw ca w ypełnia pola A DRES SPR ZĘ T O W Y N A D A W C Y i A D R E S SIE C IO W Y N A D A W C Y sw oim i adresam i. W polu A D R ES SIE C IO W Y O D B IO R C Y um ieszcza adres IP w ęzła, którego ad­ res ethernetow y chce otrzym ać. W prośbie zaw artość pola A DRES SPR ZĘ T O W Y O D B IO R C Y je s t nieistotna. W ęzeł, który ma poszukiw any adres IP, odpow iada bez­ pośrednio pytającem u, gdyż zna je g o adres ethernetow y, bo przed chw ilą otrzyma! od niego ram kę z prośbą. W odpow iedzi pole O PE R A C JA m a w artość 2. N adaw ca odpow iedzi um ieszcza sw oje adresy w polach A D R ES SPR ZĘ T O W Y NAD AW CY i A D R E S SIE C IO W Y NADAW CY. W polach A D R ES SPR ZĘ T O W Y O D B IO R C Y i A D R ES SIE C IO W Y O D B IO R C Y um ieszcza odpow iednie adresy węzła, który przysłał prośbę - te pola są kopiow ane z odpow iednich pól kom unikatu z prośbą. Pole SU M A K O N TR O LN A N A G Ł Ó W K A służy do spraw dzania integralności n u -1 głów ka. Pola A D R ES IP N A D A W C Y i A D R E S IP O D B IO R C Y zaw ierają o d p o -fj w iednie adresy, zgodnie z nazw am i tych pół. ARP - tłumaczenie adresów sieciowych na adresy sprzętowe W poprzednim podrozdziale pom inąłem bardzo istotny problem . Napisałem , że w ęzeł m oże w ysłać datagram IP bezpośrednio do innego w ęzła (w tym rutera) w sw ojej podsieci, kapsułkując go w ram ce ethernetow ej. Pow staje probiem. gdyż datagram y posługują się adresam i sieciow ym i IP, a E thernet używ a adresów sprzętow ych M A C. Potrzebny je s t ja k iś m echanizm pozw alający w ęzłow i ustalić na podstaw ie adresu sieciow ego odbiorcy je g o sprzętow y adres, który trzeba umieścić w nagłów ku ram ki ethernetow ej. T łu m aczeniem adresów sieciow ych na sprzętowe zajm u je się A R P (ang. Acldress R esolution P rotocol), opisany w R FC 826 i przyjęty jak o standard intersieci STD 37. A R P m oże tłum aczyć adresy dow olnego protokołu sieciow ego na adresy dow olnego protokołu sprzętpw ego. W dalszym ciągu ograni­ czam się do najbardziej interesującego nas przypadku, czyli do zam iany adresów IPna adresy ethernctow e. K om unikat A R P podróżu je w polu danych ram ki ethernetow ej, która m a w polu typ w artość 0x0806 (patrz tabela 2.2). Struktura kom unikatu A R P je st przedstaw iona na ry s u n k u 2.10. Pole R O D Z A J A D R E SU SPR Z Ę T O W E G O dla E thernetu ma w artość 1. Pole R O D Z A J A D R E SU SIE C IO W E G O dla IP m a w artość 0x0800. Pole DL. A DR. SPRZĘTÓ W , określa długość adresu sprzętow ego w oktetach i dla Ethernetu ma w artość 6. Pole D L. A D R . SIECIO W . określa długość adresu siecio31 RODZAJ ADRESU SPRZĘTOWEGO [0:15] DL. ADR. SPRZĘTÓW. [0:7] RODZAJ ADRESU SIECIOWEGO [16:31] D L ADR. SIECIOW. [8:15] OPERACJA [16:31] .. Sieć testowa ADRES SPRZĘTOWY ODBIORCY (oktety 1 -2 ) ADRES SIECIOWY NADAWCY (oktety 3 - 4 ) [16:31] [0:15] ADRES SPRZĘTOWY ODBIORCY (oktety 3 -6 ) [0:31] Rys. 2.10. Format komunikatu ARP dla Ethernetu i IP G dyby ograniczyć się tylko do przedstaw ionego w yżej algorytm u, kom unikacja byłaby bardzo nieefektyw na - w ysianie każdego datagram u IP w ym agałoby prze­ siania trzech ram ek ethernetow ych, w tym jednej rozgłoszeniow ej. A by popraw ić efektyw ność kom unikacji, w ęzły utrzym ują pam ięć podręczną (ang. cache) ARP, gdzie przechow ują poznane dotychczas przyporządkow ania adresów ethernetow ych do adresów IP. W ystarczy w ięc tylko raz na początku kom unikacji zapytać o ad­ res ethernetow y. D odatkow o w ęzeł proszony o adres zapam iętuje w sw ojej pam ięci podręcznej A R P pow iązanie adresu IP proszącego z je g o adresem ethernetow ym , gdyż prośba A R P poprzedza zw ykle w ysłanie datagram u IP i je s t w ysoce praw do­ podobne, że węzeł proszony o adres ethernetow y za chw ilę będzie m usiał odpo­ w iedzieć na otrzym any datagram - w ysianie prośby A R P je s t zw ykle początkiem kom unikacji dw ukierunkow ej. P oniew aż w ęzły w sieci m ogą znikać i zm ieniać adresy, to w pisy w pam ięci podręcznej A R P uaktualnia się co pew ien czas przez w ysianie ponow nego zapytania oraz na podstaw ie analizy nagłów ków otrzym yw a­ nych ram ek, rów nież tych kierow anych do innych węzłów. Jeśli w ęzeł przestaje być aktyw ny i nie odpow iada na prośby ARP, to dotyczący go w pis usuw a się z pam ięci podręcznej ARP. - ADRES SPRZĘTOWY NADAWCY (oktety 1 -4 ) [0:311 ADRES SIECIOWY NADAWCY (oktety 1 -2 ) ADRES SPRZĘTOWY NADAWCY (oktety 5 - 6 ) [16:31] [0:15] ADRES SIECIOWY ODBIORCY (oktety 1 -4 ) 10:31] 67 ! î A by uruchom ić kolejne przykłady, potrzebujem y stw orzyć m ałą sieć testow ą. M ożna ją zbudow ać w oparciu o zestaw Z L 29A R M z m ikrokontrolerem ST M 32F107, który jest w yposażony w interfejs E thernet zgodny z norm ą IE E E 802.3-2002. W sam ym m ikrokontrolerze je st w budow any układ M A C . U zyskanie w pełni funkcjonalnego interfejsu w ym aga dołączenia PIIY. W zestaw ie Z L29A R M je s t gniazdo do w ło­ żenia. m odułu Z L3E T H z PH Y zrealizow anym na układzie D P83848C . Potrzebny ■nam je s t jeszcze kom puter w yposażony w kartę elhernetow ą z gniazdem RJ-45, obsługującą 100B A SE-TX lub 10BASE-T. K om puter z m odułem ZL3E T H łączy 2.6. Przykład 2 - monitor sieci 2. Inlersieci 68 69 •s> się za pom ocą kabla skrzyżow anego, ja k to pokazano na ry s u n k u 2.11. Niestety .® nie w szystkie przykłady uda się przetestow ać w tak prostej sieci. A by sprawdzić .« dynam iczne przydzielanie adresów , trzeba na kom puterze uruchom ić serw er Dl l( P. Przykład 8 w ym aga dostępu do Internetu - aby go uruchom ić, kom puter musi miet jeszcze jakiś' inny interfejs sieciow y, łączący go z Internetem . M oże to być np. draga karta E thernet, interfejs W i-Fi, m odem A D SL podłączony do USB lub modem G SM . T rzeba w tedy na kom puterze uruchom ić funkcję rutera. Z apew ne lepszym ’§ rozw iązaniem jest zbudow anie małej sieci lokalnej. Przykłady, które opisuję w tej książce, testow ałem w sieci przedstaw ionej na ry s u n ­ k u 2.12. Z budow ałem ją na bazie w ielofunkcyjnego urządzenia W R T54G L firmy Linksys, która je s t częścią koncernu C isco. U rządzenie to je s t nazyw ane ruterem dom ow ym , ale zaw iera znacznie w ięcej niż tylko ruter. W R T54G L zaw iera przełącznik ethernetow y, którego cztery porty w yprow adzone są na gniazda R J-45. Do jed n eg o z nich podłącza się układ z m ikrokontrolerem . P ozostałe m ożna w ykorzystać do rozbudow y sieci i podłączenia kom puterów lub kolejnych m ikrokontrole­ rów. K om putery m ożna też podłączać bezprzew odow o, w ykorzystując w budow any punkt dostępow y (ang. access p o in t) W i-Fi. K onfigurow anie ustaw ień sieciow ych kom puterów w sieci testow ej, czyli uzyskiw anie adresu IP, m aski podsieci, adresu rutera i adresu serw era nazw (ang. D N S server) zapew nia zintegrow any serw er D H C P (ang. D ynam ie H ost C onfiguration P rotocol). Sieć testow ą z Internetem łą­ czy ruter, będący centralną częścią W RT54G L. D ostęp do Internetu zapew nia niodem A D SL (ang. A sym m etric D ig ita l S ubscriber Line). R uter od strony Internetu ma klienta DHCP, co um ożliw ia uzyskanie od dostaw cy Internetu (ang. Internet service provider) potrzebnych ustaw ień sieciow ych. R uter m a w budow aną prostą ścianę ogniow ą (ang. fire w a ll), która chroni sieć testow ą przed niektórym i zagroże­ niam i pochodzącym i z Internetu. C ałe urządzenie konfiguruje się za pom ocą prze­ glądarki internetow ej, łącząc się z w budow anym serw erem zarządzającym . ; i ' ■ i ■ ; i’|. jJ •/ ; ■ ; ; | Rys. 2.12. Typowa domowa sieć lokalna zarezerw ow ałem do konfigurow ania m anualnego. Adresy od 192.168.51.88 do 192.168.51.94 przeznaczyłem do konfigurow ania za pom ocą serwera DHCP. Adresem ukierunkow anego rozgłaszania w tej sieci jest 192.168.51.95. Sieć testow a używa ad­ resów z puli prywatnej. Poniew aż adresy takie nie mogą pojaw iać się w Internecie, trzeba zastosow ać ich konw ersję. Zastosow any ruter m a w budowaną usługę NAT (ang. NetWork Address Translation). NAT polega na podm ienianiu „w locie” adresów w nagłów kach datagram ów IP. Sieć testow a jest w idziana w Internecie, jakby była pojedynczym w ęzłem końcow ym o adresie przyznanym przez dostaw cę Internetu. D odatkow ą zaletą stosow ania NAT je st zw iększenie poziom u bezpieczeństwa. Węzły sieci testowej m ogą inicjow ać kom unikację do Internetu, ale nie jest m ożliw e zaini­ cjow anie kom unikacji z Internetu do w ęzła sieci testowej. W sieci testowej, której używ ałem , skonfigurow ałem pulę adresów 192.168.51.80/28. A dres 192.168.51.81 przypisałem ruterow i. A dresy od 192.168.51.82 do 192.168.51.87 N a rynku je s t dostępnych w iele urządzeń funkcjonalnie podobnych do wyżej opi­ sanego. R óżnią się m .in. liczbą portów. M ogą m ieć w budow any m odem ADSL. C zasem są też oferow ane przez dostaw cę Internetu „za złotów kę” . 2.6. ZL29ARM Rys. 2.11. Prosta sieć testowa Przykład 2 - monitor sieci Jako przykład kończący ten rozdział proponuję napisanie prostego m onitora sieci. B ędzie on w yśw ietlał na LCD inform acje o ram kach ethernetow ych i protokołach przenoszonych przez te ram ki. Jeśli sieć zbudow ana jest w oparciu o koncentrator, to m am y szansę oglądać w szystkie ram ki. JesTi zaw iera przełącznik, to zobaczym y tylko te ram ki, które przełącznik w yśle do naszego m onitora. Ekran LCD , którym 71 2.6. P rzykład 2 - m onitor sieci Tab. 2.6. Pliki przykładu 2 Źródłow e 1 biblioteczne ex eth.c lont5x8.c startup slm 32_cld.c board init.c board led ks0108.c board led.c Iibstm32f10x.a Nagłów kow e • font5x8.li util delay, c util led.c util led.c util_delay.h u tiljc d .h u tilje d .li board_det.h board_dels.li b o a rd jn it.h boardJ c d .h board led.h Nr kolejny ramki D ługość ramki Kom unikat ARP Prośba ARP Datagram IP TCP Jeef | IFfFfCffffEffH ►lOOOG] 119 2.168 ."5 1 .88p ; - » fo o o il (1 9 2 . 168 .51 . B2\‘‘ ID 00003943ee£6 ^ ( T T l lQ 0 2 5 9 c 4 4 0 c d d h HOBOOl 192 .1 6 8 . 51 . 88 —— ►i61 1 1 9 3 . 0 . 9 6 . 21-»____ stm 32f10x_cont.h - A dres ethernetowy nadawcy - R am ka rozgłoszeniowa - Adres IP nadawcy - A dres IP, o którego adres ethernetowy je st prośba ~ Adres ethernetowy odbiorcy - Adres IP odbiorcy Rys. 2.13. Wynik działania monitora sieci dysponujem y, nie je s t w ielki i m ieszczą się na nim tylko inform acje o dw óch ostat­ nio odebranych ram kach. W ys'w ietlane są: num er kolejny odebranej ram ki ethernc-1 tow ej, jej długość i pola z nagłów ka, czyli ethernetow y adres odbiorcy, ethernetowy^ adres nadaw cy oraz zaw artość pola dlugość-typ. Jeśli ram ka zaw iera datagram IP,\ to dodatkow o w yśw ietlane są: protokół kapsulkow any w tym datagram ie or: resy IP nadaw cy i odbiorcy. Jeśli ram ka zaw iera kom unikat ARP, to dodatkowo.,, w yśw ietlane są: o peracja A R P o raz adresy IP. N a LCD pow inniśm y zobaczyć obi a/ podobny do przedstaw ionego na rysu n k u 2.13. W tabeli 2.6 zaw arto nazw y plików , które należy podać kom pilatorow i ja k o pliki;; źródłow e tego przykładu. Ponadto zaw iera ona nazw y tych w ykorzystyw anych u tym przykładzie plików nagłów kow ych, które znajdują się w podkatalogu ./exam - ; pies/include. W kolejnych podrozdziałach prezentuję now e pliki, których opis nie pojaw ił się w poprzednim rozdziale. P oniew aż używ am y w yśw ietlacza graficznego, to w zestaw ie Z L 29A R M należy ustaw ić zw orkę D ISPLA Y w pozycji GRAPH. Ponadto w m odule Z L 3E T H trzeba ustaw ić zw orkę PW R _D N w pozycji uC, co w yjaśniam pod koniec n astępnego podrozdziału. 2.6.1. Pliki boardJ n it h i boardJ n iL c Pliki b o a r d jn it.h i bo ardJ n it .c o dpow iadają za zainicjow anie w ejść-w yjść binar­ nych, skonfigurow anie taktow ania m ikrokontrolera i m odułu ethernetow ego ora/ uruchom ienie interfejsu M II (lub RM1I) m iędzy m ikrokontrolerem a modułem ethernetow ym . Inicjow anie niektórych układów m ikrokontrolera, np. oscylatorów, w ym aga pew nego czasu. C zęsto nie m ożna w ykonyw ać dalszej części programu, zanim nie zakończy się u rucham ianie takiego układu. Z reguły najprościej je s t po­ czekać aktyw nie na zakończenie tego procesu. W tym celu w pliku b o a rd jn it.h definiujem y m akro a c tiv e _ c h e c k . jfdefine active_check(cond, limit) | int. i; for (i = (limit); ¡(cond); — i) if (i <= 0) return -1; } \ \ \ \ \ M akro to spraw dza w pętli, czy je s t spełniony w arunek cond. W arunek dobieram y tak, aby przyjął w artość niezerow ą, gdy urucham ianie zakończy się pow odzeniem . W tedy m akro kończy działanie. Ż eby je d n ak m akro nie zapętlilo się w nieskończo­ ność, liczba spraw dzeń je s t ograniczona param etrem l i m i t . Jeśli lim it spraw dzeń zostanie przekroczony, m akro pow oduje zakończenie bieżącej funkcji z błędem . Przyjm ujem y często stosow aną konw encję, że funkcja zw raca zero, gdy kończy się sukcesem , a w artość ujem ną, gdy w ystąpił błąd. Przykłady użycia tego m akra zo­ baczym y niżej. Pliki b o a r d jn it.h i board J n it .c udostępniają następujące funkcje: void AllPinsDisable(void); int CLKconfigure(void); int ETHconfigureMII(void); void ETHpowerDown(void); void ETHpowerUp(void); Funkcja A łlP in s D is a b le konfiguruje w szystkie w yprow adzenia m ikrokontrolera ja k o w ejścia analogow e (ang. analog input m ode). W yłączone zostają w ejściow e bram ki Schm itta (ang. Schm itt trigger off), co zm niejsza pobór prądu przez m ikro­ kontroler i zw iększa odporność układu na zakłócenia elektrom agnetyczne. Funkcję tę w yw ołujem y na początku program u, a potem konfigurujem y tylko używ ane w y­ prow adzenia - te nieużyw ane pozostaną w ejściam i analogow ym i. B iblioteka ST M 32 udostępnia porty w ejścia-w yjścia poprzez stale GPIOA, GPIOB itd. P oszczególne m odele m ikrokontrolerów m ają różną liczbę portów. Czasem chcem y iterow ać po w szystkich portach w ejścia-w yjścia, ja k na przykład w funkcji A llP in s D is a b le , ale chcem y też uniezależnić program od liczby portów. W tym celu deklarujem y w pliku b o a r d jn it.h tablicę g p io zaw ierającą identyfikatory w szystkich portów oraz stalą gpioC ount określającą liczbę portów. extern GPIO_TypeDef * const gpio[]; extern const int gpioCount; Teraz m ożem y odw oływ ać się do kolejnych portów, pisząc g p io [ 0 ] , g p i o [ l ] , ..., g p io [ g p io C o u n t- l] . D efinicje tablicy g p io i stałej gpioC ount znajdują się w pliku board J n it.c . D la ST M 32F107V C , który m a pięć portów w ejścia-w yjścia, są one następujące: GPIO_TypeDef * const g p i o U = IGPIOA, GPIOB, GPIOC, GPIOD, GPIOEI; const int gpioCount = sizeoffgpio} / sizeof(gpio(O)); Funkcja C LK configure konfiguruje oscylator kw arcow y m ikrokontrolera, pętle fazow e (PLL, ang. phase locked loop) oraz sygnały taktujące rdzeń i peryferie, w tym m oduł ethernetow y. D ystrybucja sygnałów zegarow ych w ST M 32F107 jest w uproszczony sposób przedstaw iona na rysunku 2.14. Rdzeń je st taktow any sy­ gnałem H C L K , którego m aksym alna częstotliw ość w ynosi 72 M H z. Peryferie są taktow ane, sygnałam i PCLK1 i PC LK 2 otrzym yw anym i z H C LK za pom ocą dziel­ ników w stępnych (ang. prescalers) APB1 i A PB2. Sygnał IIC L K otrzym yw any jest 2. lntersie 72 2.6. Przykleili 2 - monitor sieci 73 z w yjścia dzielnika A H B , na którego w ejście podaw any je st sygnał SY SCLK . M oże to być sygnał 8 M H z z w ew nętrznego oscylatora RC HSI (ang. high speed internal) - tak dzieje się po w łączeniu zasilania lub po w yzerow aniu m ikrokontrolera, sy­ gnał U SE (ang. high sp eed external) z oscylatora kw arcow ego lub sygnał PLLC LK z w yjścia PLL1. Do w ejścia PLL1 m ożna dołączyć sygnał HSI podzielony przez 2 lub sygnał z w yjścia dzielnika PRED1V1. Do w ejścia dzielnika PRED1V1 m oż­ na dołączyć sygnał H SE lub sygnał PL L 2C L K z w yjścia PLL2. Na w ejście PLL2 podaw any je s t sygnał H SE przez dzielnik PR ED IV 2. D obierając w artości w spół­ czynników podziału i m nożniki pętli fazow ych, m ożem y uzyskać w iele różnych częstotliw ości taktow ania rdzenia. Sygnał potrzebny do taktowania m odułu etliernetow ego m ożna uzyskać z wyjścia M C O (ang. m icrocontroller clock output), na które m ożna podać następujące sygnały: SY SCLK , HSI, HSE, PLLCLK podzielony przez 2, PLL2C LK , PLL3CLK, PLL3CLK podzielony przez 2, XT1 bezpośrednio z w yprow adzenia kwarcu. Sygnał PLL3CLK pochodzi z wyjścia pętli fazowej PLL3, która ma w spólne w ejście z PLL2. Funkcja C LK configure zw raca zero, gdy zakończyła się sukcesem lub w artość ujem ną, gdy nie udało się w ystartow ać oscylatora kw arcow ego lub któraś pętla fa­ zow a się nie zsynchronizow ała. K onfigurow anie zaczynam y od przyw rócenia usta­ wień dom yślnych. N astępnie próbujem y uruchom ić oscylator kw arcow y HSE. Jeśli się nie udało, funkcja kończy działanie, sygnalizując błąd. RCC_DeInit(); j RCCJISEConf ig(RCC_HSE_ON ) ; if (RCC_WaitForHSEStartUp() == ERROR) return -1; O program ow anie sieciow e w ym aga stosunkow o dużej m ocy obliczeniow ej. Aby uzyskać krótkie czasy reakcji m ikrokontrolera, będziem y taktow ać rdzeń z m aksy­ m alną dopuszczalną częstotliw ością, czyli 72 M Hz. N iestety przy tej częstotliw ości pam ięć Flash nie m oże dostatecznie szybko dostarczać kolejnych instrukcji do w y­ konania i aby odczyty z Flash nie stanow iły w ąskiego gardła, należy w łączyć bufor w stępnego ładow ania instrukcji (ang. prefetch buffer). Ż eby pam ięć Flash w ogóle działała przy tej częstotliw ości, trzeba jej ustaw ić dw a cykle opóźnienia (ang. la­ tency). HSI HS1 8 MHz FLASH_PrefetchBu£ferCmd(FLASH_PrefetchBuf ferJSnable); FLASH_SetLatency{FLASH_Latency_2); Rys. 2.14. Uproszczony schemat dystrybucji sygnałów taktujących w STM32F107 Aby uzyskać sygnał H CLK o częstotliw ości 72 M H z, ustaw iam y dzielnik AHB na 1. Sygnały PCLK1 i PC LK 2 m ogą m ieć m aksym alne częstotliw ości odpow iednio 36 i 72 M H z, dlatego ustaw iam y w artości dzielników APB1 i A PB2 odpow iednio na 2 i 1. RCCJiCLKConfig(RCC_SYSCLK_Divl) ; RCC_PCLKlConfig(RCC_HCLK_Div2) ; RCC_PCLK2Con fig(RCCJICLK_Divl); Zakładam y, że oscylator kw arcow y H SE m a częstotliw ość 5, 10, 15, 20 lub 25 M Hz. Sygnał z tego oscylatora przez dzielnik RREDIV2 je s t podaw any na w ejście PLL2. W artość dzielnika RCC_PREDIV2_DivX dobieram y tak, aby na w ejściu PLL2 mieć zaw sze sygnał o częstotliw ości 5 M Hz. M nożnik PL L 2M U L ustaw iam y na 8, za- 2.6. Przykład 2 —monitor sieci 2 . Intersiec i 74 75 RCC_MCOCotlfig (RCC_MCO_PLL3CLK_Div2) ; tem na w yjściu PL L2 uzyskujem y sygnał P L L 2C L K o częstotliw ości 4 0 MHz, N astępnie w łączam y PL L 2 i czekam y na jej zsynchronizow anie się. Jeśli konfigurow anie sygnałów taktujących zakończy się pow odzeniem i w szystkie oscylatory się zsynchronizują, funkcja C LK configure kończy działanie, zw racając zero. Sdefine RCC_PREDIV2_DivX RCC_PREDIV2_Div2 RCC_PREDIV2Config(RCC_PREDIV2_DivX); RCC_PLL2Con£ig(RCC_PLL2Mul_8); RCC_PLL2Cmd(ENABLE); active_check(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY), maxAttempt5); Jeśli PL L2 się nie zsynchronizuje, m akro a c tiv e _ c h e c k zakończy działanie funkcji, ■ sygnalizując błąd. L im it spraw dzeń definiujem y jak o stałą m axA ttem pts. static const int maxAttempts = 1000000; Sygnał PL L2C L K podajem y na w ejście dzielnika P R E D IV I, który ustaw iam y na .k 5. Z atem na w yjściu d zielnika PR ED IV 1 m am y sygnał o częstotliw ości 8 MHz.-;Jf. Sygnał ten podajem y na w ejście P L L l. M nożnik P L L M U L ustaw iam y na 9, aby uzyskać na w yjściu P L L l sygnał PL L C L K o częstotliw ości 72 M H z, p o czym cze-;,-| kam y na zsynchronizow anie się P L L L Funkcja ETH configureM Il konfiguruje interfejs m iędzy układem M A C w m i­ krokontrolerze a zew nętrznym PHY. M oże to być interfejs M II lub RM II. Każdy z tych interfejsów m ożna skonfigurow ać na dw a sposoby: z dom yślnym albo al­ ternatyw nym (ang. rem aped) rozkładem w yprow adzeń. Szczegóły są w tabeli 2.7. W yprow adzenia oznaczone literą I konfiguruje się jak o w ejścia pływ ające. Na w y­ prow adzeniach oznaczonych literą O należy skonfigurow ać funkcję alternatyw ną z w yjściem przeciw sobnym 50 M Hz. M II używ a 17 sygnałów : - M II_C O L (ang. collision d etect) - w ystąpienie kolizji w trybie naprzem iennym (ang. h alf-duplex), - M II_C R S (ang. carrier sense) - obecność nośnej, czyli sygnału w m edium (ang. non-idle), - M II_ R X D 0 .. .M I1_RXD3 (ang. receive data) - czterobitow a szyna odbiorcza, Jako sygnał SY SC L K , podaw any na w ejście dzielnika A H B , w ybieram y sygnał PL LC L K z w yjścia P L L l i czekam y na synchronizację. - M 1I_RX _CLK (ang. receive clock) - zegar szyny odbiorczej, 25 M H z dla 100 M b/s lub 2,5 M H z dla 10 M b/s, RCC_SYSCLKCon£ig(RCC_SYSCLKSource_PLLCLK); active_check(RCC_GetSYSCI,KSource() = = 0 x 0 8 , maxAttempts) ; - M II_R X _D V (ang. data valid) - na szynie odbiorczej są dane do odczytania, RCC_PREDIVlConfig(RCC_PREDIVl_Source_PLL2, RCC_PREDIVl_Div5); RCC_PLLCon£ig(RCC_PLLSource_PREDIVl, RCC_PLLMul_9); RCC_PLLCmd(ENABLE); active_check(RCC_GetFlagStatus(RCC_FLAG_PLLRDY), maxAttempts); i; 'i, M ikrokontroler ST M 32F 107 o bsługuje dw a w arianty interfejsu m iędzy M A C a PHY: M II (ang. M edia Independent In terfa ce ) i R M II (ang. R ed u ced M edia Independent y Interface). M II w ym aga taktow ania sygnałem o częstotliw ości 25 M H z, a RMII - 50 M H z. W artości tych częstotliw ości w ynikają z szerokości szyn danych w tych interfejsach, co stanie się ja sn e po przeczytaniu dalszej części tego podrozdziału. 5 Jeśli potrzebujem y na M C O sygnału 25 M H z i m am y akurat taki kw arc, to najpro­ ściej je s t użyć sygnału H SE lub X T1. - MII_RX__ER (ang. receive error) - odebrano błędny sym bol w trybie 100 M b/s, - M II__TX D 0...M II_TX D 3 (ang. transm it data) - czterobitow a szytia nadaw cza, Tab. 2.7. Warianty konfiguracji MII/RMII w STM32F107 Sygnał M II Sygnał R M II Kierunek MII C0L I MII CRS I W yprowadzenie domyślne W yprowadzenie alternatywne PA3 PAO 'Jj ;f§ MII RXD0 RM II RXD0 I PC4 PD9 MII RXD1 RMII RXD1 I PC5 PD10 W przeciw nym przypadku trzeba w ykorzystać PLL3. Poniew aż PL L 2 i PLL3 1 m ają w spólny dzielnik w stępny PR ED IV 2, w yżej opisana konfiguracja sprawia, > że na w ejściu PLL3 m am y sygnał 5 M H z z tego dzielnika. U staw iam y m nożnik m PL L 3M U L na 10, dzięki czem u na w yjściu PLL3 dostajem y sygnał PL L3C L K • o częstotliw ości 50 M H z. N astępnie czekam y na zsynchronizow anie się PLL3. MII RXD2 I PB0 PD11 MII RXD3 I PB1 RCC_MCOConfig(RCCJCO_HSE); RCC_MCOConfig(RCC_MC0_XT1); RCC_PLL3Con£ig(RCC_PLL3Mul_10); RCC_PLL3Cmd(ENABLE); active_check(RCC_GetFlagStatus{RCC_FLAG_PLL3RDY), maxAttempts); ■ ) Jeśli używ am y PH Y z interfejsem R M II, to na M C O podajem y bezpośrednio sygnał PLL3C LK . RCC_MCOConfig(RCC_MC0_PLL3CLK); Jeśli używ am y PH Y z interfejsem M II, to na M C O podajem y sygnał PLL3C LK przez dzielnik o w spółczynniku 2. ; MII RX CLK RMII REF CLK I MII RX DV RMII CRS DV I MII RX ER PD12 PA1 PA7 PD8 I PB10 MII_TXD0 RM II TXD0 0 PB12 MII TXD1 RMII TXD1 0 PB13 MII TXD2 0 PC2 MII TXD3 0 PB8 MII TX CLK MII TX EN RMII TX EN I PC3 0 PB11 M D I0 0 PA2 . MDC 0 PC1 76 - 77 2.6. Przykład 2 - monitor sieci 2 . Intersieci'È M 1I_TX_CLK (ang. transm it d o c k ) - zegar szyny nadaw czej, 25 M H z dlai| 100 M b/s lub 2,5 M H z dla 10 M b/s, M11_TX_EN (ang. transm it enable) - na szynie nadaw czej są dane do wysiania,i; M D IO (ang. m anagem ent d a ta input/outpnt) - dw ukierunkow a linia danych in­ terfejsu służącego do konfigurow ania układu PHY, M D C (ang. m anagem ent data d o c k ) - linia taktująca interfejs M D IO . a H O F a: o a: 2 O d d cc a Sygnał zegarow y na liniach M 1I_RX _C LK i M II_T X _C L K jest generow any prze/ PHY. Jego częstotliw ość w ynika z szybkości przesyłania danych (10 lub 100 MbA ^ i szerokości szyny danych (4 bity). RM1I używ a tylko 9 spośród w yżej opisanych'.-;' sygnałów. Poniew aż w RM1I dane są przesyłane szynam i dw ubitow ym i, sygnał ze garow y R M II_R E F _C L K musi m ieć częstotliw ość 50 M Hz. Zależnie od w ybranego wariantu konfiguracji M II lub RM1I funkcja ETHconf igureMi; w yw ołuje jed n ą z czterech funkcji konfiguracyjnych: static static static static void void void void ETHinterfaceMIIconfigure(void); ETilinterfaceRemapedMIIconfigure (void) ; ETHinterfaceRMIIconfigure(void); ETHinterfaceRemapedRMIIconfigure(void); LQ_ ■(.£ Schem at m odułu ethernetow ego Z L 3E T H je st przedstaw iony na ry s u n k u 2.15, ÿ N atom iast sposób je g o podłączenia w zestaw ie Z L 29A R M znajduje się na rysun- ;V k u 2.16. Jak w idać, zastosow ano M II z alternatyw nym układem wyprowadzeń, $ D latego zaim plem entow ano tylko funkcję ETHinterfaceRemapedMIIconfigure. Im­ plem entację pozostałych funkcji pozostaw iam jak o ćw iczenie C zytelnikow i, który będzie ich potrzebow ał. K onfigurow anie M il rozpoczynam y od w łączenia taktow ania peryferii i ustawienia w łaściw ego w ariantu interfejsu. i;>| <-81=1 X <N -T- Q, Z h -1 2B 29 30 31 32 33 34 35 36 2 o, a, y at. % to ; to N astępnie konfigurujem y w yprow adzenia zgodnie z tabelą 2.7, a na koniec wy­ prow adzenie sygnału zegarow ego M C O (PA8). D la M II z alternatyw nym układem w yprow adzeń odpow iedni fragm ent funkcji ETHinterfaceRemapedMIIconfigure w ygląda następująco: GPIO_InitTypeDef GPI0_InitStructure; GPI0_InitStructure.GPI0_Mode = G PI0_M ode_IN_FL0ATING ; GPI0__InitStructure.GPI0_Speed = 0; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 i GPI0_Pin_l | GPI0_Pin_3; GPI0_Init(GPIOA, ŁGPIO_InitStructure); GPIO_InitStructure.GPI0_Pin = GPIO_Pin_10; GPI0_Init (GPI0B, &GPI0__InitStructure) ; GPI0_InitStruciure.GPI0_Pin = GPIO_Pin_3; GPÎ0 Init(GPI0C, &GPI0 InitStructure); 5 4 3 2 1 eaxi zaxi ta x i oaxi N3 X I X1D X I O Q O O zrr» GND RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPI0A | RCC_APB2Periph_GPI0B I RCC_APB2Periph_GPI0C | RCC_APB2Periph_GPI0D | RCC_APB2Periph_AFI0, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | RCC_AIIBPe riph_ETH_MAC_Jtx, ENABLE); GPI0_PinRemapCon£ig (GPIG__Reniap_ETH, ENABLE) ; GPIOJSTHJfedialnterfaceConfig (GPIO_BTH_MediaInterface_MII) ; LED SPD LED LINK nRST MDIO MDC "1 RESERVED RESERVED RESERVED RESERVED : RESERVED PW R_D OW N/INT TX D 3 7S N LM 0D E TX D_2 TXD 1 TXD 0 ‘ TX EN TX CLK Rys. 2.15. Schemat modułu ZL3ETH 2.6. Przykład 2 - monitor sieci GPIO_InitStructure.GPIO_Pin = GPIO Pin_8 | GPIO_Pin_9 | GPIO~Pin_10 t GPIO_Pin_l1 I GPI(Tpin_12; GPIO__Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode___AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GP10_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_ll I GPIO__Pin_12 | GPIO_Pxn_13; GPIO_Init (GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_l I GPIO_Pin_2; GPIO__Init (GPIOC, SGPIO_I ni tStructure) ; GPIO_InitStructure.GPXO_Pin = GPIO_Pin_8; GPIO_Init(GPIOA, &GPIO_InitStructure); D P83484C pobiera typow o 14 mA. W ten tryb m ożna go w prow adzić, podając ni­ ski poziom na w yprow adzenie PW R D O W N . W yprow adzenie to je st podłączone do w yjścia inw ertera. Jeśli zw orka PW R _D N (JP3) w m odule ZL3E T H je s t w pozycji O ff (2 -3 ), na w ejściu tego inw ertera je s t w ym uszony poziom niski, co w ym usza na w ejściu PW R D O W N stan w ysoki i m oduł Z L3E T H jest zaw sze w stanie ak­ tyw nym . U staw ienie zw orki PWR__DN w pozycji uC (1 -2 ) um ożliw ia program ow e sterow anie trybem oszczędzania prądu. Do w ejścia inw ertera je st podłączone w y­ p row adzenie PCO m ikrokontrolera. W yprow adzenie to konfigurujem y jak o w yjście z otw artym drenem . Jeśli podajem y na nie stan niski, m oduł ZL3E T H je st w stanie aktyw nym . Jeśli w yprow adzenie PCO je s t w stanie w ysokiej im pedancji, rezystor na w ejściu inw ertera w ym usza, że m oduł Z L 3E T H je s t w stanie niskiego pobo­ ru prądu. W yprow adzenie PCO jest w stanie w ysokiej im pedancji, zanim zostanie skonfigurow ane, a rów nież wtedy, gdy układy peryferyjne m ikrokontrolera nie są zasilane, co pow oduje autom atyczne w yłączanie m odtilu Z L3E T H , gdy m ikrokon­ troler przestaje być zasilany lub gdy przechodzi w tryb oszczędzania prądu z w y­ łączonym i peryferiam i. W yprow adzenie PCO konfiguruje się za pom ocą funkcji ETHpowerConfigure. M oduł ZL3E T H m ożna w prow adzić w £ryb niskiego poboru prądu (ang. p o w e r clown m odę). Byw a to istotne w urządzeniach zasilanych bateryjnie. Interfejs E thernet po­ biera niestety sporo prądu. W edług danych katalogow ych układu D P83484C , za­ stosow anego w Z L 3E T H , w trybie 10 M B /s pobiera on typow o 92 m A, a w trybie 100 M b/s - typow o 81 m A. D o tego jeszcze kilka m A pobierają diody sfwiecące zainstalow ane w gnieździć RJ-45. N atom iast w trybie niskiego poboru prądu układ static void ETHpowerConfigure(void); Pow yższa funkcja je st zadeklarow ana ja k o s t a t i c , poniew aż je s t używ ana tyl­ ko w ew nątrz jednostki translacji. Z asilanie m odułu ethernetow ego w łącza funk­ cja ETHpowerUp. Przełączenie w tryb oszczędzania prądu w ykonuje funkcja ETHpowerDown. S TM 3 2F 1 0 7V C RXD1 RXD2 RXD3 RX ER — 1 — — 57 58 59 47 t RX C LK R X DV TX CLK 24 55 18 M D IO 25 MDC CRS CDI . PD9 PD10 PD11 PD12 N a zakończenie sw ojego działania funkcja ETH configureM II w łącza zasilanie m o­ dułu Z L 3E T H , a następnie w ykonuje zerow anie interfejsu ethernetow ego. Jeśli zerow anie się pow iodło, funkcja zw raca zero, w przeciw nym przypadku zw raca w artość ujem ną, sygnalizującą błąd. ż PC3 PA2 ETHpowerConfigure(); ETHpowerUp0 ; ETiI_DeInit{); ETH_SoftwareReset(); active_check(ETH GetSoftwareResetStatus{) == RESET, maxAttempts); return 0; 16 P C I? 23 PAO 26 , PA3 C O N 12/JP 2 --- TX D1 TX D 2 TX D 3 t , , P B12 53 P B13 17 PC2 95 P B 8 !* 25 M H z T X EN , 48 PAB PB11 PWRDW N , Funkcje i stałe, których nazw y zaczynają się od ETH_, są zdefiniow ane w bibliote­ ce S T M 32 w pliku stm 32_eth.h. Im plem entacje są w pliku stm 32_eth.c. D la nazw zaczynających się od FLASH_, GPI0_ i RCC__ są to odpow iednio pliki stm 3 2 f!0 x_ Jlash.li, s tm 3 2 fl0 x J la s h .c , stm 3 2 fl0 x_ g p io .h , stm 32fI0x_gpio.c, stm 32fJ0x_rcc.li, stm 3 2 fl 0x_rcc.c. 67 ---2.6.2. 15 PCO 14 nR S T 3.3V 100n: 79 Plikf u tilje d .h i u łilje d .c Pliki u tilje d .h i u ti lj e d .c dostarczają dw óch pom ocniczych funkcji diagnostycz­ nych. F unkcja OK m iga n razy zieloną diodą św iecącą. Funkcja E rro r m iga n razy czerw oną diodą św iecącą. void 0K(int n); void Error(int n); Rys. 2.16. Podłączenie modułu ethernetowego w ZL29ARM Ponadto w u tilje d .h definiujem y m akro error__check, które w yw ołujem y, aby spraw dzić, czy jak aś funkcja zakończyła się popraw nie. Jako pierw szy argum ent 81 2.6. Przykład 2 - monitor sieci fcjsu ethernetow ego zajm uje się funkcja ETH__Init, która zw raca zero, gdy wystąpił błąd - w tedy nasza funkcja musi zw rócić w artość ujem ną. um ieszczam y w yw ołanie funkcji, która zw raca zero przy popraw nym zakończeniu, '!'• a w artość ujem ną, gdy w ystąpił błąd. Jako drugi argum ent podajem y num er błędu : - liczbę m ignięć czerw onej diody. i łdefine error_check(expr, if ((expr) < 0! ( for (;;) ( Error(err); ) err) \ \ \ \ int ETHconfigureRX(uint8_t phyAddress) ( ETH_Init'fypeDef e; '(» 'i \ ł ETH_StructInit(&e); e.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; e.ETH_ReceiveAlł - ETH_ReceiveAlł_Enable; if (ETH_Init(&e, phyAddress) == 0} return -1; i :,j Plik ex_eth.c i W pliku ex_eth.c zaim plem entow ane są dw ie funkcje: - ETHconf igureRX konfiguruje o d bieranie ram ek przez interfejs E thernet, - main konfiguruje sprzęt, a potem w nieskończonej pętli czyta odebrane ramki Jeśli pow yższe nie zadziała, m ożna w yłączyć negocjow anie trybu pracy i spróbo­ wać ustaw ić go m anualnie. Przydatne ustaw ienia są następujące: i w ypisuje ich zaw artość na LCD. Do jednego M A C m ożna podłączyć w iele układów PHY. A by je rozróżnić, każdy musi m ieć przypisany unikalny adres, który jed n ak nie m a nic w spólnego z adresem ethernetow ym . PH Y w m odule Z L 3E T H m a adres 1. N ajlepiej je s t zdefiniow ać go ■ ja k o stalą: łdefine PHY_ADDRESS 1 Z acznijm y od funkcji konfigurującej odbieranie ram ek. Jej argum entem je s t adres ■'* PHY. Funkcja ta zw raca zero, gdy konfigurow anie zakończyło się sukcesem , a war- ■<$ tość ujem ną, gdy w ystąpił błąd. Jej sygnatura je s t następująca: ' '“i1“ static int ETHconfigureRX(uint8_t phyAddress); M ikrokontroler ST M 32F107 używ a układu D M A do odbierania i w ysyłania r; ethernetow ych. W ięcej o D M A piszę w rozdziale 3.3. W funkcji ETHconfigureRX deklarujem y E T HRXBUFNB odbiorczych deskryptorów D M A oraz po jed n y m buforze odbiorczym na każdy deskryptor. B ufory m ają rozm iar ETH_MAX__PACKET__SIZE. Stała ta je st zdefiniow ana w pliku stm 32_etli.h i m a w artość 1520, co jest m aksym alnym rozm iarem ram ki ethernetow ej (bez pream buły) pow iększonym do w ielokrotności 4, gdyż bufory DM A pow inny być w pam ięci pod adresam i w yrów nanym i do wie­ lokrotności 4 bajtów. Fragm ent inicjujący odbiorczą część D M A w ygląda tak: int ETHconfigureRX(uint8_t phyAddress) | łdefine ETHRXBUFNB 4 static ETH_DMADESCTypeDef DMARxDscrTab[ETHRXBUFNB) attribute ((aligned (4))); Static uint8_t RxBu£f[ETHRXBUFNB)[ETH_MAX_PACKET_SIZE| attribute ((aligned (4))); { e.ETH_AutoNegotiation = ETii__AutoNegotiation_Disable; e.ETH_Speed = ETH_Speed_100M; e.ETH_Speed = ETH_Speed_10M; e.ETHJłode = ETH_Mode_FullDnpIex; e.ETH_Mode = ETH_Mode_HałfDuplex; Jeśli funkcja ETH^Init zw róci w artość niezerow ą, czyli jeśli inicjow anie interfejsu się pow iedzie, m ożem y w łączyć odbieranie ram ek za pom ocą funkcji ETH_Start i zakończyć funkcję ETHconfigureRX, zw racając 0, oznaczające sukces, int ETHconfigureRX(uint8_t phyAddress) ( ETH_Start(); return 0; 1 P rzejdźm y teraz do opisu funkcji main. Z aczyna się ona od typow ej sekw encji ini­ cjującej kolejne układy: ' /■ /' int main() { Delay (1000000); AllPinsDisable(}; LEDconfigure{) / RedLEDoni); LCDconfigureO ; LCDtirite ("CLK "); error^check(CLKconfigure(), 1); LCDwrite("PASS\n"); LCDwrite("MII "); error_check(ETHconfigureMII (), 'I) ; LCDwrite{"PASS\n"); LCDwrite("ETH "); error_ciieck(ETHconfigureR)i (PHV_ADDRESS), 5); LCDwrite (ł,PASS\n"); RedLEDoff 0 ; ETH_DMARxDescChainInit(DMARxDscrTab, SRxBuf£[0][OJ, ETHRXBUENB); ) 1 Param etry pracy interfejsu E thernet zebrane są w strukturze ETH_InitTypeDef. W w iększości przypadków najlepiej je s t ustaw ić w artości dom yślne za pom ocą funkcji ETH_StructInit. W arto spróbow ać ustaw ić negocjow anie trybu pracy in­ terfejsu. Poniew aż nasz program m a być m onitorem sieci, m usim y skonfigurow ać odbieranie w szystkich ram ek, niezależnie od adresu odbiorcy. Inicjow aniem inter- N ajpierw czekam y pól sekundy - w ym agają tego niektóre kom binacje JTAG i pro­ gram u go obsługującego. Podczas całego procesu konfigurow ania św ieci czerw ona dioda, a jej w yłączenie sygnalizuje zakończenie konfigurow ania sprzętu. M iganie czerw onej diody oznacza w ystąpienie błędu. Pojedyncze m ignięcia oznaczają problem z, synchronizacją sygnałów taktujących. M iganie w rytmie: 4 m ignięcia - dłuższa przerw a, oznacza błąd interfejsu M II (m iędzy M A C a PH Y ) - np. nie 82 2. Inter «E jest w łożony m oduł Z L3E T H . M iganie w rytm ie: 5 m ignięcia - dłuższa przerwa; oznacza błąd konfiguracji E thernetu - np. sieć nie działa albo do Z L3E T H nie je s l| podłączony kabel. Inform acja o postępie urucham iania program u je st też wyświeilana na LCD. Po uruchom ieniu interfejsu ethernetow ego program w nieskończonej pętli czytaj] kolejne odebrane ram ki za pom ocą funkcji ETH_BandłeRxPkt z biblioteki STM32'fl i w yśw ietla icli zaw artość. A rgum entem funkcji ETH_HandleRxPkt je st adres bufo-Jjj ra, do którego zostanie skopiow ana odebrana ram ka. P ream buła i sekw encja kon-' trolna ram ki nie są kopiow ane. Jeśli jak a ś ram ka została odebrana, to funkcja tal] zw raca liczbę skopiow anych bajtów. N ajkrótsza ram ka ethernetow a bez preambuły»! i sekw encji kontrolnej m a 60 oktetów . S zkielet końcow ego fragm entu funkcji raair. w ygląda następująco: int main () { unsigned pkts; pkfcs = 0; for (;;) f static uir>t8_t packet (ETH_MAX_PACKET_SIZE]; uint32_t size; size = ETH_HandleRxPkt(packet); if (size >= 60) { pkts++; ... /* Wypisz ramkę na LCD. */ ) StOS TCP/IP 3.1. Przegląd implementacji Stosem T C P /IP nazyw a się kom plet protokołów intersieci (ang. internet protocol, suite). C entralnym protokołem tego stosu jest 1P, opisany w poprzednim rozdziale’,, M inim alna im plem entacja musi zaw ierać obsługę protokołów transportow ych T C P i UDP. O bow iązkow ą częścią T C P /IP je st też ICMP, który opisuję pod koniec tegov rozdziału. Ponadto im plem entacja stosu zaw iera zw ykle kilka pom ocniczych protod kolów, np. w spom niany w poprzednim rozdziale ARP. A by tw orzyć aplikacje korzystające z intersieci, m usim y m ieć im plem entację ,stosu; TCP/IP. N ie m a potrzeby sam odzielnego im plem entow ania całego stosu. To bylohyi zbyt pracochłonne i niepotrzebnie pow tarzało ju ż w ykonaną przez innych pracę,¡, Ten rozdział zaczynam od p obieżnego przeglądu dostępnych im plem entacji stosu! TCP/IP. N astępnie skupiam się na w ybranej im plem entacji. Przedstaw iam , ja k dotj pasow ać ją do architektury m ikrokontrolera i ja k ją skonfigurow ać. Potem opisuję! zainstalow any w m ikrokontrolerze S T M 32F107 przeznaczony do obsługi Ethernetu, układ D M A. G łów nym celem tego rozdziału je s t przedstaw ienie im plem entacji ste­ row nika (ang. driver) E thernetu, pośredniczącego m iędzy stosem protokołów sL ciow ych a sprzętem . O m aw iam trzy w ersje sterow nika: - pierw sza używ a dodatkow ych buforów do przekazyw ania ram ek ethernetow y"' m iędzy stosem a D M A; druga nie potrzebuje dodatkow ych buforów w części odbiorczej, D M A kopiuje! odebrane ram ki bezpośrednio do buforów stosu; trzecia nie m a rów nież dodatkow ych buforów w części nadaw czej. Pozbycie się dodatkow ych buforów odbiorczych lub nadaw czych zm niejsza zaję-,'^ tość R A M i spraw ia, że ram ki nie są niepotrzebnie kopiow ane (ang. zero copy)!-M Pow odem prezentacji aż trzech sterow ników je s t też chęć przedstaw ienia różnych i trybów pracy DM A. Z aim plem entow ane sterow niki porów nuję pod w zględem jętości pam ięci RAM i Flash o raz szybkości działania. Na koniec tego rozd podaję nieco użytecznych inform acji o protokołach IC M P i DHCP. Przegląd implementacji D ostępne są zarów no kom ercyjne, ja k i darm ow e im plem entacje stosu TCP/IP,•';( Przykładem rozw iązań kom ercyjnych są stosy oferow ane przez firm ę InterNiche Inform acje o nich m ożna znaleźć na stronie http://w w w .iniche.com . Jest tam w ie w szystko, czego m ożem y potrzebow ać w system ie w budow anym . Jednak cenyi|; poszczególnych pakietów są zaporow e naw et dla dużej firmy, nie wspomii o hobbystach. InterN iche, aby zachęcić do sw oich produktów , oferuje darm ow y N icheL ite [4]. Z aim plem entow ano w nim okrojoną w ersję IP nieobslugującą nag m entacji. N icheL ite zaw iera protokoły TCP, UDP, ICMP, A R P oraz klienty p kolów BOOTP, DHCP, D N S, TFTP. Jest też dem onstracyjna w ersja serw era H I 1P • N icheL ite udostępnia interfejs program istyczny m inisockets, naśladujący inlt gniazd (ang. sockets), dostępny w uniksow ych system ach operacyjnych i systemach •■ W indow s, ale nie w pełni z nim kom patybilny. Pow ażną w adą stosu N ichiL ite licencja, na której je s t udostępniany. Z abrania ona łączenia N ichiL ite z oprogram ow aniem , które je s t ro zpow szechniane ja k o oprogram ow anie otw arte (ang. open", source softw are) i tw orzenia aplikacji używ ającycli N ichiL ite za pom ocą otwartych 85 narzędzi program istycznych, np. narzędzi pow stających w ram ach projektu GNU i udostępnianych na licencji G PL (ang. general public license). Na drugim biegunie są w pełni darm ow e im plem entacje stosu TCP/IP. Przykładem jest projekt ulP (m ikro IP), którego strona znajduje się pod adresem littp://www. sics.se/~adain/uip. O ryginalnie stw orzono go dla m ikrokontrolerów 8-bilow ych, ale został przeniesiony też na architekturę ARM . Ź ródła tego stosu są przyzw oicie udo­ kum entow ane i skom entow ane. W ym aga on niew ielkiej pam ięci, zarów no RAM , jak i Flash. Im plem entuje podstaw ow y zestaw protokołów : IP, TCP, UDP, ICMP, ARP, SLIP. D ostępne są też dem onstracyjne im plem entacje serw era i klienta HTTP, klienta D N S, klienta SM T P oraz serw era protokołu Telnet. Jest udostępniany na licencji um ożliw iającej jeg o kom ercyjne w ykorzystanie. Do napisanie tej książki w ybrałem stos lw IP (ang. lightw eight IP) [5]. Projekt lwIP ma sw oją stronę http://savannah.nongnu.org/projects/lw ip. Biblioteka lw IP jest dystrybuow ana na bardzo liberalnej licencji, która um ożliw ia tw orzenie produktów kom ercyjnych zaw ierających lw IP i ich sprzedaw anie bez konieczności udostępnia­ nia tekstu źródłow ego. W bibliotece lw IP zaim plem entow ano standardow y zestaw protokołów : IP, TCP, UDP, ICMP, ARP. Ponadto lw IP zaw iera dodatkow e moduły: - D H C P - klient konfigurujący ustaw ienia sieciow e w ęzła, czyli uzyskujący adres 1P, m askę podsieci, adres rutera i adres serw era nazw (w podsieci musi działać serw er tej usługi); - D NS - klient tłum aczący nazw y dom enow e na adresy IP; - A utoIP - protokół APIPA (ang. A utom atic P rivate IP A ddressing), udostępniają­ cy alternatyw ny do D H C P sposób zdobyw ania adresu IP, opisany w RFC 3927, przydziela adresy nierutow alne z puli 169.254.0.0/16, nie w ym aga żadnego ser­ wera; - S N M P (ang. Sim ple N etw ork M anagem ent Protocol) - protokół służący do zdal­ nego m onitorow ania w ęzłów sieci i zarządzania urządzeniam i sieciow ym i, np. ruteram i (w brew nazw ie w cale nie je s t to prosty protokół); - 1GMP (ang. Internet G roup M anagem ent Protocol) - protokół służący do zarzą­ dzania grupam i węzłów, osiąganym i pod w spólnym adresem grupow ym (ang. m ul t i cast address)', - SL IP (ang. Serial Line Internet Protocol) - kapsulkow anie IP w łączach szerego­ wych; - PPP (ang. P oint to P oint Protocol) - protokół w arstw y łącza używ any w wielu interfejsach szeregow ych. B iblioteka lw IP udostępnia trzy interfejsy program istyczne: - Interfejs surow y (ang. raw), który je s t podstaw ow ym interfejsem biblioteki lwIP. - Interfejs sekw encyjny (ang. neteonn), który obsługuje kom unikację sieciow ą w paradygm acie otw órz-czytąj-pisz-zam knij. W yw ołania funkcji tego interfejsu są blokujące. W ynika stąd, że biblioteka i aplikacja m uszą działać w osobnych w ątkach - potrzebny je s t system operacyjny, który um ożliw ia urucham ianie w ie­ lu w ątków lub procesów. 86 3. Stos TCP/ip Interfejs gniazd (ang. sockets), który obudow uje interfejs sekw encyjny i w zalo-; żenili m a być zgodny z interfejsem gniazd używ anym w „dużych” komputerach - nie je st jed n ak z nim w pełni zgodny. B iblioteka lw IP je st ustaw icznie rozw ijana, co kilka m iesięcy pojaw ia się jej nowa w ersja. W niniejszej książce korzystam z w ersji 1.3.2. Jest niem al pew ne, żcw chw ili ukazania się tej książki będzie ju ż dostępna kolejna w ersja tej biblioteki, Jest to jed n ak zaleta, a nie w ada, gdyż nie w arto pośw ięcać czasu na poznawanie oprogram ow ania, które nie je s t popraw iane i rozw ijane. O program ow anie, które nie je s t rozw ijane, po ja k im ś czasie staje się bezużyteczne. N ie należy też obaw iać się. że napisane dotychczas program y nie będą działać z now ym i w ersjam i biblioteki, Z apew ne m ogą w ystąpić ja k ie ś problem y, ale tw órcy biblioteki lwIP, będąc prze­ cież jednocześnie jej użytkow nikam i, nie będą chcieć utrudniać sobie pracy i na pew no będą starać się zachow ać w steczną kom patybilność. ,; finclude "cortex-m3.h" R dzenie A R M m ogą pracow ać ja k o grubokońców kow e (ang. big-endion) lub cieńkokońców kow e (ang. little-endian). W S T M 32 rdzeń C ortex-M 3 m a na stale usta­ w ioną cienkokońców kow ą kolejność bajtów (ang. byte order). B ibliotekę lw IP trze­ ba poinstruow ać o rodzaju końców kow ości za pom ocą definicji: -.w,- W następnych rozdziałach staram się szczegółow o w yjaśnić, ja k pisze się aplika­ cje sieciow e korzystające z biblioteki lw IP i używ ające protokołów transportowych T C P i UDP. Spośród dodatkow ych m odułów prezentow ane przykłady korzystają z Dł-ICP i D N S. W szystkie przykłady używ ają interfejsu surow ego. Pozw ala on na lepszą integrację aplikacji ze stosem TCP/IP. Stos i aplikacja działają we wspólnym w ątku. Program je st sterow any zdarzeniam i (ang. event based) za pom ocą funkcji, zw rotnych (ang. callback fu n c tio n s) w yw oływ anych przez stos. Ź ródłem zdarzeń są przerw ania. Interfejs surow y je s t preferow any w system ach w budow anych, gdy/ ' z trzech interfejsów dostarczanych przez bibliotekę lw IP m a najm niejsze narzuty "i, pam ięciow e i czasow e. Interfejs surow y je st trudniejszy do opanow ania przez pro--'-' gram istę od pozostałych dw óch, ale je d n y m z celów tej książki je s t w łaśnie przy­ bliżenie go C zytelnikow i. Żaden z wyżej opisanych darm ow ych stosów nie im plem entuje IP w w ersji fi. ■' Tw órcy lw IP podjęli próbę zaim plem entow ania tej w ersji IP, ale w chw ili rozpoczy­ nania pisania książki im plem entacja nie była jeszcze w pełni gotow a. 3.2. Biblioteka lwIP W ielką zaletą biblioteki lw IP je s t m ożliw ość bardzo elastycznego je j skonfigurow ania. D zięki tem u m ożem y skom pilow ać tylko te protokoły i moduły, które są nam rzeczyw iście potrzebne. Im plem entacje protokołów są sparam elryzow ane i możemy ■ je łatw o dopasow ać do w ym agań konkretnej aplikacji. M anipulując param etram i bi­ blioteki, m ożem y leż w szerokich granicach zm ieniać zapotrzebow anie na pamięć, co pozw ala pisać aplikacje zarów no na system y dysponujące gigabajtam i pamięci operacyjnej, ja k i na m ikrokontrolery w yposażone w kilkadziesiąt kilobajtów RAM. O czyw iście zm niejszenie rozm iaru potrzebnej pam ięci nic jest za darm o, w iąże się zw ykle ze zm niejszeniem w ydajności lub ograniczeniem liczby w ęzłów , z którymi ■ m ożna się rów nocześnie kom unikow ać. 3.2.1. 87 liniow ać m akra do pom iaru w ydajności (ang. perform ance) im plem entacji. W tej książce nie korzystam y jed n ak z tej m ożliw ość, pozostaw iając dom yślny plik, do­ starczany w raz z biblioteką. W szelkie pozostałe adaptacje należy um ieścić w pliku cc.h. Żeby jed n ak nie m odyfikow ać pliku dostarczonego z biblioteką, tw orzym y w łasny plik cortex-m 3.h, w którym um ieszczam y w szystkie niezbędne definicje, a w pliku cc.h um ieszczam y tylko dyrektyw ę preprocesora: t z y pij.- - 3.2. Biblioteka lwIP łdefine BYTE_ORDER L i m E _ E N D M N B iblioteka lw IP używ a w łasnych nazw dla typów reprezentujących liczby całkow ite (ang. integral types). D efiniujem y te typy, korzystając z definicji typów dostarcza­ nych przez standardow ą bibliotekę języ k a C w pliku stdint.h. Typ mem p t r t jest ogólnym w skaźnikiem . N ie je s t on zdefiniow any ja k o void*, jak b y tego należało oczekiw ać w języku C, aby m ożna były w ykonyw ać na nim w szystkie operacje arytm etyczne. typedef typedef typedef typedef typedef typedef typedef int8_fc uint8_t intl6_t uint!6_t int32_t uint32_t u32__t s8_t; u8_L; sl6_t; ul6_t; s32_t; u32__t; mem_ptr_t; P oniew aż standard języka C pozostaw ia jeg o im plem entatorom pew ną sw obodę, typy 16-bitow e i 32-bitow e m ogą być różnie zdefiniow ane w różnych architektu­ rach. D la architektur A RM typy i n t l 6 _ t , u i n t l 6 _ t , in t3 2 _ t, u in t3 2 _ t są zde­ finiow ane w stdint.h odpow iednio ja k o s h o r t, u n sig n ed s h o r t, lo n g , u n sig n ed lo n g . D la tych typów biblioteka lw IP potrzebuje specyfikatorów form atow ania dla funkcji p r i n t f , s n p r i n t f itp. S pecyfikatory zaczynające się od litery X służą do w ypisyw ania danych szesnastkow o. Ponadto definiujem y speeyfikator form atow a­ nia SZT_F dla typu size__t. ffdefine Idefine idefine Idefine Idefine Idefine Idefine S16_F U16_F X16 F S32~F U32~F X32~F SZT_F "hd" "hu" "hx" "Id" "lu" "lx" "zu" Przykład użycia jednej z pow yższych stałych w idzieliśm y ju ż w pliku util_lcd.c, gdzie znajduje się następujący fragm ent program u: Dopasowanie do architektury mikrokontrolera - plik cortex-m3.h uintl6_t port; char b u f [8); snprintf(buf, sizeof(buf), ":V'U16_F, port); Za adaptację biblioteki lw IP do konkretnej architektury odpow iadają pliki nagłów ­ kow e um ieszczone w katalogu ./exam ples/include/arch. W pliku perf.h m ożna zde- Sieciow y porządek oktetów je st porządkiem grubokońców kow ym , a zastosow any m ikrokontroler je s t cienkokońców kow y, zatem oprogram ow anie sieciow e bardzo 88 89 3.2. Biblioteka lwIP 3. Stos T C P /n t często musi odw racać kolejność oktetów (bajtów ). B iblioteka lw IP m a zaimplemen-'l; tow ane odpow iednie funkcje i jeśli nie zdefiniujem y w łasnych operacji odwracania, to zostaną skom pilow ane te dom yślne funkcje, które są jed n a k napisane w C, aby.,|' były przenośne i w zw iązku z tym nie są optym alne. A rchitektura A R M m a instruk- fe' cje asem blerow e REV16 i REV um ożliw iające szybkie (realizow ane sprzętow o) od-,§ w racanie kolejności bajtów odpow iednio w słow ie dw ubajtow ym i czterobajtowym , B iblioteka STM 32 dostarcza funkcji korzystających z tych instrukcji, co u m o ż liw ia j proste zdefiniow anie potrzebnych operacji. pobiera dw a m łodsze bajty z rejestru %1, zam ienia ich kolejność i um ieszcza w ynik w rejestrze %0. Przypisanie konkretnych rejestrów pozostaw iam y jednak kom pila­ torow i. W napisie idefine LWIP_PLATFORM_HTONS (x) _RE V 1 6 ( x ) »define LWIP_PLATFORM_HTONL(x) REV(x! "r" (x) fl W nazw ach pow yższych m akr sk ró t H TO N S (ang. host to netw ork short) o zn a -ij cza zam ianę kolejności w słow ie dw ubajtow ym (ang. short) z porządku używanego "$ przez daną m aszynę, w ęzeł (ang. host) na porządek sieciow y. N atom iast H T O N L $ (ang. host to netw ork long) oznacza analogiczną zam ianę w słow ie czterobajtow ym (ang. long). D ualnych operacji N TO H S (ang. netw ork to h ost short) i N TO H L (ang.Vf netw ork to host long) nie m usim y definiow ać, bo są identyczne. Pow yższe makra (ï są przeznaczone tylko do użycia w ew nątrz biblioteki lwIP. W naszych programach pow inniśm y w łączać plik Iwip/inet.h (lub ja k iś inny go w łączający) i używ ać zdr- ' finiow anych w nim m akr h to n s , n to h s , h to n l, n to h l, które m ają standardow e na- p zwy, pow szechnie używ ane w oprogram ow aniu sieciow ym . ul6__t u!6_t u32_t u32__t htons(u!6_t ntohs(u!6_t htonl(u32_t ntohl(u32_t x); x); x); x); •■ Pow yższe m akra zaim plem entow ano za pom ocą m akr LWIP_PLATFORM_HTONS i LWI P_PLATFORM_HTONL. Im plem entację tych m akr m ożna jeszcze bardziej zoptym alizow ać, likw idując narzut w yw ołania fu n k c ji REV16 i REV przez zdefiniow a- ■ nie w staw ek asem blerow ych. Jest to jed n a k bardzo zależne od użytego kom pilatora. N iestety w staw ki asem blerow e często blokują kom pilatorow i m ożliw ość optym ah- t zacji kodu w ynikow ego. G C C m a m echanizm definiow ania takich w staw ek nieblo- /■: kujący optym alizacji kodu. O kupione je st to jed n ak bardzo skom plikow aną składnią, którą zaprezentuję na przykładzie m akra H TO N S. M akro H T O N L definiuje się analogicznie. »define LWIP_PLATFORM_HTONS (x) (( u!6_t result; asm ("revl6 $0, '-U" : "=r"(result) result; i) \ \ )ji : "r" <x> ) ; \ \ Treść m akra otaczają podw ójne naw iasy składające się z naw iasu okrągłego i kłamrow ego. M akro operuje na dw óch zm iennych: sw oim argum encie x oraz zadeklaro- ). w anej w ew nątrz m akra 16-bitowej zm iennej r e s u l t . U m ieszczenie nazw y r e s u l t ( w ostatnim w ierszu treści m akra oznacza, że je s t to w artość zw racana przez makro. ■■ W iersz zaczynający się od słow a kluczow ego asm definiuje operację, którą chcemy w ykonać. Instrukcja rev!6 40, %1 "=r" (result) litera r oznacza, że argum ent %0 musi być rejestrem . Instrukcja r e v l6 nie może um ieścić w yniku w pam ięci. Z nak rów ności oznacza, że rejestr jest m odyfikow any przez tę instrukcję. N azw a zm iennej w naw iasach oznacza, że rejestr ten musi prze­ chow yw ać w artość tej zm iennej. N apis oznacza, że argum ent %1 m usi być rejestrem , gdyż drugi argum ent instrukcji r e v i 6 rów nież m usi być rejestrem . B rak znaku rów ności oznacza, że w artość tego rejestru nie je st m odyfikow ana przez instrukcję. Ponadto rejestr len musi przechow yw ać w artość zm iennej x. B iblioteka lw IP zaw iera sporo kodu diagnostycznego. Jeśli chcem y z tego skorzy­ stać, m usim y zaim plem entow ać urządzenie, na które będą w ypisyw ane kom unikaty diagnostyczne i m akra w ypisujące te kom unikaty. O pcja ta jest przydatna przede w szystkim tw órcom biblioteki, dlatego definiujem y dw a puste makra: »define LWIP_PLATFORM_ASSERT(x) »define LWIP_PLATFORM_DlAG(x) ((void)0) ((void)0) A rgum ent m akra LWIP_PLATFORM_ASSERT je s t w skaźnikiem na kom unikat, który ma być w ypisany. K om unikat je st napisem w stylu C i m usi być zakończony term i­ nalnym zerem . A rgum ent m akra L W I P _ P L ATFORM_DIAG jest otoczonym naw iasam i okrągłym i ciągiem argum entów , które akceptuje funkcja p r i n t f . Zakładając, że dysponujem y funkcją p r i n t f , w ypisującą gdzieś w ynik sw ojego działania, m akra to m ogłoby być w ięc zaim plem entow ane tak: »define LWIP__PLATFORM_ASSERT (x) printf (x) »define LWIP_PLATFORM_DIAG(x) printf X A plikacje, które prezentuję w tej książce, dla zapew nienia w spółbieżności korzysta­ ją z system u przerw ań. Funkcje biblioteki lw IP są w yw oływ ane w program ie głów ­ nym i w procedurach obsługi przerw ań. N iektóre krytyczne fragm enty program u nie m ogą być przeryw ane. Jednak funkcje biblioteczne w wielu przypadkach nie są w spółużyw alne (ang. reentrant). O gólnie każdą funkcję, która odw ołuje się do ja k ic h ś globalnych zasobów , np. zm iennych globalnych czy układów peryferyjnych m ikrokontrolera lub używ a zm iennych statycznych, należy traktow ać jak o niew spółużyw alną. Funkcje zarządzające pam ięcią program u (przydzielające i zw alniają­ ce pam ięć) nie są w spółużyw alne, gdyż korzystają z globalnej struktury, jak ą jest sterta. N iew spółużyw alność oznacza, że jeśli w ykonyw anie takiej funkcji zostanie przerw ane (np. przez procedurę obsługi przerw ania) i zostanie w yw ołana ta sam a lub inna, ale korzystająca z tych sam ych zasobów funkcja, to istnieje pow ażne ryzy­ ko błędnego działania program u. M ożna oczyw iście zabronić w yw ołania niew spółużyw ałnych funkcji w procedurach obsługi przerw ań, ale zapew ne lepszym roz­ w iązaniem jest w ykonyw anie krytycznych fragm entów program u z w yłączonym i przerw aniam i. W bibliotece lw IP przew idziano w tym celu trzy makra. »define SYS_ARCH_DECL_PROTECT(x) u32 t X \ 91 3.2. Biblioteka IwlP łdefine SYS_ARCII_PROTECT(x) \ (x = get_PRIMASK(), disable_irq()) łdefine SYS_ARCH_UNPROTECT(x) \ _set_PRIMASK(x) 'if Ą M akro S Y S _ A R CH_DECL_PROTECT d eklaruje zm ienną x, w której zapisuje się aktualif' m askę przerw ań. M akro S YS_ARC H _ P R O T E C T zapisuje w zm iennej x aktualną zawati; tos'ć rejestru PRIMASK i w yłącza przerw ania. U żyw a do tego f u n k c ji get_PRlMAs;J i disable_irq z biblioteki ST M 32. R ejestr PRIMASK je st jed n y m ze specjalnyoi| rejestrów rdzenia C ortex-M 3 i służy d o m askow ania przerw ań o konfigurow alny^ priorytecie. W C ortex-M 3 są to w szystkie przerw ania z w yjątkiem zerow ania (ang^ reset), przerw ania niem askow alnego N M I (ang. non-m askable interrupt) i poważ* nego niepow odzenia (ang. hard fa u lt). Jeśli najm łodszy bit rejestru PRIMASK je j' w yzerow any, przerw ania są w łączone, a jeśli je st ustaw iony - w yłączone. Pozostał bity tego rejestru nie są używ ane - są zarezerw ow ane do przyszłego wykorzystania'5 F u n k c ja disable_irq w yw ołuje instrukcję A sem blera cpsid (ang. change prók. cessor state, disable interrupt), która ustaw ia najm łodszy bit w rejestrze PRIMASK, M akro SYS_ARCH__UNPROTECT przyw raca poprzednią, zapam iętaną w zmiennej x;: w artość rejestru PRIMASK. Jako przykład użycia pow yższych m akr rozw ażm y chronione w ersje standardów w ych funkcji zarządzających pam ięcią: m a llo c , f r e e , c a l l o c , r e a l l o c . Wersje chronione nazw ijm y odpow iednio: p r o te c te d _ m a llo c , p r o t e c te d _ f r e e , p ro te c ted _ _ callo c, p r o t e c t e d _ r e a l l o c . W ołają one o d pow iednie funkcje niechronionc przy w yłączonych przerw aniach. Ż eby ich w yw ołanie było efektyw ne, są zadekhw row ane jak o rozw ijane w m iejscu (ang. inline). S ta ła INLINE dla poszczególnych kom pilatorów je s t zdefiniow ana w pliku core_cm 3.h, który je s t częścią biblioteki;.’ ST M 32 i znajduje się w katalogu Jst/L ibraries/C M S IS /C M 3 /C o reS u p p o rt/. Niżej podałem przykłady dw óch funkcji w w ersji chronionej. Im plem entacja dw óch po­ zostałych je s t analogiczna. static INLINE void *protected_malloc(size_t size) { void *ret; SYS_ARCH_DECL_PROTECT(v); SYS_ARCH_PROTECT(v); ret = mal l o c (size); SYS_ARCH_UNPROTECTfv); return ret; ) static INLINE void protected_free(void *ptr) { SYS_ARCH__DECL_PROTECT (v) ; SYS_ARCH_PROTECT(v); free (ptr); SYS_ARCH_UNPROTECT(v); 3 Jak poprzednio, jeśli używ am y G C C , m ożem y m akra zaim plem entow ać efektyw ­ niej, bezpośrednio w A sem blerze. Instrukcja mrs (ang. m ove from special register to register) przepisuje zaw artość rejestru specjalnego do rejestru ogólnego prze­ znaczenia. Instrukcja msr (ang. m ove from register to special register) przepisuje zaw artość rejestru ogólnego przeznaczenia do rejestru specjalnego. Znaki \ n \ t po tej instrukcji oznaczają przejście do now ego w iersza i tabulator. S łużą one tylko do form atow ania tekstu, który jest przekazyw any do asem blacji. Idefine SYS_ARCH_DECL_PROTECT(x) u32_t x »define SYS__ARCH_PROTECT(x) !l asm volatile ( "mrs %0, PRIMASK\n\t" "cpsid i" : "=r" (x) : ); \ \ \ \ \ \ \ 1) »define SYS_ARCH_UNPROTECT(x> (1 \ asm volatile C'msr PRIMASE, 10" : : ” r" (x)i; \ I) O pisany dotychczas m echanizm m oże być niew ystarczający. W ykonyw anie długich fragm entów program u przy w yłączonych przerw aniach je s t niepożądane. Z w ykle w ystarczy zablokow ać tylko pew ną grupę przerw ań. M ożna to zrobić, w ykorzystu­ jąc priorytety. W architekturze C orlex-M 3 m ożna przerw aniom przydzielać prio­ rytety od 0 do 15. Przerw ania, których priorytet nie je st konfigurow alny, m ają na stale przypisany priorytet ujem ny: zerow anie m a priorytet -3 , N M I m a priorytet - 2 , a pow ażne niepow odzenie priorytet - 1 . Jak to zw ykle byw a, w yższy priorytet ma m niejszą w artość. Przerw ania są w yw łaszczalne. Jeśli w trakcie w ykonyw ania procedury obsługi przerw ania pojaw i się przerw anie o w yższym priorytecie, to ak­ tualnie w ykonyw ana procedura obsługi zostanie przerw ana i procesor przejdzie do obsługi przerw ania o w yższym priorytecie. Przerw ana procedura zostanie dokoń­ czona, gdy nie będzie ju ż żadnych przerw ań o w yższym priorytecie do obsłużenia. Priorytet przerw ania je s t zapisyw any na czterech bitach, które m ożem y podzielić na dw a pola: priorytet w yw łaszczania (ang. preem ption priority) i podpriorytet (ang. subpriority). Przerw anie m oże być w yw łaszczone tylko przez przerw anie o w yż­ szym priorytecie w yw łaszczania. Podpriorytet decyduje o kolejności obsługi p rze­ rwań w ram ach tego sam ego priorytetu w yw łaszczania. N a potrzeby tej książki ustalam y za pom ocą stałej PRE£MPTION_PRIORITY_BITS, że dw a bity priorytetu określają priorytet w yw łaszczania, a dw a pozostałe podprio­ rytet. M am y w tedy m ożliw ość zdefiniow ania czterech priorytetów w yw łaszczania. W ystarczą nam trzy. Z najw yższym priorytetem , oznaczonym HIGH_IRQ_PRIO, o b­ sługujem y przerw ania w ym agające szybkiej reakcji. Ich czas obsługi m usi być krót­ ki i nie m ogą w nich być w ołane żadne funkcje biblioteki lwIP. Średni priorytet, oznaczony LWIP_IRQ_PRIO, przypisujem y przerw aniom biblioteki lwIP. Pozostałym przerw aniom nadajem y niski priorytet LOW_IRQ_PRIO. Idefine łdefine łdefine łdefine PREEMPTION_PRIORITY_BITS 2 l!IGH_IRQ_PRIO 1 LWIP__IRQ_PRIO 2 LOW_IRQ_PRIO 3 M akro S E T_IRQ_PROTECTION uaktyw nia m ożliw ość blokow ania przerw ań zależnie od ich priorytetu i musi być w yw ołane na początku program u, zanim w łączym y jak iek o lw iek przerw anie. A by ustaw ić liczbę bitów przeznaczonych na priorytet w yw łaszczania, najlepiej je s t w yw ołać funkcję NVIC__SetPriorityGrouping z bi­ blioteki STM 32. idefine SET_IRQ_PROTECTION() \ NVIC_SetPriorityGrouping(7 - PREEMPTION_PRIORITY_BITS) 92 93 3.2. Biblioteka IwlP 3. Stos TCP/lp$ ■ ]W "~r" (prv), "=r" (tmp) : \ "i" ((lvl) « (8 - PREEMPTION_PRIORITY_BITS)) \ A by ustaw ić priorytet przerw ania, m ożna użyć funkcji NVIC_SetPriority, do-j" starczanej przez bibliotekę ST M 32, a dokładniej przez C M SIS. N iestety fu n k cja^ ta nie uw zględnia zm ienionej liczby bitów priorytetu w yw łaszczania i używ a dof' tego stałej NVIC__PRIO_BITS, która m a w artość 4, Żeby zm ienić tę w artość, na-ji. leżałoby zm odyfikow ać pliki źródłow e biblioteki C M SIS. Stała la je s t zdefiniow al i na w pliku stm 3 2 fI0 x.h , który znajduje się w katalogu Jst/L ibraries/C M SIS/C M 3/Ą D eviceSupport/ST /ST M 32 F 10x, a potem używ ana w pliku core_cm 3.h. Funkcja bi-’ blioteczna nie uw zględnia rów nież podpriorytetu. A by nie m odyfikow ać biblioteki, co m ogłoby spow odow ać problem y z kom patybilności;! naszych program ów z jej ” przyszłym i w ersjam i, definiujem y w łasne m akro SET_PRIORITY, które umieszcza,, priorytet w yw łaszczania w starszych bitach, a podpriorytet w m łodszych bitach ’' priorytetu. łdefine SET_PRIORITY(irq, prio, subprio) \ NVIC_SetPriority((irq), (subprio) [ ((prio) << \ (__NVIC_PRIO_BITS - PREEMPTION_PRIORITY_BITS) ) ) ); 0 poprzedniej w artości priorytetu, pow yżej którego przerw ania nie są b lo k o w an e., M akro IRQ_PROTECT zapisuje w zm iennej p rv stan aktualnie blokow anych przerwań '■ 1 blokuje przerw ania o priorytecie niższym lub rów nym l v ł . M akro IRQ_UNPROTECT przyw raca stan blokow ania przerw ań zapisany w zm iennej p rv. Priorytet, powyżej ■ którego przerw ania nie są blokow ane, przechow yw any je s t w m ikrokontrolerach C ortex-M 3 w rejestrze BASEPRI. D o tego rejestru m ożem y odw oływ ać się za pom o­ cą fu n k c ji get__BASEPRI i set_BASEPRI z biblioteki STM 32. W artość argum en­ tu ł v l trzeba przesunąć o odpow iednią iiczbę bitów w lew o, we w łaściw e miejsce; w rejestrze BASEPRI. H f defined GNUC__ idefine ALIGN4 attribute {{aligned (4))) ielse terror Define ALIGNS macro for your compiler, iendif ? T ab . \ \ \ \ \ \ 3.1. Stale identyfiku ące kompilator Kompilator ARMCC GCC IAR TASKING łdefine IRQ_DECL_PROTECT(prv) \ u32 t prv Idefine IRQ_PROTECT(prv, lvl) \ (prv = get_BASEPRI{), \ _set_BASEPRIiilvl) « (8 - PREEMPTION_PRIORITY_BITS})) Idefine IRQ__UNPROTECT (prv) \ _set_BASEPRI(prv) \ \ (prv)); \ A by pisać program y, które używ ają konstrukcji specyficznych dla kom pilatora, do­ brze je s t posługiw ać się instrukcjam i kom pilacji w arunkow ej i stałym i definiow a­ nymi w tym celu przez poszczególne kom pilatory. Stałe dla popularnych kom pila­ torów zam ieszczone są w tabeli 3.1. Popatrzm y na następujący przykład kom pilacji w arunkow ej, zależnej od użytego kom pilatora. ¥ M ożem y teraz zdefiniow ać m akra analogiczne do w yżej opisanych m akr SYS łdefine IRQ_DECL_PROTECT(prv) u32_t prv łdefine IRQ_PROTECT(prv, lvl) (( u32_t tmp; asm volatile ( "mrs *0, BASEPRI\n\t" "movs %1, t2\n\t" "msr BASEPRI, %1" : 1,0"; : "r" Przestaw ione tu sposoby ochrony krytycznych i niew spółużyw alnych fragm entów program u m ogą w ydać się przesadzone ja k na potrzeby stosunkow o prostych przy­ kładów zam ieszczonych w kolejnych rozdziałach. Jednak w bardziej skom plikow a­ nych aplikacjach porządne przem yślenie tego problem u i zaim plem entow anie odpo­ w iednich m echanizm ów chroni przed bardzo trudnym i do zlokalizow ania błędam i, których usuw anie je st bardzo czasochłonne. Z aprezentow ane w tym podrozdziale rozw iązania należy traktow ać jako przykład i inspirację do w łasnych przem yśleń na ten tem at. ARCH. M akro I RQ_DECL_PROTECT deklaruje zmienni! p rv przechow ującą informację Pow yższych m akr używ a się podobnie ja k m akr SYS_ARCH. Jak poprzednio, dła G CC m ożem y je zdefiniow ać bardziej optym alnie. Z m ienną p rv przechow ujem j w rejestrze ogólnego przeznaczenia %0. Zakładam y, że ja k o argum ent l v l zawsze podaw ana jest je d n a z w yżej zdefiniow anych stałych IRQ_PRIO. Poniew aż argu­ m entem instrukcji msr nie m oże być stała, m usim y najpierw tę stałą załadow ać do rejestru ogólnego przeznaczenia 41 (zm ienna tmp) za pom ocą instrukcji movs. Napis " i " oznacza, że argum ent %2 je st stałą. W naw iasach za tym napisem jest podana w artość tej stałej. \ )) łdefine IRQJ)NPROTECT(prv) (( asm volatile ("msr BASEPRI, I) Siata CC ARM GNUC ICCARM TASKING C ortex-M 3 je st architekturą 32-bitow ą i czasem , ze w zględu na efektyw ność, do­ brze je st w yrów nać położenie danych w pam ięci do adresu będącego w ielokrotno­ ścią 4 bajtów. Przykład użycia atrybutu a lig n e d w idzieliśm y ju ż w poprzednim rozdziale, przy deklaracji deskryptorów i buforów D M A . Poniew aż w yrów nyw anie nie je st częścią standardu języ k a C, każdy kom pilator m a w tym celu sw oje specy­ ficzne instrukcje. Pow yższy fragm ent program u je st przeznaczony dla G CC. Inny k om pilator w ypisze błąd przypom inający, że należy dodać w łaściw ą definicję. 3.2.2. Parametry konfiguracyjne - plik Iwipopts.h W szystkie param etry, które m ożem y ustaw ić w bibliotece IwlP, są zgrom adzone w jed n y m m iejscu - znajdują się w pliku opt.h. K ażda opcja je st opatrzona kom en­ tarzem i m a zdefiniow aną w artość dom yślną. Plik ten je s t w archiw um w katalo­ gu ,/lw ip -1.3.2/src/include/lw ip, ale nie należy go m odyfikow ać. Plik opt.h w łącza plik Iw ipopts.h, który pow inniśm y dostarczyć. W szelkie zm iany param etrów należy um ieścić w pliku Iwipopts.h. Jeśli nie zdefiniujem y jak ieg o ś param etru, zostanie użyta je g o w artość dom yślna. Plik Iwipopts.h dla przykładów prezentow anych w tej 95 3.2. Biblioteka Iw IP książce znajduje się w katalogu ./exam ples/include. O piszę teraz po kolei zdefinio-i; w ane w tym pliku param etry konfigurujące bibliotekę lwIP. Idefine LWIP_PLATFORM_BYTESWAP 1 W artość 1 w łącza używ anie przez bibliotekę lw IP operacji odw racania kolejności ,;Ji bajtów LWIP_PLATFORM_HTONS i LWIP_PLATFORM__HTONL, które przedstaw iłem w p0. przednim podrozdziale. W artość 0 oznacza, że używ ane są operacje dom yślne, do - ;» starczane w raz z biblioteką. Idefine SYS_LIGHTWEIGHT_PROT 1 W artość 1 spraw ia, że funkcje biblioteczne przydzielające i zw alniające bufory chronione w ew nątrz m akram i SYS_ARC H _ P R O T E C T i SYS_ARCH_UNPROTECT. W ailnA % 0 w yłącza tę ochronę. Idefine NO SYS 1 '■ W artość 1 oznacza, że nie ma system u operacyjnego - cala aplikacja działa jak o po-ijfl. jedynczy wątek. W artość 0 oznacza, że używ am y system u operacyjnego, w którym i,i m ożna urucham iać w iele w ątków lub procesów. Idefine LWIPJJETCONN idefine LWIP__SOCK£T 0 0 Pow yższe ustaw ienia w yłączają interfejsy sekw encyjny i gniazd, pozostaw iając tyl- i ko podstaw ow y interfejs surowy. idefine LWIP_STATS 0 W artość 0 w yłącza zbieranie statystyk, co przyspiesza działanie stosu. U stawienie ,4 w artości 1 um ożliw ia zbieranie statystyk. W yśw ietlanie statystyk w ym aga zaim ple­ m entow ania, w spom nianego w poprzednim podrozdziale, m akra LWIP_PLATFORM DIAG. Statystyki te są niew ątpliw ie bardzo użyteczne dla program istów chcących rozw ijać bibliotekę lwIP, ale ich interpretacja w ym aga głębokiego w niknięcia w tekst źródłowy. ''tw idefine MEM_LIBC_MALLOC 1 W artość 1 spraw ia, że biblioteka lw IP używ a sterty i funkcji zarządzających pa­ m ięcią na stercie dostarczanych przez standardow ą bibliotekę C, czyli funkcji lo c , f r e e , c a l l o c i r e a l l o c . U staw ienie w artości 0 pow oduje, że biblioteka używa sw ojej w ew nętrznej sterty i w łasnego m echanizm u alokacji pam ięci. T rzeba wted\ zdefiniow ać rozm iar M EM_SIZE tej w ew nętrznej sterty. idefine MEM_SIZE (0 * 102-1) Jeśli aplikacja w ysyła dużo danych, które w ym agają kopiow ania, sterta ta pow inna V być duża. K opiow anie jest potrzebne, jeśli aplikacja przekazuje dane do w ysiania ■ w buforze i używ a ponow nie tego bufora, zanim dane zostaną faktycznie wysiane. Sterta w ew nętrzna je s t alokow ana w sekcji ,bss. Jeśli staia M E M _LIBC_MALLOC ma w artość I , sterta w ew nętrzna nie je s t alokow ana. {(define idefine idefine idefine mem_free mem_calloc mem_malloc mem_realloc protected_free prot:ected_calloc protected_malloc protected_realloc B iblioteka lw IP nie w yw ołuje bezpośrednio funkcji zarządzających stertą. W szystkie w yw ołania realizuje poprzez identyfikatory poprzedzone prefiksem mera_. D zięki tem u pow yższe definicje um ożliw iają użycie chronionych w ersji tych funkcji, które przedstaw iłem w poprzednim podrozdziale. idefine MEM_ALIGNMENT -I Pow yższa stała definiuje w yrów nyw anie struktur alokow anych w pam ięci. Różni się od opisanego w poprzednim podrozdziale m akra A L I G N -l tym , że tam to m akro służy do w yrów nyw ania w czasie kom pilacji, a staia MEM_ALIGNMENT je s t używ ana w czasie w ykonyw ania program u. K olejne stale definiują rozm iary w ew nętrznych struktur biblioteki i m ają istotny w pływ na zajętość RAM . Stale te zostały dobrane do prezentow anych w tej książce przykładów . Inne aplikacje będą z pew nością w ym agały dopasow ania tych w arto­ ści. Z naczenie poszczególnych struktur będzie się stopniow o w yjaśniać w m iarę poznaw ania kolejnych przykładów użycia biblioteki lwIP. Idefine PBUF_P00L_SIZE 16 D efiniuje liczbę buforów puli zarządzanej przez bibliotekę lwIP. Z puli tej aloko­ w ane są m iędzy innym i bufory, w których um ieszczane są odbierane ram ki ethernetowe. Idefine PBUF_POOL_BUFSIZE 152-1 D efiniuje rozm iar pojedynczego bufora w puli. R ozm iar ten jest dobrany tak, aby w buforze zm ieściła się cala ram ka ethernetow a, która bez pream buły, ale z uw zględ­ nieniem sekw encji kontrolnej, m oże m ieć m aksym alnie długość 1518 bajtów. N a przyszłość uw zględniam y też dodatkow e 4 bajty na znacznik V LA N . R ozm iar bu­ fora w yrów nujem y do w ielokrotności 4 bajtów. Idefine MEMP_NUM_PBUF 16 D efiniuje liczbę struktur typu p b u f, które są alokow ane jak o PBUF_REF lub PBUF_ ROM, patrz rozdział 3.2.5. Struktury te opisują m iędzy innym i dane um ieszczone w pam ięci stałej, czyli RO M lub Flash. Jeśli aplikacja w ysyła dużo danych bez­ pośrednio z pam ięci stałej, bez ich kopiow ania do R A M , to liczba tych struktur pow inna być duża. (define MEMP_NUM_UDP_PCB 5 D efiniuje liczbę jednocześnie otw artych deskryplorów U D R L iczba ta determ inuje ilość sym ultanicznie prow adzonych kom unikacji za pom ocą U D P i m usi uw zględ­ niać deskryptory używ ane przez D H C P i D NS. D eskryptory U D P są potrzebne tyl­ ko wtedy, gdy używ a się U D P lub protokołów korzystających z UDP. Idefine MEMP_NUM_TCP_PCB 2 D efiniuje liczbę jednocześnie otw artych połączeń TCP. Jeśli T C P nie je s t używany, m ożna zrezygnow ać z tych struktur. Idefine MEMP_NUM_TCP_PCB_LISTEN 3 D efiniuje rozm iar kolejki połączeń T C P oczekujących na otw arcie. K olejka jest potrzebna w aplikacji działającej ja k o serw er TCP. N ie je st natom iast potrzebna w aplikacji działającej ja k o klient. 96 — łdefine MEMP_NUM_TCP_SEG 3. Stos TCP/a• ' . i; 8 D ane przesyłane za pom ocą T C P są dzielone na segm enty, które są przesyłanej w datagram ach IP. Stała ta definiuje liczbę jednocześnie kolejkow anych segmentów' ,4i TCP. Idefine MEMP_NUM_REASSDATA 4 O dbierane datagram y IP m ogą przychodzić pofragm entow ane. Stała ta definiuje'^; liczbę jed no cześn ie kolejkow anych datagram ów IP (całych datagram ów , a nie frag-!-||. m entów ) czekających na złożenie. K olejne definicje ustalają szczegółow e opcje dla poszczególnych protokołów'.;^. W iększość z nich nie w pływ a na zajętość RA M lub w pływ a w niew ielkim stopniuj;.*, ale m a istotne znaczenie dla d ziałania biblioteki lwIP. Sdefine ARP QUEUEING 1 W ' '■'■‘•i W łącza kolejkow anie datagram ów IP, które pow inny zostać w ysiane, ale oczekują"/; na przetłum aczenie za pom ocą A R P adresu IP na adres ethernetow y. V 97 3.2. Biblioteko lwIP Jeśli stała ta ma w artość 0, odebrane datagram y IP, których nagłów ek m a dodatko­ we opcje, nie będą przetw arzane. Jeśli stała ta ma w artość 1, w szystkie odebrane datagram y IP będą przetw arzane, ale dodatkow e opcje um ieszczone w nagłów ku datagram u IP będą ignorow ane. B iblioteka lw IP nie obsługuje dodatkow ych opcji w nagłów kach IP. łdefine IP_REASSEMBLY 1 W artość 1 w łącza składanie odbieranych pofragm entow anych datagram ów 1P. W artość 0 pow oduje, że przetw arzane będą tylko niepofragm entow ane datagram y, a w szystkie odebrane fragm enty datagram ów IP będą ignorowane. łdefine IP_ERAG 1 W artość 1 w łącza fragm entow anie w ysyłanych datagram ów IP, jeśli ich rozm iar przekracza M TU sieci. W artość 0 pow oduje, że próba w ysiania datagram u dłuższe­ go niż M TU się nie pow iedzie. łdefine IP_REASS_MAXAGE 3 D efiniuje m aksym alną liczbę je d n o cz eśn ie kolejkow anych datagram ów IP, czeka- -le­ jących na przetłum aczenie adresu za pom ocą ARP. O pcja ta w ym aga, aby stała .‘iy A R P _ Q UEUEING m iała w artość 1. T-." D efiniuje m aksym alny czas oczekiw ania na otrzym anie w szystkich fragm entów da­ tagram u IP. Jeśli w tym czasie w szystkie fragm enty nie zostaną odebrane, to cały datagram je s t porzucany. C zas je s t liczony w w ielokrotnościach kw antu czasu okre­ ślonego za pom ocą stałej IP_TMR_INTERVAL. D om yślnie stała ta definiuje interw al 1000 ms. łdefine ARP_TABLE_SIZE łdefine IP_REASS_MAX_PBUE;S łdefine MEMP_NUM_ARP_QUEUE 3 .ifc 4 10 D efiniuje rozm iar pam ięci podręcznej ARP. W artość ta pow inna być rów na przewi dyw anej m aksym alnej liczbie w ęzłów , do których w danej podsieci będą bezpośred-, d nio w ysyłane datagram y IP, z uw zględnieniem rutera. i,.’ D efiniuje m aksym alną liczbę buforów odbiorczych z czekającym i na złożenie frag­ m entam i datagram ów IP. W artość ta m usi być m niejsza niż PBUF_P00L_SIZE, żeby stos lw IP byl w stanie odbierać kolejne datagram y i się nie zablokow ał. łdefine ETHARP_TRUST_IP_MAC łdefine IP_DEFAULT_TTL 1 W artość 1 oznacza, że pam ięć podręczna A R P będzie uaktualniana na podstawie inform acji z nagłów ków w odbieranych ram kach ethernetow ych. W artość 0 blokuje d takie uaktualnianie - w tym przypadku pam ięć podręczna A R P m oże być m o d y f ik o - . w ana tylko po w ysianiu prośby A R P i odebraniu na nią odpow iedzi. Z ablokow anie' tej opcji w prow adza dodatkow e, niew ielkie opóźnienia w tłum aczeniu adresów, a]e też w prow adza pew ne zabezpieczenie przed zatruw aniem pam ięci podręcznej ARP (ang. spoofing). Jeśli w szystkie w ęzły w podsieci są zaufane, m ożem y śm iało uaktyw nić tę opcję. łdefine ETHARP_SUPPORT_VLAN 0 W artość 1 uaktyw nia odbieranie ram ek ethernetow ych V LA N . Z nacznik V LA N ra­ m ek, które m ają być odbierane, należy zdefiniow ać ja k o stalą ETHARP_VLAN_CHECK. Jeśli stała ta nie je s t zdefiniow ana, to odbierane są ram ki ze w szystkim i znaczni- , kam i. łdefine IP_FORWARD 0 W artość 1 uaktyw nia przekazyw anie datagram ów IP, co oznacza, że w ęzeł mo/e być ruterem . Jeśli w ęzeł m a jed e n interfejs sieciow y, raczej nie będzie ruterem i n a-': leży tej stałej przypisać w artość 0. łdefine IP OPTIONS ALLOWED 1 64 D efiniuje dom yślną w artość czasu życia (TTL, ang. tim e to live) um ieszczaną w na­ głów kach w ysyłanych datagram ów IP. łdefine łdefine łdefine łdefine LWIP_ICMP ICMPJTTL LWIP_BROADCAST_PING LWIP_MULTICAST_PING 1 64 0 0 Pierw sza z pow yższych opcji w łącza obsługę ICMP. D ruga ustaw ia w artość czasu życia um ieszczaną w nagłów kach datagram ów IP, w których są w ysyłane kom u­ nikaty ICMP. D w ie ostatnie opcje w yłączają odpow iadanie na kom unikaty ECH O (używ ane przez program p in g ) w ysyłane na adres rozgłoszeniow y (ang. broadcast) i grupow y (ang. m ulticast). Ze w zględu na bezpieczeństw o w ęzeł nie pow inien od­ pow iadać na takie kom unikaty, gdyż m ogą one być próbą ataku typu odm ow a usłu­ gi (D oS, ang. denial o f service). O pcje te m ożem y uaktyw nić w zam kniętej sieci, w której w szystkie w ęzły są zaufane, ijdefine LWIP_RAW 0 W artość 1 tej stałej w łącza m ożliw ość bezpośredniego korzystania z w arstwy sie­ ciow ej. M ożem y być w tedy pow iadam iani o odebraniu datagram u IP i możem y w ysyłać w łasne datagram y IP. O pcja ta je s t użyteczna, gdy chcem y rozszerzyć bi­ bliotekę lw IP o obsługę dodatkow ych opcji 1P lub zaim plem entow ać w łasny proto­ kół transportow y. Jeśli używ am y standardow ych protokołów transportow ych T C P 3. Slos TCP/IpL 98 i UDP, nie potrzebujem y bezpośredniego dostępu do w arstw y sieciow ej i dlatego y przypisujem y tej staiej w artość 0. łdefine LWIPJJDP »define UDP_TTL 1 64 •■ ■ 'jj Pierw sza z pow yższych staiych w łącza obsługę UDP. D ruga ustaw ia w artość czasu$ życia um ieszczaną w nagłów kach datagram ów 1P, w których są w ysyłane datagra-..^ my UDP. łdefine LWIPJTCP łdefine TCP_TTL 1 64 Pierw sza z pow yższych stałych w łącza obsługę TCP. D ruga ustaw ia w artość czasu ’■ życia um ieszczaną w nagłów kach datagram ów IP, w których są w ysyłane segmenty ... TCP. łdefine TCP_MSS (1500 - 40) D efiniuje m aksym alny rozm iar segm entu TCP, tak aby w ysyłane datagram y IP za-':/; w ierające segm enty T C P nie m usiały być fragm entow ane. W artość tej stałej powin­ na być rów na w artości M TU sieci pom niejszonej o sum ę rozm iarów nagłów ków ll> .. i TCP. M TU E thernetu w ynosi zw ykle 1500 oktetów. N agłów ki IP i T C P g e n e ro -/ w ane przez bibliotekę lw IP m ają po 20 oktetów - porów naj w pliku pbuf.h definicje^ stałych PBUF_IP_HLEN i PBUF_TRANSPORT_HLEN, które określają odpow iednio długo-"” ści tych nagłów ków i obie m ają w artość 20. łdefine TCP_WND (4‘TCP_MSS) D efiniuje m aksym alny rozm iar okna odbiorczego JC P . O kno odbiorcze m usi po­ m ieścić co najm niej dw a segm enty danych. O kno odbiorcze je st w irtualnym buforem służącym do kontroli przepływ u. R ozm iar okna w yznacza ilość danych, które X' w ęzeł je s t skłonny przyjąć. W ęzeł odbierający inform uje w ęzeł w ysyłający o swi im aktualnym rozm iarze okna. W ysłanie zerow ego rozm iaru okna oznacza piośbę 0 w strzym anie transm isji, gdyż w ęzeł odbierający nie przetw orzył jeszcze dotych- f ; czas otrzym anych danych. P óźniejsze zaproponow anie niezerow ego rozm iaru oznacza prośbę o w znow ienie transm isji. W bibliotece lw IP okno odbiorcze nie jest / alokow ane ja k o ciągły obszar R A M . T w orzą go bufory alokow ane z puli ipołącząne w listę. D latego w artość tej stałej nie w pływ a istotnie na zajętość pam ięci. łdefine TCP_QUEUE_0OSEQ 0 D atagram y IP m ogą być dostarczane w innej kolejności niż zostały w ysłane. Wartość 1 tej stałej spraw ia, że stos kolejkuje segm enty TCP, które zostały odebrane w złej kolejności. W artość 0 w yłącza to kolejkow anie. D ostarczanie datagram ów w zmie­ nionej kolejności w praktyce zdarza się bardzo rzadko, a w sieciach lokalnych praw ie nigdy. System y w budow ane m ają m ało pam ięci, a kolejkow anie blokuje bufory, , dlatego przypisujem y tej stałej w artość 0. łdefine TCP_SND_BUF (4 * TCP_MSS) D efiniuje rozm iar w irtualnego bu fo ra nadaw czego TCP. B ufor ten pełni lunkcję podobną do okna odbiorczego, ale po stronie nadaw czej. Sieć nie działa nieskoń­ czenie szybko. Ponadto odbiorca m oże w strzym ać nadaw cę, w ysyłając mu zerowy ; rozm iar okna. B ufor nadaw czy służy do przechow yw ania danych czekających na ■ w ysłanie. A plikacja przed w ysłaniem kolejnej porcji danych pow inna sprawdzić. ; 3.2. Biblioteka lwIP 99 czy jest dostatecznie dużo m iejsca w buforze nadaw czym . Jeśli nie ma, próba wy­ słania zakończy się niepow odzeniem - w yw ołanie funkcji w ysyłającej zakończy się błędem . O kno nadaw cze nie je s t alokow ane ja k o ciągły obszar pam ięci. Tw orzą go połączone w listę bufory z ram kam i do w ysłania. D latego w artość tej stałej nie w pływ a istotnie na zajętość pam ięci. łdefine TCP__SND_QUEUELEN (4 * TCP_SND_BUF / TCP_MSS) D efiniuje m aksym alną liczbę fizycznych buforów , które m ogą tw orzyć bufor nadaw czy. D la praw idłow ego działania biblioteki param etr ten m usi m ieć w artość co najm niej 2*TCP_SND_BUF/TCP_MSS. W artość lego param etru nie w pływ a istotnie na zajętość pam ięci, łdefine LWIP_DHCP 1 W artość 1 w łącza kom pilow anie klienta DHCP, który um ożliw ia uzyskanie adresu IP, m aski podsieci, adresu rutera i adresu serw era nazw. W artość 0 w yłącza m ożli­ w ość konfigurow ania za pom ocą DHCP. łdefine łdefine łdefine łdefine LWIP_DNS DNS_TABLE_SI2E DNS_MAX_NAME_LENGTH DNS_MAX_SERVERS 1 3 48 2 Pierw sza z pow yższych stałych w łącza kom pilow anie klienta D N S. K olejne defi­ niują rozm iary struktur danych używ anych przez tego klienta. Stała DNS_TABLE_ SI ZE określa, ile odw zorow ań nazw dom enow ych na adresy IP będzie pam iętanych. Stała DNS_MAX_NAME_LENGTH definiuje m aksym alną długość nazw, które będą obsłu­ giw ane. Stała DNS_MAX_SERVERS definiuje m aksym alną liczbę serwerów , które są do dyspozycji klienta D N S. O pcje te m ają w pływ na zajętość RAM . łdefine DNS_SERVER_ADDRESS inet_addr("194.204.152.34") K lient D N S potrzebuje adresu serw era D N S. A dresy serw erów D NS m ożna konfi­ gurow ać na kilka sposobów : - Jeśli nie podam y żadnego adresu, to w pliku dns.c zdefiniow any je s t adres d o ­ m yślny 208.67.222.222. Plik dns.c je s t w katalogu Jlw ip-1,3.2/src/core. - A dres dom yślny m ożna podać, przedefiniując stałą DNS_SERVER_ADDRESS. - A dres m ożna uzyskać za pom ocą DHCP. - A dres m ożna skonfigurow ać za pom ocą funkcji d n s _ s e ts e r v e r . U żyta w yżej funkcja i n e t ad d r je s t przestarzała (ang. obsolete), ale je s t nadal uży­ w ana w pliku dns.c. W now ych projektach należy raczej używ ać funkcji in e t_ a to n . Jeśli nie chcem y korzystać z D N S łub nie m a dostępu do serw era D N S, m ożna skonfigurow ać listę stałych odw zorow ań nazw na adresy IP - patrz opis stałej DNS_ L0CAL_H0STLI ST w pliku opt.h. O statnia grupa opcji, które m ożem y skonfigurow ać, dotyczy obliczania sum kontrol­ nych. Jak być m oże pam iętam y, sekw encja kontrolna w ram ce elhernelow ej jest w y­ liczana i spraw dzana sprzętow o przez układ M A C m ikrokontrolera. M ikrokontroler S T M 32F107 m oże też sprzętow o w yliczać i spraw dzać sum y kontrolne w nagłów ­ kach protokołów IP, TCP, U D P i ICMP. Jest to kusząca propozycja, gdyż realizacja sprzętow a jest zaw sze szybsza od im plem entacji program ow ej. N iestety w yliczanie sum kontrolnych protokołów intersieci przez sprzęt łam ie fundam entalną zasadę po­ działu na warstwy. Popraw na im plem entacja sum kontrolnych w ym aga uw zględnie­ nia w szystkich opcji protokołu, co w praktyce je st niem ożliw e, gdyż oznacza ko­ nieczność zaim plem entow ania całości protokołu. Jak należało się tego spodziewać, im plem entacja sum kontrolnych w ST M 32F107 jest niepełna. N ie uw zględnia fragm entacji IP. Jest też praw dopodobne, że nie poradzi sobie z dodatkow ym i opcjami" IP. Ponadto w bibliotece lw IP nie przew idziano prostego sposobu przekazania stoso­ wi inform acji o stw ierdzeniu przez sprzęt błędnej sum y kontrolnej. W łączenie przez sprzęt w yliczania sum kontrolnych IC M P w ym aga dodatkow o m odyfikacji tekstu źródłow ego biblioteki lwIP, co m oże pow odow ać problem y z kom patybilnością apli kacji z przyszłym i w ersjam i tej biblioteki. W szystko to przem aw ia przeciw w łącza­ niu sprzętow ych sum kontrolnych. W poniższych definicjach w artość 0 oznacza uak­ tyw nienie realizacji sprzętow ej, a 1 oznacza w łączenie im plem entacji programowej. łdefine CHECKSUM_GEN_IP znajduje się w katalogu ./exam ples/include. O pisana w poprzednim podrozdziale konfiguracja biblioteki lw IP w ym aga skom pilow ania tylko plików, których nazwy są zam ieszczone w tabeli 3.3. 3.2.4. 0 Tab. 3.4. W artości zwracane przez funkcje biblioteki lwIP Stała 1 Sum a kontrolna odbieranych datagram ów IP je st spraw dzana program ow o, gdyż ; | m ogą pojaw ić się nagłów ki IP z dodatkow ym i opcjam i. łdefine łdefine łdefine łdefine CHECKSUM_GEN_UDP CHECKSUM_GEN_TCP CHECKSUM_CHECK_UDP CHECKSUM_CHECK_TCP 1 1 1 1 Sum y kontrolne U D P i T C P są generow ane i spraw dzane program ow o. 3.2.3. Kody błędów F unkcje biblioteki lw IP i funkcje w spółpracujące z nią zw racają w artość typu e r r _ t , sygnalizującą popraw ne zakończenie lub kod błędu, gdy w ykonanie funkcji zakoń­ czy się niepow odzeniem . Stale reprezentujące w artości typu e r r _ t są zdefiniow ane w pliku err.h. Znaczenie poszczególnych stałych jest opisane w tabeli 3.4. Stała E R R _ 0 K ma w artość 0 i oznacza popraw ne zakończenie funkcji. Pozostałe stale mają w artości ujem ne i oznaczają w ystąpienie błędu. W przykładach stosuję podobne podejście. Jeśli funkcja m a poinform ow ać, że zakończyła się popraw nie, to zwraca zero. G dy w ystąpił błąd, funkcja zw raca w artość ujem ną. Sum a kontrolna w ysyłanych datagram ów IP je st generow ana sprzętow o. Tę opcję"’' m ożem y w łączyć, poniew aż lw IP praw dopodobnie nigdy nie w ygeneruje nagłówka:; IP z dodatkow ym i opcjam i, łdefine CHECKSUM_CHECK_IP 101 3.2. Biblioteka lwIP 3. Stos TCP/IP 100 Opis ERR OK Poprawne zakończenie ERR MEM Brak pamięci ERR BUF Problem z buforem ERR TIMEOUT Przekroczony czas ERR RTE Problem z trasowaniem ERR ABRT Połączenie przerwane ERR RST Połączenie skasowane ERR CLSD Połączenie zamknięte ERR CONN Połączenie nieotwarte ERR VAL Błędna wartość Kompilowanie - plik Iiblw ip4.a ERR ARG Problem z argumentem B ibliotekę lw IP należy skom pilow ać, posługując się w skazów kam i podanymi w rozdziale 1.4. D alej zakładam , że skom pilow ana biblioteka została um ieszczo­ na w pliku liblw ip4.a. N azw y katalogów , które zaw ierają pliki biblioteki lwIP, s ą , zebrane w tabeli 3.2. Ponadto potrzebny je s t plik nagłów kow y Iw ipopts.h, który ERR USE Adres lub port zajęty ERR IF Niskopoziomowy błąd interfejsu sieciowego Tab. 3.2. Katalogi z plikami biblioteki lwIP Źródłowe Jlw ip-1.3.2/src/api Jlw ip-1.3.2/srclcore Jlw ip-1.3.2/src/carelipv4 J lw ip -1.3.2/src/core/snm p Jlw ip-1.3.2/src/netif 3.2.5. Nagłówkowe ERR ISCONN Połączenie już zestawione ERR INPROGRESS Operacja w trakcie Struktura pbuf B iblioteka lw IP przechow uje pakiety sieciow e w buforach, które są w skazyw ane za pom ocą struktury typu pbuf zdefiniow anej w pliku pbuf.h. Zrozum ienie zasad posługiw ania się buforam i je st bardzo istotne. B ez tego trudno jest pisać popraw ne i efektyw ne aplikacje używ ające biblioteki lwIP. Struktura typu p b u f opisuje poje­ dynczy bufor. Jlw ip-1,3.2/srclinclude/ipv4/lwip Jlw ip -1.3.2/srclincludellwip Jlw ip-1.3.2/srclinclude/netif Jexampleslinclude/arch Tab. 3.3. Pliki źródłowe biblioteki lwIP Inicjow anie 1 obsługa pam ięci Jlw ip- 1.3.2/src/core/inlt.c . /Iw ip -1.3.2/src/core/m em . c Jlw ip- 1.3.2lsrclcorelm em p. c Jlwip- 1.3.2lsrc/core/pbuf.c A R P IIP Jlw ip-1.3.2/src/netifletharp.c Jlwip- 1.3.2/src/core/neti!.c ./Iw ip -1.3.2lsrc/core/ipv4/icm p. c J lw ip -1.3.2/src/core/ipv4/inet. c Jlw ip-1.3.2/src/corelipv4/inet_chksum .c Jlw ip -1.3.2/srclcorelipv4/ip. c Jlwip-1.3.2/src/corelipv4/ip_addr.c Jlw ip- 1.3.2/src/corelipv4/lp Irag.c W arstw y transportowa 1 aplikacji! Jlw ip -1.3.2/srclcore/dhcp. c Jlwip- 1.3.2/srclcore/dns.c Jlw ip-1.3.2/src/core/lcp.c Jlwip- 1.3.2/src/c o re ltcp jn .c .Ilw ip -1.3.2/src/co re /tcp jiu t. c Jlwlp-1.3.2/src/core/udp.c struct pbuf ( struct pbuf void uI6 t ul6_t uB t u8_t ul6 t . ); *next; *payload; tot len; len; type; flags; ref; 102 3.2. Biblioteka lwiP 3. Stos TCP/ip tokołów. D zięki tem u dokładanie tych nagłów ków nie w ym aga polem dodatkow ej alokacji pam ięci czy kopiow ania zaw artości bufora. A rgum ent ten m oże przyjm o­ wać następujące w artości: Składow a p ay lo a d je s t w skaźnikiem do bufora przechow ującego dane. B ufor może, być zarów no w pam ięci operacyjnej (R A M ), ja k i w pam ięci staiej (R O M , Flash), W skaźnik n e x t łączy struktury w listę. W skaźnik ten w ostatniej strukturze na li: scic m a w artość NULL. L ista struktur p bu f um ożliw ia podział pakietu na fragmenty, i um ieszczenie poszczególnych fragm entów w kolejnych buforach. Taka lista na-: żyw a się w dokum entacji biblioteki lw IP łańcuchem buforów (ang. buffer chain); Z a pom ocą w skaźnika n e x t pakiety m ogą też być łączone w kolejkę (ang. packetqueue). Z atem kolejka pakietów składa się z jed n eg o lub w iększej liczby pakietów,' z których każdy je st um ieszczony w łańcuchu buforów. Łańcuch m oże zawierać'} jeden lub w iele buforów. K oniec łańcucha m ożna rozpoznać za pom ocą składowych -; t o t _ l e n i len . Składow a l e n zaw iera długość bufora. S kładow a to t _ l e n zawieracałkow itą długość pakietu, czyli sum ę długości w szystkich buforów w łańcuchu., O statnia struktura w łańcuchu m a rów ne w artości tych składow ych i je s t to je d y n v popraw ny sposób rozpoznaw ania k ońca łańcucha buforów. Ponadto dla łańcucha buforów obow iązuje niezm iennik: - Funkcja p b u f _ r e a l l o c zm niejsza rozm iar łańcucha buforów w skazyw anego przez p do podanego rozm iaru new le n . Z ależnie od podanej nowej długości łańcuch m oże zostać skrócony, a niepotrzebne bufory m ogą być zw olnione. W brew nazw ie, funkcja ta nie m oże pow iększyć rozm iaru bufora. Jeśli bufor je s t typu PBUF REF łub PBUF_R0M, m odyfikow ane są tylko składow e t o t _ l e n i le n struktury typu pbuf. Składow a ty p e oznacza sposób alokacji bufora i m oże przyjm ow ać następujące; w artości: - PBUF RAM - bufor je s t alokow any w jed n y m kaw ałku na stercie; PBUF_R0M - struktura opisuje dane tylko do odczytu, bufor je s t w pam ięci stałej; A; PBUF_REF - struktura je s t referencją do innej struktury typu pbuf, żaden bufor nic ij| je st alokow any; ( PBUF_P00L - bufor je s t alokow any z puli buforów biblioteki lw iP o stałym roz- ■ m iarze; jeśli żądam y bufora o rozm iarze w iększym niż PBUF_P00L_SIZE, to jest-'(j!> przydzielany łańcuch buforów zaw ierający w iele buforów. .!;) Składow a f l a g s je s t przeznaczona do przechow yw ania znaczników , ale w ydaje się, ■ że nie je s t używ ana przez bibliotekę lwiP. Składow a r e f je s t licznikiem referencji, zaw iera liczbę w skaźników odw ołujących się do tej struktury. M oże to być wskażnik n e x t w innej strukturze typu p b u f lub ja k iś inny w skaźnik w ew nątrz biblioteki .“ lw iP lub aplikacji. W pliku p hu f.c zaim plem entow ane są funkcje obsługujące bufory. N ajw ażniejsze z nich opisuję niżej. void pbuf_ref(struct pbuf *p ) : Funkcja p b u f _ r e f zw iększa licznik referencji w podanej strukturze typu pbuf. u8_t pbuf_£ree(struct pbuf *p); Funkcja p b u f f r e e zm niejsza licznik referencji i jeśli licznik ten osiągnie zero, zw alnia nieużyw ane bufory i struktury je opisujące. D la łańcucha buforów operacja ta je st pow tarzana dla w szystkich struktur na liście, aż do natrafienia na pierw szą, która po zm niejszeniu nadal ma licznik referencji w iększy od zera. Zatem , jeśli w szystkie liczniki referencji w łańcuchu m ają w artość jed en , cały łańcuch je st zw al­ niany. F unkcja ta zw raca liczbę zw olnionych struktur typu pbuf. u8_t pbuf_clen(struct pbuf *p); struct pbuf * pbuf_alloc{pbuf_layer layer, ul6_t length, pbuf_type type); Funkcja p bu f a l l o c alokuje łańcuch buforów. Z w raca w skaźnik do pierwszej struktury typu pbuf w łańcuchu łub w artość NULL, gdy alokacja się nie powiodła. A rgum ent ty p e ma to sam o znaczenie, co składow a o lej sam ej nazw ie w struktu­ rze typu pbuf i określa sposób alokacji buforów. A rgum ent l e n g t h określa żądanj rozm iar bufora. Jeśli żądam y alokacji z puli buforów biblioteki lw iP i rozm iar teri jest w iększy niż rozm iar pojedynczego bufora w puli, to przydzielony będzie łań­ cuch składający się z odpow iedniej liczby buforów. A rgum ent l a y e r określa, ile dodatkow ego m iejsca na początku bufora m a być zarezerw ow ane na nagłów ki pro­ PBUF_TRANSPORT - alokujem y bufor na dane protokołu transportow ego (T C P lub U D P); PBUF IP - alokujem y bufor na pole danych datagram u 1P; PBUF_LINK - alokujem y bufor na pole danych protokołu dostępu do sieci, np. pole danych ram ki ethernetow ej; PBUF RAW - alokujem y bufor na surow e dane, np. kom pletną ram kę ethernetow ą. void pbuf_realloc(struct pbuf *p, u!6_t new_len); p->tot_len == p->len + (p->tot_len != p->len ? p->next->tot_len ; 0) - 103 Funkcja p b u f c le n zw raca liczbę struktur na liście, począw szy od w skaźnika p, aż do napotkania w skaźnika n e x t zaw ierającego NULL. . err_t pbuf_take(struct pbuf *buf, const void *dataptr, u!6 t len); F unkcja p b u f _ t a k e kopiuje le n bajtów danych w skazyw anych przez d a t a p t r do łańcucha buforów w skazyw anego przez b uf. Z w raca ERR_0K, gdy kopiow anie po­ w iodło się, a ERR ARG, gdy jeden z podanych w skaźników jest zerow y lub w łańcu­ chu buforów nie m a dostatecznie dużo m iejsca. 'I vj 3. Stos TCP/ft* 104 F unkcja p b u f _ c o p y j ? a r t i a l kopiuje dane z łańcucha buforów b u f do bufora dat a p t r . K opiow anych je st le n bajtów, ale nie w ięcej niż b u f - > t o t _ l e n . A rgum ent'! o f f s e t je s t przesunięciem , od którego dane są kopiow ane z łańcucha buforów,tj Funkcja ta zw raca liczbę skopiow anych bajtów lub zero, gdy w ystąpił błąd. Struktura n e tif B iblioteka lw IP przechow uje konfigurację interfejsu sieciow ego w strukturze typu n e t i f , która jest zdefiniow ana w pliku netif. h. Struktura ta m a w iele pól. Niektóre $ pola są kom pilow ane w arunkow o, zależnie od ustaw ień w plikach opt.h i lwiopts.h]$B Poglądow a definicja tej struktury, ale zupełnie w ystarczająca do zrozum ienia /a s.i- $ dy działania sterow nika interfejsu sieciow ego, je s t następująca: struct netif { struct netif *next; struct ip_addr ip_addr; struct ip_addr netmask; struct ip_addr gw; err_t {* input)(struct pbuf *p, struct netif *inp); err_t {* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr); err_t (* linkoutput)(struct netif *netif, struct pbuf *p); void *state; struct dhcp *dhcp; ul6_t mtu; u8_t hwaddr_len; u8_t hwaddr [NETIF_MAX__HWADDR_LEN) ; u8_t flags; char name(2); u8_t num; 105 w arstw y dostępu do sieci. D la Ethernetu biblioteka lw IP m a ju ż gotow ą funkcję odbiorczą e t h e r n e t in p u t , która jest zadeklarow ana w pliku etharp.h, a jej im ­ plem entacja znajduje się w pliku etharp.c. Funkcja e t h e r n e t _ i n p u t analizuje na­ głów ek ram ki ethernetow ej i zajm uje się obsługą ARP, dlatego w tym przypadku bufor pow inien zaw ierać ram kę ethernelow ą. Jeśli używ am y w arstw y dostępu do sieci innej niż E thernet, to jak o funkcji odbiorczej m ożna użyć funkcji ip _ i n p u t , która je s t zadeklarow ana w pliku ip.h, a jej im plem entacja znajduje się w pliku ip.c. F unkcja ip _ i n p u t oczekuje w buforze datagram u IP i w tym przypadku to sterow ­ nik interfejsu sieciow ego musi przeanalizow ać nagłów ek w arstw y dostępu do sieci, a następnie usunąć go z odebranego pakietu. ul6_t pbuf_copy_partial{struct pbuf *buf, void *dataptr, ul6_t len, ul6 t offset); 3.2.6. 3.2. Biblioteka IwiP r(* '.¿T • J"•$, v. l; B iblioteka lw IP m oże obsługiw ać w iele interfejsów sieciow ych. S truktury typu t i f opisujące kolejne interfejsy tw orzą listę. Składow a n e x t w skazuje na następną strukturę na lis'cie i je st używ ana tylko w ew nątrz biblioteki lwIP. Składow e ip__addr, netmask, gw zaw ierają odpow iednio adres IP, m askę podsieci i adres rutera. D ane te są zapisyw ane w sieciow ym porządku oktetów. Składowi te są inicjow ane w funkcji n e t i f _ a d d , której opis znajduje się w dalszej c rozdziału. Ponadto są też m odyfikow ane przez klienta DHCP, jeśli zostanie urucho- * miony. Składow a in p u t zaw iera adres funkcji odbiorczej, którą sterow nik interfejsu sie­ ciow ego w yw ołuje, aby przekazać odebrany pakiet do stosu TCP/IP. Składow a l je st konfigurow ana za pom ocą funkcji n e t i f _ a d d . Pierw szym argum entem funkcji-'A* odbiorczej je s t w skaźnik do struktury typu pbuf, która opisuje b u for zawiei odebrany pakiet. D rugim argum entem je s t w skaźnik do struktury typu n e t i f , o p i­ sującej interfejs sieciow y, który odebrał pakiet. Funkcja odbiorcza zależy od użył -•pili ■¿c Składow ej o u t p u t należy podczas inicjow ania sterow nika przypisać adres funk­ cji nadaw czej, którą stos TCP/1P pow inien w yw ołać, aby w ysiać datagram IP. Dla E thernetu należy użyć funkcji e t h a r p _ o u t p u t , która obsługuje A R P i je st częścią biblioteki lwIP. F unkcja ta je s t zadeklarow ana w pliku etharp.h, a jej im plem entacja je st w pliku etharp.c. Pierw szym argum entem funkcji nadaw czej je s t w skaźnik do struktury typu n e t i f , opisującej interfejs sieciow y, przez który ma być wystany datagram . D rugim argum entem jest w skaźnik do struktury typu pbuf, opisującej łańcuch buforów z datagram em IP do w ysiania. Trzeci argum ent jest w skaźnikiem do .struktury zaw ierającej adres IP, na który należy w ysiać datagram . Pam iętajm y, że datagram często je s t w ysyłany na inny adres niż ten um ieszczony w jeg o nagłów ku, np. na adres rutera. I Składow ej l i n k o u t p u t należy podczas inicjow ania sterow nika interfejsu sieciow e­ go przypisać adres niskopoziom ow ej funkcji nadaw czej, która pow inna być w y­ w ołana w celu w ysiania pakietu przez ten interfejs. Ta niskopoziom ow a funkcja m usi być zaim plem entow ana w sterow niku i zw ykle nazyw a się l o w _ le v e l _ o u tp ut. P ierw szym jej argum entem je st w skaźnik do struktury typu n e t i f , opisującej interfejs sieciow y, przez który m a być w ysłany pakiet. D rugim argum entem je st w skaźnik do struktury typu pbuf, opisującej łańcuch buforów zaw ierający w ysyłany pakiet, który m usi zaw ierać nagłów ki w szystkich w arstw kom unikacji. Funkcja ta nie pow inna m odyfikow ać w ysyłanych danych. Składow a s t a t e je s t przew idziana do w ykorzystania przez sterow nik interfejsu sie­ ciow ego. B iblioteka lw IP je j nie czyta i nie m odyfikuje. W tej składow ej m ożna przechow yw ać adres struktury zaw ierającej pryw atne dane sterow nika. Składow a dhcp zaw iera adres struktury w ykorzystyw anej przez klienta D H C P zw ią­ zanego z interfejsem sieciow ym . Składow a mtu zaw iera M T U sieci. Składow a hw addr_len zaw iera długość w okte­ tach adresu sprzętow ego. Składow a hwaddr zaw iera adres sprzętow y. Stała NETIF_ MAX_HWADDR_LEN m a w artość 6. Składow e te m uszą być ustaw ione podczas inicjo­ w ania sterow nika interfejsu sieciow ego. Składow a f l a g s jest zbiorem jednobitow ych znaczników opisujących stan interfejsu sieciow ego. Z naczniki zdefiniow ano w pliku n e tif h. Są one zam ieszczone w ta b e ­ li 3.5. Z naczniki należy m odyfikow ać za pom ocą operatora alternatyw y logicznej, gdyż biblioteka lw IP rów nież m odyfikuje niektóre z nich. 107 3.3. DMA Jeśli ram ka nie m ieści się w pojedynczym buforze, m oże być um ieszczona w kilku kolejnych buforach, w skazyw anych przez kolejne deskryptory. W trybie pierście­ niow ym każdy deskryptor m oże w skazyw ać na dw a kolejne bufory. Tab. 3.5. Znaczniki opisujące stan interfejsu sieciowego Opis Znacznik NETIF FLAG UP W arstwa sieciowa jest aktywna - interfejs przetwarza pakiety NETIF FLAG BROADCAST Ten interfejs może wysyłać pakiety rozgloszeniowe NETIF FLAG POINTTOPOINT Jest to interfejs typu punkt-punkt NETIF FLAG DHCP Dla tego interfejsu został skonfigurowany klient DHCP NETIF FLAG LINK UP Warstwa dostępu do sieci jest aktywna NETIF FLAG ETHARP Jest to interfejs ethernetowy używający ARP NETIF FLAG IGMP Ten interfejs używa IGMP Z astosow any w m ikrokontrolerze S T M 32F 107 układ D M A nie m oże obsługiw ać jed n o cześnie obu kolejek. Jeśli w kolejce nadaw czej czekają ram ki do w ysłania i rów nocześnie są odbierane ram ki, które trzeba skopiow ać do kolejki odbiorczej, potrzebny je st arbitraż. P rzew idziano dw a w arianty arbitrażu: - Składow a name zaw iera dw uznakow ą nazw ę interfejsu sieciow ego. N azw a pozwala-1; w yszukiw ać interfejs za pom ocą funkcji n e t i f _ f i n d . O pcja ta je s t przydatna, gdy.', je s t w iele interfejsów sieciow ych. S kładow a num zaw iera num er interfejsu sieciowe- " go. Pozw ala to rozróżniać interfejsy o tej sam ej nazw ie. Składow a nura ja k dotąd nie : je s t używ ana w ew nątrz biblioteki lwiP. stosow any je s t karuzelow y algorytm szeregow ania (ang. round robin scheduling a lg o rithm ); - zaw sze preferow ana je s t kolejka odbiorcza, ram ki są kopiow ane z buforów nadaw czych do M A C tylko wtedy, gdy żadna odebrana ram ka nie czeka na sko­ piow anie do bufora odbiorczego. Tab. 3.6. Składowa s ta tu s deskryptora odbiorczego Pola DMA status Bufor Bufor 1 Deskryptor 0 Jest to pole statusu, wypełniane przez DM A po zakończeniu kopiowania. Najważniejsze bity tego pola opisane są w następnych wierszach FL 2 9 ...1 6 Całkowita długość w bajtach odebranej i skopiowanej ramki (ang. tramę length). To pole jest istotne tylko dla deskryptora, który ma wyzerowany bit e s i ustawiony bit l s ES 15 W artość 0 oznacza, że kopiowanie zakończyło się poprawnie. Wartość 1 oznacza, że w y­ stąpił błąd (ang. error sum m ary). Dokładny opis błędu zawierają inne bity pola status FS 9 Wartość 1 oznacza, że jest to pierwszy w kolejce deskryptor opisujący odebraną ramkę. Innymi słowy, ten deskryptor wskazuje na bufor zawierający pierwszy fragment ramki (ang. lirst segment) LS 8 Wartość 1 oznacza, że jest to ostatni w kolejce deskryptor opisujący odebraną ramkę. Innymi słowy, ten deskryptor wskazuje na bufor zawierający ostatni fragment ramki (ang. last segment) Tab. 3.7. Składowa controlB ufferSize deskryptora odbiorczego Polo Deskryptor 0 31 O * OWN Opis W artość 1 oznacza, że DMA jest właścicielem (ang. own) deskryptora. DMA zeruje ten bit, gdy zakończy kopiowanie odebranej ramki i wypełni bufor lub bufory wskazywane przez ten deskryptor. Program ustawia ten bit, aby zwrócić deskryptor odbiorczy układowi DMA O co Do obsługi interfejsu ethernetow ego przew idziano w m ikrokontrolerze STM 32F107 układ D M A , który używ a dw óch cyklicznych kolejek buforów. D M A kopiuje ode­ % brane przez układ M A C ram ki d o kolejki odbiorczej, gdzie czekają na obsłużenie przez aplikację. A plikacja w staw ia ram ki do kolejki nadaw czej, gdzie czekają na ł.Wf •tttt skopiow anie ich przez D M A do układu M A C . K olejki zorganizow ane są za pom o­ i f cą deskryptorów D M A . D eskryptor m a dw ie składow e, które przechow ują adresy. K olejka buforów m oże tw orzyć łańcuch (ang. chain), ja k w idać to na ry s u n k u 3.1. Jeden z adresów jest w tedy używ any do w skazania bufora w pam ięci, a drugi w ska­ zuje następny deskryptor w kolejce. M ożna też użyć tablicy deskryptorów , ja k na ry s u n k u 3.2, Ten w ariant nazyw any je st w dokum entacji pierścieniem (ang. ring). W tedy oba adresy w deskryptorze m ogą w skazyw ać bufory w pam ięci, a o kolejno­ ści deskryptorów w kolejce decyduje indeks w tablicy. A by uzyskać zapętlenie, po ostatnim deskryptorze następuje pierw szy - o zerow ym indeksie. K olejki działają w edług zasady: pierw szy zgłoszony - pierw szy obsłużony (ang. fir s t in , fir s t out). Bity DIC Biły Opis 31 Ustawienie tego bitu blokuje zgłaszanie przerwania po odebraniu ramki (ang. disable inter­ rupt on completion). Gdy jest wyzerowany, przerwanie jest zgłaszane po odebraniu i skopio­ waniu ramki Bufor 2 30...29 Zarezerwowane Bufor 1 Bufor 2 Bufor D eskryptor n - 15 Gdy bit r c h ma wartość 0, to wartość 1 w tym polu oznacza, że jest to ostatni deskryptor w pierścieniu (ang. receive end o! ring) RCH 14 Wartość 0 oznacza, że ten deskryptor jest skonfigurowany w trybie pierścieniowym. War­ tość 1 oznacza, że ten deskryptor jest skonfigurowany w trybie łańcuchowym (ang. receive chain), a składowa Bu£fer2NextDescAddr zawiera adres następnego deskryptora 13 Zarezerwowane Bufor 1 D eskryptor n-1 RBSł Rys. 3.2. Pierścień deskryptorów Gdy bit r c h ma wartość 0, pole to zawiera długość w bajtach bufora (ang. receive buffer 2 size) wskazywanego przez składową Bu£fer2NextDescAddr. Wartość w tym polu musi być wielokrotnością 4. Gdy bit r c h ma w artość 1, pole to nie jest używane RER Bufor 2 Rys. 3.1. Łańcuch deskryptorów CD Deskryptor 1 RBS2 Deskryptor 1 CO CO Bufor 1 2 .. .0 Zawiera długość w bajtach bufora (ang. receive buffer 1 size) wskazywanego przez składo­ w ą Buf feriAddr. Wartość w tym polu musi być wielokrotnością 4 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu Tab. 3.9. Składowa controiB ufferSize deskryptora nadawczego Jeśli stosujem y arbitraż karuzelow y, to m ożna dodatkow o ustaw ić w sp ó łc z y n n ik określający, ile razy częściej je st w ybierana kolejka odbiorcza w stosunku do koJi lejki nadaw czej. W spółczynnik ten m oże mieć jed n ą z czterech w artości: 1 do 1, '¿Ą do 1, 3 do 1, 4 do 1. Pole TBS2 typecief struct { uint32_t Status; uint32_t ControlBufferSize; uint32_t BufferlAddr; uint32_t Buffer2NextDescAddr; } E?H__DMADESCTypeDef; TBS1 Bity Opis OWN 31 Wartość 1 oznacza, że DMA jest właścicielem (ang. own) deskryptora. DMA zeruje ten bit, gdy zakończy t kopiowanie z bufora lub buforów wskazywanych przez ten deskryptor. Program ustawia ten bit, aby zasy­ gnalizować układowi DMA, że deskryptor wskazuje na dane, które są gotowe do wysiania IC 30 Wartość 1 oznacza, że po zakończeniu transmisji ramki, opisanej tym deskryptorem, zostanie zgłoszone przerwanie (ang. interrupt on completion) LS 29 Wartość 1 oznacza, że jest to ostatni w kolejce deskryptor opisujący ramką do wysiania, Innymi słowy, ten' deskryptor wskazuje na bufor zawierający osfafni fragment ramki (ang. iast segment) FS 28 W artość 1 oznacza, że jest to pierwszy w kolejce deskryptor opisujący ramkę do wysiania. Innymi stówy, ten deskryptor wskazuje na bufor zawierający pierwszy fragment ramki (ang. //rei segment) DC 27 W artość 1 blokuje automatyczne dołączanie przez MAC sekwencji kontrolnej (ang. disable CRC) do wysy­ łanej ramki. Ten bit jest istotny tylko dla deskryptora, w którym bit f s m a wartość 1 26 Wartość 1 blokuje automatyczne uzupełnianie przez MAC wysyłanej ramki do minimalnej długości (ang. disable pad). Ten bit jest istotny tylko dla deskryptora, w którym bit f s ma wartość 1 25 W artość 1 aktywuje dla wysyłanej ramki, opisanej tym deskryptorem, znacznik czasu zgodny z normą IEEE 1588 (ang. transmit time stamp enable). Ten bit jest istotny tylko dla deskryptora, w którym bit fs m a wartość 1 24 Zarezerwowane DP TTSE X* 3.4. 10 - wstawiane są suma kontrolna nagłówka datagramu IP oraz sumy kontrolne ICMR TCP i UDR ale suma kontrolna pseudonaglówka nie jest wyliczana sprzętowo, 11 - wstawiane są suma kontrolna nagłówka datagramu IP oraz sumy kontrolne ICMR TCP I UDR suma kontrolna pseudonaglówka jest wyliczana sprzętowo TER 21 Gdy bit TCH ma wartość 0, to wartość 1 w tym polu oznacza, że jest to ostatni deskryptor w pierścieniu (ang. transmit end o1 ring) TCH 20 Wartość 0 oznacza, że ten deskryptor jest skonfigurowany w trybie pierścieniowym. W artość 1 oznacza, że ten deskryptor jest skonfigurowany w trybie łańcuchowym (ang. transmit Chain), a składowa Buf fer2NextDescAddr zawiera adres następnego deskryptora TTSS 17 status 1 6 ...0 ES 15 Zarezerwowane Wartość 1 oznacza, że składowe BufferlAddr i Buf fer2NextDescAddr zawierają znacznik czasu wysta­ nej ramki, opisanej tym deskryptorem, zgodny z IEEE 1588 (ang. transmit time stamp status). Ten bit jest istotny tylko dla deskryptora, w którym bit l s m a wartość 1 Jest to pole statusu, wypełniane przez DM A po zakończeniu transmisji. Najważniejszy bit tego pola jest opisany w następnym wierszu Wartość 0 oznacza, że transmisja przebiegła poprawnie. Wartość 1 oznacza, że wystąpił błąd (ang. error sum m ary). Dokładny opis błędu zawierają pozostałe biiy pola status 12. ..0 Zarezerwowane Długość w bajtach butora wskazywanego przez składową BufferlAddr (ang. transmit bul/er 1 size) Przykład 3a - pierwsza wersja sterownika Ethernetu Podstaw ow ym celem tego przykładu je s t napisanie sterow nika pośredniczącego m iędzy biblioteką lw IP a m ikrokontrolerem . N azw y plików, które zaw ierają im ­ plem entację przykładu, zam ieszczone są w tabeli 3.10. Sterow nik prezentow any w tym przykładzie jest pierw szym z trzech, które opisuję. Stosuje on najprostsze podejście, polegające na alokow aniu statycznych buforów odbiorczych i nadaw ­ czych. D M A kopiuje odebraną ram kę ethernetow ą do takiego bufora odbiorczego. N astępnie sterow nik kopiuje odebraną ram kę z bufora odbiorczego do bufora bi­ blioteki lwIP. W ysyłaną ram kę sterow nik kopiuje z bufora biblioteki lw IP do bufora nadaw czego, z którego D M A kopiuje ją do układu M AC. 01 - wstawiana jest tylko suma kontrolna nagłówka datagramu IR 1 9 ...1 8 2 8 . . .16 B ardziej szczegółow y)opis deskryptorów m ożna znaleźć w 1.8]. O m ów ienie znacz­ ników czasu i norm y IE E E 1588 w ykracza poza zakres tej książki. Sumy kontrolne i pseudonaglów ki U D P i T C P są opisane odpow iednio w RFC 768 i RFC 793. Sum a kontrolna IC M P je st opisana w RFC 792. %A' To pole steruje wstawianiem sum kontrolnych (ang. cliecksum insertion contro1) w protokołach intersieci: 2 3 ...2 2 Opis Zarezerwowane Jeśli pole TCH składowej status ma wartość 0, pole to zawiera długość w bajtach drugiego bufora (ang. transmit butler 2 size), wskazywanego przez składową Buffer2NextDescAddr. Jeśli pole t c h składowej status ma wartość 1 , pole to nie jest używane D eskryptor zajm uje 128 bitów. W bibliotece ST M 32, w pliku stin32_elh.li zde­ finiow ano go ja k o strukturę ETH_DMADESCTypeDef składającą się z czterech słów 32-bilow ych. Składow a B u ffe r lA d d r struktury typu ETH_DMADESCTypeDef zaw iera adres pierw szego bufora. Składow a B uffer2NextDescAddr w trybie łańcuchow ym zaw iera adres następnego deskryptora, a w trybie pierścieniow ym - adres drugiego bufora. Poszczególne bity dw óch pierw szych składow ych dla deskryptora odbior­ czego są om ów ione w tabelach 3.6 i 3.7. O pisy tych składow ych dla deskryptora nadaw czego zam ieszczone są w tabelach 3.8 i 3.9. Bity w tabelach num erow a­ ne są typow o dla procesora cienkokońców kow ego, czyli od najm niej znaczącego do najbardziej znaczącego. N ajstarszy bit składow ej S t a t u s w yznacza w łaściciela deskryptora. G dy w łaścicielem deskryptora je s t D M A , program ow i nie w olno go m odyfikow ać i nie pow inien też go czytać. 00 - sumy kontrolne nie są wstawiane, CIC Bity 31...29 15...13 Tab. 3.8. Składowa status deskryptora nadawczego Polo 109 i i ■ 3.4.1. Pliki u tiljim e .h i u tiljim e .c P rotokoły sieciow e w ym agają odm ierzania czasu. Jest to potrzebne na przykład po to, aby nie czekać w nieskończoność na odpow iedź. B iblioteka lw IP je st ste­ row ana zdarzeniam i. Jednym ze zdarzeń jest odebranie pakietu sieciow ego. Innym rodzajeni zdarzenia je st upłynięcie czasu. B iblioteka lw IP potrzebuje zegara, któ­ ry będzie zgłaszał cykliczne zdarzenia. Jednak im plem entacja takiego zegara jest 110 3. Stos TCP/lfiI Tab. 3.10. Pliki przykładu 3a Źródłowe i biblioteczne e x jp .c font5x8.c startup _stm32__cld. c board conf.c board init.c board_lcd_ks0108.c boardJed. c lont5x8.h board conf.h board def.h board deis.h board init.h b o a rd je d .h b o a rd je d .h util delay, c util eth.c utilJed. c utilJed_ex,c utilJ e d . c util Iwip.c util time.c Iiblwip4.a Iibstm 32l10x.a Maylówkowe util delay.h util eth.h util led.h util led ex.h u tilje d .h ulHJwip.h util time.h cc.h cortex-m 3.li Iwipopts.h stm 32/10x conf.h bardzo zależna od sprzętu. W rdzeniach C ortex-M 3 przew idziano do tego celu 24-’; -bitow y licznik system ow y (ang. system tim er), nazyw any w dokum entacji SysTick.. W ykorzystam y ten licznik do cyklicznego zgłaszania przerw ania, które będzie sy­ gnalizow ało bibliotece lw IP upływ czasu. W tym podrozdziale opisuję m oduł ob-’ sługujący SysTick. Jest on napisany na tyle ogólnie, że m oże być w ykorzystany nie'; tylko z biblioteką lwIP. W pliku nagłów kow ym util_tim e.h definiujem y częstotliw os'ć zegara biblioteki lw IP w H z i je g o okres tykania w m ilisekundach. Lcjkalny czas będziem y mierzyć,' w m ilisekundach za pom ocą 64-bitow ych liczb bez znaku. W praktyce pozw ala to;.’, odm ierzać dow olnie długie odstępy czasu. Z m ienne przechow ujące lokalny czas; będą typu l t i m e _ t . Ponadto definiujem y typ t i m e _ c a l l b a c k _ t funkcji zwrotnej,;, którą będzie m ożna skonfigurow ać, aby była cyklicznie w yw ołana w procedurze, obsługi przerw ania zegara system ow ego. Podana funkcja zw rotna będzie generowa-; la w łaściw e zdarzenia czasow e. D efinicje te są następujące: (¡define łdefine typedef typedef SYSTICK_FREQUENCY 100 SYSTICK_PERIOD_MS (1000 / SYSTICK_FREQUENCY) unsigned long long ltime_t; void (*time_callback_t)(void); W pliku u tiljtim e .c deklarujem y dw ie zm ienne globalne. Z m ienna lo c a lT im e od-: m ierzą czas od uruchom ienia m ikrokontrolera. Z m ienna tim eC allB a ck zaw iera ad­ res funkcji zw rotnej. A dres o w artości zero oznacza, że żadnej funkcji zw rotnej nie skonfigurow ano. Z m ienne te są zadeklarow ane ja k o s t a t i c , aby nie były w idocz­ ne na zew nątrz m odułu obsługującego SysTick. Z m ienna lo c a lT im e je s t ponadto zadeklarow ana jak o ulotna (ang. volatile), gdyż je st m odyfikow ana w procedurze obsługi przerw ania. static volatile ltime_t localTime » 0; static time__callback t timeCallBack = 0; Procedura obsługująca przerw anie licznika system ow ego nazyw a się SysTick H andler. W tej procedurze zw iększam y czas, który upłynął od uruchom ienia mi­ krokontrolera i jeśli skonfigurow ano funkcję zw rotną, w yw ołujem y ją. 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu 111 void SysTickJtandler(void) ( localTime += SYSTICK_PERIOD_MS; if (timeCallBack) timeCallBack(); I L icznik system ow y m oże być taktow any z tą sam ą częstotliw ością co rdzeń lub przez dzielnik z częstotliw ością 8 razy m niejszą. L icznik ten zlicza w dół do zera, po czym je s t przeładow yw any w artością początkow ą. Po osiągnięciu zera m oże zgłosić przerw anie. A by go skonfigurow ać, najw ygodniej je s t użyć funkcji SysTick_Conf ig z biblioteki ST M 32. Jako argum ent należy podać okres, który je s t rów ny w artości początkow ej licznika zw iększonej o jed en . F unkcja S ysT ick_C onfig aktyw uje prze­ rw anie licznika system ow ego i ustaw ia ja k iś priorytet, który trzeba zm ienić zgodnie z naszym w ym aganiem . L icznikow i system ow em u przypisujem y w ysoki priorytet, aby czas biegi rów nież podczas obsługi przerw ań o niższych priorytetach. Funkcja RCC_GetClocksFreq z biblioteki S T M 32 oblicza częstotliw ości sygnałów , którym i taktow any je s t m ikrokontroler (sygnał SY SC L K ), rdzeń (sygnał H C LK ) i peryferie (sygnały PC LK 1, PC LK 2, A D C C L K ) i um ieszcza ich w artości w strukturze typu RCC ClocksTypeDef. C zęstotliw ości te są w yrażone w hercach. K onfigurow anie licznika system ow ego im plem entujem y w funkcji LocalTim eC onfigure. int LocalTimeConfigure(void) I RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCCClocks); if (SysTick Config(RCC_Clocks.HCLK_Frequency / SYSTICK_FREQUENCY)) return -1; SET_PRIORITY(SysTick_IRQn, HIGH_IRQ_PRIO); return 0; } F unkcję zw rotną konfigurujem y za pom ocą funkcji TiraerC allBack. M ożna ją skon­ figurow ać w dow olnym m om encie, dlatego odbyw a się to przy w yłączonych prze­ rw aniach. Podanie zerow ego adresu pow oduje usunięcie funkcji zw rotnej. void TimerCallBack(time_callback_t f) ( IRQ_DECL_PROTECT(x ) i IRQ_PROTECT(x, HIGH_IRQ_PRIO); timeCallBack = Ł; IRQJJNPROTECT(X); } M oduł obsługujący licznik system ow y pow inien udostępniać w artość czasu, któ­ ry upłynął od uruchom ienia m ikrokontrolera. B ezpośrednie udostępnienie global­ nej zm iennej lo c a lT im e je s t bardzo złym pom ysłem . Lepiej je st zaim plem entow ać w tym celu funkcję, którą nazw iem y LocalTime. Poniew aż zm ienna loca lT im e je st 64-bitow a, jej odczyt nie je s t atom ow y. A by zapew nić odczytanie spójnej w artości, odczyt odbyw a się przy zablokow anym przerw aniu SysTick. W ym aga to zadekla­ row ania zm iennej tym czasow ej i zadeklarow ania w artości zw racanej przez funkcję ja k o ulotnej, żeby kom pilator, optym alizując, nie usunął tej zm iennej tym czaso­ wej. volatile ltime_t LocalTime(void) ( ltime_t t; IRQ DECL PROTECT(x); 112 3.4. Przykład 3ct - pierwsza wersja sterownika Ethernetu 3. Stos TCP/ip 113 .»— IRQ_PROTECT(x, HIGH_IRQ_PRIO) ; t = looalTime; IRQJJNPROTECT(x); return t; I Funkcja LocalTime zw raca czas w m ilisekundach. D la w ygody dobrze je st też mieć funkcję, która zw raca czas w bardziej przyjaznym form acie. W m odule obsługują­ cym licznik system ow y im plem entujem y funkcję GetLocalTime, która podaje czas od uruchom ienia m ikrokontrolera w dniach, godzinach, m inutach, sekundach i mili­ sekundach. Jako argum enty należy podać w skaźniki do zm iennych, w których mają być zapisane te w artości. void GetLocalTime(unsigned *day, unsigned ‘hour, unsigned ‘ minute, unsigned ‘ second, unsigned ‘ milisecond); 3.4.2. Pliki u tiljeth .h i utU eth.c - inicjowanie interfejsu sieciowego Pliki opisane w tym i kolejnych dw óch podrozdziałach zaw ierają w łaściw ą im ple­ m entację sterow nika interfejsu ethernetow ego. W tym podrozdziale opisuję inicjo­ w anie interfejsu. W pliku util_eth.h zdefiniow any je s t adres układu PH Y oraz struk­ tura typu e t h n e t i f , która przechow uje ten adres i statystyki działania interfejsu U kład PH Y w m odule Z L 3 E T II m a adres 1. Statystyki zaw ierają: - R X _packets - liczba prób w ysiania ram ki, - T X _packets - liczba w szystkich odebranych ram ek, R X _errors - liczba nieudanych prób w ysiania ram ki, T X _errors - liczba odebranych ram ek, które okazały się błędne. idefine PHYJtDDRESS 1 struct ethnetif f uint8__t phyAddress; unsigned RX_packets; unsigned TX_packets; unsigned RX_errors; unsigned TX_errors; i; W pliku util_eth.h zadeklarow ana je s t też funkcja ETHinit, która w ykonuje niskopoziom ow e inicjow anie interfejsu ethernetow ego. A dres tej funkcji jest przekazywany jak o argum ent w spom nianej ju ż funkcji netif__add biblioteki IwIP. Funkcja ETHinit m a jeden argum ent. Jest to w skaźnik do struktury typu n e t i f opisującej inicjowany interfejs. Przekazyw ana struktura n e t i f m usi m ieć w składow ej hwaddr adres sprzę­ tow y interfejsu. Ponadto składow a s t a t e musi zaw ierać w skaźnik do struktury typu e t h n e t i f zw iązanej z tym interfejsem . Ta struktura e t h n e t i f musi m ieć zainicjow a­ ną składow ą phyAddress. Składow a s t a t e struktury n e t i f je s t inicjow ana w funkcji n e t i f _ a d d . G dy inicjow anie interfejsu się pow iodło, funkcja E THinit zw raca war­ tość ERR_OK. W przeciw nym przypadku funkcja ta zw raca kod błędu wg tabeli 3.4. Im plem entacja funkcji ETH init znajduje się w pliku util_eth.c. err__t ETHinit (struct netif ‘netif) { struct ethnetif ‘ ethnetif = netif->state; if (ETHconfigurePHY(ethnetif->phyAddress) < 0) return ERR IF; ETHconfigureMAC(netif); ETHconfigureDMA{netif, LWIP_IRQ_PRIO, 0); netif->name(0] = ,s'; netif->name(ł] « , t'; netif->output = etharp_output; netif->linkoutput = low_level_output; ethnetif->RX_packets = 0; ethnetif->TX_packets = 0; ethnetif~>RX_errors = 0; ethnetif->TX_errors = 0; ETH_Start(); netif->flags i= NETIF_FLAG_LINK_UP; return ERR_OK; 1 W łaściw e inicjow anie zostało podzielone pom iędzy, opisane niżej, funkcje ETHconfigurePHY, ETHconfigureMAC, ETHconfigureDMA. K ażda z tych funkcji, zgodnie ze sw oją nazw ą, konfiguruje odpow iedni podukład interfejsu etherneto­ wego. Po skonfigurow aniu tych podukładów inicjow ane są składow e struktur typu n e t i f i e t h n e t i f . Składow ej o u t p u t przypisujem y adres funkcji e t h a r p _ o u t p u t , która je s t dostarczana przez bibliotekę IwIP, zajm uje się pakow aniem datagram ów IP w ram ki ethernetow e i obsługą ARP. Jeśli przed w ysłaniem pakietu sieciow ego trzeba w ykonać jak ieś działania, np. spraw dzić stan łącza, to tej składow ej m ożna przypisać adres w łasnej funkcji, która w ykonuje to zadanie, a następnie w yw ołuje funkcję e t h a r p o u tp u t . Składow ej l i n k o u t p u t przypisujem y adres niskopoziom ow ej funkcji lo w _ le v e l _ o u tp u t , która zajm uje się w ysyłaniem gotow ych ram ek elhernetow ych i je s t opisana w następnym podrozdziale. N a koniec w yw ołujem y funkcję ETH_Start, która je s t dostarczana przez bibliotekę STM 32 i w łącza inter­ fejs ethernetow y. Funkcja ETHconfigurePHY zajm uje się przede w szystkim konfigurow aniem układu PHY, ale też, z uw agi na strukturę biblioteki ST M 32, konfiguruje niektóre ustaw ie­ nia układów M A C i DM A. A rgum entem tej funkcji je s t adres układu PHY. Funkcja ta zw raca zero, gdy zakończyła się sukcesem , a w artość ujem ną w przeciw nym przypadku. K onfigurow anie m oże zakończyć się niepow odzeniem , jeśli nie uda się skontaktow ać z układem PHY. static int ETHconfigurePHY(uint8_t phyAddress) ETH_InitTypeDef e; { ETłi_Struct2nit (Se); e.ETH AutoNegotiation = ETH_AutoNegotiation_Enable; e.ETH_BroadcastFramesReception = ETH BroadcastFramesReception_Enable; e.ETH ReceiveOwn = ETH_ReceiveOwn_Disable; U f CHECKSUM_GEN__IP == 0 e.ETH ChecksuroOffload = ETJ!_ChecksumOffload_Enable; e.ETH DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disabłe; iendif e .ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable; e .ETH_FixędBurst = ETH_FixedBurst_Enabłe; e.ETH_RxDMABurstLength = ETll_RxDMABurstLength_32Beat; e.ETH TxDMABurstLength = ETH_TxDMABurstLength__32Beat; 114 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu 3. Stos TCP/ip if (!ETH_Init(&e, phyAddress)) return -1; - F unkcja ETHconfigureMAC konfiguruje adres sprzętow y M A C , M TU sieci i znacz­ niki. N ależy zadbać, aby w artość, opisanej w cześniej, stałej TCP_MSS, zdefiniow anej w pliku Iw ipopts.h, była spójna z w artością M T U ustaw ianą przez tę funkcję. Stała MAX_ETH_PAYLOAD je s t zdefiniow ana w pliku stm 32_eth.h i m a w artość 1500. Stała ETHARP_HWADDR_LEN jest zdefiniow ana w pliku etharp.h i ma w artość 6. phyreg = ETH_ReadPHYRegister(phyAddress, PHYCR); phyreg &= - (LED__CNFG0 I LED_CUFG1); ETH_WritePHYRegister(phyAddress, PHYCR, phyreg); lendif return 0; I A by ułatw ić konfigurow anie interfejsu ethernetow ego, w b ibliotece ST M 32 zdefi-J niow ano strukturę ETH_InitTypeDef oraz funkcję E T H _ S tr u c tI n i t, która in ic ju je ^ tę strukturę w artościam i dom yślnym i. W iększości ustaw ień dom yślnych nie trzeba/jjj zm ieniać. W arto natom iast ustaw ić au tom atyczne negocjow anie trybu pracy inter-■> . fejsu ethernetow ego. Jeśli auto m aty czn e negocjow anie nie działa, m ożna spróbo-f w ać ustaw ień opisanych w ro zdziale 2.6.3. N a pew no też należy uaktyw nić o d b ić-1 | ranie ram ek rozgloszeniow ych. G dy zam ierzam y używ ać sprzętow ego wsparcia M dla sum kontrolnych (ang. checksum offload) protokołów intersieci, trzeba uaktyw- -; nić tryb zapisz i w yślij (ang. store a n d fo rw a rd ) dla w ysyłania i odbierania. Wtedy .fi cala ram ka je s t grom adzona w F IF O , zanim zostanie przesiana, aby m ożna b ylo'i|* w staw ić lub zw eryfikow ać sum ę kontrolną. T ryb zapisz i w yślij jest ustaw iany! dom yślnie przez funkcję E T H _ S tr u c tI n i t. D om yślhie też ustaw iany je s t karuzc- $ Iowy algorytm szeregow ania kolejek nadaw czej i odbiorczej ze w spółczynnikiem • 1 do 1. W funkcji ETHconfigurePHY o statnie cztery p rzy p isan ia d o pól struktu-.-w ry e dotyczą DM A. Ich celem je s t zo p tym alizow anie działan ia transakcji DMA. W A by skonfigurow ać interfejs, w yw ołana je s t funkcja ETH_Init z biblioteki S T M 32/'-|, Pierw szym je j argum entem je s t w skaźnik do struktury e, a drugim arg u m en tem ; “ je st adres układu PHY. - zielona dioda sygnalizuje status łącza (ang. link status): • św ieci się, gdy łącze pracuje popraw nie (ang. g o o d link), • nie św ieci się, gdy w kablu nie m a w łaściw ego sygnału lub kabel je s t odł; ny (ang. no link), • m iga, gdy transm itow ane są ram ki (ang. activity): pom arańczow a dioda sygnalizuje przepływ ność (ang. speed): • św ieci się, gdy jest to 100 M b/s, * nie św ieci się, gdy je s t to 10 M b/s. #if ETH__BOARD == ZL3ETH Idefine PHYCR 0x19 Sdefine LED_CNFG0 0x0020 idefine LED_CNFG1 0x0040 uintl6_t phyreg; N a zakończenie funkcji ETHconfigurePHY konfigurujem y ustaw ienia zależne od użytego układu PHY. K ażdy układ PH Y m a rejestry konfiguracyjne, pozwalaj; dostosow ać je g o ustaw ienia do potrzeb konkretnej aplikacji. D ostęp do rejestrów układu PH Y um ożliw iają funkcje ETH_ReadPHYRegister i ETH_WritePHYRegister z biblioteki STM 32. W m odule ZL3ETI-I zastosow ano układ D P83848C oraz gniazdo RJ-45 z dw om a diodam i św iecącym i. Po szczegóły odsyłam do schem atu modułu ZL3E T H i noty katalogow ej układu D P83848C . Jako przykład ilustrujący użycie rejestrów układu PIIY zm ieńm y konfigurację tych diody św iecących. W yzerowanie bitu LED_CNFG0 i bitu LED_CNFG1 w rejestrze PHYCR (ang., P H Y contro! register) pow oduje, że: 115 r',| !■ j>: f. ’d 'A. static void ETHconfigureMAC{struct netif *netif) { netif->hwaddr_len = ETHARP_HWADDR_LEN; neti£->mtu = MAX_ETH_PAYLOAD; neti£->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; ETH_MACAddressConfig(ETH_MAC_AddressO, netif->hwaddr ) ; i O statnim układem do skonfigurow ania je s t D M A . T rzeba określić, ja k ą liczbą bu­ forów nadaw czych i odbiorczych będzie dysponow ać D M A . Poniższe w artości są w ybrane dość sw obodnie, przy założeniu, że przykładow e aplikacje nie generują dużego ruchu sieciow ego. łdefine ETH_RXBUFNB 4 {(define ETH_TXBUFNB 4 D M A będzie zgłaszało przerw anie po odebraniu ram ki. Procedura przerw ania musi m ieć dostęp do struktury typu n e t i f , opisującej interfejs sieciow y. N ajprostszym rozw iązaniem jest zadeklarow anie globalnego w skaźnika, który będzie przechow y­ wał adres tej struktury. static struct netif *p_netif; DM A konfigurujem y za pom ocą funkcji ETHconfigureDMA. Pierw szym jej argu­ m entem je st w skaźnik do struktury typu n e t i f . D rugim i trzecim argum entem są odpow iednio priorytet w yw łaszczania i podpriorytet, z jakim i m a być obsługiw ane przerw anie D M A. static void ETHconfigureDMA(struct netif *netif, uint8_t priorityi uint8_t subpriority) ( static ETH_DMADESCTypeDef DMARxDscrTab[ETII_RXBUFNB] ALIGN4; static ETH_DMADESCTypeDef DMATxDscrl'ab[ETH_TXBUFNB| ALIGN4; static uint8_t RxBuff{ETH_RXBUFNBJ{ETH_MAXJ>ACKET_SIZE] ALIGN4; static uint8_t TxBuff|ETH_TXBUFNB)[ETH_MAX_PACKET_SIZE1 ALIGN4; ETH_DMARxDescChainInit(DMARxDscrTab, SRxBuff[0)[0], ETH_RXBUFNB); ETH_DMATxDescChainInit(DMATxDscrTab, STxBuff(OJ[OJ, ETHJFXBUFNB ) i NVIC__InitTypeDef NVIC_InitStruct; int i; p netif = netif; MVIC_InitStruct.NVIC_IRQChannel = ETH_IRQn; NVIC InitStruct.NVIC_IRQChannelPreemptionPriority = priority; 3.4. P n yld a d 3a - pierwsza wersja sterownika Ethernetu NVIC_InitStruct.NVIC_IRQChannelSubPriority = subpriority; NVIC_InitStruct.NVIC_IRQChanneiCmd * ENABLE; NVIC_Init(SNVIC_InitStruct); ETH_DMAITConfig(ETH_DMA_IT_NIS ! ETH_DMA_IT_R, ENABLE); for (i = 0; i < ETH_RXBUFNB; ++i) ETH__DMARxDescReceiveITConfig (&DMARxDscrTab{i ], ENABLE); iif CHECKSUM_GEN__IP == 0 for (i = 0; i < ETH_TXBUFNB; ++i) ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab(i), ETH_DMATxDesc_CIC_IPV4HeaderJ; iendif i N a początku funkcji ETHconfigureDMA deklarujem y deskryptory oraz bufory o biorcze i nadaw cze. Później za pom ocą funkcji ETH_DMARxDescChainInit z 1 blioteki S T M 32 konfigurujem y łańcuch deskryptorów odbiorczych, a za ponio funkcji ETH_DMATxDescChainInit łańcuch deskryptorów nadaw czych. Pierwszy argum entem tych funkcji je s t tablica deskryptorów , choć w trybie łańcuchowy deskryptory nie m uszą zajm ow ać ciągłego obszaru pam ięci. U żyw ając tych fun cji, nie m ożem y zm ienić rozm iaru buforów, gdyż obie funkcje ja k o drugi argumeijl oczekują adresu ciągłego obszaru pam ięci o rozm iarze ETH_MAX_PACKET_SIZE ra/\ liczba buforów. Pow iększenie rozm iaru buforów je st konieczne, jeśli chcielibyśmy używ ać ram ek V LA N , g dyż stała ETH_MAX_PACKET_SIZE, zdefiniow ana w pliku stm 32_eth.h, m a w artość 1520, co nie uw zględnia dodatkow ych pól w ramkach'' V LA N . T rzecim argum entem tych funkcji je s t liczba deskryptorów w łańcuchu, bęV dąca zarazem liczbą buforów. Jak w idać, funkcje z biblioteki S T M 32 nie pozwalają na dow olne konfigurow anie łańcucha deskryptorów . ‘ Plik u tilje th .c - wysyłanie ramek ethernetowych A by w ysłać ram kę, trzeba znać adres pierw szego w olnego deskryptora w kolejce nadaw czej D M A i w staw ić tę ram kę do tej kolejki. W bibliotece STM 32 w pliku stm 32_eth.c zdefiniow ano w tym celu zm ienną DMATxDescToSet, która w skazuje bieżący, pierw szy w olny deskryptor nadaw czy. D ostęp do tej zm iennej zapew nia poniższa deklaracja. extern ETH_DMADESCTypeDef *DMATxDescToSet; W staw ianiem ram ek ethernetow ych do kolejki nadaw czej zajm uje się funkcja łow_ l e v e l _ o u t p u t , którą m usim y zaim plem entow ać. Pierw szym argum entem tej funk­ cji je s t w skaźnik do struktury typu n e t i f opisującej interfejs sieciow y, przez który ma być w ysiana ram ka. D rugim argum entem je s t w skaźnik do łańcucha buforów zaw ierających ram kę do w ysiania. F unkcja ta zw raca w artość ERR_0K, gdy zakoń­ czyła się pow odzeniem , a w przeciw nym przypadku w łaściw y kod błędu. static err_t low__level_output (struct netif *netif, struct pbuf *p) { ((struct ethnetif *)netif->state)->TX_packets++; if (p == NULL) | ((struct ethnetif*) netif->state) ->TX_errors-H-; return ERR_ARG; 1 if (p->tot__len > ETH__MAX_PACKET_SIZE - ETH_CRC) ( ((struct ethnetif *)netif->state)->YX_errors++; return ERRJ3UF; } if (DMATxDescToSet->Stiatus & ETH_DMATxDesc_OWN) ( ((struct ethnetif *)netif->state)->TX_errors++; return ERR_IF; 1 pbuf_copy_partial(p, (void *)DMATxDescToSet->BufferlAddr, p->tot_len, 0); DMATxDescToSet->ControlBufferSize p->tot_len £ EYH_DMATxDesc_TBS2; DMATxDescToSet->Statuś 1= ETH_DMATxDesc_FS | E'i’ H_DMATxDesc__LS 1 ETH_DMATxDesc_OWN; if (ETH->DMASR h ETH_DMASR_TBOS) i ETH->DMASR = ETH_DMASR_TBUS; ETH->DMATPDR = 0; N astępnie w funkcji ETHconfigureDMA konfigurujem y przerw anie D M A . Wszystkie] źródła przerw ań zw iązane z interfejsem ethernetow ym zgłaszają przerw anie . 1 IRQn. Przerw anie ustaw iam y tak, aby było zgłaszane, gdy D M A odbierze ramkę i skopiuje ją do sw ojego bufora odbiorczego. W procedurze obsługi tego przerwania ram ka będzie kopiow ana z bufora D M A do bufora biblioteki lwIP, po czym będ zię; w yw ołana funkcja biblioteki lw IP przetw arzająca tę ram kę. N ajpierw inicjujemy,1 globalny w skaźnik p _ n e t i f , aby procedura obsługi m iała dostęp do struktury typy n e t i f . N astępnie korzystam y z funkcji biblioteki STM 32: - - konfigurujem y priorytet przerw ania i uaktyw niam y go za pom ocą funkcji NY ; In it; ustaw iam y źródło przerw ania za pom ocą funkcji ETH_DMAITConfig, ustawieni^ bitu ETH_DMA_IT_R aktyw uje p rzerw anie odbiorcze (ang. receive interrupt), usta* w ienie bilu ETH_DMA_IT_NIS aktyw uje podstaw ow e przerw ania D M A (ang. nor­ m al interrupt sum m ary); aktyw ujem y zgłaszanie przerw ania (zerujem y bit D IC w deskryptorach odbior czych) za pom ocą funkcji ETH_DMARxDescReceiveITConfig. N a koniec funkcji ETHconfigureDMA, jeśli została skonfigurow ana opcja sprzęt , w ego w staw iania sum kontrolnych w nagłów kach datagram ów IP, trzeba ustawić tę( opcję w e w szystkich deskryptorach nadaw czych za pom ocą funkcji ETH_DMATxDt C h e c k su m ln se rtio n C o n fig . 117 ) DMATxDescToSet = (ETH_DMADESCTypeDef *)DMATxDescToSet->Buffer2NextDescAddr; return ERR OK; 1 F unkcja lo w _ le v e l _ o u tp u t najpierw spraw dza popraw ność argum entów i uaktu­ alnia statystykę w ysłanych ram ek. W ysyłana przez bibliotekę lw IP ram ka ethernetow a nie zaw iera sekw encji kontrolnej, która je s t w yliczana przez układ M AC. D latego przekazana do w ysiania ram ka nie m oże być dłuższa niż m aksym alny rozm iar ram ki ethernetow ej (siała ETH_MAX_PACKET_SIZE) pom niejszony o długość sekw encji kontrolnej (stała ETH_CRC). Funkcja spraw dza też, czy bieżący deskryp­ tor nadaw czy nie je s t zajęty przez D M A , czyli czy je s t w yzerow any bit OWN. Jeśli spraw dzenia w ypadną pozytyw nie, funkcja kopiuje ram kę do bufora w skazyw ane­ go p rzez bieżący deskryptor i ustaw ia w tym deskryptorze długość tej ram ki (pole TBS1). N astępnie inform uje D M A , że bufor zaw iera całą ram kę (ustaw ia bity ES 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu i LS) oraz zw raca deskryptor układow i D M A (ustaw ia bit OWN). N a koniec trze ba jeszcze spraw dzić, czy przeglądanie kolejki nadaw czej nie zostało w strzym ani Sygnalizow ane je s t to przez ustaw ienie bitu TBUS w rejestrze DMASR (ang. D M A staI lus register). P rzeglądanie zatrzym uje się, gdy w łaścicielem kolejnego deskryptor’' w kolejce nie je s t D M A , czyli gdy nie m a nic do w ysiania. P rzeglądanie kolcjk'1' nadaw czej w znaw ia się przez w yzerow anie bitu TBUS (w pisując do niego jedynkę)' i zapisanie jakiejk o lw iek w artości do rejestru DMATPDR (ang. D M A transm it p o ll de'ir ntancl register). O statnią czynnością je s t przesunięcie w skaźnika bieżącego deskryp'i tora na następny deskryptor w łańcuchu. 119 ((struct ethnetif *)netif->state)->RX_errors++; pbuf_free(p); 1 return err; Plik utiljeth .c - odbieranie ramek ethernetowych ) B iblioteka lw IP w ym aga, aby odebrana ram ka została um ieszczona w buforze opi­ syw anym strukturą typu pbuf. Z ajm uje się tym funkcja lo w _ łe v e l_ in p u t, która alokuje bufor i kopiuje do niego ram kę. Z w rócony przez tę funkcję w skaźnik do bufora je st przekazyw any do funkcji w skazyw anej za pom ocą składow ej in p u t struktury n e t i f . B iblioteka lw IP nie zw alnia przekazanego jej bufora, jeśli prze­ tw arzanie ram ki zakończy się błędem . D latego w przypadku błędu trzeba w funkcji e t h e r n e t i f _ i n p u t zw olnić przekazany bibliotece bufor. A dres pierw szego deskryptora w kolejce odbiorczej, gdzie zostanie um ieszczona kor lejna odebrana ram ka elhernetow a, przechow yw any je st w zm iennej DMARxDescToGelj* zdefiniow anej w bibliotece ST M 32 w pliku stm 32_eth.c. static struct pbuf * low_level_input(struct netif ‘netif) ( struct pbuf *p = NULL; uint32__t len; extern ETH_DMADESCTypeDef ‘DMARxDescToGet; if O debrane ram ki są przetw arzane w procedurze ETH_IRQHandler obsługującej przeć rw anie, które je st zgłaszane przez D M A po um ieszczeniu ram ki w kolejce odbiorczej;' Poniew aż jed n o przerw anie m oże zostać zgłoszone dla w ielu ram ek, spraw dzam ^ w pętli, czy bieżący deskryptor, w skazyw any przez zm ienną DMARxDescToGet, miii) w yzerow any bit OWN. W yzerow anie tego bitu oznacza, że deskryptor został zwolnioi) ny przez DM A i w skazuje na o debrane dane. R am ka je st przetw arzana przez funk^ cję e th e r n e tif_ _ in p u t, po której zakończeniu w skaźnik DMARxDescToGet wskazujó$ na następny deskryptor w kolejce. A by nie zgubić,żadnego przerw ania, bity o c /e -■ kującego (ang. pend in g bit) p rzerw ania ETH_DMA_IT‘_NIS i ETH_DMA_IT_R m uszą hyć,'n w yzerow ane przed spraw dzeniem bitu OWN w kolejnym deskryptorze. void ETH_IRQHandler(void) ( ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS I ETH_DMA_IT_R); while {!(DMARxDescToGet->Status 6 ETH_DMARxDesc_OWN)) ethernetif__input (p_netif}; ) err = netif->input(p, netif); if (err != ERR OK) ( DMARxDescToGet~>Status = ETH__DMARxDesc_OWN; DMARxDescToGet (ETH_DMADESCTypeDef *)DMARxDescToGet“>Buffer2NextDescAddr; if (ETH->DMASR & ETH_DMASR_RBUS) { ETH->DMASR = ETH__DMASR__RBUS; ETH->DMARPDR = 0; } A rgum entem funkcji e t h e r n e t i f _ i n p u t je st w skaźnik do struktury n e t i f opisują­ cej interfejs sieciow y. Z godnie z konw encją obow iązującą w bibliotece lw IP funk­ cja ta zw raca w artość E R R „O K , gdy zakończyła się sukcesem , lub w łaściw y kod1 błędu w przeciw nym przypadku. Jednak w szelkie błędy zw racane przez tę funkcję są ignorow ane, gdyż nie m a realnej m ożliw ości ich obsłużenia w procedurze ob- j sługi przerw ania. Z am iast tego funkcja ta uaktualnia w strukturze typu e th n e tif-.' statystykę odebranych ram ek. ((struct ethnetif *)netif->state)->RX_packets++; p = Iow level_input(netif); if (p == NULL) { ((struct ethnetif *)netif->state)->RX_errors++; return ERR_MEM; ) } return p; ) static err_t ethernetif__input{struct netif *netif) { struct pbuf *p; err_t err; ((DMARxDescToGet->Status fiETH_DMARxDesc_£S) =*= 0 && {DMARxDescToGet~>Status fi £TH_DMARxDesc_LS) != 0 && (DMARxDescToGet->Status & ETH_DMARxDesc_FS) 1= 0) { len = ETH_GetDMARxDescFrameLength(DMARxDescToGet); if (len >= ETHJiEADER + MIN__ETH_PAYLOAD + ETH_CRC) { len ETH_CRC; p « pbuf_alloc(PBUF^RAW, len, PBUF_P00L); pbuf take(p, (void *)DMARxDescToGet->BufferlAddr, len); 1 ) A rgum entem funkcji io w _ le v e l_ in p u t jest w skaźnik do struktury n e t i f opisują­ cej interfejs sieciow y. Funkcja ta najpierw spraw dza, czy bieżący deskryptor za­ w iera popraw nie odebraną ram kę i czy ram ka ta nie je s t za krótka. Funkcja ETH_ GetDMARxDescFraraeLength z biblioteki S T M 32 zw raca długość odebranej ram ki, łącznie z sekw encją kontrolną. Jeśli spraw dzenie w ypadnie pozytyw nie, alokow any je s t now y bufor i kopiow ana jest do niego ram ka bez sekw encji kontrolnej. Jeśli alokacja bufora nie pow iedzie się i do funkcji p b u f ta k e zostanie przekazany zero­ wy w skaźnik p, to funkcja ta nie w ykona żadnego kopiow ania. Funkcji pbuf ta k e je s t odporna na zerow ą w artość pierw szego argum entu. N astępnie funkcja low l e v e l_ in p u t zw raca deskryptor układow i D M A (ustaw ia bit OWN) i przesuw a w skaź­ nik bieżącego deskryptora na następny deskryptor w łańcuchu. N a koniec trzeba jeszcze spraw dzić, czy przeglądanie kolejki odbiorczej nie zostało w strzym ane. S ygnalizow ane je s t to przez ustaw ienie bitu RBUS w rejestrze DMASR. Przeglądanie zatrzym uje się, gdy w łaścicielem kolejnego deskryptora w kolejce nie je st D M A (w yzerow any je s t bit OWN). M oże się to zdarzyć, gdy kolejka odbiorcza zapełni się, bo aplikacja nie nadąża przetw arzać odebranych ram ek. Przeglądanie kolejki od- 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu biorczej w znaw ia się przez w yzerow anie bitu RBUS (w pisując do niego jedynkę i zapisanie jakiejkolw iek w artości do rejestru DMARPDR (ang. DMA receive poll (/e m and register). 3.4.5. Pliki u tiljw ip .h i u łiljw ip .c - inicjowanie interfejsu sieciowego Plik u tiljw ip .h zaw iera deklarację funkcji LWIPinterfacelnit inicjującej bibli tekę IwIP, a następnie konfigurującej interfejs sieciow y do w spółpracy z tą bibli teką. int LWIPinterfacelnit(struct netif *netif, struct ethnetif *ethnetif); Im plem entacja tej funkcji znajduje się w pliku u tiljw ip .c . Jej argum entam i są, opi­ sane w poprzednich podrozdziałach, w skaźniki do struktur, które przechow ują daru? konfigurow anego interfejsu. Jeśli składow a ip_addr w strukturze netif m a wartość różną od zera, interfejs sieciow y zostanie skonfigurow any statycznie z adresem 1 m aską podsieci i adresem rutera przekazanym i w tej strukturze. Jeśli składow a t m a w artość zero, to w celu pozyskania ustaw ień sieciow ych dla tego interfejs zost'-' nie podjęta próba uruchom ienia klienta DHCP. W przekazanej strukturze typu n. tif m usi być w ypełniony adres sprzętow y. W przekazanej strukturze typu ethn tif m usi być w ypełniony adres układu PHY. Funkcja zw raca zero, gdy zakończył się sukcesem , a w artość ujem ną, gdy w ystąpił błąd. F unkcja je s t przeznaczona do; w yw ołania z program u głów nego, dlatego w szystkie w ystępujące w niej wywołania' funkcji biblioteki IwIP są otoczone m akram i chroniącym i przed konkurencyjnj w ykonyw aniem . Funkcja ta korzysta z niżej przedstaw ionych funkcji biblioteki', IwIP. void Iwip_init(void); F unkcja lwip_init je st zadeklarow ana w pliku init.h i zaim plem entow ana w pliku init.c. Inicjuje w szystkie skom pilow ane m oduły biblioteki IwIP. struct netif * netif add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)); Funkcja netif_add je s t zadeklarow ana w pliku netif.h i zaim plem entow ana w pliku netif.c. D odaje interfejs sieciow y do listy interfejsów obsługiw anych przez bibliote­ kę IwIP. Param etr netif je st w skaźnikiem do struktury opisującej dodaw any inter-i. fejs. Param etry ipaddr, netmask i gw są odpow iednio w skaźnikam i do struktur za­ w ierających adres IP, m askę podsieci i adres rutera. Jeśli zam ierzam y użyć DHCT, należy podać zerow e w artości adresów i m aski. Param etr State je s t wskaźnikiem, do struktury zaw ierającej pryw atne dane sterow nika interfejsu sieciow ego. W na-, szym przypadku przekazujem y w skaźnik do struktury typu ethnetif. Parametr. 121 init musi zaw ierać adres funkcji inicjującej sterow nik. Przekazujem y adres funkcji ETHinit, która została opisana w poprzednim podrozdziale. Param etr input musi zaw ierać adres funkcji przetw arzającej odebrane ram ki sieciow e. Przekazujem y ad­ res funkcji ethernet__input z biblioteki IwIP. G dy funkcja zakończyła się sukce­ sem , zw raca w skaźnik do skonfigurow anej struktury typu netif, a gdy wystąpił błąd, zw raca w artość NULL. void netif_set_defauit(struct netif *netif); F unkcja n e t i f _ s e t _ d e f a u l t je s t zadeklarow ana w pliku netif.h i zaim plem entow a­ na w pliku n e tif c. U staw ia interfejs sieciow y w skazyw any przez param etr n e t i f ja k o dom yślny. W szystkie datagram y IP bez jaw nie określonej trasy są w ysyłane przez interfejs domyślny. err_t dhcp_start(struct netif *netif); F unkcja d h c p _ s t a r t je s t zadeklarow ana w pliku dhcp.h i zaim plem entow ana w pliku dhcp.c. U rucham ia klienta D H C P w celu zdobycia ustaw ień sieciow ych dla interfejsu w skazyw anego za pom ocą argum entu netif. Jeśli klient D H C P był ju ż uruchom iony dla tego interfejsu, restartuje tego klienta. Z w rócenie w artości ERR OK oznacza tylko p o m yślne uruchom ienie klienta, a nie zakończenie konfigu­ row ania ustaw ień siećiow ych. K lient działa niejako w tle. G dy klient zdobędzie u staw ienia sieciow e, odblokow uje interfejs sieciow y, ustaw iając znacznik NETIF_ FLAG UP. void netif_set_up(struct netif *netif); F unkcja n e tif_ _ set_ u p je st zadeklarow ana w pliku netif.h i zaim plem entow ana w pli­ ku netif.c. Jeśli konfigurujem y statyczne ustaw ienia sieciow e, pow inniśm y w ywołać tę funkcję w celu odblokow ania interfejsu sieciow ego przez ustaw ienie znacznika NETIF_FLAG__UP. Jeśli używ am y DHCP, w yw ołanie tej funkcji jest zbędne. O prócz pow yższych funkcji, użyteczne m ogą być rów nież inne funkcje dostarczane w plikach netif.h i netif.c. Z a pom ocą następujących funkcji m ożna zablokow ać interfejs sieciow y, spraw dzić jeg o stan i skonfigurow ać statyczny adres IP, maskę podsieci oraz adres rutera. void u8_t void void void netif_set_down(struct netif ‘netif); netif_is_up(struct netif ‘netif); netif_set__ipaddr (struct netif ‘netif, struct ip__addr ‘ipaddr); netif_set__netmask (struct netif ‘netif, struct ip_addr ‘ netmask); netif_set_gw(struct netif ‘ netif, struct ip_addr *gw); K onfigurow anie ustaw ień sieciow ych za pom ocą D H C P trwa pew ien czas. Przed je g o zakończeniem nie m a sensu podejm ow ow anie jakiejkolw iek kom unikacji sie­ ciow ej. W funkcji DHCPwait im plem entujem y aktyw ne (w pętli) oczekiw anie na zakończenie procesu konfigurow ania. int DHCPwait(struct netif ‘netif, unsigned timeout, unsigned tries); 122 3. Stos TCP/ip Funkcja DHCPwait zw raca zero, gdy konfigurow anie za pom ocą D H C P zakończy-; lo się sukcesem lub gdy nie je s t używ any klient DHCP. Funkcja zw raca w artość1 ujem ną, gdy konfigurow anie nie zakończyło się w ciągu tim e o u t sekund lub klient1’ w ykonał bez pow odzenia co najm niej t r i e s prób. Jeśli aktyw ne oczekiw anie na i zakończenie procesu konfigurow ania je s t nieakceptow alne, to m ożna użyć funkcji: zw rotnej inform ującej o zm ianie stanu interfejsu. W tym celu należy w pliku Zwi-: popis, h zdefiniow ać następującą opcję: łdefine LWIP_NETIF_STATUS_CALLBACK void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif)); Przydatne m ogą okazać się rów n ież następujące funkcje dostarczane w plikach dhcp.h i dhcp.c. void dhcp_stop(struct netif ‘netif); Funkcja d h cp _ sto p zatrzym uje działanie klienta DHCP. err_t dhcp_release(struct netif ‘netif); Funkcja d h c p _ re le a s e zw alnia w ynajęte od serw era DFICP ustaw ienia sieciowe. Serw er D H C P w ynajm uje ustaw ienia sieciow e na określony czas - patrz rozdział 3.9. Funkcja ta jest zw ykle w yw ołana przed funkcją d h cp _ sto p . err t dhcp_renew(struct netif *netif); Funkcja dhcp renew odnaw ia w ynajem ustaw ień sieciow ych. N orm alnie nie ma potrzeby w yw ołania lej funkcji, gdyż klient D H C P autom atycznie próbuje odnowić w ynajem przed je g o zakończeniem . 3.4.6. Tab. 3.11. Budziki biblioteki lwiP Funkcja Pliki u tiljw ip .h i u tiljw ip .c - budziki B iblioteka lw IP musi być pobudzana do działania w regularnych odstępach czasu. W szystkie jej budziki opisane są w ta b e li 3.11. Pierw sza kolum na zaw iera nazwę funkcji, która m a być w yw ołana. D ruga kolum na zaw iera nazw ę stałej definiującei odstęp czasu, w którym m a być w yw ołana ta funkcja. T rzecia kolum na zawiera dom yślną w artość tego czasu. O prócz budzików biblioteki lw iP będziem y jeszcze potrzebow ać budzika dla pro­ tokołu w arstw y aplikacji. C ałość im plem entacji budzików znajduje się w plikach u tiljw ip .h i u tiljw ip .c . W dalszym ciągu zam ieszczam tylko tekst źródłow y dla Stała dolinlująca Interw al czasowy w y­ wołania Dom yślna wartość Interwalu ip reass_tmr IP_TMR_INTERVAL 1000 ms etharp_tmr ARP_TMR_INTERVAL 5 0 0 0 ms tcp_tmr TCP TM R INTERVAL 2 5 0 ms dhcp_fine_tmr DHCP FINE TIMER MSECS 50 0 ms DHCP_COARSE_TIMER_MSECS 60 0 0 0 ms 1 Funkcja zw rotna s t a t u s _ c a l l b a c k pow inna być typu v o id i przyjm ow ać jed en ar­ gum ent, który musi być w skaźnikiem do struktury typu n e t i f opisującej interfejs sieciow y. Funkcję zw rotną ustaw ia się za pom ocą funkcji n e t i f s e t s t a t u s c a l ­ lb ack . 123 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu dhcp coarse tmr DHCP_COARSE_TIMER_SECS 60s dns tmr DNS_TM RJNTERVAL 1000 ms autoip_tmr AUTOIP_TMR_INTERVAL 100 ms igmp tmr IGMP TM R INTERVAL 10 0 ms budzików D H C P i budzika aplikacji. Im plem entacja pozostałych budzików je st ana­ logiczna. N ajpierw deklarujem y zm ienne odm ierzające czas. static ltime_t DHCPfineTimer; static ltime_t DHCPcoarseTimer; static ltime_t appTimer; N astępnie deklarujem y typ app_callback_t dla funkcji zw rotnej budzika aplikacji. Typ ten oznacza w skaźnik do bezparam etrow ej funkcji typu void. Zm ienna app trar przechow uje w skaźnik tego typu, czyli adres budzika aplikacji. Z m ienna app tmr_interval przechow uje interw al czasow y budzika aplikacji. typedef void (*app_callback_t)(void); static app_callback_t app_tmr = 0; static unsigned app_tmr_interval = 0; C zas je s t odm ierzany w m ilisekundach za pom ocą licznika system ow ego SysTick. Funkcja LWIPtimersStart inicjuje budziki biblioteki lw iP i ustaw ia funkcję zw rot­ ną LWIPtmr, która będzie w yw ołana cyklicznie w przerw aniu SysTick. Funkcja LWIPtimersStart je s t przew idziana do w yw ołania z program u głów nego i m anipu­ luje zm iennym i używ anym i w procedurze obsługi przerw ania, dlatego w ykonuje się przy zablokow anych przerw aniach. P oczątkow e w artości budzików lw iP ustalam y tak, aby uniknąć czasow ej korelacji ich w yw ołania. void LWIPtimersStart(void) { IRQ__DECL__PROTECT (X } ; ltime_t localTime = LocałTimeO; IRQ_PROTECT(x, LWIP_IRQ_PRIO); DHCPfineTimer = localTime + 31/ DHCPcoarseTimer = localTime; SET_PRIORITY (PendSV__IRQn, LWIP_IRQ_PRIO, 0); TimerCallBack(LWIPtmr); IRQ_UN PROTECT(x ); 1 P rzerw anie SysT ick ma w yższy priorytet (HIGH_IRQ_PRIO) niż priorytet przerw ań biblioteki lw iP (LWIP_IRQ_PRIO), gdyż czas m usi biegnąć podczas przetw arzania pakietów przez bibliotekę. D latego funkcja zw rotna LWIPtmr nie w yw ołuje bez­ pośrednio budzików , a tylko zgłasza przerw anie PendSV, które je s t obsługiw ane 3.4. Przykład 3a - pierwsza wersja sterownika Ethernetu z tym sam ym priorytetem co przerw ania biblioteki IwIP. Przerw anie PendSV nię je s t zw iązane z żadnym sprzętem . Jest to przerw anie program ow e, przeznaczone clij'1 w yw oływ ania niskopoziom ow ych usług system u operacyjnego, np. do przełączania' kontekstu w s'rodowisku w ielozadaniow ym , a zatem doskonale nadaje się do wyi| w ołania budzików . Jedynym sposobem w yzw olenia tego przerw ania je st ustawieni^ bitu PENDSVSET w rejestrze ICSR (ang. interrupt control a n d state register), któr'$ znajduje się w bloku rejestrów sterujących SCB (ang. system control block) rdzenia1' C ortex-M 3. graniu od stanu pew nych w yprow adzeń m ikrokontrolera. W zestaw ie ZL29A R M m ożna do tego w ykorzystać zw orkę B O O T1, podłączoną do w yprow adzenia PB2. Z w orka ta w ym usza na tym w yprow adzeniu stan niski lub w ysoki. Stan zw orki od­ czytujem y na początku program u za pom ocą funkcji GetConfBit, która znajduje się w pliku board_conf.c. D eklaracja tej funkcji znajduje się w pliku boarcl_conf.lt. idetine GPIO_CONF łdetine CONF_PIN idefine RCC_PERIPH_CONF GPIOB GPI0_Pin_2 RCC_APB2Periph_GPI0B static void LWIPtmr(void) { SCB->ICSR |* SCB_ICSR_PENDSVSET; uint8_t G e t C o n f B i t (void) uinŁ8__t bit; ( ) RCC_APB2Per i p h C l o c k C m d ( R C C _ P E R I P H _ C O N F , E N A B L E ) ; bit = GPIO__ReadInputDataBit (GPIO_CONF, CONFJ?IN); D opiero procedura obsługi przerw ania PendSV PendSV_Handler w yw ołuje właścbj we budziki biblioteki IwIP. 64-bitow a zm ienna typu zliczająca milisekundy, przepełni się po ok. 584 m ilionach lat. Z atem w praktyce m ożem y założyć, że nigdy’1;, się nie przepełnia, co upraszcza im plem entację. void PendSV_Handler(void) { ltime_t localTime = LocalTime(); RCC__APB2PeriphClockCmd (RCC_PERIPH_CONF, DISABLE) ; return bit; i 3.4.8. void LCDwritelP(const struct ip_addr *ip); void LCDwriteXPport(const struct ip_addr *ip, uintl6_t port); void LCDwriteRXTX(unsigned rx_pkts, unsigned rx_errs, unsigned tx_pkts, unsigned tx_errs); void LCDwriteTime(time_t rtime); i if (localTime >= DHCPcoarseTimer) ( DHCPcoarseTimer += DHCP_COARSEJHMER_MSECS; dhcp_coarse__tmr (); Pow yższe funkcje korzystają z funkcji LCDwrite. Funkcja LCDwritelP w ypisuje adres 1P w postaci czytelnej dla człow ieka, czyli jak o cztery liczby dziesiętne od­ dzielone kropkam i. Jej argum entem jest adres struktury reprezentującej adres IP w ew nątrz biblioteki IwIP. Funkcja LCDwriteIPport w ypisuje adres IP i num er por­ tu oddzielone dw ukropkiem . Funkcja LCDwriteRXTX w ypisuje liczby odebranych i w ysianych pakietów oraz błędów transm isji. Statystyk tych będzie nam dostarczał sterow nik m odułu ethernetow ego. W reszcie funkcja LCDwriteTime w ypisuje datę i czas w form acie czytelnym dla człow ieka. Jako argum ent pobiera liczbę sekund, które upłynęły od początku epoki uniksa, czyli od godziny 0:00:00 dnia 1 stycznia 1970 roku. I if (app_tmr__interval > 0 && localTime >= appTimer) { appTimer += app_tmr interval; if (app_tmr) app tmr(); Funkcja LWIPsetAppTimer konfiguruje budzik aplikacji. F unkcja ta manipuluje ; zm iennym i używ anym i w procedurze obsługi przerw ania, dlatego w ykonuje się-; przy zablokow anych przerw aniach. Pierw szym jej argum entem je s t adres funkcji: zw rotnej. D rugim argum entem je s t interw al czasow y w yw ołania budzika aplikacji'! w m ilisekundach. void LWIPsetAppTimer(app_callback t tmr, unsigned tmr interval) { IRQ_DECL_PROTECT(x); IRQ_PROTECT(x, LWIP_IRQm PRIO); app_tmr = tmr; app_tmr_interval = tmr_interval; appTimer = LocalTime(); IRQ_UNPROTECT(x); Pliki u tiljc d je x .h i u tiIJ c d je x .c Pliki u tiljc d _ e x .il i u tiljc d _ e x .c udostępniają bardzo przydatne funkcje przezna­ czone do w ypisyw ania specyficznych danych: if (localTime >= DHCPfineTimer) { DHCPfineTimer += DHCP_ITINE_TIMER_MSECS; dhcp_fine tmr(); 3.4.7. 125 3.4.9. Plik e x jp .c Plik e x j p . c zaw iera funkcję main przykładu. N a początku tej funkcji czytam y stan zw orki B O O T 1, od której ustaw ienia będzie zależeć konfiguracja adresów. int main () { uint8_t confBit; confBit = GetConfBit{) ; } i Pliki board_conf.h i board_conf.c Potem konfigurujem y poszczególne podukłady m ikrokontrolera, analogicznie jak bylo to w przykładzie 2. Podczas konfigurow ania św ieci czerw ona dioda. U staw ienia sieciow e w przykładow ych program ach m ogą być konfigurow ane sta-.;, tycznie lub dynam icznie za pom ocą DHCP. Sposób konfiguracji je s t w ybierany pr/> starcie program u. Z astosow ałem typow e rozw iązanie, które uzależnia działanie pro-;;;| int m a i n () ( AllPinsDisable(); 127 3.5. Przykład 3b - sterownik Ethernetu bez kopiowania LEDconfigure{); RedLEDonO; LCDconfigure {); SET_IRQ_PROTECTION(); LCDwrite("Clock "); error_check{CLKconfigure(}, 1); LCDwrite("PASS\n"); LCDwrite("Local Time "); error_check(LocalTimeConfigure(), 2); LCDwrite("PASS\n"}; LCDwrite("Ethernet "); error_check(ETHconfigureMII(), 4); LCDwrite("PASS\n"); K ażde urządzenie w sieci E thernet pow inno m ieć inny adres M A C . W ykorzystujeiij dostępne stale, aby utw orzyć niepow tarzalny adres. Przydzielam y adres M A C adni nistrow any lokalnie. Jeśli zw orka BOOT1 jest w pozycji 0, konfigurujem y ustawie’ nia sieciow e statycznie. Jeśli zw orka ta je st w pozycji 1, używ am y DHCP. Poniżśajf fragm ent program u konfiguruje interfejs sieciow y i bibliotekę lwIP. int m a i n O ( static struct netif netif; static struct ethnetif ethnetif = {PHY_ADDRESS}; LCDwrite("lwIP stack "); netif,hwaddr[0] 2; netif.hwaddr(l) (BOARD_TYPE » 8) & Oxff; netif.hwaddr[2] BOARDJTYPE 6 Oxff; netif,hwaddr[3] (ETHJ30ARD » 8) & Oxff; netif.hwaddr(4} ETH_BOARD & Oxff; netif.hwaddr[5] 1 + confBit; if (iconfBit) { IP4_ADDR(&neti£.ip_addr, 192, 168, 51, 84); IP4_ADDR(&netif.netmask, 255, 255, 255, 240); IP4_ADDR(finetif.gw, 192, 168, 51, 81); else { IP4_ADDR(Snetif.ip__addr, IP4_ADDR ({¿netif.netmask, IP4_ADDR(&neti£.gw, 0, 0, 0, 0) 0, 0, 0, 0) 0, 0, 0, 0) error_check (LWIPinterfacelnit (Snetif, {¿ethnetif), 5); LWIPtimersStart(); LCDwrite("PASS\n"); O statnią czynnością zw iązaną z konfigurow aniem je s t poczekanie na zakoric/cnie zdobyw ania ustaw ień sieciow ych przez klienta DHCP. C zekam y maksymalnie 10 sekund lub 4 próby. W artości te w ybrano dość sw obodnie i m ogą w ym agać mo-' dylikacji. Funkcja DHCPwait kończy działanie natychm iast, sygnalizując poprawne zakończenie, jeśli nie je s t w ykorzystyw any klient DHCP. Skonfigurow any adres II’ w yśw ietlam y na ekranie LCD. Z gaśnięcie czerw onej diody oznacza zakończenie konfigurow ania. C l o c k PASS L o c a l T i m e PASS E t h e r n e t PASS l w I P s t a c k P A S S .. Liczba odebranych ramek ’ 1 P 1 1 92,166,51.89 Liczba prób wysłania ramki Inform acje o uruchom ieniu " poszczególnych podukładów Skonfigurowany adres IP Liczba błędnie odebranych ramek Liczba błędów podczas w ysyłania ramek Rys. 3.3. Wygląd LCD podczas działania programu int raaind ( LCDwrite("IP error_check{DHCPwait(Snetif, 10, 4), 6); LCDwritelP(snetif.ip_addr); RedLEDoff 0 ; I W głów nej pętli program u w yśw ietlam y statystyki odebranych i w ysłanych ram ek ethernetow ych. W ygląd w yśw ietlacza ciekłokrystalicznego przedstaw iono na r y ­ s u n k u 3.3. int main{) 1 for (;;} { LCDgoto(6, 0); LCDwriŁeRXTX(ethnetif,RX_packets, ethnetif.RX_errors, ethnetif,TX_packets, ethnetif.TX_errors); Delay(1000); ł ) Przykład 3b - sterownik Ethernetu bez kopiowania W tym przykładzie prezentuję ulepszony sterow nik interfejsu ethernetow ego. Jest to podstaw ow y sterow nik dla w szystkich przykładów w kolejnych rozdziałach. Jest on kom patybilny z poprzednim i w e w szystkich przykładach oba m ogą być stosow ane zam iennie. U lepszenie polega na rezygnacji z buforów odbiorczych D M A i kopio­ w aniu odebranych ram ek bezpośrednio do buforów biblioteki lwIP. Ponadto w tym sterow niku w kolejkach odbiorczej i nadaw czej używ am y pierścieni deskryptorów . N azw y plików , które zaw ierają im plem entację tego przykładu, zam ieszczone są w ta b e li 3.12. W stosunku do przykładu poprzedniego je s t tylko jed n a różnica. Plik util_eth.c zastąpiono plikiem util_etli_nc.c. W dalszym ciągu opisuję tylko różnice m iędzy tym i plikam i. Plik u tilje th jjc .c - inicjowanie interfejsu sieciowego W tej w ersji sterow nika bufory odbiorcze pochodzą z puli buforów biblioteki lwIP. D o ich obsługi definiujem y dw ie globalne tablice. W tablicy rxBuf ferFlags prze­ chow ujem y znaczniki. W tablicy rxBuffer przechow ujem y w skaźniki do struktury typu pbuf opisującej bufory odbiorcze. Tablice te m ają tyle sam o elem entów co pierścień deskryptorów , czyli po jed n y m elem encie dla każdego deskryptora. 128 3. Stos TCp/ffl Tab. 3.12. Pliki przykładu 3b Zrńdlnwi! i biblioteczne ex_ip.c font5x8.c startup_stm 32_cld. c board_conf.c boardJn it.c board_lcd_ks0108. c board led.c utiljfelay.c util_eth_nc.c u tiljc d .c u tiljcd _e x.c u tilje d .c u tiljw ip .c util time.c tibtwip4.a Hbstm32f10x.a font5x8.h board_conl.li board_def.fi board_defs.li b o a rd jn it.li b o a rd jc d .li b o a rd je d .h CC.Il cortex-m 3.h Iwipopts.h stm 32l10x_conf.li static uint8_t rxBufferFlags[ETH_RXBUFNB); static struct pbuf *rxBuffer(ETiJRXBUFNB); B ufory odbiorcze alokuje funkcja A l locRxBuffers w yw ołana w funkcji ETHiniii przed skonfigurow aniem D M A . Z m iana w funkcji ETHinit jest następująca: if (AllocRxBufferso < 0) return ERR MEM; ETHconfigureDMA(netif, L W I P J R Q J R I O , 0}; Funkcja A l locRxBuffers zw raca zero, gdy zakończyła się sukcesem , a warlo? ujem ną w przeciw nym przypadku. B ufory alokujem y z puli buforów bibliote! lwIP. Poniew aż alokujem y bufory o rozm iarze rów nym buforom w puli, przydziel ne łańcuchy buforów m ają p o jed n y m elem encie, czyli bufory są w jed n y m kawat (patrz opis stałej PBUF_POOL_BUFSIZE zdefiniow anej w pliku Iw ipopts.h). static int AllocRxBuffers(void) int i, j; ( for (i = 0; i < ETHJWBUFNB; ++i) { rxBufferFlags(i) = 0; rxBuffer[il = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, P B U F J O O L ) ; if (rxBufferii] == NULL) ( for (j = i - 1; j >= 0; — j) pbuf free(rxBuffer(i)); return -1; D o w ysyłania ram ek będziem y, ja k w poprzednim sterow niku, używ ać statycznych buforów nadaw czych. Jednak, aby om inąć ograniczenia ukryte w im plem entacji bi­ blioteki ST M 32, nie skorzystam y z funkcji oferow anych przez tę bibliotekę. Dzięki tem u m ożem y na przykład zdefiniow ać w łasny rozm iar buforów nadaw czych, aby uw zględniał ram ki V LA N, które być m oże w przyszłości zechcem y obsługiw ać. Funkcja ETHconf igureDMA m a podobną strukturę do jej odpow iednika z poprzednie­ go sterow nika. R óżnica polega na tym , że teraz konfigurujem y kolejki deskryptorów ja k o pierścienie i nie używ am y do tego funkcji z biblioteki STM 32. N ajpierw kon­ figurujem y pierścień deskryptorów odbiorczych. Składow ą ControlBufferSize we w szystkich deskryptorach zerujem y m iędzy innym i po to, aby w yzerow ać bit DIC i tym sam ym uaktyw nić przerw anie odbiorcze. W łaściw ym inicjow aniem deskryp­ torów odbiorczych zajm uje się, opisana niżej, funkcja DMAr x B u f ferSet. N astępnie konfigurujem y pierścień deskryptorów nadaw czych. Z erujem y też indeksy bieżą­ cych deskryptorów . R eszta funkcji je s t analogiczna ja k w poprzednim sterow niku. static void ETHconfigureDMA(struct netif ‘netif, uint8_t priority, uint8_t subpriority) NVIC_InitTypeDef NVIC_IniŁStruct/ int i; { DMArxIdx = 0; j for {i * 0; i < ETH_RXBUFNB; ++i) i DMArxRing[ij.ControlBufferSize = 0; DMArxBufferSet(&DMArxRing{i], rxBuffer[i]); } DMArxRingfETH_RXBUFNB - 1).ControlBufferSize ¡= ETH_DMARxDesc_RER; ETH->DMARDLAR = (uint32_t)DMArxRing; DMAtxIdx = 0; for (i = 0; i < ETHJXBUFNB; ++i) ! i if CHECKSUMJ5ENJP =* 0 DMAtxRing[i).Status = ETHJ)MATxDesc_CICJPV4Header; jjelse DMAtxRingEi].Status = 0; tfendif DMAtxRing[i].ControlBufferSize = 0; DMAtxRing[i].BufferlAddr = (uint32_t)TxBuff(i); DMAtxRing(i].Buffer2NextDescAddr = 0; ) } I return 0; ) K olejną różnicą w stosunku do poprzedniego sterow nika je st użycie pierścienia < skryptorów . D eklarujem y dw ie tablice, w których zorganizujem y te pierścienie < dw a indeksy, które będą w skazyw ać odpow iednio bieżący deskryptor odbiorczy i i nadawczy. static static static static 129 »define TX_BUFFER_SIZE (ETIi MAX_PACKET_SIZE ł VLAN_TAG - ETH_CRC) static uint8_t TxBuff(ETH_TXBUFNBJ¡TX_BUFFER_SIZEj ALIGN4; Nagłówkowe util_delay.il utH_eth.h u tiljc d .h u tiljcd _e x.li u tilje d .h u tiljw ip .h util time.h 3.5. Przykład 3b - sterownik Ethernetu bez kopiowania ETH_DMADESCTypeDef DMArxRin g {ETH_RXBUFNB] ALIGN4; ETH_DMADESCTypeDef DMAtxRing[ETHJ’ XBUFNB] ALIGN4; int DMArxIdx; int DMAtxIdx; DMAtxRing (ETHJ’ XBUFNB - 1].Status |= ETH_DMATxDesc J E R ; ETH->DMATDLAR = (uint32_t)DMAtxRing; p_netif = netif; NVIC_InitStruct .NVICJRQChannel = ETHJRQn; NVICJnitStruct .NVICJRQChanneiPreemptionPriority = priority; NVICJnitStruct.NVICJRQChannelSubPriority = subpriority; NVICJnitStruct.NVICJRQChannelCmd * ENABLE; NVI C J n i t ( S N V I C J n i t S t r u c t ) ; ETH_DMAITConfig(ETH_DMAJT_NIS ! ETH_DMAJT_R, ENABLE); ) Pierw szym argum entem funkcji DMArxBuf ferSet je s t w skaźnik do inicjow anego deskryptora odbiorczego. D rugim argum entem je s t w skaźnik do struktury typu pbuf 3. Si os TCP/ip< 13 0 opisującej bufor, do którego m a być skopiow ana odebrana ram ka. B ufor je st przy-, dzielony w jednym kaw ałku, w ięc w ykorzystujem y tylko składow ą B ufferlA dd: Adres drugiego bufora B uffer2N extD escA ddr zerujemy. N a koniec zerujem y polo statusu i przekazujem y w łasność dcskryptora układow i DM A. static void DMArxBufferSet(ETH_DMADESCTypeDef *rxDesc, struct pbuf *p) { rxDesc->ControlBufferSize &= ~ (E'i'H_DMARxDesc_RBSl j ETH_DMARxDesc_RBS2) ; rxDesc->ControlBufferSize |= p->len & ETH_DMARxDesc_RBSl; rxDesc->BufferlAddr = (uint32_t) p->payload; rxDesc->Buffer2NextDescAddr = 0; rxDesc->Status = ETH DMARxDesc OWN; 3.5.2. Plik util_eth_nc.c - wysyłanie ramek ethernetowych Jedyną istotną różnicą w funkcji l ow_level_output w ysyłającej ram ki elhernetovu' w stosunku do poprzedniego sterow nika je s t użycie pierścienia zam iast łańcucha deskryptorów . static err_t low_level_output(struct netif *netif, struct pbuf *p) { ((struct ethnetif *)netif->state)->TX_packets++; if (p == NULL) { {(struct ethnetif *)netif->state)->TX_errors++; return ERR_ARG; ) if (p->tot_łen > TX_BUFFER_SIZE) { ((struct ethnetif *)netif->state)->TX_errors+-ł; return ERR_BUF; I if (DMAtxRing[DMAtxIdx].Status & ETH_DMATxDesc_OWN) ((struct ethnetif *) netif->state) ->TX__errors+ł; return ERR_XF; i { i pbuf_copy_partial(p, (void *)DMAtxRing(DMAtxIdx).BufferlAddr, p->tot_len, 0); DMAtxRing[DMAtxIdx].ControlBufferSize = p->tot_len & ETH_DMATxDesc__TBSl; DMAtxRing(DMAtxIdx).Status j= ETH_DMATxDesc_FS I ETH_DMATxDesc_LS i ETH_DMATxDesc_OWN; if (ETH->DMASR & ETH_DMASR_TBUS) ( * ETH->DMASR = ET H_DMAS R_T BUS; ETH->DMATPDR = 0; ) if (DMAtxRing(DMAtxIdx] .Status 6 ETHJ3MATxDescJFER) DMAtxIdx = 0; else -i+ DMAtxIdx; return ERR OK; 3.5.3. Plik util_eth_nc.c - odbieranie ramek ethernetowych DM A kopiuje odebraną ram kę do bufora, który przekazujem y bibliotece lwIP. Od tego m om entu w łaścicielem tego bufora je s t biblioteka. B iblioteka zw olni bufoi, gdy ju ż nie będzie je j potrzebny. Z w alniany b u for w raca do puli buforów biblioteki. Z atem bufor przekazany bibliotece nie m oże ju ż dłużej być w skazyw any przez de- 3.5. Przykicui 3b - sterownik Ethernetu bez. kopiowania 131 skryptor w kolejce odbiorczej i w jeg o m iejsce trzeba przydzielić nowy bufor z puli. A lokow aniem now ych buforów zajm uje się funkcja ReallocRxBuffers, w yw ołana w procedurze obsługi przerw ania ETH_IRQHandler. void ETH_IRQHandłer(void) | ETH_DMACiearITPendinqBit(ETH_DMR_IT_NIS | ETH_DMA_IT_R); while (!(DMArxRinglDMArxIdxJ.Status s ETH_DMARxDesc_OWN)) 1 ethernetif_input(p_netif); ReallocRxBuffers ( ) t ) ) Funkcja ReallocRxBuffers przegląda cyklicznie kolejkę odbiorczą. Statyczna zm ienna idx je s t indeksem w pierścieniu deskryptorów . W skazuje deskryptor, któ­ ry należy uaktualnić. U staw iony znacznik RX_BUF_U S E D _ U P oznacza, że deskryptor został w ykorzystany i trzeba go zw rócić układow i D M A . W artość NULL w tablicy rxBuffer oznacza, że bufor został przekazany bibliotece lw IP i trzeba przydzielić now y bufor. Jeśli nie uda się przydzielić bufora, funkcja kończy działanie oczeku­ jąc, że uda się to przy następnym jej w yw ołaniu. Jeśli bufor je s t przydzielony, czyli w skaźnik w tablicy rxBuffer je s t niezerow y, to zerujem y znacznik RX_BUF_USED_ UP i inicjujem y deskryptor za pom ocą funkcji DMArxBufferSet. Idefine RX_BUF_USED_UP 1 static void ReallocRxBuffers(void) static int idx = 0; { while (rxBufferFlags(idx) & RX_BUF_USED_UP) { if (rxBuffer[idx] == NULL) { rxBufferfidx] = pbufj*lloc(PBUF_RAW, PBUF_POOL__BUFSIZE, PBUF__POOL) ; if (rxBufferfidx] == NULL) return; ) rxBufferFlags(idx] &= ~RX_BUF_USED_UP; DMArxBufferSet(SDMArxRing(idx ) , rxBuffer(idx)); if (DMArxRing(idx].ControlBufferSize & ETH_DMARxDesc_RER) idx * 0; else ++idx; ) } Jak poprzednio przekazaniem odebranej ram ki bibliotece lw IP zajm uje się funkcja ethernetif_input. Poniew aż funkcja ta je s t w yw ołana w procedurze obsługi prze­ rw ania, gdzie nie m ożna zrobić w ielkiego użytku ze zw racanego przez nią kodu błędu, ta jej w ersja nie zw raca żadnej w artości. Funkcja la uaktualnia statystykę odebranych ram ek. N ależy pam iętać, że jeśli w yw ołanie funkcji przetw arzającej ram ki w bibliotece lwIP, czyli funkcji w skazyw anej przez składow ą input struk­ tury netif, zakończy się pow odzeniem , to bufor został zw olniony. Jeśli natom iast zakończy się błędem , to m usim y zw olnić ten bufor. static void ethernetif_input(struct netif *netif) { struct pbuf *p; ((struct, ethnetif *) netif->state) ->RX_packets-M; p = low__łevel_input (netif); if (p «= NULL) 3.6. Przykład 3c - eksperymentalny sterownik Ethernetu bez. kopiowania ((sfcruct ethnetif *)netif->state)->RX_errorsi+; else if <netif->input(p, netif) !«* ERR_OK) { pbuf_free(p)/ {(struct ethnetif *)netif->state)->RX_errors++; ) } N iskopoziom ow ą obsługą odebranej ram ki zajm uje się funkcja low_level_inputf F unkcja la najpierw spraw dza, czy bieżący deskryptor zaw iera popraw nie odebraną, ram kę i czy ram ka nie je st za krótka. Jeśli spraw dzenie w ypadnie pozytyw nie, funkcja zw róci w skaźnik do struktury typu p b u f opisującej bufor z odebraną rani-' ką. Z anim jed n ak zakończy działanie, w pisuje do tablicy rx B u ff e r w artość NUL aby poinform ow ać funkcję R e a llo c R x B u ffe rs, że trzeba przydzielić nowy bufoi*B iblioteka łw IP oczekuje ram ki ethernetow ej bez sekw encji kontrolnej. Funkcj p b u f_ _ reallo c ustaw ia w łaściw y rozm iar ram ki. D la buforów typu PBUF_POOL funk* cja ta niczego nie kopiuje, uaktualnia tylko składow e le n i tot__len struktury typ'1 p b u f. N a koniec, ja k poprzednio, trzeba jeszcze w znow ić przeglądanie kolejki od­ biorczej, jeśli zostało w strzym ane. static struct pbuf * low_level_input(struct netif *netif) { struct pbuf *p = NULL; uint32_t len; if {(DMArxRing[DMArxIdxl.Status £ ETH_DMARxDesc_ES) == 0 ££ (DMArxRing[DMArxIdx).Status £ ETH_DMARxDesc_LS) != 0 ££ (DMArxRing[DMArxIdx).Status £ ETH_DMARxDesc_FS) != 0} I len = ETl!_GetDMARxDescFrameLength (£DMArxRing(DMArxIdxj); if (len >= ETH_HEADER + MIN_ETH_PAYLOAD + ETH_CRC) f len -= ETH_CRC; p = rxBuffer(DMArxIdx); pbuf_realloc(p, len); rxBuffer(DMArx!dx] = NULL; i } rxBufferFlags(DMArxIdx) j» RX_BUF_USED_UP; if (DMArxRing[DMArxIdx}.ControlBufferSize £ ETH_DMARxDesc_RER) DMArxIdx = 0; else + t-DMArxIdx; if (ETH->DMASR £ ETH_DMASR_RBUS) { ETH->DMASR = ETH_DMASR_RBUS; ETH->DMARPDR = 0; I return p; Przykład 3c - eksperymentalny sterownik Ethernetu bez kopiowania W tym przykładzie prezentuję kolejne ulepszenie sterow nika interfejsu sieciowego. U lepszenie zm ierza w kierunku pełnej realizacji idei „zero-copy” . Rezygnujemy z buforów nadaw czych D M A i w ysyłam y ram ki bezpośrednio z buforów bibliote­ ki IwIP. N azw y plików, które zaw ierają im plem entację, zebrane są w tabeli 3.13. W stosunku do poprzedniego przykładu plik util_eth_nc.c został zastąpiony plikiem util_eth_zc.c. W dalszym ciągu opisuję tylko różnice m iędzy tym i plikam i. 133 Tab. 3.13. Pliki przykładu 3c Źródłowe i biblioteczne BX_ip.C lonl5x8.c startup_stm32_cld. c board_conl.c b o a rd jn it.c b o a rd jcd _k s01 08.c b o a rd je d .c font5x8.h board_conl.lt board_del.lt board_deis.it b o a rd jn it.h board_lcd.lt b o a rd je d .h util_delay.c util_eth_zc.c u tiljc d .c u tiljc d _ e x .c u tilje d .c u tiljw ip .c u tiljim e .c Iiblwip4.a Iibstm 32l10x.a Nagłówkowe util_delay.h util_eth.li u liljc d .h utilJcd_ex.it u tilje d .h u liljw ip .h util time.b CC.il corlex-m 3.li Iwipopts.li stm 32l10x_con/.h S terow nik ten je st eksperym entalny, gdyż nie będzie działał ze w szystkim i przykła­ dam i. Pow ody są następujące: - -Biblioteka IwIP um ieszcza w ysyłaną ram kę w łańcuchu buforów. Zakładam , że łańcuch składa się z co najw yżej dw óch struktur typu pbuf. Ten sterow nik nie potrafi w ysiać ram ki rozm ieszczonej w łańcuchu składającym się z w iększej liczby elem entów . Z aobserw ow ałem jednak, że biblioteka sporadycznie generuje dłuższy łańcuch, eh^tć zaw sze było to w sytuacji, gdy w cześniej w ystąpił pro­ blem z siecią. W praktyce, gdy sieć działa stabilnie, sterow nik spisuje się zado­ w alająco. - B iblioteka IwIP m oże m odyfikow ać zaw artość bufora z ram ką przekazaną do w ysiania, jeśli w ykonuje retransm isję segm entu TCP. Z atem sterow nik musi zdą­ żyć w ysiać ram kę, zanim biblioteka podejm ie decyzję o retransm isji. W prakty­ ce, gdy sieć pracuje popraw nie, zaw sze zdąży. - D M A m a problem z w ysyłaniem danych um ieszczonych w pam ięci Flash. Zw ykle jed n ak w ysyłane dane są przygotow yw ane w buforze, który jest w RAM , więc problem ten nie je s t dotkliw y. Jeśli jed n ak dane do w ysiania są w e Flash, trzeba je najpierw skopiow ać do RAM . Jest to sprzeczne z ideą „zero-copy” przyśw ie­ cającą stw orzeniu tego sterow nika. Do problem u w ysyłania danych um ieszczo­ nych w pam ięci Flash w rócę jeszcze w kolejnym przykładzie. M im o pew nych niedoskonałości tego sterow nika, postanow iłem go jednak zapre­ zentow ać w takiej postaci, aby nie kom plikow ać tekstu źródłow ego. N apisanie na tej podstaw ie w pełni funkcjonalnego sterow nika pozostaw iam C zytelnikow i jako ćw iczenie. Plik util_eth_zc.c - inicjowanie interfejsu sieciowego Ta w ersja sterow nika nie używ a statycznych buforów nadaw czych. Z am iast nich używ a buforów z puli biblioteki IwIP. W globalnej tablicy tx B u ff e r przechow u­ jem y otrzym ane od biblioteki IwIP w skaźniki do struktur typu pbuf. Tablica ta ma tyle sam o elem entów , ile je s t deskryptorów w pierścieniu nadaw czym , czyli po je d ­ nym dla każdego deskryplora. 3.6. Przykład 3c - eksperymentalny sterownik Ethernetu bez, kopiowania static struct pbuf ‘txBufferIETHJTXBUFNB]; Teraz w funkcji E T H init przed skonfigurow aniem D M A , oprócz alokow ania bii' forów odbiorczych, trzeba jeszc z e zainicjow ać pow yższą tablicę wskaźnikó," M odyfikacja je s t następująca: Aj if (AilocRxBuffers() < 0) return ERR_MEM; InitTxBuffers{); ETHconfigureDMA(netif, LWIP__IRQ_PRIO, 0) ; 135 B uforów nadaw czych je s t niew iele, w ięc funkcja FreeTxBuf f e r s m oże przy każ­ dym w yw ołaniu przeglądać j e naiw nie, liniow o. Jeśli znajdzie w tablicy tx B u ff e r niezerow y adres łańcucha buforów i deskryptor o tym sam ym indeksie został zw olniony przez DM A, to zw alnia ten łańcuch buforów . Funkcja ta uaktualnia też statystykę błędów. static void FreeTxBuffers(struct netif *netif) ( int i; for (i = 0; i < ETHJTXBUFNB; ++i) I if (txBuffer(i) SS (DMAtxRingli].Status s ETH_DMATxDesc_OWM) == 0) ( if (DMAtxRingli).Status S ETH_DMATxDesc_ES) ((struct ethnetif *) netif->state) ->TX_errorst *f; pbuf_free(txBuffer(i}}; txBuffer(i) = NULL; Funkcja in itT x B u ff e r s po prostu zeruje w szystkie w skaźniki. W łaściw e wartośęi będą przypisyw ane d y nam icznie w funkcji w ysyłającej ram ki. N iezerow a warlośd w skaźnika będzie oznaczać, że w skazuje on na łańcuch buforów. static void InitTxBuffers(void) ( int i; ) for (i = 0; i < ETH_TXBUFNB; ++i) txBuffer[i] = NULL; 1 :!'/ Funkcja ETHconfigureDMA różni się od sw ojej poprzedniczki tylko dw om a instruk­ cjam i: DMAtxRing[i].BufferlAddr = 0; ETH_DKAXTConfig(ETH_DMA_IT_NIS | £TH_DMA_IT__R | ETH_DMA_IT_T, ENABLE); Nie znam y adresów buforów z w ysyłanym i ram kam i, więc na razie zerujem y skla* dow ą B u ffe rlA d d r we w szystkich deskryptorach nadaw czych. A by móc dynamicz^ nic obsługiw ać bufory nadaw cze, potrzebujem y inform acji o zakończeniu transmisji; D latego, oprócz przerw ania zgłaszanego po skopiow aniu odebranej ram ki, uaktyw­ niam y też przerw anie inform ujące o zakończeniu przez D M A transm isji wysyłanej ram ki (ustaw iam y dodatkow o bit ETH_DMA_IT_T). Plik util_eth_ 2c.c - wysyłanie ramek ethernetowych Poniew aż uaktyw niliśm y now e źródło przerw ania, m usim y zm odyfikow ać proce durę ETH_IRQHandler o bsługującą przerw ania E thernetu. C zęść obsługująca pi/c-1 rw anie odbiorcze je st w zasadzie identyczna ja k w poprzedniej w ersji sterownik W części obsługującej przerw anie nadaw cze w yw ołujem y funkcję FreeTxB uffers', zw racającą do puli te bufory, których zaw artość została ju ż w ysłana przez DMA. void ETH_IRQHandler(void) ( ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS ) ; if (ETH_GetDMAITStatus(ETH_DMA_IT_T)) ( ETH_DMAClearITPendingBit(ETH_DMA_IT_T); FreeTxBuffers(p_netif); ) if (ETH_GetDMAITStatus(ETH_DMA_IT_R)) ( ETH_DMAClearITPendingBit(ETH_DMA_IT_R); while (!(DMArxRing[DMArxIdx).Status S ETIl_DMARxDesc_OWN)) ( ethernetif_input(p_netif); ReallocRxBuffers(); ) , ! Za w staw ienie ram ki do kolejki nadaw czej odpow iada, jak poprzednio, funkcja lo w _ le v e ł_ o u tp u t. Funkcja ta najpierw spraw dza popraw ność argum entów i do­ stępność w olnego deskryptora w kolejce nadaw czej oraz uaktualnia statystykę w y­ słanych ram ek. N astępnie zw iększa licznik referencji łańcucha buforów p i zapisuje je g o adres w tablicy tx B u ffe r. B iblioteka lw IP po popraw nym zakończeniu funkcji lo w _ łe v e l_ o u tp u t w yw ołuje na łańcuchu buforów funkcję pbuf__free. Z w iększenie licznika referencji spraw ia, że bufory zostaną zw olnione dopiero wtedy, gdy funkcja p b u f_ f re e zostanie w yw ołana po raz drugi w funkcji FreeTxBuf f e r s . D eskryptor je st inicjow any za pom ocą funkcji DMAtxBuff e r S e t. N a koniec w znaw iane jest przeglądanie kolejki nadaw czej i indeks DMAtxIdx jest przesuw any na następny de­ skryptor w pierścieniu. static err t low__level_output (struct netif *netif, struct pbuf *p) ( {(struct ethnetif *)netif->state)->TX_packets+-f-; if (p NULL) ( ({struct ethnetif *)netif->state)->TX_errors++; return ERR ARG; 3 if (pbuf_chain_łen(p) > 2 |j txBuffer[DMAŁxIdx] || DMAtxRing[DMAtxIdx].Status & ETH_DMATxDesc_OWN) ({struct ethnetif *)netif->state)->TX_errors++; return ERR_IF; } pbuf_ref(p); txBuffer[DMAtxIdx] = p; DMAtxBufferSet(SDMAtxRingfDMAtxIdx], p ) ; if (ETff->DMASR & ETH_DMASR_TBUS) i ETH->DMASR - ETH_DMASR_TBUS; ETH->DMATPDR = 0; ) if (DMAtxRing(DMAtxIdxj.Status & ETH_DMATxDesc_TER) DMAtxIdx «= 0; else ■f+DMAtxIdx; return ERR_0K; { 137 3.8. ICMP - komunikaty kontrolne i komunikaty o błędach Jak napisałem w cześniej, zakładam y, że w ysyłana ram ka będzie umieszczony w 7łańcuchu buforów o długości co najw yżej dw a. D ługość łańcucha sprawdzarriyj, za pom ocą funkcji p b u f_ c h a in _ le n , która je st bardzo podobna do funkcji pb c le n z biblioteki łwIP, ale w przeciw ieństw ie do niej je s t popraw na. static iiit pbuf_chain_len(struct pbu£ int len; T a b . 3 .1 4 . ■pi i Porównanie sterowników Przykład Sterownik Flash HAM 3a util_eth.c 53 488 42 988 917 ± 1 2 p s 3b util eth nc.c 53556 36924 877 ± 3 2 ps 3c u til_ e th jc .c 53768 30 860 85 9 ± 2 5 ps Tab. 3.15. Użyte parametry programu p in g len = p != NULL; while (p i= NULL &S p->tot_len != p->len) { •H len; p “ p~>next:; Param etr Linux Param etr Windows -n liczba Wysyła podaną liczbę próśb o echo -s liczba -1 liczba Tworzy komunikat z polem danych o podanej długości. Wysyłając więcej niż 1472 oktety danych, można przetestować poprawność działania tragmentacji i składania datagramów IP -n Funkcja DM AtxBufferSet inicjuje deskryptor w kolejce nadaw czej i przekazu­ je go układow i DM A. U staw ia też b it IC, aby po zakończeniu transm isji zostĄ ło zgłoszone przerw anie. Z ależnie od długości łańcucha buforów p wykot/yi styw any je st tylko adres je d n eg o bufora lub oba adresy (składow e B u fferlA d d ' i Buf fer2N extD escA ddr). Nie podejmuje próby przetłumaczenia adresu IP na nazwę węzła 192.168.51.89 Adres węzła, do którego są wysyłane prośby o echo że kolejne w ersje sterow ników m ają coraz bardziej skom plikow any tekst źródłow y i zajm ują coraz w ięcej pam ięci program u, ale przyrost ten jest nieznaczny i nie ma praktycznego znaczenia. N atom iast likw idacja statycznych buforów odbiorczych w przykładzie 3b, a następnie rów nież statycznych buforów nadaw czych w przy­ kładzie 3e, w yraźnie zm niejsza zajętość pam ięci danych. Pozostaje więcej m iejsca na stertę i stos, co pozw ala bardziej elastycznie gospodarow ać niew ielką pam ięcią m ikrokontrolera. static void DMAtxBufferSet(ETH_DMADESCTypeDef *txDesc, struct pbuf *p) { txDesc->ControłBufferSize = (uint32_t)p->len & ETHJ3MATxDesc_TBSl; txDesc->BufferlAddr = (uint32_t)p->payload; if (p->tot_len > p->len) { p - p->next; txDesc->ControlBufferSize |= ((uint32_t)p->len « 16) S, ETH_DMATxDesc_TBS2; txDesc~>Buffer2NextDescAddr = (uint32_t)(p->payload); Aby spraw dzić, czy pozbycie się kopiow ania ram ek przyspiesza ich obsługę, zm ie­ rzyłem za pom ocą program u ping czasy odpow iedzi program u na kom unikaty p ro ś­ ba o echo protokołu IC M P - patrz rozdział 3.8. W L inuksie polecenie jest nastę­ pujące: ) else txDesc->Buffer2NextDescAddr = 0; txDesc->SŁatus 1= ETH_DMATxDesc_IC | ETH_DMATxDesc_FS | ETH_DMATxDescJLS i ETH_DMATxDesc_OWN; ping -c 100 -s 1472 -n 192.168.51.89 W system ach W indow s w ygląda tak: i Jeśli chcielibyśm y zaim plem entow ać obsługę łańcuchów buforów o długości w ic i­ szej niż dw a, to do w ysłania jednej ram ki m ożna użyć kilku kolejnych deskryptoiów W pierw szym z tych deskryptorów ustaw iam y tylko bit FS, a w ostatnim tylko bi^ LS. O czyw iście w tedy odpow iednio kom plikuje się też zw alnianie buforów. Nalęż rów nież pam iętać, żeby bit OWN w pierw szym z tych deskryptorów ustaw ić dopierona końcu, po zainicjow aniu w szystkich deskryptorów . W przeciw nym przypadk D M A m oże rozpocząć transm isję, zanim cała ram ka będzie golow a do wysłania. W tabeli 3.14 zam ieszczone je s t porów nanie w yżej opisanych sterow ników . W ko?; lum nie Flash je st podana całkow ita zajętość pam ięci program u, uw zględniająca ta-* blicę przerw ań, sekcję . t e x t (w tym sekcję .r o d a ta ) oraz sekcję .d a ta . W kolunP nie R A M je s t pod an a zajętość pam ięci danych, uw zględniająca sekcje .d a ta i J'-: 3 ale nieuw zgłędniająea pam ięci alokow anej dynam icznie na stosie i stercie. Wida Opis -c liczba } return len; Testy sterowników Czas odpowiedz! ping -n 100 -1 1472 192.168.51.89 U żyte param etry opisane są w tabeli 3.15. Test polegał na w ysianiu 100 próśb, z któ­ rych każda zaw ierała po 1472 oktety danych, aby w ypełnić całą ram kę ethernetow ą. O statnia kolum na tabeli 3.14 zaw iera średni czas oczekiw ania na otrzym anie odpo­ wiedzi i je g o odchylenie standardow e, w ypisane przez linuksow ą w ersję program u ping. W ersja w system ie W indow s m ierzy czas zbyt m ało dokładnie. M im o sporego rozrzutu tych czasów w idać, że likw idacja niepotrzebnego kopiow ania przyspiesza przetw arzanie ram ek. 3.8. ICMP - komunikaty kontrolne i komunikaty o błędach IC M P (ang. Internet C ontro/ M essage Protocol) to intersieciow y protokół kom u­ nikatów kontrolnych, opisany w RFC 792. Jest on obow iązkow ą częścią IP, co oznacza, że każda im plem entacja IP musi też im plem entow ać ICMP. Przyjęto go 138 3.8. ICM P —komunikaty kontrolne i komunikaty o błędach 3' •V,','v lifts k om po n en ty intersieci d ziałają praw id ło w o - o p ro g ram o w an ie IP nadaw cy w y­ syła i o d b iera datagram y, rutery p o średnie m iędzy nad aw cą a od b io rcą p raw id ­ łow o p rzesy łają datagram y, w ęzeł d o celo w y je s t u ru chom iony i d ziała na nim o p ro g ram o w an ie IP. N ależy je d n a k zazn aczy ć, że w ęzły nie m uszą odpow iadać na p ro śb ę o ech o - m oże to być ze w zględów b ezp ieczeń stw a zablokow ane ad ­ m in istracyjnie. Tab. 3.16. Wybrane wartości pola TYP komunikatu ICMP Komunikat Typ Odpowiedź z echem 0 3 Odbiorca nieosiągalny 4 Tłumienie nadawcy 8 Prośba o echo 11 Przekroczenie czasu 12 Problem z parametrem TYP [0:7] 3.8.2. IDENTYFIKACJA (0:31) DANE Rys. 3.4. Format komunikatu ICMP O dbiorca m oże być nieosiągalny z w ielu pow odów . M oże w ystąpić aw aria odcina­ ją c a podsieć, w której znajduje się w ęzeł odbiorcy. W ęzeł m oże być po prostu w yłą­ czony. T rzeba jednak jasn o zaznaczyć, że w sieci E thernet nie m a prostego sposobu stw ierdzenia, że ja k iś w ęzeł nie działa. M im o działania w ęzła odbiorcy, m oże nie działać aplikacja, do której adresow any je s t datagram IP. K om unikat o nieosiągal­ ności m oże też pojaw ić się, gdy kom unikacja z odbiorcą je s t zablokow ana adm ini­ stracyjnie. w spólnie z 1P, ja k o standard intersieci S T D 5. IC M P um ożliw ia diagnozow anie prdł blcm ów w działaniu intersieci. IC M P pow iadam ia pierw otnego nadaw cę datagram! IP o problem ie z tym datagram em . K om unikaty ICM P są kapsulkow ane w data* graniach IP, aby m ogły być dostarczane w dow olne m iejsce intersieci. Mimo IC M P nie je st uw ażany za protokół w arstw y transportow ej. JesTi w ystąpi probier) z dostarczeniem datagraniu przenoszącego kom unikat ICMP, nie w ysyła się koloj^ nego kom unikatu IC M P inform ującego o tym błędzie, aby nie spow odow ać lawiny kom unikatów , które m ogłyby zapchać sieć. K om unikat odbiorca nieosiągalny um ożliw ia rów nież poznanie M TU ścieżki do odbiorcy. M T U ścieżki je s t to najm niejsze M T U w śród w szystkich sieci, przez któ­ re w ędruje datagram IP. Z najom ość M T U ścieżki um ożliw ia w ysyłanie datagraniów IP o takiej długości, aby nie m usiały być po drodze fragm entow ane. A by poznać M T U ścieżki, w ysyła się próbne datagram y IP o różnych długościach z ustaw ioną w nagłów ku IP opcją nie fra g m en tu j. Jeśli datagram IP je s t za długi, to ruter po­ rzuci go i poinform uje nadaw cę kom unikatem odbiorca nieosiągalny z polem KOD rów nym 4, co oznacza, że konieczna je s t fragm entacja, ale ustaw iona je s t opcja nie fra g m en tu j. M TU ścieżki to długość najdłuższego datagram u IP, który dotrze do odbiorcy. O dotarciu datagram u IP do odbiorcy m ożna przekonać się za pom ocą na­ stępującego triku. W ysyła się datagram IP zaw ierający datagram UDP, skierow any do usługi, która nie jest uruchom iona w w ęźle odbiorcy. Jeśli taki datagram U DP dotrze do odbiorcy, odeśle on nadaw cy kom unikat odbiorca nieosiągalny z polem K O D rów nym 2 lub 3, inform ującym o nieosiągalności usługi, co jed n ak ew ident­ nie św iadczy o osiągalności w ęzła odbiorcy. Form at kom unikatu IC M P je s t przedstaw iony na ry s u n k u 3.4. W ybrane, najczy­ ściej spotykane w artości pola T Y P zam ieszczone są w ta b e li 3.16. W polu SUN K O N TR O LN A um ieszcza się sum ę spraw dzającą integralność kom unikatu. Pól. KOD, ID E N T Y FIK A C JA i D A N E są interpretow ane zależnie od w artości poi: TYP. Pole D A N E je s t opcjonalne i nie musi w ystępow ać. 3.8.1. Sprawdzanie osiągalności odbiorcy A by spraw dzić osiągalność odbiorcy, w ysyła się kom unikat prośba o echo (warto 8 w polu T Y P). Pole KOD zaw iera 0. Pole ID E N T Y F IK A C JA składa się wtedy, z dw óch 16-bitowych pól. W pierw szych 16 bitach um ieszcza się unikalny identyfH;: kator kom unikatu. W pozostałych 16 bitach um ieszcza się kolejny num er komunika­ tu. Pole D A N E m a dow olną zaw artość. W ęzeł, który odbierze prośbę o echo, odpo.-; w iada kom unikatem o d p o w ied ź z. echem . O dpow iedź zaw iera w polu T Y P wartość 0. W polu KOD też jest w artość 0. Pola ID E N T Y F IK A C JA i D A N E zaw ierają danfe. ^ skopiow ane z odpow iednich pól kom unikatu z prośbą. Pole ID EN TY FIK A t ■ um ożliw ia pow iązanie odpow iedzi z prośbą. K om unikaty p ro śb a o echo i o d p o w ie d ź z echem są u ży w an e przez progi p in g do sp raw d zan ia o siąg aln o ści w ęzłów . P o n iew aż k o m u n ik aty IC M P w ędrują^, w d atag ram ach IP, o trzy m an ie pop raw n ej odp o w ied zi św iadczy, że p o d staw Powiadamianie o nieosiągalności odbiorcy Jeśli datagraniu IP nie m ożna dostarczyć, w ysyła się je g o pierw otnem u nadaw ­ cy kom unikat odbiorca nieosiągalny. Pole T Y P zaw iera w artość 3. Pole K OD zaw iera szczegółow ą inform ację o przyczynie odrzucenia datagraniu. Pole ID E N T Y FIK A C JA nie je s t używ ane i zaw iera 0. Pole D A N E zaw iera początkow y fragm ent datagraniu, który spow odow ał problem . Fragm ent ten zaw iera nagłów ek datagraniu i początkow e 64 bity je g o pola danych. Początkow e 64 bity poła danych datagraniu IP zaw ierają zw ykle kluczow e inform acje z nagłów ka protokołu trans­ portow ego. D zięki tem u odbiorca kom unikatu IC M P m oże łatwiej zidentyfikow ać przyczynę problem u. SUMA KONTROLNA [16:31] KOD [8:15] 13 9 3.8.3. Kontrola przepływu Jeśli ruter je s t przeciążony i nie je s t w stanie przetw arzać odbieranych datagraniów IP, w ysyła ich nadaw com kom unikaty tłum ienie nadaw cy. Pole T Y P m a w artość 4. Pole K O D zaw iera 0. Pole ID E N T Y FIK A C JA nie je s t używ ane i m a w artość 0. 140 3. Stos TOjM Pole D A N E zaw iera, ja k poprzednio, początkow y fragm ent dalagram u, którego ni m ożna przetw orzyć. P rzeciążenie (ang. congestion) m oże być spow odow ane przez jed en bardzo szff ki kom puter, który w ysyła datagram y IP szybciej niż ruter potrafi je obsłużyć R uter m oże też być przeciążony przez w iele kom puterów , w ysyłających do n ić * rów nocześnie datagram y IP, m im o że żaden z tych kom puterów osobno nie wywo lałby tego problem u. Przeciążenie m oże być objaw em ataku typu odm ow a usług P rzeciążenie m oże pojaw ić się też, gdy ruter łączy dw ie sieci o różnych p rze p ły ń nos'ciach, na przykład szybką sieć lokalną (L A N , ang. local area netw ork) z wo» ną siecią rozległą (W AN, ang. w ide area netw ork). W tedy datagram y naplywajäf* z sieci lokalnej m ogą pojaw iać się zbyt szybko, aby w szystkie m ogły być p r z e ||| zane do sieci rozleglej. R uter broni się przed przeciążeniem , stosując buforow anie, które zabezpiecza prze chw ilow ym zw iększeniem natężenia ruchu. Jeśli zw iększony ruch trw a dostateczni' długo, to każdy bufor w reszcie zapełni się i datagram y IP będą tracone. Ruter mozje" stosow ać różne strategie. M oże w ysyłać po jed n y m kom unikacie tłum ienie nadaWi cy dla każdego straconego datagram u. R uter m oże w ysyłać ten kom unikat tylko cii) nadaw ców przysyłających najw ięcej datagram ów . R uter m oże też próbow ać uniknij przeciążenia, w ysyłając tłum ienie na d a w cy, gdy je g o bufor będzie blisko przepej£ nienia. W ęzeł, który otrzym uje kom unikaty tłum ienie n adaw cy, pow inien zmniojj szać liczbę w ysyłanych datagram ów , aż przestanie otrzym yw ać te komunikaty. Pty pew nym czasie m oże spróbow ać zw iększyć liczbę w ysyłanych datagram ów , dopókj 'A znów nie zacznie być tłum iony. ■ '.iii 3.8.4. Przekroczenie czasu K om unikat przekroczenie czasu m a w polu T Y P w artość 11. Pole KOD ma wartość/'' 0, gdy w yczerpał się czas życia datagram u IP, a w artość 1, gdy upłynął czas nąskładanie fragm entów . Pole ID E N T Y F IK A C JA nie je s t używ ane i zaw iera 0. Pole'' D A N E zaw iera początkow y fragm ent datagram u, który został porzucony. 141 je st rów nież wtedy, gdy pojaw i się problem , który nie da się opisać żadnym innym kom unikatem ICMP. Pole T Y P m a w artość 12. Pole KOD zaw iera 0 lub 1. Jeśli ma w artość 0, to pierw sze 8 bitów pola ID E N T Y FIK A C JA w skazuje na oktet, który spow odow ał problem , a pozostałe 24 bity tego pola są w ypełnione zeram i. Jeśli pole K O D m a w artość różną od 0, to pole ID E N T Y FIK A C JA nie jest używ ane i zaw iera 0. Pole D A N E zaw iera początkow y fragm ent datagram u, który spow odo­ wał problem . DHCP - konfigurowanie ustawień sieciowych węzła D H C P (ang. D ynam ie Most C onfiguration P rotocol) je s t protokołem d y n am icz­ nego k o n fig u ro w an ia w ęzłów . O pisany je st w R FC 2131. Za pom ocą D H C P w ę­ zeł m oże uzyskać w szystkie niezbędne ustaw ien ia sieciow e, do których należą adres IP, m aska podsieci, nazw a w ęzła, adres rutera, adres serw era D N S, adresy serw erów innych usług. K om unikaty D H C P są k apsułkow ane w datagram ach UDP, które z kolei są kapsu łk o w an e w datag ram ach IP. P ierw szy problem , który w ym aga ro zw iązania, to sposób, w ja k i w ęzeł m oże używ ać IP, zanim pozna sw ój adres. D H C P ro zw iązuje go tak, że pierw szy kom unikat je s t w ysyłany za p o m o cą ro zg łaszan ia UDP. W ten sposób m ożna w ysłać kom unikat do w szy st­ kich w ęzłów w podsieci. O d p o w ied ź też m oże być w ysłana za pom ocą ro zg ła­ szania. Po otrzym aniu odpow iedzi w ęzeł pozn aje adres drugiej strony i dalsze ko m u n ikaty m ogą być w ysyłane ju ż bezpośrednio. R o zgłaszanie m oże odbyw ać się tylk o w obrębie podsieci, w ięc D H C P w ym aga, aby w każdej podsieci zn aj­ dow ał się serw er tego protokołu albo je g o p ośrednik (ang. relay agent), który d ziała w im ieniu serw era. Problem z parametrem W ęzeł, rozpoczynając pracę, staje się klientem DHCP. N ajpierw rozgłasza kom uni­ kat m ający na celu poznanie serw erów DHCP. K lient czeka przez określony czas na oferty od serwerów . Po upłynięciu tego czasu, jeśli nie dostał żadnej oferty, ponaw ia rozgłoszenie. Jeśli dostał co najm niej je d n ą ofertę, w ysyła do w ybranego serw era żądanie w ynajm u ustaw ień sieciow ych. Jeśli w szystko poszło dobrze, serw er po­ tw ierdza w ynajem . U staw ienia w ynajm ow ane są na określony czas. Jeśli upłynęła połow a czasu w ynajm u, klient zw raca się do serw era, od którego w ynajął ustaw ie­ nia, o przedłużenie czasu w ynajm u. Jeśli serw er potw ierdzi nowy czas w ynajm u, to klient zaczyna odliczać go od początku. Jeśli klient nie uzyskał przedłużenia w ynajm u i m inęło 87,5% czasu w ynajm u, klient próbuje przedłużyć w ynajem od w szystkich serw erów , które poznał po fazie rozgłaszania. Jeśli m im o to klient nie uzyskał przedłużenia w ynajm u i miną! cały czas w ynajm u, klient rezygnuje z uży­ w ania otrzym anych ustaw ień sieciow ych. W tej sytuacji klient musi rozpocząć całą procedurę od now a. W praktyce zdarza się to rzadko i zw ykle jest spow odow ane aw arią serw era DHCP. K lient w każdej chw ili m oże też sam zrezygnow ać z dalsze­ go w ynajm u. Jeśli zostanie stw ierdzony błąd w nagłów ku dalagram u IP, jeg o pierwotnem nadaw cy odsyłany je s t kom unikat problem z param etrem . Taki kom unikat o d sy ła n y S erw er D H C P rozpoznaje klienta za pom ocą identyfikatora przesyłanego w fazie rozgłaszania. Z w ykle identyfikatorem je s t adres sprzętow y klienta. Strategia przy­ Poniew aż rutery podejm ują d ecyzje o przesyłaniu datagram ów IP na podstawie;]; lokalnych tablic tras, błąd w ich konfiguracji m ógłby spow odow ać nieskończone:/ krążenie datagram ów w sieci. N agłów ek datagram u IP zaw iera licznik czasu życia, (ang. tim e to live), nazyw any też licznikiem etapów . R uter zm niejsza licznik czasu* życia datagram u przed je g o przetw orzeniem i porzuca datagram , gdy licznik tetk osiągnie w artość zero. K om unikat przekroczenie czasu pozw ala w ykryw ać zbyt diu/*' gie lub zapętlone trasy. L icznik czasu na składanie datagram u IP startuje, gdy przychodzi pierw szy frag' m ent datagram u. W ęzeł porzuca w szystkie dotychczas otrzym ane fragm enty data­ gram u i w ysyła kom unikat p rzekroczenie czasu, gdy w ustalonym czasie nie odbieg, rze w szystkich fragm entów . • 3.8.5. 3.9. DHCP —konfigurowanie ustawień sieciowych węzła dzielania adresu IP m oże być konfigurow ana. S erw er m oże przydzielać klientowi zaw sze ten sam adres. U żyw anie klienta D H C P za pom ocą biblioteki lw IP opisałem w rozdziale 3.4,5ę O protokole UDP, rozgłaszaniu i m odelu klient-serw er piszę w ięcej w dalszych roz­ działach. Programowanie w modelu klient-serw er 4. Programowanie w modelu klient-seiĘk 14 4 S erw er to program kom puterow y św iadczący jak ą ś usługę sieciow ą. Przykłada5 usług najczęściej oferow anych w sieciach kom puterow ych są w ysyłanie e-matí przesyłanie stron www, przesyłanie plików czy tłum aczenie nazw dom enow ych)! adresy IP. K lient to program kom puterow y korzystający z usługi oferow anej pr2¿ serwer. Serw erem często też nazyw a się kom puter (w ęzeł sieci), na którym d ziff serwer. P odobnie klientem m ożna nazyw ać w ęzeł, na którym działa klient, je'^j z kontekstu w ynika, o które z tych znaczeń chodzi. Z punktu w idzenia komunik cji sieciow ej serw er je s t stroną pasyw ną, a klient stroną aktyw ną. S erw er o c z e k || na kom unikaty od klienta. K lient inicjuje kom unikację sieciow ą z serw erem , v.y syłając prośbę lub żądanie realizacji określonej usługi. .Serwer realizuje tę usługi odpow iadając klientow i na o trzym ane od niego kom unikaty. W tym m odelu serwe* je s t często centralnym w ęzłem . Jeśli klienty m uszą kom unikow ać się ze sobą, ((j serw er pośredniczy w ich kom unikacji - klient nie m oże w ysiać kom unikatu bèzi' pośrednio do innego klienta. M odel klien t-serw er przedstaw iony je st schematycznie' na ry s u n k u 4.1. Jak zobaczym y w dalszej części tego rozdziału, protokoły transí portow e intersieci i interfejs program istyczny biblioteki lwJP tak zaprojektowano!1 aby w spierać ten m odel kom unikacji. Interfejs program istyczny biblioteki IwIP nić jest tu bynajm niej w yjątkiem . Inne interfejsy program istyczne, w tym powszechnie', stosow any interfejs gniazd, też preferują m odel klient-serw er. Innym m odelem kom unikacji, często spotykanym w intersieciach, je s t m odel równy) z rów nym (ang. peer-to-peer). M odel ten je st pokazany na r y s u n k u 4.2. W tym' m odelu w szyscy uczestnicy są rów nopraw ni, nie m a w yróżnionego żadnego cen-1' tralnego węzła. D zięki tem u m odel ten je st bardziej odporny na aw arie niż model.' klient-serw er. W m odelu k lient-serw er w yłączenie centralnego serw era uniemożliw w ia jak ąk o lw iek dalszą kom unikację. Pierw otnie Internet miał być siecią wojskową;? a potem akadem icką, odporną na aw arie pojedynczych kom puterów i byl projekto- Rys. 4.1. Wlodel klient-serwer Rys. 4.2. Model równy z równym 4 .1. Num er portu 145 wany ja k o sieć rów nopraw nych węzłów . Jednak postępująca kom ercjalizacja sieci spraw ia, że obecnie w iększość usług oferow anych w Internecie opiera się na m o­ delu klient-serw er. Z punktu w idzenia program isty m odel klient-serw er je st bardzo ważny rów nież dla­ tego, że aplikacje działające w m odelu rów ny z rów nym używ ają w w arstw ie trans­ portow ej m odelu klient-serw er. T ransport kom unikatów m iędzy dw om a instancjam i aplikacji odbyw a się zaw sze w m odelu klient-serw er. W danym m om encie jedna instancja pełni rolę klienta, a druga serw era. R óżnica w stosunku do czystego m o­ delu klient-serw er je st taka, że aplikacja m oże dow olnie często zm ieniać pełnioną funkcję. Ponadto ta sam a instancja aplikacji m oże w stosunku do jednej instancji odgryw ać rolę klienta, a w stosunku do innej rolę serw era. Taka aplikacja, pełniąca w sieci obie funkcje, je st po angielsku określana term inem servent. Termin ten po­ wstał z połączenia dw óch angielskich term inów - początkow ej części słow a server z końcow ą częścią słow a client. Jak w przypadku serw era i klienta, servent może też. oznaczać w ęzeł, na którym działa taka aplikacja. N ależy przypom nieć, że rzeczow nik klient w znaczeniu inform atycznym przyjm uje w m ianow niku i bierniku liczby m nogiej form ę klienty. W tym znaczeniu odm ienia się tak sam o ja k rzeczow nik pilot, oznaczający urządzenie do zdalnego sterow ania. Numer portu A dres IP identyfikuje jednoznacznie interfejs sieciow y, a dzięki tem u rów nież w ę­ zeł sieci. N atom iast w rzeczyw istości to nie w ęzły sieci kom unikują się ze sobą, a aplikacje uruchom ione w tych w ęzłach. D latego potrzebny je st dodatkow y po­ ziom adresow ania, um ożliw iający w skazanie aplikacji, która w ysyła dane i do której te dane są skierow ane. Protokoły transportow e intersieci, czyli T C P i UDP, używ ają w tym celu portów. P ort je s t abstrakcyjnym końcem kom unikacji. Porty są num erow ane liczbam i całkow itym i od 1 do 65 535. N um er portu m ożna więc zapisać ja k o liczbę 16-bitową. K lient, który inicjuje kom unikację z serw erem , może w ybrać dow olny num er portu. Serw er, aby m ożna się było z nim skom unikow ać, musi nasłuchiw ać na porcie o pow szechnie znanym num erze. D latego num er portu, na którym nasłuchuje serwer, identyfikuje też usługę św iadczoną przez ten serw er i używ any przez niego protokół. A ktualna lista przydzielonych num erów portów znajduje się pod adresem http://w w w .iana.org/assignm ents/port-num bers. W ta b e li 4.1 zam ieszczone są najpopularniejsze usługi internetow e w raz z przy­ dzielonym im num erem portu i używ anym protokołem transportow ym . Krótki opis usługi w ym aga kilku w yjaśnień. W FT P (ang. File Transfer Protocol) serw er na­ słuchuje na porcie 21, ale to połączenie je s t używ ane tylko do przesyłania poleceń. W celu przesiania pliku budow ane je s t oddzielne połączenie m iędzy klientem a ser­ w erem . W trybie aktyw nym serw er inicjuje takie połączenie z portu 20 na uzgod­ niony w cześniej port klienta. W trybie pasyw nym połączenie, którym będzie prze­ syłany plik, inicjuje klient. W niektórych protokołach, np. DHCP, rów nież klient m usi nasłuchiw ać odpow iedzi od serw era na porcie, którego num er je st pow szech­ nie znany. W pozostałych przypadkach (patrz tabela 4.1) podany je s t num er portu, na którym serw er odbiera kom unikaty od klienta. 14 6 TCP, w przeciw ieństw ie do IP, je s t protokołem połączeniow ym . Z anim rozpocz­ nie się przesyłanie danych, trzeba zbudow ać połączenie. B udow anie połączenia je st asym etryczne. Jedna strona (zw ykle nazyw ana serw erem ) w ykonuje otw arcie pasyw ne, czyli nasłuchuje na w ybranym porcie. D ruga strona (zw ykle nazyw ana klientem ) w ykonuje otw arcie aktyw ne, czyli inicjuje połączenie z aplikacją, któ­ ra w ykonała w cześniej otw arcie pasyw ne. D la każdego zestaw ionego połączenia oprogram ow anie stosu T C P /IP utrzym uje w pam ięci pew ne struktury danych, m.in. bufor nadaw czy i odbiorczy. Z w olnienie tych struktur następuje po zam knięciu po­ łączenia. Tab. 4.1. Niektóre powszechnie znane numery portów i przyporządkowane im usługi Num er portu Protokół transportowy Protokół w arstw y aplikacji 20 TCP FTP Przesyłanie plików 21 TCP FTP Przesyłanie plików Królkl opis usługi . 22 TCP SSH Zdalny terminal, transmisja szyfrowana 7$ 23 TCP TELNET Zdalny terminal, transmisja nieszyfrowana "71 25 TCP SMTP Wysyłanie poczty elektronicznej 53 UDP DNS Tłumaczenie adresów domenowych na adresy IP i er: ■ u wrotnie 67 UDP DHCP Konfigurowanie ustawień sieciowych, port serwera 68 UDP DHCP Konfigurowanie ustawień sieciowych, port klienta 69 UDP TFTP Prosty protokół przesyłania plików T C P korzysta z zaw odnego dostarczania oferow anego przez IP. Segm enty T C P są k apsulkow ane w datagram ach IP. Ż eby zapew nić, że w szystkie dane dotrą do od­ biorcy, T C P potw ierdza otrzym anie danych i retransm ituje te segm enty, które nie zostały potw ierdzone przez określony czas. W celu w yznaczenia czasu, po którym m a nastąpić retransm isja (RTO, ang. retransm ission tim eout), T C P estym uje średni czas od w ysiania segm entu do otrzym ania potw ierdzenia jeg o odbioru (ang. SRTT - sm o o th ed round trip tim e) i w ariancję tego czasu (RTTVAR, ang. round trip time variation). Do pom iaru brane są tylko czasy dla segm entów , które nie były retransm itow ane, gdyż dla retransm itow anego segm entu nie m ożna stw ierdzić, której z w ysianych jeg o kopii dotyczy odebrane potw ierdzenie. Czas, po którego upływ ie następuje retransm isja, je s t obliczany ze w zoru iąi ^ TT 80 TCP HTTP Przesyłanie stron w w w ■} '< 110 TCP POP3 Odbieranie poczty elektronicznej 'ą 123 UDP NTR SNTP Synchronizowanie czasu K om unikaty w ym ieniane m iędzy klientem a serw erem są identyfikow ane za m ocą czterech w artości: adres IP klienta, num er portu klienta, adres IP serwcraj num er portu serw era. D zięki tem u w iele klientów działających w jed n y m w ęźle s ci m oże kom unikow ać się rów nocześnie z tym sam ym serw erem . M im o że wtcciyJ w szystkie klienty używ ają tego sam ego adresu IP, m ożna je rozróżnić za pomocy num eru portu. U żyw anie w intersieciach ja k o adresu źródłow ego lub docełowegój łącznie adresu IP i num eru portu zaciera nieco granicę m iędzy w arstw ą sieciow^ a transportow ą. 4.2. 4.2.1. RTO = SRTT + m ax(G , 4 • RTTVAR), gdzie G (ang. granularity) je s t rozdzielczością zegara używ anego do pom iaru cza­ su. Jako początkow ą w artość RTO, zanim w yznaczy się estym aty SR TT i RTTVAR, przyjm uje się 3 sekundy. Szczegóły są opisane w R FC 2988. D zięki dynam iczne­ mu w yznaczaniu czasu retransm isji T C P skutecznie adaptuje się do sieci o różnych opóźnieniach transm isji. TCP T C P (ang. T ransm ission C ontrol P rotocol) je s t głów nym protokołem transporto w ym inlersieci, co w yraża się w pow szechnie stosow anej nazw ie stosu protokołów intersieci, czyli TCP/IP. P odstaw ow a w ersja T C P je s t opisana w RFC 793. TCP1; przyjęto jak o standard intersieci S T D 7. Podstawowe własności , /1.'. T C P je st protokołem strum ieniow ym . Przesyłany strum ień danych nie ma żadnej ¡»I struktury. O znacza to, że jeśli ap likacja przekazuje dane do w ysiania w jakichś por-'1 cjach, to nie ma gw arancji, że aplikacja, która te dane odbiera, odczytu je w takich;.! sam ych porcjach. T C P przesyła sw oje dane w datagram ach IP. IP je st protokoienhí pakietow ym , więc T C P musi dzielić przesyłany strum ień danych na porcje, nazyV^ w ane segm entam i, m ieszczące się w polu danych datagram ów IP. T C P optymalizuje#! rozm iar segm entów danych, aby m aksym alnie w ykorzystać przepustow ość sieciAjg T C P stara się najlepiej w ykorzystać M TU sieci i dzieli w ysyłany strum ień danych:'^ na segm enty o najw iększym m ożliw ym rozm iarze, który nie spow oduje jeszc/e ■ fragm entacji datagram ów IP. W tym celu T C P buforuje przesyłane dane. Dane.ii przekazyw ane do w ysiania przez aplikację m ogą być łączone w w iększe porcje lub.; dzielone na m niejsze kaw ałki. 147 4.2. TCP 4. Programowanie w modelu klient-seĄm, T C P um ożliw ia kom unikację dw ukierunkow ą. D ane m ogą być transm itow ane je d ­ nocześnie w obu kierunkach połączenia. Segm ent przesyłany w jed n y m kierunku zaw iera potw ierdzenie danych w ysłanych w przeciw nym kierunku. 4.2.2. Nagłówek S egm ent T C P składa się z nagłów ka i następującego po nim pola danych, przy czym pole danych jest opcjonalne - m oże go nie być, jeśli nie ma żadnych da­ nych do w ysiania. C ały segm ent T C P je s t przesyłany w polu danych datagram u IP. Form at podstaw ow ej w ersji nagłów ka je s t przedstaw iony na ry s u n k u 4.3. Pierw sze dw a pola, zgodnie z ich nazw am i, zaw ierają num er portu nadaw cy i odbiorcy. Pole DL. N A G Ł. zaw iera długość nagłów ka w stów ach 32-bilow ych. Specyfikacja okre­ śla, że pole to zaw iera przesunięcie części z danym i w ew nątrz segm entu (ang. data offset). N agłów ek m oże być rozszerzony o pola zaw ierające dodatkow e opcje, ale zaw sze musi m ieć długość, która je s t w ielokrotnością 4 oktetów. P odstaw ow a w er­ sja nagłów ka m a 20 oktetów, w ięc w tedy pole DL. N A G Ł. m a w artość 5. Bity, które zarezerw ow ano do przyszłego w ykorzystania, pow inny być rów ne zeru. P ole SU M A K O N TR O LN A służy zapew nieniu integralności segm entu. Jest obli­ czana na podstaw ie nagłów ka TCP, pola danych T C P i pseudonagłów ka utw orzo- 148 4. Programowanie w modelu klient-serwe jf- Tab. 4.2. Znaczniki TCP NR PORTU NADAWCY NR PORTU ODBIORCY Znacznik Bit [0:15] [16:31] CWR 8 NUMER PORZĄDKOWY [0:311 NUMER POTWIERDZENIA zarezerwowane [5:7] ZNACZNIKI [8:15] SUMA KONTROLNA [0:15] ECE 9 Potwierdza informację o przeciążeniu (ang. explicit congestion echo) URG 10 Przesyłany segment zawiera dane pilne (ang. urgent) ACK 11 Pole zawierające numer potwierdzenia jest Istotne ROZMIAR OKNA [16:31] PSH 12 Ten segment jest prośbą o wypchnięcie (ang. push) danych. Poinformuj aplikację, że po­ winna przeczytać dane z bufora odbiorczego WSKAŹNIK DANYCH PILNYCH [16:31] RST 13 Natychmiast skasuj połączenie w obu kierunkach SYN 14 Synchronizuj numer porządkowy. Tylko pierwszy komunikat wystany w danym kierunku może mieć ustawiony ten bit FIN 15 Oznacza koniec strumienia danych u nadawcy i początek procedury zamykania połącze­ nia. Każdy kierunek transmisji jest zamykany osobno [0:31] DL. NAGL. [0:4] Opis Okno przeciążeniowe zo siato zredukowane (ang. congestion window reduced) Rys. 4.3. Format nagłówka TCP bez dodatkowych opcji nego na podstaw ie nagłów ka IP. Pseudonagłów ek składa się z adresów IP nadawcyS i odbiorcy, pola PR O T O K Ó Ł z nagłów ka dalagram u IP oraz pola zaw ierającego'! obliczoną długość całkow itą segm entu TCP. Po szczegóły dotyczące dodatkowych’®; opcji nagłów ka T C P i sposobu liczenia sum y kontrolnej odsyłam do RFC 793.it Zauw ażm y, że w nagłów ku nie m a inform acji o dlugos'ci pola danych. Ta długość’;! musi być obliczona. Od całkow itej długości datagram u IP trzeba odjąć długości' nagłów ków IP i TCP. Sposób liczenia długości pola danych segm entu T C P i sumyf kontrolnej T C P są kolejnym i przejaw am i ścisłego zw iązku protokołów IP i TCP,1, oraz braku w intersieciach ostrej granicy m iędzy w arstw ą sieciow ą a transportową,1? IP nie gw arantuje, że datagram y d o trą do odbiorcy w tej sam ej kolejności, w kuuej zostały w ysłane. TCP, aby zapew nić, że dane dotrą do odbiorcy w e w łaściw ej kolej-;; ności, num eruje przesyłane oktety m odulo 2 32 . N um eracja je st prow adzona osobno?;? dla każdego kierunku transm isji. Pole N U M E R PO R Z Ą D K O W Y (ang. sequence:|j num ber) zaw iera num er pierw szego oktetu w ysyłanego w bieżącym segm encie’^ Pole N U M E R P O T W IE R D Z E N IA (ang. acknow ledgm ent nu m b er) zaw iera numery następnego oczekiw anego oktetu. Innym i słowy, potw ierdza popraw ne odebranie.? oktetów o poprzednich num erach. Pole to je st w ażne tylko wtedy, gdy ustawio-,£ ny jest znacznik A C K (ang. ackn o w led g m en t), patrz ta b ela 4.2. P ole ROZMIAR?/ O K N A określa ilość m iejsca w buforze odbiorczym , służy do kontroli przepływu,:n inform uje drugą stronę kom unikacji, ile oktetów danych m oże być odebranych’.':;' T C P dopasow uje rozm iar okna do szybkości przetw arzania danych przez aplikację??; Jeśli dane napływ ają szybciej, niż aplikacja je s t w s ta n ie je czytać, b ufor odbiorc/y ’ zapełnia się i T C P w strzym uje drugą stronę kom unikacji, w ysyłając zerow y roz­ m iar okna. W znow ienie przesyłania, czyli zaproponow anie niezerow ego rozmia-' ru okna nastąpi wtedy, gdy w buforze odbiorczym zrobi się m iejsce na segment? o m aksym alnym rozm iarze. W ten sposób T C P unika nieefektyw nego przesyłaniu?■■ m ałych porcji danych. P odsum ow ując, odebranie potw ierdzenia i niezerow ego roz­ m iaru okna oznacza, że druga strona kom unikacji oczekuje na oktety o numerach..?! od N U M E R P O T W IE R D Z E N IA do (N U M ER P O T W IE R D Z E N IA + R O Z M IA R '' O K N A - 1) m od 2 n . C zasem zachodzi potrzeba przesłania danych poza głów nym strum ieniem transjJ m isyjnym , na przykład gdy trzeba przerw ać działanie aplikacji, z którą się komuĄ, nikujenty. W T C P przew idziano w tym celu m ożliw ość przesiania danych pilny (ang. urgent). Pole W S K A Ź N IK D A N Y C H PIL N Y C H określa num er oktetu, od którego w przesyłanym segm encie rozpoczynają się dane pilne. Pole to je st ważne tylko w tedy, gdy ustaw iony je st znacznik U RG , patrz tabela 4.2. T C P nie okre­ śla dokładnie, jak aplikacja ma być poinform ow ana o odebraniu danych pilnych. S zczegóły pozostaw iono im plem entatorom stosu. B iblioteka lw IP nie obsługuje danych pilnych. Z naczniki przesyłane w nagłów ku T C P są opisane w tabeli 4.2. Pierw otnie w RFC 793 bity num er 8 i 9 w polu znaczników były zarezerw ow ane do przyszłego w y­ korzystania i pow inny mieć w artość 0. W R FC 3168 do obsługi zatorów zdefinio­ w ano now e znaczniki C W R i ECE, które um ieszczono w tych bitach. Nie opisu­ ję ich, gdyż w bibliotece lw IP nie zaim plem entow ano ich obsługi. W yzerow anie tych bitów zapew nia popraw ną w spółpracę z oprogram ow aniem , które je obsługuje. U życie pozostałych znaczników w yjaśniam w kolejnych podrozdziałach. 4.2.3. Otwieranie połączenia D iagram sekw encji otw ierania połączenia T C P jest przedstaw iony na ry s u n k u 4.4. W idzim y na nim zaznaczone schem atycznie dw ie instancje biblioteki lwIP. Po lewej stronie um ieszczone są funkcje klienta, a po praw ej funkcje serw era. Strzałka skie­ row ana od funkcji do biblioteki oznacza, że jest to funkcja biblioteki lwIP w yw ołana przez klienta lub serwer. Strzałka skierow ana od biblioteki do funkcji oznacza, że je s t to funkcja zw rotna, w yw ołana przez bibliotekę lwIP. Strzałka z gw iazdką ozna­ cza, że to w yw ołanie je st opcjonalne. Pośrodku, m iędzy instancjam i biblioteki lwIP, narysow ane są segm enty T C P w ym ieniane m iędzy nimi. D la przejrzystości diagram nie uw zględnia obsługi błędów, których jed n ak nie w olno ignorow ać. N ależy bez­ w zględnie spraw dzać w artości zw racane przez funkcje i w łaściw ie reagow ać, jeśli ja k a ś funkcja zakończy się niepow odzeniem . Przykłady klientów i serw erów pre­ zentow ane w następnych rozdziałach obsługują błędy. B iblioteka lw IP przechow uje inform acje o stanie połączenia T C P w strukturze typu tc p _ p c b (ang. TCP protocol control błock). K lient rozpoczyna sw oje działanie od w yw ołania funkcji tcp_new , która przydziela now ą strukturę typu tcp_pcb i zw raca w skaźnik do niej. W skaźnik ten jest następnie przekazyw any w szystkim funkcjom obsługującym TCP. Przydzieloną strukturę typu tcp _ p cb nazyw am dalej deskryptorem TCP. 15 0 4. Programowanie w modelu klient-serw eł Klient IwIP Iw/P pcb « tcp_new{) --> S erw er <— tcp_bind(pcb, addr, port) *-> pcb = tcp_new() <-- tcp_bind(pcb, addr, port) tcp_arg(pcb, arg) *-> <— tcp_err(pcb, conn_err_callback) — > li3ten_pcb » tcp_listen(pcb) <-* tcp_arg(listen_pcb, arg) tcp_rGcv(pcb, recv_callback) *-> <-- tcp_accept (Xisten_pcb, accept_c.i iIbackjf tcp_sent(pcb, sent_calłback) *-> tcp_poll(pcb, poll_callback, time) *-> tcp_connect(pcb, addr, port, connect_callback) — > SYN(/?k) > SYN(ns), connect_callback(arg, pcb, err) <— ACK(nk + 1) tcp_recv(pcb, recv_callback) *-> tcp_sent(pcb, 3ent_calłback) *-> tcp_poll(pcb, polł_callback, time) ł-> A CK(ns + 1) — > accept_callback(arg, conn_pcb, err) <-* tcp_arg(conn_pcb, conn_arg) <-- tcp_err(conn_pcb, conn_err_callback) <-- tcp_recv (conn_pcb, recv__cailback) <-* tcp_sent(conn_pcb, sent__callback) < - ‘ tcp_poll (conn_pcb, połl jjallback, tim<’ i Rys. 4.4. Otwieranie połączenia TCP K lient w yw ołuje funkcję tc p _ b in d , aby w ybrać adres IP i port, których będzie uży­ wał. O czyw iście m ożna w ybrać tylko adres IP, który został skonfigurow any. Adres , 1P je s t zaw sze zw iązany z określonym interfejsem sieciow ym . Z atem w ybór adresu determ inuje też interfejs, przez który będzie odbyw ać się kom unikacja. Jeśli jest tylko jed en adres IP, to w yw ołanie tej funkcji m ożna pom inąć. K lient m oże wybrać dow olny port. Jeśli nie w yw ołam y funkcji tc p _ b in d , biblioteka przydzieli kliento­ wi jak iś w olny port. Za pom ocą funkcji tc p _ a rg m ożna ustaw ić w deskryptorze T C P dodatkow y ar­ gum ent arg , który będzie przekazyw any w szystkim funkcjom obsługującym TCP. A rgum ent ten najczęściej je s t w skaźnikiem do struktury przechow ującej prywatne dane klienta. Dla każdego p ołączenia T C P przydzielam y now ą instancję tej struk­ tury. Dzięki tem u za pom ocą w spólnej funkcji zw rotnej m ożna obsługiw ać sym ul­ tanicznie w iele klientów. Funkcja tcp__err rejestruje funkcję zw rotną c o n n _ e rr _ c a łlb a c k , która będzie wy­ w ołana przez bibliotekę IwIP, gdy w ystąpi ja k iś błąd, np. próba otw arcia połączenia zakończy się niepow odzeniem lub połączenie zostanie skasow ane. W tej funkcji zw rotnej trzeba zw olnić całą pam ięć przydzieloną klientow i, a w szczególności . strukturę przechow ującą pryw atne dane klienta. Funkcje tc p _ r e c v i tc p _ s e n t rejestrują funkcje zw rotne r e c v _ c a llb a c k i sent c a llb a c k , które będą w ołane odpow iednio, gdy zostaną odebrane dane lub zostanie odebrane potw ierdzenie dostarczenia danych. F unkcja tc p p o l l rejestruje funkcję zw rotną p o ll_ c a łl b a c k , która będzie w yw ołana cyklicznie w ustalonych odstępach czasu tim e, co um ożliw ia zaim plem entow anie budzika w aplikacji klienta. Funkcje . 4.2. TCP 151 te są opcjonalne i trzeba ich użyć tylko w tedy, gdy potrzebna je s t odpow iednia funkcja zw rotna. Jeśli klient chce odbierać dane od serw era, to oczyw iście musi zarejestrow ać funkcję re c v _ c a llb a c k . Te funkcje zw rotne m ożna też zarejestrow ać później, gdy ju ż zostanie otw arte połączenie. W łaściw e otw ieranie połączenia przez klienta rozpoczyna się od w yw ołania funkcji te p c o n n e c t. Jako jej argum enty podaje się adres IP i num er portu serw era oraz ad­ res funkcji zw rotnej c o n n e c t_ c a llb a c k , która zostanie w yw ołana, gdy serw er odpo­ w ie pozytyw nie na prośbę otw arcia połączenia. Funkcja tc p c o n n e c t tylko inicjuje otw ieranie połączenia i nie czeka na zakończenie procedury otw ierania. O tw arcie połączenia T C P w ym aga zsynchronizow ania num erów porządkow ych. W tym celu w ym ieniane są trzy segm enty. R ozpoczyna biblioteka IwIP po stronie klienta, w y­ syłając pierw szy segm ent zaw ierający sam nagłów ek TCP, bez pola danych, z usta­ w ionym znacznikiem SY N i początkow ym num erem porządkow ym nk, nazyw anym w skrócie segm entem SY N . B iblioteka Iw IP po stronie serw era odpow iada drugim segm entem , który zaw iera sam nagłów ek T C P z ustaw ionym i znacznikam i SY N i A CK . Ten drugi segm ent je s t w skrócie nazyw any segm entem SY N +A C K . Za pom ocą tego segm entu strona serw era proponuje sw ój początkow y num er porząd­ kow y ns i potw ierdza, że oczekuje pierw szego oktetu o num erze n k + 1, um ieszcza­ ją c tę w artość ja k o num er potw ierdzenia. G dy strona klienta odbierze ten segm ent, w yw ołana je s t funkcja zw rotna c o n n e c t_ c a llb a c k . N a koniec, po zakończeniu tej funkcji biblioteka Iw IP po stronie klienta za pom ocą trzeciego segm entu potw ier­ dza, że oczekuje pierw szego oktetu o num erze ns + 1, um ieszczając w nagłów ku T C P tę w artość jako num er potw ierdzenia i ustaw iając znacznik ACK. Ten trzeci segm ent je s t nazyw any w skrócie segm entem A CK . Od tego m om entu połączenie je s t otw arte i m ożna przesyłać dane w obu kierunkach. W łaściw ie to klient może ju ż w ysiać dane w segm encie A C K , kończącym procedurę otw ierania połączenia. W funkcji c o n n e c t_ c a lIb a c k m ożna opcjonalnie w yw ołać funkcje tcp__recv, tcp__ s e n t i tc p _ p o ll, jeśli odpow iednie funkcje zw rotne nie zostały dotychczas zareje­ strow ane. Jeśli funkcja tc p _ c o n n e c t zw róci w artość ERR_0K i zbudow anie połącze­ nia nie pow iedzie się, czyli nie dotrze praw idłow y segm ent SY N +A C K , to zam iast funkcji c o n n e c t_ c a llb a c k zostanie w yw ołana funkcja c o n n _ e rr_ c a llb a c k . Ze w zględów bezpieczeństw a początkow e num ery porządkow e pow inny być w y­ bierane pseudolosow o, aby utrudnić ataki na TCP, czyli np. nieupraw nione w strze­ lenie segm entów w strum ień danych (ang. TC P session hijackitig) lub nieupraw nio­ ne zestaw ienie połączenia (ang. TC P spoofing). Serw er, podobnie ja k klient, rozpoczyna działanie od w yw ołania funkcji tcp_new, która przydziela nowy deskryptor TCP. N astępnie za pom ocą funkcji tc p _ b in d ser­ w er w ybiera adres IP i port, na których będzie nasłuchiw ał połączeń od klientów. Funkcja t c p _ l i s t e n uaktyw nia kolejkę klientów oczekujących na zaakceptow anie połączenia patrz opis stałej MEMP_NUM_TCP_PCB_LISTEN w pliku Iwiopts.h. Należy zw rócić uw agę, że funkcja t c p _ l i s t e n przydziela now y deskryptor TCP. U w aga, to w skaźnik zw rócony przez funkcję te p l i s t e n , a nie w skaźnik zw rócony przez funkcję te p new, musi być przekazany ja k o argum ent dw óm następnym w ołanym funkcjom . Funkcja tcp__accept rejestruje funkcję zw rotną a e c e p te d _ c a llb a c k , która będzie w yw ołana po zaakceptow aniu połączenia od klienta. Funkcja te p a rg 152 4. Programowanie w modelu klient-serwer cjach, ja k i aplikacją, która w ysyła dane znak po znaku. N atychm iastow e w ysianie danych m ożna w ym usić za pom ocą funkcji tc p _ o u tp u t. Biblioteka lw lP w ywołuje tę funkcję przy okazji obsługi różnych zdarzeń. Jeśli funkcja tc p _ w rite jest w y­ w ołana w ew nątrz jak iejś funkcji zw rotnej, to zw ykle nie trzeba w yw oływ ać funkcji tc p _ o u tp u t. N atom iast jej w yw ołanie m oże okazać się konieczne, gdy tc p _ w rite je st w yw ołana spoza biblioteki lwlP. ustaw ia w deskryptorze T C P argum ent a rg , który zw ykle je s t w skaźnikiem do pryw alnych danych serw era i który będzie przekazyw any funkcji a c c e p te d _ c a llb a c k . i co um ożliw ia obsługę w ielu serw erów za pom ocą w spólnej funkcji zw rotnej. Każdy 'i serw er m oże mieć sw oją pryw atną strukturę danych. Jeśli biblioteka lw lP po stronie serw era zaakceptuje now e połączenie od klienta' tw orzy dla tego połączenia now y deskryptor T C P i w yw ołuje funkcję zw rotną ac- a c e p t_ c a llb a c k , której drugim argum entem je st w skaźnik do tego now ego deskryp-j! tora. Każde połączenie T C P m a sw ój unikalny deskryptor. W funkcji a c c e p t ca' Ib a c k trzeba zarejestrow ać funkcje zw rotne, które będą w ołane dla tego nowego.!* połączenia. N ajpierw je d n a k funkcja tc p _ a r g ustaw ia w deskryptorze T C P argu- f rnent conn_arg, który będzie przekazyw any funkcjom zw rotnym . A rgum ent ten jest zw ykle w skaźnikiem do alokow anej w ew nątrz funkcji a c c e p t_ c a llb a c k struktury: zaw ierającej pryw atne dane zw iązane z połączeniem , co um ożliw ia obsługę wie­ lu połączeń za pom ocą w spólnych funkcji zw rotnych. Podobnie ja k w przypadku i klienta, funkcja t c p _ e r r rejestruje funkcję zw rotną c o n n _ e rr _ c a llb a c k wołaną, gdy w ystąpi błąd. Funkcje tc p _ r e c v i tc p _ s e n t rejestrują funkcje zw rotne recv ■ c a llb a c k i s e n t_ c a llb a c k w ołane odpow iednio, gdy zostaną odebrane dane lub' zostanie odebrane potw ierdzenie dostarczenia danych. F unkcja tc p p o l l rejestruje cyklicznie w ołaną funkcję zw rotną p o ll _ c a ll b a c k , co um ożliw ia zaim plem ento­ w anie budzika w aplikacji serw era. 4.2.4. Strona B odbiera dane za pom ocą funkcji zw rotnej re c v _ c a lłb a c k . W ew nątrz tej funkcji po przetw orzeniu odebranych danych trzeba poinform ow ać o tym bibliotekę lw lP za pom ocą funkcji tc p _ re c v e d , która oblicza now y rozm iar okna odbiorczego po stronie B. Jeśli strona A zarejestrow ała funkcję zw rotną s e n t_ c a llb a c k , to za jej pom ocą zostanie poinform ow ana o otrzym aniu od strony B potw ierdzenia ode­ brania danych. T C P przesyła dane łącznie z potw ierdzeniem otrzym ania danych przesianych w dru­ gim kierunku. Strona A, w ysyłając segm ent danych do B, rów nocześnie inform uje B o num erze oktetu, którego oczekuje od B, ustaw iając w nagłów ku T C P znacznik A C K i odpow iedni num eru potw ierdzenia. Strona B po otrzym aniu od A segm entu danych potw ierdza go i jednocześnie w tym sam ym segm encie w ysyła do A dane, które czekają na w ysianie w buforze nadaw czym B. N ie każdy segm ent musi być potw ierdzony. Specyfikcja T C P nakazuje potw ierdzanie przynajm niej co drugiego segm entu. Zauw ażm y, że potw ierdzenie danych otrzym anych w jak im ś segm encie oznacza też polw ierdzęnie w szystkich danych z poprzednich segm entów. Przesyłanie danych Sekw encja zdarzeń tow arzysząca przesyłaniu danych za pom ocą T C P przedstawio-" na je s t na ry s u n k u 4.5. P oniew aż w ym iana danych jest sym etryczna, kom unikujące , się strony są oznaczone literam i A i B. W konkretnym przypadku A je s t klientem, a B serw erem albo odw rotnie - A je s t serw erem , a B klientem . Strona A przekazuje dane do w ysiania za pom ocą funkcji tc p _ w rlte . T C P tyl-lk ko pierw szą porcję danych w now o otw artym połączeniu w ysyła natychmiast, i: N atom iast z w ysianiem kolejnych porcji czeka, aż uzbiera się dostatecznie dużo : danych, aby w ypełnić segm ent o m aksym alnym rozm iarze. Ponadto T C P wysyła zgrom adzone w buforze nadaw czym dane, niezależnie od ich rozm iaru, rów nie/ wtedy, gdy otrzym a potw ierdzenie o trzym ania poprzednio w ysianych danych. Taka" strategia zm niejsza liczbę przesyłanych segm entów i narzut zw iązany z wysyłaniem., m ałych porcji danych, unikając jed n o cz eśn ie sytuacji, w której dane czekałyby zbyt’,: długo w buforze nadaw czym . A plikacja m oże nigdy nie w staw ić do w ysiania w y -. starczająco dużej porcji danych, aby zapełnić segm ent o m aksym alnym rozmiarze T C P dobrze w spółpracuje zarów no z aplikacją, która w ysyła dane w dużych por1:: i ’1: A lw lP tcp_write(pcb, data, len, flags) — > lw lP sent_callback(arg, pcb, len) <-* Rys. 4.5. Przesyłanie danych TCP Zamykanie połączenia Sekw encja zdarzeń podczas zw ykłego zam ykania połączenia T C P jest pokazana na ry s u n k u 4.6. N atom iast na ry s u n k u 4.7 przedstaw ione jest aw aryjne zam ykanie (kasow anie) połączenia TCP. K ażda ze stron m oże zainicjow ać zam knięcie połącze­ nia. D latego na tych diagram ach strony kom unikacji są oznaczone, ja k poprzednio, literam i A i B. Strona A inicjuje zw ykle zam knięcie połączenia, w yw ołując funkcję tc p _ c lo s e . Po w yw ołaniu tej funkcji do B je s t w ysyłany segm ent FIN, czyli segm ent, w którego nagłów ku T C P je s t ustaw iony znacznik FIN , co oznacza, że rozpoczyna się zam y­ kanie połączenia w kierunku od A do B i strona A nie będzie ju ż w ysyłać do B żad­ nych danych. N atom iast strona A nadal m oże odbierać dane od B i po w yw ołaniu przez A funkcji tc p _ c lo s e biblioteka lw lP m oże w yw ołać funkcję zw rotną recv_ c a llb a c k , jeśli pojaw ią się jak ieś now e dane od B. Jeśli nie chcem y otrzym yw ać A RN callback(arg, pcb, pbuf, err) <-* [A C K ] data ................> — > recv_całlback(arg, pcb, pbuf, er ii 1 < ............... --------- > <— < --------- < --------- FIN --------- > tcp_recved(pcb, len) Rys. 4.6. Zamykanie połączenia TCP — > recv_callback(arg ACK ACK ACK [data] B lwlP lwlP tcp_close(pcb) --> B tcp_write(pcb, data, len, flags) — > tcp_outpiłt (pcb) *-> 4.2.5. <— tcp_close(pcb) 154 4. Programowanie w modelu klient-seńW A Iw IP IwIP B RST tcp abort{pcb) — > — > conn_err_callback(arg, void tcp_abort(struct tcp_pcb *pcb); conn_err_callback(arg, err) <— Rys. 4.7. Awaryjne zamykanie połączenia TCP danych po w yw ołaniu tc p _ c lo s e , trzeba w cześniej w yrejestrow ać funkcję zwr< za pom ocą funkcji tc p _ re c v , podając NULL ja k o adres nowej funkcji zwrotnej. Strona B, otrzym aw szy znacznik FIN , odsyła segm ent ze znacznikiem A ''” " A plikacja po stronie B o zam knięciu połączenia je st inform ow ana dopiero po czytaniu w szystkicli danych z bufora odbiorczego. O dbyw a się to za pom ocą koś lejnego w yw ołania funkcji zw rotnej r e c v _ c a llb a c k , w której w skaźnik do buforai z odebranym i danym i m a w artość NULL. W ew nątrz tej funkcji zw rotnej strona 13 zw ykle zam yka połączenie w kierunku od B do A, w yw ołując funkcję tc p clo r c, co inicjuje w ysłanie do A segm entu ze znacznikiem FIN. Strona A, po otrzyma^ niu takiego segm entu, odsyła segm ent ze znacznikiem A CK . To kończy procedurę; zw ykłego zam ykania połączenia. O program ow anie T C P po obu stronach zwalnia’ zasoby biblioteki IwIP zw iązane z tym połączeniem , czyli strukturę typu tc p buf; oraz bufor nadaw czy i odbiorczy. Połączenie m ożna też zam knąć aw aryjnie (skasow ać) za pom ocą funkcji tcp_aboi t. W tedy w szelkie dane nieodczytane z buforów odbiorczych i czekające na wysłanie w buforach nadaw czycli zostają utracone. Strona inicjująca aw aryjne zamknięcie w ysyła segm ent RST (ang. reset), czyli segm ent z ustaw ionym w nagłów ku znaczki nikiem RST. Segm ent len nie w ym aga potw ierdzenia. Funkcja tc p _ a b o r t zwalnia; zasoby biblioteki IwIP zw iązane z połączeniem . A by rów nież aplikacja m ogła zwol­ nić sw oje zasoby, biblioteka IwIP w yw ołuje bo obu stronach skasow anego połącze­ nia funkcję zw rotną c o n n _ e rr _ c a llb a c k . 4.2.6. Funkcje biblioteczne Teraz opiszę bardziej szczegółow o i w kolejności alfabetycznej poszczególne funk­ cje biblioteki iw IP w ykorzystyw ane przy pisaniu aplikacji kom unikujących się z.i pom ocą TCP. void tcp_abandon(struct tcp_pcb *pcb, int reset); F unkcja tcp_abandon kasuje połączenie i zw alnia deskryptor TCP. Pierw szym ar­ gum entem tej funkcji je s t w skaźnik pcb do deskryptora T C P opisującego kasowane połączenie. Jeśli drugi argum ent r e s e t je st różny od zera, to w ysyłany je st seg­ m ent RST. W yw ołanie funkcji tcp _ ab a n d o n z argum entem r e s e t rów nym zeru nic pow oduje żadnej kom unikacji sieciow ej. Jest to przydatne przy obsłudze błędów, gdy trzeba zw olnić deskryptor TCP, a połączenie nie zostało jeszcze otw arte. Przed zakończeniem tej funkcji w yw ołana je s t funkcja zw rotna c o n n _ e rr_ c a llb a c k , w której należy zw olnić przydzielone przez aplikację zasoby zw iązane z kasowanym połączeniem . F unkcja tc p a b o r t kasuje połączenie i zw alnia deskryptor TCP. A rgum ent pcb jest w skaźnikiem do deskryptora T C P opisującego kasow ane połączenie. A ktualna im ­ plem entacja biblioteki IwIP definiuje tę funkcję jak o makro: idefine tcp_abort(pcb) tcp_abandon((pcb), 2) void tcp accept(struct tcp pcb *pcb, err t (* accept callback)(void *arg, struct tcp pcb *conn_pcb, err t err)); — Funkcja tc p _ a c c e p t rejestruje funkcję zw rotną, którą biblioteka IwIP w oła, gdy w stanie pasyw nego nasłuchiw ania zostanie odebrane now e połączenie. Pierw szym argum entem tej funkcji je s t w skaźnik pcb do deskryptora T C P przydzielonego za pom ocą funkcji t c p _ l i s t e n . D rugi argum ent a c c e p t_ _ callb ack je st adresem reje­ strow anej funkcji zw rotnej. void tcp_accepted(struct tcp_pcb *pcb|; Funkcja tc p _ a c c e p te d inform uje bibliotekę IwIP, że należy zaakceptow ać odebrane połączenie. Funkcja ta pow inna być w yw ołana w ew nątrz funkcji zw rotnej a c c e p t_ c a llb a c k . A rgum ent pcb je st w skaźnikiem do deskryptora T C P zw róconego przez funkcję tc p l i s t e n , a nie w skaźnikiem do deskryptora T C P now ego połączenia, przekazanym jak o drugi argum ent funkcji a c c e p t_ c a lłb a c k , co bardzo kom plikuje logikę program u. N a szczęście funkcja ta m usi być w yw ołana tylko wtedy, gdy do nasłuchiw ania przychodzących połączeń używ am y kolejki o zm iennym rozm iarze, czyli gdy w pliku Iw ipopts.h została zdefiniow ana stała TC P_LISTEN_BACKLOG o w ar­ tości 1. W m ałych aplikacjach m ikrokontrolerow ych nie w ydaje się to potrzebne. D latego proponuję używ anie kolejki o stałym rozm iarze zdefiniow anym w pliku Iw ipopts.h za pom ocą stałej MEMP_NUM_TCP_PCB_LISTEN. A ktualna im plem entacja biblioteki Iw IP definiuje tę funkcję ja k o m akro, które je s t puste, jeśli w pliku Iw i­ p o pts.h nie zdefiniujem y stałej TCP_LISTEN_BACKLOG. void tcp_arg(struct tcp_pcb *pcb, void *arg); Funkcja tc p a rg przypisuje do deskryptora T C P w skaźnik, który będzie przeka­ zyw any funkcjom zw rotnym , w ołanym z tym deskryptorem . Pierw szym argum en­ tem tej funkcji je st w skaźnik pcb do deskryptora TCP. D rugim argum entem jest w skaźnik a rg , który m oże być w dow olny sposób w ykorzystyw any przez aplika­ cję. N ajczęściej je s t to w skaźnik do struktury przechow ującej stan kom unikacji. Za przydzielenie i zw olnienie pam ięci adresow anej tym w skaźnikiem odpow iedzialna je st aplikacja. 156 4.2. TCP 4. Programowanie w modelu klient-serweM err_t tcp_bind(struct tcp_pcb ‘ pcb, addr, struct ip_addr ‘ u!6 t port); § Funkcja tc p _ b in d w iąże deskryptor T C P z lokalnym adresem IP i portem . P ie rw v \ mi® argum entem tej funkcji je s t w skaźnik pcb do deskryptora TCP. D rugim argumenteijtff jest w skaźnik a d d r do struktury zaw ierającej adres IP. Jeśli argum ent ten m a wartości IP_ADDR_ANY, deskryptor je st w iązany ze w szystkim i skonfigurow anym i w węźla adresam i IP. Jest to szczególnie przydatne, gdy w ęzeł m a w iele interfejsów siecio-i wych (co oznacza, że ma też w iele adresów IP) i chcem y uruchom ić serwer, któryś będzie odbierał połączenia na w szystkich interfejsach. Trzeci argum ent p o r t jest'f num erem portu, który ma być użyty. Jeśli argum ent ten m a w artość zero, biblioteka" lw IP przydzieli dow olny niezajęty port. Ten argum ent m a zw ykle w artość zero, gdyj urucham iam y klienta, gdyż w tedy num er portu je s t nieistotny. D la serw era zwykle* podaje się w artość niezerow ą, g dyż serw er m usi nasłuchiw ać na pow szechnie zna-' nym porcie. Funkcja zw raca ERR_OK, gdy zakończyła się sukcesem , lub ERR USEji gdy nie m ożna użyć podanych w artości, np. żądany port je s t zajęty. err_t tcp_close(struct tcp^pcb 'pcb); Funkcja tc p _ c lo s e inicjuje zam ykanie połączenia i zw alnianie deskryptora TCP; A rgum ent pcb jest w skaźnikiem d o deskryptora T C P opisującego zam ykane połą­ czenie. D eskryptor je s t utrzym yw any przez bibliotekę lw IP jeszcze przez pewien czas i jest zw alniany dopiero po zakończeniu procedury zam ykania połączenia, ale po w yw ołaniu tej funkcji aplikacja pow inna przestać go używ ać. Jedynym wyjął, kiem jest sytuacja, gdy w tym połączeniu są jeszcze ja k ie ś dane do przeczytania i biblioteka lw IP przekaże aplikacji w skaźnik do tego deskryptora w funkcji zwrot­ nej re c v _ c a llb a c k . F unkcja zw raca ERR_OK przy popraw nym zakończeniu lub kod ■ f błędu, gdy w ystąpił problem , np. brakuje pam ięci, aby w ysiać segm ent FIN. Jeśli funkcja ta kończy się niepow odzeniem , deskryptor T C P nie je st zwalniany. err t tcp connect(struct tcp pcb *pcb, struct ip__addr *addr, u!6 t port, err t {* connect callback)(void *arg, struct tcpjpcb *pcb, err t err)); — 1 #1 157 m iast kończy działanie, zw racając ERR_OK, gdy tylko uda się w ysłać segm ent SYN rozpoczynający otw ieranie połączenia. Jeśli w ysłanie segm entu SY N nie pow iodło się, funkcja zw raca kod błędu inform ujący o przyczynie niepow odzenia. void tcp err(struct tcp pcb *pcb, void (* conn err collback)(void *arg, err t err)); Funkcja t c p _ e r r rejestruje funkcję zw rotną w ołaną przez bibliotekę lwIP, gdy połą­ czenie zostanie skasow ane. Pow odem skasow ania połączenia może być na przykład otrzym anie segm entu RST, w yw ołanie funkcji tcp_abandon, tc p _ a b o r t łub brak pam ięci. Pierw szym argum entem tej funkcji je s t w skaźnik pcb do deskryptora TCP. D rugi argum ent c o n n _ e rr_ c o llb a c k je s t adresem rejestrow anej funkcji zw rotnej. struct tcp_pcb * tcp^listen(struct tcp_pcb *pcb); Funkcja t c p _ l i s t e n inicjuje pasyw ne otw arcie, czyli nasłuchiw anie połączeń TCP. A rgum ent pcb je s t w skaźnikiem do deskryptora TCP, który m a być użyty. Funkcja zw raca now y deskryptor T C P i zw alnia deskryptor przekazany jako argum ent. Takie d ziw ne zachow anie biblioteki lw IP w ynika z tego, że deskryptor potrzebny do na­ słuchiw ania połączeń zajm uje mniej pam ięci. D eskryptor przeznaczony do pasyw ­ nego nasłuchiw ania połączeń m oże być używ any przez serwer, ale nie m oże być używ any przez klienta - nie m ożna za je g o pom ocą zainicjow ać aktyw nego otw ar­ cia połączenia. Jeśli nie udało się utw orzyć now ego deskryptora, funkcja zw raca NULL. A ktualna im plem entacja biblioteki lw IP definiuje tę funkcję jak o makro: Idef ine tcp_listen (pcb) tcp_listen_with_backlog (pcb, 255) struct tcp__pcb * tcp__listen_with_backiog (struct tcp_pcb *pcb, u8_t backlog); F unkcja tc p _ lis te n _ w ith _ _ b a c k lo g działa analogicznie ja k funkcja t c p _ ł i s t e n , ale ogranicza rozm iar kolejki oczekujących połączeń do w artości podanej jak o dru­ gi argum ent b ack lo g . A by móc używ ać tej funkcjonalności, trzeba w pliku Iwip o pts.h zdefiniow ać stałą T C P _ L I S TEN_BACKLOG o w artości 1. m struct tcp_pcb * tcp__new(void); > ■ Funkcja tc p _ c o n n e c t inicjuje aktyw ne otw arcie połączenia i rejestruje funkcję : '{'r ■ zw rotną, którą biblioteka lw IP w yw oła, gdy połączenie zostanie otw arte. Pierwszym mm argum entem tej funkcji je st w skaźnik pcb do deskryptora TCP, który ma być użyty do otw arcia połączenia. D rugim argum entem je s t w skaźnik a d d r do struktury za­ w ierającej adres IP, z którym chcem y się połączyć. Trzeci argum ent p o r t je s t nu­ m erem portu, z którym chcem y się połączyć. C zw arty argum ent c o n n e c t_ c a llb a c ;i je st adresem funkcji zw rotnej, która będzie w yw ołana, gdy zostanie odebrany seg­ m ent SY N +A C K . F unkcja tc p _ c o n n e c t nie czeka na otw arcie połączenia i natych-. Funkcja tcp_new przydziela nowy deskryptor TCP. Z w raca w skaźnik do now ego deskryptora lub NULL, gdy nie udało się przydzielić now ego deskryptora. err__t tcp__output (struct tcp_pcb *pcb); F unkcja tc p _ o u tp u t w ym usza w ysłanie segm entów czekających w buforze nadaw ­ czym . A rgum ent pcb je s t w skaźnikiem do deskryptora T C P opisującego połączenie, przez które dane m ają być w ysiane. Funkcja zw raca ERR_OK, gdy w ysianie pow iod- 158 4. P rogram ow an ie w m odelu klient-seiĘ io się lub nie m a nic do w ysiania. W przeciw nym przypadku zw raca właściwy ko błędu. Funkcja ta je st używ ana w ew nątrz biblioteki IwlP. A plikacja nie m u si. w yw oływ ać, gdy funkcja tc p _ w r ite je st w yw ołana w ew nątrz obsługi jakiegoś zd'i' rżenia biblioteki IwlP, czyli np. w ew nątrz jak ie jś funkcji zw rotnej. i void top_poll(struct tcp_pcb *pcb, err_t {* poll_callback)(void *arg, struct tcp_pcb 'pcb), u8_t time); Funkcja tc p _ p o ll rejestruje w ołaną cyklicznie funkcję zw rotną. Pierw szym argijf m entem tej funkcji je s t w skaźnik pcb do deskryptora TCP. D rugi argum ent p o l$ c a llb a c k je s t adresem funkcji zw rotnej. Trzeci argum ent tim e określa interwał cząii sow y w yw ołania funkcji zw rotnej. Interw al ten wynosi 4.2. TCP argum entem tej funkcji je s t w skaźnik pcb do deskryptora TCP. D rugi argum ent s e n t_ c a llb a c k je s t adresem rejestrow anej funkcji zw rotnej. ul6_t tcp sndbuf (struct tcp__pcb *pcb); Funkcja tc p _ s n d b u f zw raca liczbę bajtów, które m ogą być w staw ione do bufora nadaw czego. Próba w ysłania w iększej porcji danych za pom ocą funkcji t c p w r i t e zakończy się niepow odzeniem . A rgum ent pcb je st w skaźnikiem do deskryptora T C P opisującego połączenie, przez które dane m ają być w ysiane. A ktualna im ple­ m entacja biblioteki Iw lP definiuje tę funkcję ja k o makro. err_t tcp_write(struct tcp_pcb *pcb, const void *data, ul6_t len, u8_t flags); 2 • time • TCP_TMR_INTERVAL, gdzie TCP_TMR_INTERVAL je s t interw alem czasow ym w yw ołania budzika T C P w i lisekundach. Standardow o budzik ten je s t w ołany co 250 ms. Z atem funkcja zv na p o łl _ c a ll b a c k je s t w yw ołana co tim e /2 s. void tcp_recv(struct tcp_pcb *pcb, err_t {* recv_callback)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err t err)); i. Funkcja tcp__recv rejestruje funkcję zw rotną, którą biblioteka Iw lP w ola, aby pi za­ kazać aplikacji dane odebrane w połączeniu TCP. Pierw szym argum entem tej funk­ cji je s t w skaźnik pcb do deskryptora TCP. D rugi argum ent r e c v _ c a llb a c k jest adv resem rejestrow anej funkcji zw rotnej. void tcp_recved(struct tcp_pcb rpcb, ui6 t len); Funkcja tc p re c v e d inform uje bibliotekę IwlP, że aplikacja przetw orzyła otrzymane dane i je st gotow a na otrzym anie kolejnej porcji danych. P ierw szym argumentem iii tej funkcji jest w skaźnik pcb do deskryptora T C P opisującego połączenie, z kt< otrzym ano dane. Drugi argum ent l e n zaw iera liczbę bajtów przeczytanych przez i aplikację. Po w yw ołaniu tej funkcji biblioteka oblicza now y rozm iar okna odbii czego i jeśli rozm iar okna zm ienił się, inform uje o tym drugą stroną komuniki void tcp_sent(struct tcp_pcb *pcb, err_t (* sent_callback)(void *arg, struct tcp_pcb *pcb, u!6 t len)); Funkcja tc p _ s e n t rejestruje funkcję zw rotną, którą biblioteka Iw lP w ola, aby inform ow ać aplikację, że druga strona potw ierdziła odebranie danych. Pierwsz; 159 F u n k cja t c p _ w r i t e w staw ia dane do bufora nadaw czego. P ierw szym argum en­ tem tej funkcji je s t w skaźnik pcb do d esk ry p to ra T C P o p isu jąceg o połączenie, przez któ re dan e m ają być w ysiane. D ru g im argum entem je s t w sk aźn ik d a t a do w y sy łan y ch danych. T rzeci argum ent l e n o k reśla ilość danych do w ysiania w bajtach . C zw arty argum ent f l a g s m oże być zerem lub altern aty w ą n astęp u ją­ cych w artości: - TCP_WRITE_FLAG_COPY - skopiuj dane do pam ięci stosu; - TCP_WRITE_FLAG__MORE - będą następne dane. Jeśli nie użyjem y opcji TCP_WRITE_FLAG_COPY, biblioteka Iw lP zakłada, że dane w skazyw ane przez d a ta nie ulegną m odyfikacji, aż zostaną w ysiane i potw ierdzo­ ne. O dpow iada za to aplikacja. Jest to szczególnie użyteczne, gdy d a ta w skazuje na dane w pam ięci stałej. U nika się w tedy zbędnego kopiow ania. Jeśli ustaw im y opcję TCP_WRITE_FLAG_COPY, dane w skazyw ane przez d a ta zostaną skopiow ane do pa­ mięci zarządzanej przez bibliotekę IwlP. W tym przypadku, jeśli funkcja tc p w r ite zakończy się popraw nie, aplikacja m oże natychm iast zw olnić pam ięć w skazyw aną przez d a ta lub użyć jej ponow nie. Jeśli używ am y sterow nika util_eth__zc.c i d a ta w skazuje na obszar pam ięci Flash, należy koniecznie ustaw ić opcję TCP_WRITE_ FLAG_C0PY. B iblioteka Iw lP dzieli dane otrzym ane do w ysłania na segm enty i w staw ia te seg­ m enty do kolejki nadaw czej. W ostatnim w staw ionym segm encie ustaw ia znacznik PSH , chyba że podana została opcja TCP_WRITE_FLAG_MORE. W tedy znacznik PSH nie je s t ustawiany. O pcja ta je st przydatna, jeśli w ysyłam y dane za pom ocą wielu kolejnych w yw ołań funkcji tc p _ w ite . W tedy ustaw iam y tę opcję w e w szystkich w yw ołaniach tej funkcji z w yjątkiem ostatniego. F unkcja t c p _ w r i t e zw raca ERR OK, jeśli w staw ienie danych do bufora nadaw czego pow iodło się, a w przeciw nym przypadku zw raca kod błędu inform ujący o przyczy­ nie niepow odzenia. 160 4.2.7. 4.2. TCP 4. Programowanie w modelu klient-scrwek Funkcje zwrotne W tym podrozdziale opisuję bardziej szczegółow o, w kolejności alfabetycznej'* funkcje zw rotne używ ane przez bibliotekę lwIP. Te funkcje zw rotne, które w danej1' aplikacji są nam potrzebne, m usim y zaim plem entow ać sami. err_Ł accept_callback(void *arg, struct tcp_pcb *conn_pcb, err t err); Funkcja zw rotna a c c e p t_ c a llb a c k je s t w yw ołana po stronie w ykonującej otwarcie’? pasyw ne (zw ykle je st to serw er). B iblioteka lw IP w yw ołuje ją po odebraniu m-um entu A C K kończącego otw ieranie połączenia. Pierw szym argum entem tej funk-;'i cji je s t w skaźnik a rg do danych aplikacji, przypisany za pom ocą funkcji tc p a r :..’ D rugim argum entem je s t w skaźnik conn pcb do now ego deskryptora TCP, utwórz, i nego dla w łaśnie otw artego połączenia. W szelkie dalsze operacje zw iązane z tym ^ połączeniem pow inny używ ać tego now ego deskryptora, a nie deskryptora zwró-Kconego przez funkcję t c p _ l i s t e n ani tym bardziej deskryptora zw róconego przez ’ funkcję tcp__new. Trzeci argum ent e r r je st kodem błędu. A naliza tekstu źródłowego >' biblioteki lw IP pokazuje, że m a on zaw sze w artość ERR_0K. F unkcja a c c e p t_ c a l] back pow inna zw rócić ERR_0K, jeśli połączenie m a być kontynuow ane. Jeśli zwróci'^ w artość różną od ERR_0K, połączenie zostanie skasow ane. err_t connect_callback(void *arg, struct tcp_pcb *pcb, err t err); .«SI Funkcja zw rotna c o n n ect_ _ callb ack je s t w yw ołana po stronie w ykonującej otwar-1 cie aktyw ne (zw ykle je s t to klient). B iblioteka lw IP w yw ołuje ją po odebraniu seg­ ł1wBBB f|||l mentu SYN+ACIC. Pierw szy argum ent a rg je s t w skaźnikiem przypisanym za po-; ■i m ocą funkcji tc p _ a rg . D rugi argum ent pcb je s t w skaźnikiem do deskryptora TCP opisującego otw arte połączenie. T rzeci argum ent e r r zaw iera kod błędu. Analiza tekstu źródłow ego biblioteki lw IP pokazuje, że ten argum ent m a zaw sze wartość' ERR_0K. Po zakończeniu tej funkcji zw rotnej biblioteka lw IP w ysyła segm ent ACK. kończący otw ieranie połączenia. A naliza tekstu źródłow ego pokazuje też, że biblio­ teka lw IP nie spraw dza w artości zw racanej przez ąędiinkcję. ; i i void conn_err_coilback(void *arg, err t err); iftw&S ■ m n i Funkcja zw rotna c o n n _ e rr_ c o llb a c k je s t w yw ołana przez bibliotekę lw IP w celu poinform ow ania aplikacji o aw aryjnym zam knięciu połączenia. M oże to być skut-j kiem otrzym ania segm pntu RST, w yw ołani^ funkcji tcp_abandon, w yw ołania funk-j, cji tc p _ a b o r t lub w ystąpienia błędu, np. braku pam ięci. Pierw szym argumentem; tej funkcji je st w skaźnik a rg do danych aplikacji, przypisany za pom ocą funkcji; tc p _ a rg . A plikacja pow inna zw olnić zasoby w skazyw ane przez ten wskaźnik,*; Drugi argum ent e r r je s t kodem błędu, który spow odow ał skasow anie połączenia,v\ 161 Zauw ażm y, że funkcja ta nie dostaje w skaźnika do deskryptora TCP, gdyż w m o­ m encie jej w yw ołania połączenie m oże ju ż nie istnieć. err_t poll__callback(void *arg, struct tcp_pcb *pcb); Funkcja zw rotna p o ll _ c a łl b a c k jest w yw ołana cyklicznie przez bibliotekę lwIP. Pierw szym argum entem tej funkcji je st w skaźnik a rg ustaw iony dla tego deskrypto­ ra za pom ocą funkcji tc p _ a rg . D rugim argum entem je s t w skaźnik pcb do deskryp­ tora TCP. Jeśli funkcja p o ll _ c a ll b a c k zw róci w artość ERR_0K, to po jej zakończe­ niu zostanie w yw ołana funkcja tc p _ o u tp u t. A naliza tekstu źródłow ego biblioteki lw IP pokazuje, że inne zw racane w artości są ignorow ane. err_t recv_callback(void *arg, struct tcp_pcb ‘ pcb, struct pbuf *p, err_t err); Funkcja zw rotna re c v _ c a llb a c k je s t w yw ołana przez bibliotekę lw IP w celu po­ inform ow ania aplikacji o otrzym aniu danych, które aplikacja pow inna przeczytać. P ierw szym argum entem tej funkcji je s t w skaźnik a rg do danych aplikacji, przypi­ sany za pom ocą funkcji tc p _ a rg . D rugim argum entem jest w skaźnik pcb do de­ skryptora T C P opisującego połączenie, z którego zostały odebrane dane. Trzecim argum entem je st w skaźnik p do łańcucha buforów zaw ierającego odebrane dane. C zw arty argum ent e r r jest kodem błędu. A naliza tekstu źródłow ego biblioteki lw IP pokazuje, że argum ent ten m a zaw sze w artość ERR_0K. Funkcja re c v _ c a llb a c k słu­ ży też do poinform ow ania aplikacji, że połączenie zostało zam knięte przez drugą stronę kom unikacji i nie m a ju ż żadnych danych do przeczytania. W tedy w skaźnik p m a w artość NULL. A plikacja pow inna zam knąć połączenie w przeciw nym kierun­ ku za pom ocą funkcji tc p _ c lo s e . Jeśli otrzym ane dane zostały przetw orzone, to aplikacja pow inna w ew nątrz funkcji recv _ _ callback poinform ow ać o tym bibliotekę lw IP za pom ocą funkcji tc p _ r e cved, zw olnić łańcuch buforów w skazyw any przez p za pom ocą funkcji p b u f_ fre e i zw rócić w artość ERR_0K. Jeśli aplikacja z jak ieg o ś pow odu nie m oże przetw orzyć otrzym anych danych, to funkcja recv__calłback m oże zw rócić kod błędu różny od EPf^OK.i nie w olno jej w tedy zw alniać łańcucha buforów. W tym przypadku biblio­ teka lw IP spróbuje w yw ołać funkcję zw rotną ponow nie z tymi sam ym i danymi. S tanie się to przy najbliższej okazji, czyli po w ystąpieniu następnego zdarzenia w y­ w ołującego bibliotekę lwIP. C iągle odrzucanie danych przez aplikację m oże pow o­ dow ać odrzucanie przez bibliotekę lw IP kolejnych napływ ających segm entów T C P z pow odu przepełnienia bufora odbiorczego. N ie pow oduje to utraty danych, bo T C P radzi sobie z taką sytuacją i retransm ituje niepotw ierdzone segm enty. W pływ a to jed n ak niekorzystnie na w ydajność aplikacji. err__t sent ¿callback(void ‘ arg, *0zt aJ*i struct tcp_pcb *pcb, •. ~ ' i-ul6 t len); ----------- 1— (LI Z----------------- 162 4. Programowanie u* modelu klient-serweĄ Funkcja zwrotna se n t_ c a llb a c k jest wywołana przez bibliotekę lwIP, gdy otrzyJi! mano potwierdzenie odebrania danych. Pierwszym argumentem tej funkcji jecP wskaźnik arg do danych aplikacji, przypisany za pomocą funkcji tcp_arg. Drugi argumentem jest wskaźnik pcb do deskryptora TCP opisującego połączenie, z kti rego odebrano potwierdzenie. Trzeci argument len to liczba oktetów, które zosta potwierdzone od poprzedniego potwierdzenia. Analiza tekstu źródłowego pokazuje '3 że biblioteka lwIP ignoruje wartość zwracaną przez tę funkcję. 4.3. metyce uzupełnieniowej do jedynek, gdzie zero ma dw ie reprezentacje: wszystkie bity równe zeru oraz w szystkie bity równe jedności. Gdy w yliczona suma kontrolna jest równa zeru, używa się reprezentacji zawierającej jedynki. Suma kontrolna UDP obejmuje nagłówek UDP, pole danych U DP i pseudonagłówek utworzony na pod­ stawie nagłówka IP, co jest kolejnym przejawem zacierania w intersieciach granicy między warstwą sieciow ą a transportową. Sposób obliczania sumy kontrolnej UDP jest opisany szczegółow o w RFC 768. 4.3.3. UDP Podstawowe własności U DP rozszerza 1P o numery portów, zachowując w szystkie pozostałe własnos;ci II* ' czyli przesyłanie bezpołączeniowe i zawodne. Jednak w praktyce datagramy giną; bardzo rzadko. UDP bardzo dobrze sprawdza się w protokołach typu pylanie-odpo-.' wiedź, gdzie cała komunikacja sprowadza się do wymiany dwóch pakietów: klient1 zadaje serwerowi pytanie, a serwer odpowiada klientowi. Według takiej zasady * działa na przykład protokół D N S. Przy tego rodzaju komunikacji zgubienie data-, graniu nie jest groźnie. Klient nie otrzym awszy odpowiedzi w ustalonym czasie, zadaje pytanie ponownie. Zaletą UDP, w stosunku do TCP, jest mniejszy narzut: komunikacyjny. Nie trzeba otwierać i zamykać połączenia. Nagłów ek UDP je st.. krótszy niż nagłówek TCP. *. 4.3.2. Za pom ocą funkcji udp_recv klient i serwer rejestrują funkcję zwrotną r e c v _ c a llb ack , która będzie w ywołana przez bibliotekę lwIP, gdy pojawią się dane. Serwer w yw ołuje funkcję udp_bind, aby uaktywnić nasłuchiwanie na wybranym adresie IP i porcie. R ów nież klient m oże użyć tej funkcji. Funkcja udp con n ect ustawia w lokalnej strukturze typu udp pcb adres IP i numer portu serwera, co powoduje, że będą odbierane tylko datagramy U D P od tego serwera. Jeśli nie w yw ołuje się tej funkcji, będą odbierane w szystkie datagramy kierowane pod adresem IP i na port klienta. W ołanie funkcji udp_bind i udp_connect po stronie klienta jest opcjonal­ ne. Nagłówek Pakiety U DP nazywane są datagram am i. Datagram U DP składa się z przedsta- ' w ionego na rysunku 4.8 nagłówka i następującego po nagłówku pola danych, , Datagram UDP jest przesyłany w polu danych datagramu IP. U DP rozszerza IP : o mechanizm portów, w ięc dwa pierwsze pola nagłówka zawierają odpowiednio numer portu nadawcy i odbiorcy. P ole DŁUGOŚĆ DATAGRAMU UDP zawiera , całkowitą długość w oktetach datagramu, łącznie z nagłówkiem. Wartość w tym . polu jest zaw sze większa lub równa 8. Projektanci protokołów intersieci postąpili niekonsekwentnie. D ługość datagramu U DP daje się w yliczyć na podstawie długo­ 1* ści datagramu IP, podobnie jak w TCP, gdzie nic.,,przcwidziano w nagłówku pola zawierającego długość segmentu TCP. •. W UDP suma kontrolna jest opcjonalna. Jeśli pole SUM A KONTROLNA zawiera zero, to nie obliczono sumy kontrolnej. Pojawia się problem, co zrobić, gdy wyli-; '.'¡'■A czona suma kontrolna jest równa zeru. Suma kontrolna U DP jest obliczana w arytI® b 'W ® 0 31 '/!? NR PORTU ODBIORCY . NR PORTJJ NADAWCY Klient pcb » udp_new() — > [0:15] [16:31] SUMA KONTROLNA [16:31] Rys. 4.8. Format nagłówka UDP ■ lw IP <— Serw er pcb = udp_new() <— udp_recv(pcb, recv_cailback, arg) <— udp_bind(pcb, s_addr, s_port) udp_connect(pcb, s_addr, sjport) *-> ucp_recv(pcb, recv_callback, arg) — > Rys. 4.9. Inicjowanie klienta i serwera UDP 4.3.4. Przesyłanie danych Diagram przesyłania danych za pom ocą UDP przedstawiony jest na rysunku 4.10. Biblioteka lwIP udostępnia dw ie funkcje w ysyłające datagram UDP. Można go Klient lw IP udp_send(pcb, pbuf) --> udp_sendto (pcb, pbuf, s__addr, s_port) — > % lw IP S erw er — > recv_callback(arg, pcb, pbuf, c_addr, c_port) — > recv_callback(arg, pcb, pbuf, c_addr, c__port) recv ¿jallback(arg, pcb, pbuf, ■i® 1 lw IP udp_bind{pcb, c_addr, c_port) *-> 1 DŁUGOŚĆ DATAGRAMU UDP [0:151 Inicjowanie klienta i serwera Procedury inicjowania klienta i serwera U DP przedstawione są schem atycznie na rysunku 4.9. U DP nie tworzy połączenia, w ięc podczas inicjowania nie są w y­ mieniane żadne datagramy m iędzy klientem i serwerem, nie jest generowany ża­ den ruch w sieci. Funkcja udp_new przydziela strukturę typu udp_pcb (ang. UDP p ro toco l control błock), w której biblioteka lwIP przechowuje kontekst komunika­ cji UDP. Strukturę tę nazywam deskryptorem UDP. Wskaźnik do tego deskryptora jest przekazywany jako argument pozostałym funkcjom obsługującym komunikację UDP. U DP (ang, User D atagram Protocol) jest pakietowym protokołem transportowym'! intersieci. Jest opisany w RFC 768 i został przyjęty jako standard intersieci STD 6. '4 4.3.1. 163 4.3. UDP # m idr' s_p°r t i Rys. 4.10. Przesyłanie danyijh UDP <— udp_sendto(pcb, pbuf, c_addr, c_port) 164 4. Programowanie w modelu klient-serwefc •:»n w ysiać za pom ocą funkcji u d p _ se n d to , podając adres 1P i num er portu odbiorcy.Jeśli klient skonfigurow ał adresu IP i port serw era za pom ocą funkcji udp_oc:',J n e c t, to nie m usi ich podaw ać za każdym razem i m oże w ysiać datagram za poi* m ocą funkcji udp sen d . A plikacja je s t inform ow ana o odebraniu datagram u /.¡p pom ocą funkcji zw rotnej re c v _ c a llb a c k . U D P nie potw ierdza o debrania danycl{$ Jeśli takie potw ierdzenie je s t w ym agane, m usi być zaim plem entow ane w warstwi^; aplikacji. 4.3.5. 4.3. UDP 165 udp_bind. D latego funkcja u dp_connect m oże zw rócić te sam e w artości co funkcja udp_bind. void udp_disconnect(struct udp__pcb *pcb); F unkcja u d p _ d is c o n n e c t usuw a z deskryptora U D P adres IP i num er portu zdalne­ go końca kom unikacji. O dw raca działanie funkcji udp_connect. N ie generuje żad­ nego ruchu w sieci. A rgum ent pcb je s t w skaźnikiem do deskryptora UDP. Funkcje biblioteczne . 'Si W tym podrozdziale opisuję bardziej szczegółow o i w kolejności alfabetycznej funkcje biblioteki lw IP obsługujące kom unikację za pom ocą UDP. Funkcja udp_new przydziela now y deskryptor UDP. Z w raca w skaźnik do przydzie­ lonego deskryptora lub N U L L , gdy nie udało się go przydzielić. err t udp bind (struct udp_pcb *pcb, struct ip addr *addr, u!6_t port); Funkcja udp b in d w iąże deskryptor U D P z lokalnym adresem IP i portem, któ’ re m ają być używ ane do o d bierania datagram ów . W ybrany adres i port będą też'15 um ieszczane ja k o adres i port nadaw cy w w ysyłanych za pom ocą tego deskryptofąf datagram ach UDP. Pierw szym argum entem tej funkcji je st w skaźnik pcb do de-, skryptora UDP. D rugim argum entem je s t w skaźnik a d d r do struktury zawierającej? adres IP. Jeśli argum ent ten m a w artość IP_ADDR_ANY, deskryptor w iązany jest n ■ w szystkim i lokalnym i adresam i IP, co je s t przydatne, gdy je s t tylko jeden interfejs1 sieciow y lub gdy chcem y, aby serw er odbierał datagram y U D P ze w szystkich in-' terfejsów sieciow ych. Trzeci argum ent p o r t je s t num erem portu. Jeśli ma w artość zero, to biblioteka lw IP przydziela dow olny niezajęty port. Ten argum ent m a zwyt* kle w artość zero, gdy urucham iam y klienta, gdyż w tedy num er portu je s t nieistotny,. D la serw era zw ykle podaje się w artość niezerow ą, gdyż serw er m usi nasłuchiwać.; na pow szechnie znanym porcie. F unkcja zw raca ERR_OK, gdy zakończyła się suk­ cesem , a ERR_USE, gdy nie m ożna użyć podanych w artości, np. żądany port jesti' zajęty. err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *addr, ul6_t port)/ struct udp_pcb * udp j i e w (void); * Funkcja udp _ co n n ect przypisuje d o deskryptora U D P adres IP i num er portu zdah; nego końca kom unikacji. U staw ia dom yślny adres IP i port, na które będą wysy-' lane datagram y U D P za pom ocą funkcji udp send. Ponadto pow oduje, że będą odbierane i przetw arzane tylko datagram y, które zostały w ysłane z podanego źrór dla. Pierw szym argum entem je s t w skaźpjk pcb do deskryptora UDP. D rugim atr gum entem je s t w skaźnik a d d r jlo.stru k tu fy zaw ierającej adres IP. Trzeci argumenj? p o r t je s t num erem portu. Podany adres IP i num er portu są tylko zapisyw ane w ItA, kalnym deskryptorze UDP. N ie odbyw a się żadna kom unikacja sieciow a. Jeśli me; został przypisany lokalny adres IP i num er portu, najpierw je s t w yw ołana funkcją void udp__recv (struct udp_pcb *pcb, void (* recv__callback) (void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u!6_t port), void *arg); Funkcja u d p _ recv rejestruje funkcję zw rotną, która będzie w yw ołana przez biblio­ tekę lw IP po odebraniu datagram u UDP. Pierw szym argum entem tej funkcji jest w skaźnik pcb do deskryptora UDP, w którego kontekście będą odbierane datagra­ my. D rugi argum ent recv__callback je s t adresem rejestrow anej funkcji zw rotnej. T rzecim argum entem je st w skaźnik a rg do danych aplikacji. W skaźnik ten będzie p rzekazyw any jttko pierw szy argum ent funkcji zw rotnej, co um ożliw ia obsługę w ie­ lu klientów i serw erów za pom ocą w spólnej funkcji zw rotnej. void udp_remove(struct udp pcb *pcb); Funkcja udp_remove zw alnia deskryptor UDP. A rgum ent pcb je st w skaźnikiem do deskryptora, który m a być zw olniony. F unkcja ta pow inna być w yw ołana, gdy klient lub serw er kończą działanie. w--------- -------------------------------- -—-------------------------- -----------------------------------err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) F unkcja udp_send w ysyła datagram U D P na adres IP i port, które zostały skon­ figurow ane za pom ocą funkcji u d p _connect. Pierw szym argum entem tej funkcji jest w skaźnik pcb do deskryptora UDP, w którego kontekście m ają być w ysyłane datagram y UDP. D rugim argum entem je st w skaźnik p do łańcucha buforów z da­ nymi, które m ają być um ieszczone w polu danych datagram u UDP. Ten łańcuch bufonów przydzielam y za pom ocą funkcji p b u f_ a llo c , której pierw szy argum ent poW łmen ¡htUć w artość P B U F _ T R A N S P O R T . A ktualna im plem entacja funkcji udp_send w yw ołuje >pó ¡prostu funkcję ud p _ sen d to z adresem IP i num erem portu pobranym i 4. Programowanie w modelu klicnt-serwem 166 4.4. Uwagi końcowe im plem entow ać sam em u. O czyw iście zaproponow ane nazw y funkcji zw rotnych są tylko przykładow e i m ożna je w ybrać dow olnie. z przekazanego jej deskryptora UDP. Funkcja udp_send zw raca te sam e wartości Gęjl funkcja udp_ sen d to . err_t udp_sendto(struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, ul6_t port); Funkcja ud p _ sen d to w ysyła datagram U D P na podany adres IP i port. Pierwszymi! argum entem tej funkcji je s t w skaźnik pcb do deskryptora UDP, w którego kotWi tekście m ają być w ysyłane datagram y UDP. D rugim argum entem je s t wskaźnik p i| do łańcucha buforów z danym i, które m ają być um ieszczone w polu danych d au ,.^ gram u UDP. Łańcuch buforów przydzielam y za pom ocą funkcji p b u f_ a llo c , któi-J rej pierw szy argum ent m a w artość PBUF_TRANSPORT. T rzecim argum entem funkcji' u d p _ sen d to je s t w skaźnik a d d r do struktury zaw ierającej adres IP, na który ma by<$ w ysłany datagram UDP. C zw arty argum ent p o r t je st num erem portu, na który ma] być w ysłany ten datagram . Jeśli nie został przypisany lokalny adres IP i num er por-i^ tu, najpierw w yw ołana je s t funkcja udp__bind. Funkcja u d p _ sen d to zw raca ERR_0K,:i gdy udało się w ysłać datagram UDP. Jeśli w ystąpił problem , funkcja ta zw raca właściw y kod błędu. 4.3.6. Funkcja zwrotna O program ow anie U D P używ a tylko jed n ej fu n k c ji,zw rotnej, która służy do odbieg rania danych. M usim y ją sam i zaim plem entow ać. void recv_caliback(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u!6_t port); Funkcja zw rotna r e c v _ c a llb a c k je s t w yw ołana przez bibliotekę łwIP, gdy zosta-' nie odebrany datagram UDP. P ierw szym argum entem tej funkcji je s t w skaźnik arg; podany przy rejestrow aniu lej funkcji zw rotnej. D rugim argum entem je st wskaźnik pcb do deskryptora UDP, w którego kontekście odebrano datagram UDP. Trzecim argum entem je st w skaźnik p do łańcucha buforów ^żaw ierającego pole danych datagranut UDP. C zw artym argum entem je st w skaźnik a d d r do struktury zaw ierającej, adres IP nadaw cy datagram u U D P Piąty argum ent p o r t je s t num erem portu nadaw-cy datagram u UDP. A rgum enty a d d r i p o r t są potrzebne, aby aplikacja mogła odr pow iedzieć na otrzym any kom unikat. A rgum enty te m ogą być przekazane wprost funkcji udp _ sen d to . 4.4. Uwagi końcdwe O pisane w tym rozdziale struktury danych i funkcje biblioteki łwIP, z wyjątkiem funkcji zw rotnych, są zadeklarow ane w plikach tcp.h i udp.h, a ich implementację l l l 5^ znajdują się w plikach tcp.c, tcp_in.c, tcp_oul.c, udp.c. Funkcje zw rotne trzeba z.i- 167 W tym m iejscu książki kończy się opis dolnych w arstw inter,sieci. Stąd je st to dobre m iejsce na m ale podsum ow anie. Przedstaw iony dotychczas m aterial w ystarcza, aby zacząć pisać aplikacje sieciow e na m ikrokontroler ST M 32F107 z w ykorzystaniem biblioteki lwIP, co je st tem atem następnych rozdziałów , które zaw ierają przykłady serw erów i klientów korzystających z opisanego w tym rozdziale interfejsu progra­ m istycznego. W kolejnych rozdziałach pojaw ią się rów nież dodatkow e inform acje 0 protokołach intersieci. Przykłady będą też okazją do zaprezentow ania niektórych peryferii m ikrokontrolerów STM 32. C zytelnikom , którzy chcieliby bliżej poznać zasady działania intersieci i nie chcą czytać dokum entów RFC, polecam w yda­ ną przed w ielom a laty, ale w ciąż aktualną i bardzo przystępnie napisaną książkę D ouglasa C om era [1]. D otychczas kilka razy w spom niałem o bezpieczeństw ie. Ten tem at w ym aga po­ św ięcenia mu nieco uw agi. B ezpieczeństw o w inform atyce należy postrzegać jak o odporność na celow e działanie zm ierzające do zm uszenia system u inform atycznego, aby działał niezgodnie z je g o pierw otnym przeznaczeniem , niezgodnie ze specyfi­ kacją lub w ręcz, aby w ogóle przestał działać. N a bezpieczeństw o m ożna patrzeć z różnych punktów w idzenia. Jednym z fundam entalnych elem entów bezpieczeństw a aplikacji je s t jej popraw ­ ność. Jeśli aplikacja działająca w sieci kom puterow ej ma ja k iś błąd lub lukę, to kiedyś zostanie to w ykorzystane. Pisząc aplikacje sieciow e, należy zakładać, że druga strona kom unikacji m oże zachow ać się złośliw ie. W szczególności nie w ol­ no zakładać, że otrzym yw ane kom unikaty zaw sze będą zgodne z ich specyfikacją 1 należy przeprow adzać ich skrupulatną w alidację. Jeśli na przykład program ista piszący serw er założy, że kom unikaty od klienta są zaw sze popraw ne i zaniecha ich spraw dzania, to zaw sze znajdzie się inny program ista, który napisze klienta w ysy­ łającego niepopraw ny kom unikat, co w najlepszym przypadku doprow adzi do unie­ ruchom ienia serw era. W mniej optym istycznym w ariancie błąd w im plem entacji m oże doprow adzić do nadużycia usługi. N ikt nigdy nie zw olni nas z obow iązku pisania popraw nych program ów , a program y sieciow e w ym agają szczególnej sta­ ranności. N ależy przyjąć założenie, że druga strona kom unikacji m oże zachow yw ać się zupełnie dow olnie lub w ręcz złośliw ie i należy m aksym alnie uodparniać pisaną aplikację, na takie zachow ania. Takie podejście staram się prezentow ać w przykła­ dach. Innym i, nie mniej istotnym i, elem entam i bezpieczeństw a są: - poufność (ang. confidentiality), integralność (ang. integrity), - dostępność (ang. availability). N ieprzypadkow o pierw sze litery angielskich nazw tych elem entów bezpieczeństw a tw orzą skrót CIA . P oufność oznacza ochronę inform acji przed nieautoryzow anym ujaw nieniem . R ealizuje się ją , stosując kontrolę dostępu do usługi np. za pom ocą hasei'® szy-ffijłjąc przesyłane dane. Integralność oznacza ochronę inform acji przed ich nieupraw nionym zm odyfikow aniem . Z w ykle integralność chroni się przez sku- 168 4. Programowanie w modelu klient-serwer teczne w ykryw anie każdej próby m odyfikacji. Protokoły sieciow e stosują w tym 1'' celu sum y kontrolne. Jednak zw ykle sum y kontrolne są łatw e do podrobienia i z.! pew niają ochronę tylko przed losow ym i przekłam aniam i. N ie zapew niają je d n a k ; żadnej ochrony przed celow o w prow adzanym i zm ianam i. W celu zapew nienia ■ integralności stosuje się kryptograficzne sum y kontrolne i podpisy elektroniczne. ■ Podpis elektroniczny służy też do zapew nienia autentyczności (ang. authenticity) inform acji, czyli pew ności co do pochodzenia danych i ich autorstw a. D ostępność je st to zdolność do św iadczenia usługi bez przerw, 24 godziny na dobę, 7 dni w ty- ‘ godniu itd. N ajczęstszą przyczyną braku dostępności w sieci są aw arie i ataki typu ; odm ow a usługi (D oS). D ostępność zapew nia się, stosując rozw iązania programowe i sprzętow e, np. przez dublow anie krytycznych elem entów system u. N ależy wy- '■ raźnie zaznaczyć, że pełna ochrona nie je st m ożliw a, a stosow ane środki zawsze w ynikają z pew nego kom prom isu, często o podłożu ekonom icznym . Pow yższy akapit ma tylko uczulić C zytelnika na w spom niane problemy. Ich ■ uw zględnienie w ykracza daleko poza ram y tej książki. W w ielu zastosow aniach nie je st to też konieczne. W dalszym ciągu zakładam , że przykłady będą urucham iane ■' w zaufanej sieci lokalnej, chronionej od niebezpieczeństw czyhających w Internecie', co najm niej za pom ocą ściany ogniow ej. Serwer TCP 170 5. Sen Tem atem tego rozdziału je st serw er używ ający protokołu transportow ego T C p | M ateriał podzieliłem na dw a przykłady. W pierw szym z nich pokazuję, ja k zaii plem enlow ać kom unikację sieciow ą. P rzykładow a aplikacja um ożliw ia zdalne w łąi czanie i w yłączanie diod św iecących podłączonych do m ikrokontrolera oraz odczy t! czasu, jaki upłynął od w łączenia układu, ale m ożna ją łatw o rozbudow ać i dodać ste-tl row anie innym i peryferiam i. Drugi przykład je st rozszerzeniem pierw szego. Serwera pow inien działać bezobsiugow o i radzić sobie z sytuacjam i aw aryjnym i. W tyłgl celu w drugim przykładzie dodaję obsługę układu nadzorcy (ang. watchclog), k t ó lf ry zeruje m ikrokontroler, gdy oprogram ow anie sieciow e nie w ykazuje aktywno przez określony czas. N adzorca w ym usza też ponow ienie próby uruchom ienia : w era, gdy w ystąpi problem podczas konfigurow ania ustaw ień sieciow ych. 5.1. Protokół warstwy aplikacji Przystępując do napisania aplikacji sieciow ej, m usim y w ybrać protokół warsty/y* aplikacji. M ożem y użyć jakiegoś istniejącego protokołu lub zaprojektow ać własr ' Przykłady w ykorzystujące istniejące standardow e protokoły aplikacyjne intersieM ■ pojaw iają się w rozdziale 8 i rozdziale 10. W tym rozdziale oraz w rozdziale 6 : i rozdziale 7 pokazuję, ja k zaprojektow ać w łasny protokół. 5.1.1. Projekt protokołu Projekt protokołu pow inien zaw ierać specyfikację w ym ienianych komunikatów i opis interakcji m iędzy klientem a serw erem . Istnieją zasadniczo dw a podejścia do projektow ania form atu kom unikatów : kom unikaty m ogą być opisane za pomocą struktur binarnych albo m ogą to być kom unikaty tekstow e, czytelne dla człowieka, i K om unikatom tekstow ym też m ożna nadać strukturę - zw ykle za pom ocą X M L -a,, W szystkie dotychczas opisane w tej książce protokoły intersieci m ają komunikaty,-' zdefiniow ane ja k o struktury binarne. N atom iast w iele protokołów aplikacyjnych in -. tersieci używ a kom unikatów tekstow ych. O ba podejścia m ają sw oje zalety i w ady., K om unikaty binarne są zw ykle krótsze od odpow iednich kom unikatów tekstowych niosących tę sam ą treść i łatwiej je s t zaim plem entow ać analizę kom unikatów bi­ narnych niż tekstow ych, dlatego kom unikaty binarne są preferow ane w dolnych w arstw ach intersieci. Jednak człow iekow i zdecydow anie łatwiej czytać komunikaty i tekstow e. W przypadku kom unikatów tekstow ych ułatw iona je s t analiza śladu (ang,. ■ tracę) przebiegu protokołu i ..łatwiej je s t napisać-skrypty testujące protokół, d la te-. #r:. «■ go kom unikaty tekstow e tak często są używ ane' w^-protokołach w arstw y aplikacji,:; Do testow ania kom unikacji z serw erem używ ającym protokołu tekstow ego możnaw ykorzystać program telnet, który je s t standardow o dostępny zarów no w systemie Linux, ja k i W indow s. P rogram telnet je s t klientem protokołu Telnet, cłioć sam ter; stow any serw er nie m usi w pełni obsługiw ać tego protokołu. W tym rozdziale oraz • w rozdziałach 6 i 10 pokazuję protokoły tekstow e. Protokoły aplikacyjne, których kom unikaty mają posłać binarną, pojaw iają się jeszcze w rozdziałach 7 i 8. Interakcję m iędzy klientem a serw erem iribżna opisać słow nie lub w yrazić za po­ m ocą diagram u autom atu stanow ego. O pis słow ny byw a preferow any w przypadku ; prostych protokołów bezslanow ych. B ezstanow ość oznacza, że reakcja protokołu., zależy tylko od aktualnie odebranego kom unikatu i nie zależy od komunikatów 171 5.1. Protokół warstwy aplikacji Tab . 5 .1 . Polecenia obsługiwane przez serwer Opis Polecenie h ? Wyświetl tekst pomocy zawierający opis obsługiwanych poleceń G Włącz zieloną diodę świecącą g R Wyłącz zieloną diodę świecącą r Wyłącz czerwoną diodę świecącą t Podaj, ile czasu upłynęło od włączenia mikrokontrolera X Zakończ komunikację Wyświetl tekst pomocy zawierający opis obsługiwanych poleceń Włącz czerwoną diodę świecącą w ym ienionych poprzednio. O pis za pom ocą autom atu byw a bardziej precyzyjny. W dokum entach RFC przeplatają się oba podejścia. Z aprojektow any na potrzeby przykładów zam ieszczonych w tym rozdziale protokół je st bardzo prosty i bezstanowy, dlatego w zupełności w ystarczy je g o opis słowny. N ależy zw rócić uw agę, że projekt protokołu je st czym ś innym niż projekt im plem entacji protokołu. Projekt protokołu opisuje głów nie kom unikację sieciow ą, czyli przede w szystkim dane, które m ożna podejrzeć w kanale kom unikacyjnym , w pinając się analizatorem sieci. Projekt protokołu opisuje też inform acje, które m ożna w yw nioskow ać na podsta­ wie obserw acji tej kom unikacji. Protokół m usi dać się zaim plem entow ać w różnych środow iskach i nie m oże zależeć od architektury sprzętu, języ k a program ow ania czy interfejsu program istycznego udostępnianego przez jak ieś biblioteki. N atom iast p rojekt im plem entacji m usi uw zględniać specyficzne w łasności sprzętu, języ k a p ro ­ gram ow ania i w ykorzystyw anych bibliotek. Po tym krótkim w stępie przejdźm y do opisu protokołu, za pom ocą którego będzie­ my kom unikow ać się z naszym serw erem . W tab eli 5.1 zaw arto polecenia, które ob­ sługuje serwer. W ta b eli 5.2 podano odpow iedzi udzielane przez serwer. D ziałanie protokołu je st następujące. K lient inicjuje połączenie T C P z serw erem . Serw er po zaakceptow aniu połączenia w ysyła klientow i tekst pow itania i znak zachęty do w pi­ sania polecenia. K lient w ysyła jednoliterow e polecenie zakończone znakiem końca w iersza. Jeśli klient poprosi o tekst pom ocy, serw er w ysyła go i ponow nie w ysyła Tab . 5 .2 . Odpowiedzi udzielane przez serwer Odpowiedź This is TCP server running on top of the IwIP-st^ek.. Press h or ? to get help. Opis Tekst powitania > Znak zachęty db wpisania polecenia h or ? print this help G turn on the green led g turn off the green led R turn on the red led r turn off the red led t get microcontroller running time x exit Tekst pomocy d gg:mm:ss.xxx Czas w formacie: liczba dni, godzin, minut, sekund, milisekund ERROR B *3 | „1; Przekroczony czas oczekiwania na polecenie Błędne polecenie 173 5.1. Protokół warstwy aplikacji znak zachęty. Jeśli klient zażąda w ykonania operacji na diodzie św iecącej, serwer■: w ykonuje tę operację i w ysyła kolejny znak zachęty. Jeśli klient zażąda informacji cji o czasie, serw er odsyła czas, który upłynął od uruchom ienia m ikrokontrolera^ w form acie: liczba dni, godzin, m inut, sekund i m ilisekund, a następnie wysyła znak zachęty do w pisania kolejnego plecenia. Jeśli klient w yśle polecenie zakoń,)*; czenia połączenia, serw er nie odpow iada i natychm iast zam yka połączenie TCP,, Jeśli klient w yśle puste polecenie, sam znak końca w iersza, serw er odsyła znaki1' zachęty. Jeśli klient przez 30 sekund nie w ykazuje żadnej aktyw ności, nie przysyła żadnego polecenia, serw er w ysyła kom unikat o przekroczeniu czasu i zam yka pot' łączenie TCP. Jeśli serw er odbierze polecenie, którego nie potrafi zinterpretować/^* to w ysyła kom unikat inform ujący, że odebrał błędne polecenie i ponow nie w y s y ła ć znak zachęty. Przesyłane teksty są kodow ane za p om ocą A SCII. K lient i serw er ja k o znak końca'1 w iersza w ysyłają kolejno znak pow rotu karetki C R (ang. carriage return) i znakżprzejścia do now ego w iersza LF (ang. line fe e d ). K onw encja ta je st pow szechnie. stosow ana w protokołach intersieci, np. w protokołach Telnet i HTTP. Program tel-'X net po w ciśnięci klaw isza E nter w ysyła w łaśnie znaki C R i LF. Taką sam ą kon- ;$ w encję stosuje się w system ie W indow s. W A SC II znak CR m a kod 0x0D , a znak L F kod 0x0A . S erw er pow inien pom ijać białe znaki w poleceniach odbieranych od1, klienta. B iałym i znakam i, oprócz C R i LF, są np. spacja (znak SP, kod A SC II 0x20) • i tabulacja (znak HT, kod A SCII 0x09). Projekt implementacji protokołu if. G dy m am y ju ż gotow y projekt protokołu, m ożem y przejść do im p lem en to w an ia"'^ , serw era obsługującego ten protokół. W ym aga to najpierw zaprojektow ania analiza- -'4\ tora (ang. parser) odbieranych kom unikatów . W tym celu najw ygodniej jest u/ \ i autom atu stanow ego. N a ry s u n k u 5.1 um ieszczone są sym bole, których będę u; wał do rysow ania takich autom atów . A utom at m a pew ną skończoną liczbę stanów. Jest to pam ięć autom atu. M ożna sobie ' w yobrażać, że stan to zm ienna w yliczeniow a przyjm ująca tyle różnych w artości, ile autom at m a stanów. Podczas pracy autom at zm ienia stan. Z m iana stanu m oże być w ynikiem odebrania kom unikatu lub zajścia zdarzenia. K om unikaty są zdefinio­ w ane przez protokół i pochodzą z sieci. N atom iast zdarzenia są generow ane lokal­ nie. Z darzenia m ogą być generow ane przez sp rzę tJu b m ogą być efektem działania użytkow nika. Specjalnym rodzajem zdarzenia jest.b u d zik inform ujący o upłynięciu określonego czasu. Sym bol budzika przypom ina klepsydrę. Podczas zm iany stanu .■j.yij. autom at m oże w ysłać kom unikat do sieci lub w ygenerow ać zdarzenie, które może . być też inform acją dla użytkow nika. K om unikaty i zdarzenia reprezentow ane są"' przez pięciokąty w kształcie strzałek z opisem w środku. Strzałka po praw ej ozna­ cza kom unikaty, a strzałka po lew ej - zdarzenia. Strzałka skierow ana do wewnątrz oznacza odebranie kom unikatu lub zajście zdarzenia, a strzałka skierow ana na ze w nątrz oznacza w ysłanie kom unikatu lub m y generow anie zdarzenia. A utom at rozpoczyna pracę w stanie początkow ym . Podczas pracy autom at pr/.ei dzi pom iędzy stanam i w ew nętrznym i, które m ożna ponum erow ać. Jednak wygod­ niej je s t nadać stanom nazwy, co istotnie popraw ia czytelność rysunku i ułatwia zro-1 O d ebranie k o m unikatu Z W ysianie kom unikatu Zajście zd arzenia W yg e ne ro w an ie zdarzenia M odyfikacja zm ie n n ej w ew n ę trzn ej ! S tan począ tkow y Stan końcow y S tan w ew n ę trzn y B udzik A ltern a tyw a P rze pływ ste ro w a n ia Rys. 5.1. Symbole używane w automatach stanowych opisujących protokół zum ienie algorytm u, yżedług którego działa autom at. Stan w ew nętrzny reprezento­ w any jest przez ow al z nazw ą tego stanu. A utom at m oże zatrzym ać się i zakończyć pracę w stanie końcow ym . Stanów końcow ych m oże być w iele. Stanu końcow ego m oże też nie być, gdy nie przew idujem y zatrzym ania autom atu. Przepływ sterow a­ nia w autom acie zaznaczam y, łącząc poszczególne sym bole strzałkam i. Z danego stanu autom at m oże zostać w yprow adzony przez w iele różnych kom unikatów lub zdarzeń, co rysujem y za pom ocą rozgałęziających się strzałek. A by nie tw orzyć zbyt w ielu stanów, czasem w ygodnie jest w prow adzić do auto­ m atu zm ienne w ew nętrzne. Z m iany w artości zm iennych w ew nętrznych rysuje się w prostokątach. Jeśli autom at zaw iera zm ienne w ew nętrzne, to przepływ sterow a­ nia m ożna uzależnić od ich w artości. R ysuje się to przez um ieszczenie w łaściw ego w arunku w rom bie, do którego prow adzi je d n a strzałka, a z którego w ychodzą dw ie strzałki. Jedna, ta oznaczona etykietą tak, pokazuje przepływ sterow ania, gdy waru"ifek“je ś f spełniony, a druga - oznaczona etykietą nie - gdy nie je st spełniony. F orm alnie w szystkie zm ienne w ew nętrzne tw orzą pam ięć autom atu, czyli są częścią je g o stanu. W szystkie zm ienne w ew nętrzne m ożna usunąć, w prow adzając dodatko­ we stany. Przykładow o, jeśli zm ienna m oże przyjm ow ać 30 w artości, to każdy stan należy zastąpić trzydziestom a stanam i, po jednym dla każdej w artości usuw anej zm iennej. W idać, że prow adzi to do law inow ego w zrostu liczby stanów i zm niej­ sza czytelność diagram u opisującego autom at. Z drugiej strony, m ożna zredukow ać liczbę nazw anych stanów w ew nętrznych do jednego, um ieszczając całą pam ięć au­ tom atu w zm iennych. Takie skrajne podejście też zm niejsza czytelność diagram u. 0 .'W b q ^ |e ), co m a być stanem , a co zm ienną, decyduje więc przede w szystkim czytelnosś ćji(izyskanego projektu autom atu. -K.v: 174 5. Serwer TCP.i* N a kolejnych rysunkach pokazano projekt im plem entacji serw era realizującego’’ protokół opisany w poprzednim podrozdziale. D la każdego połączenia serw er uru-ą cham ia now ą kopię autom atu. N a r y s u n k u 5.2 przedstaw iony je s t początkowyfragm ent działania autom atu. Po odebraniu now ego połączenia serw er w ysyła d o / klienta tekst p ow itania oraz znak zachęty do w pisania p o lecenia i przechodzi do"' stanu InilState, w którym czeka na polecenie. P oniew aż T C P je s t protokołem stru-,;'/ m ieniow ym , o dbierane dane trzeba analizow ać znak po znaku. W stanie InitStale.: serw er ignoruje znaki spacji SP, tabulacji IIT i pow rotu karetki C R , a po każdym i znaku now ego w iersza w ysyła kolejny znak zachęty. Z e specyfikacji protokołu wi,j.' dać, że końcem w iersza je s t para znaków C R i LF. Form alnie należałoby traktować \ sam znak LF ja k o błąd. Jednak w sy stem ach uniksow ych ja k o znak końca w iers/a stosuje się sam znak LF. Z atem bardziej rozsądnym podejściem je s t uznanie sam e­ go znaku LF ja k o popraw nego zak ończenia w iersza. U praszcza to im plem entację ' - nie trzeba w prow adzać d o datkow ego stanu o czekiw ania po znaku C R na znak ’ LF. Ponadto taka im plem entacja serw era toleruje klienta, który nie działa w pełni '<• zgodnie ze specyfikacją, ale odstęp stw o od niej je s t na tyle drobne, że polece- ■ nia m ogą być popraw nie zinterpretow ane. A lternatyw nie należałoby potraktow ać brak znaku CR przed LF ja k o błąd, ale takie rygorystyczne traktow anie błędów nie zaw sze je s t dobrą strategią. O d ebranie w stanie InitS tale je d n eg o ze znaków w ym ienionych w tabeli 5.1 pow oduje przejście do stanu, w którym serw er bę­ dzie oczekiw ał na zakończenie polecenia, czyli na o debranie znaku LF. Serw er ma " w spółpracow ać z klientem protokołu Telnet, w ięc dodatkow o w stanie InilState rozpoznaje znak IA C (ang. interpret cis com m and) o kodzie OxFF, o czym dalej. 175 5 . 1. Protokół warstwy aplikacji SP, HT, CR <( LF Tekst pom ocy \ 1znak zachęty / Rys. 5.3. Projekt implementacji serwera - stan HelpState D o im plem entacji serw era w prow adzam y celow y błąd. O debranie znaku dolara zaw iesza działanie serw era - na rysunku nie m a strzałki w ychodzącej z sym bolu o zn aczającego odebranie tego znaku. Ten błąd posłuży w następnym przykładzie do przetestow ania działania nadzorcy. O debranie każdego innego znaku w stanie InilS tate w prow adza autom at serw era w stan E rrorState. N a r y s u n k u 5.3 zilustrow ane je s t działanie serw era w stanie H elpState. B iałe zna­ ki są ignorow ane. Po odebraniu znaku L F serw er w ysyła tekst pom ocy i znak za­ chęty, po czym w raca do stanu InitState, w którym będzie oczekiw ał na kolejne polecenie. O debranie niebiałego znaku w stanie H elpState pow oduje przejście do stanu E rrorS tate. Na r y s u n k u 5.4 w idoczne je s t działanie serw era w stanach do­ tyczących obsługi diod św iecących. Jak poprzednio w tych stanach białe znaki są ignorow ane. Po odebraniu znaku L F serw er zależnie od stanu, w którym się znajduje, w łącza lub w yłącza odpow iednią diodę, a następnie w ysyła znak zachęty i w raca do stanu InitState. O debranie niebiałego znaku traktow ane je s t jak o błąd i pow oduje przejście do stanu E rrorS tate. N a r y s u n k u 5.5 przedstaw iony je st frag­ m ent autom atu dotyczący stanu G etL ocalT im eState. Schem at działania je st analo- lim 1 Rys. 5.2. Projekt implementacji serwera - stan początkowy II I ■ In n y znak <( 1 Rys. 5.4. Proijśkt implementacji serwera - stany LedState 5. /. Protokół warstwy aplikacji 177 Rys. 5.5. Projekt implementacji serwera - stan GetLocalTimeState Rys. 5.8. Projekt implementacji serwera - stan ErrorState giczny ja k na poprzednich rysunkach, z tą tylko różnicą, że po odebraniu znaku j L F serw er w ysyła klientow i inform ację zaw ierającą czas, który upłynął od urucho-L m ienia m ikrokontrolera. N a r y s u n k u 5.6 pokazano fragm ent autom atu dotyczący;;; stanu E xitState. Po odebraniu znaku L F serw er zam yka p o łączenie i kończy działanie autom atu. N a ry s u n k u 5.7 pokazano działanie serw era w stanie lA C State. Serw er znajdzie się w tym stanie po odebraniu znaku IAC, który oznacza początek polecenia pro­ tokołu Telnet. Pow odem w prow adzenie tego stanu je s t um ożliw ienie w spółpracy serw era z program em telnet. W tym celu w ystarczy, aby serw er ignorow ał polece­ nia D O (kod OxFD), D O N T (kod OxFE), W IL L (kod OxFB) i W O N T (kod OxFC). Po każdym z tych poleceń w ystępuje jednooktetow y kod opcji, na którą serw er czeka w stanie O ptionState i którą ignoruje, w racając po je g o odebraniu do stanu InitState. Inne polecenje nie pow inno się pojaw ić i jest traktow ane przez serw er ja k o błąd. W ięcej na teh tem at m ożna przeczytać w [1, rozdz. 23]. N a r y s u n k u 5.8 objaśniono działanie serw era w stanie ErrorState. W tym stanie serw er pow inien starać się w yjść z błędu i rozpoznać początek popraw nego polece­ nia. D latego serw er ignoruje w szelkie znaki z w yjątkiem LF, po którego odebraniu w ysyła do klienta inform ację o błędzie i znak zachęty do w pisania popraw nego polecenia, po czym w raca do stanu InitState. Rys. 5.6. Projekt implementacji serwera - stan ExitState I , Nowe połączenie <T tłm eout = 30 Tekst powitania \ i znak zachęty / • lii Rys. 5.7. Projekt implementacji serwera - stan lACState s || Rys. 5.9. Projdikt implementacji serwera - przekroczenie czasu 5.2. Przykład 5a - pierwsza wersja serwera TCP 5. Serwer 7 178 179 R. f poczekają w kolejce odbiorczej D M A i zostaną przetw orzone przez stos dopiero po ponow nym uaktyw nieniu przerw ań - nic złego się nie stanie. Specyfikacja protokołu nakazuje serw erow i zaniknięcie poleczenia TCP, gdy kii nie odzyw a się, nie przysyła żadnego polecenia przez 30 sekund. A by zrealizowa to w ym aganie, dodajem y budzik, który generuje zdarzenie upływ u czasu co sekuĄl dę. Ponadto dodajem y zm ienną timeout, która zlicza upływ czasu - je st zr szana o jed en po odebraniu zdarzenia budzika. O dpow iednie m odyfikacje automatu! przedstaw ione są na ry s u n k u 5.9. Po odebraniu now ego połączenia serw er inicji zm ienną timeout w artością 30. D odatkow o w każdym stanie (na rysunku zaznaczo-^ nym ja k o ow al z w ielokropkiem ) po odebraniu dow olnego kom unikatu (na rysunkui kom unikat oznaczony w ielokropkiem ) trzeba ponow nie zainicjow ać tę zmienną,i' W każdym stanie należy też dodać obsługę zdarzenia budzika: serw er zm niejsza’! w artość zm iennej timeout i jeśli osiągnie ona w artość zero, to inform uje klientki! o upłynięciu czasu oczekiw ania na polecenie i zam yka połączenie TCP. 5.2. int TCPserverStart(uintl6__t port) { struct tcp_pcb *pcb, *listen_pcb; err_t err; IRQ~DECL_PROT£CT(x) ; IRQ^PR0TECT(x, LWIP_IRQ_PRI0) ; pcb = tcp_new(); IRQ UNPROTECT(X); i f Tpcb *== NULL) return -1; IRQ^PROTECT(x, LWIP_IRQ_PRI0); err = tcp_bind(pcb, IP_ADDR_ANY, port); IRQ_UNPROT£CT(x); i f (err != ERR_0K) ( IRQ_PROTECT(x, LWIP_IRQ_PRI0); tcp_abandon(pcb, 0); IRQ_UNPROTECT(x); return -1; Przykład 5a - pierwsza wersja serwera TCP N azw y plików przykładu 5a zam ieszczone są w ta b e li 5.3. W iększość z nich zosta­ ła ju ż opisana w poprzednich rozdziałach. D alej opisuję tylko now e pliki. 5.2.1. } IRQ_PR0TECT(x , LWIP_IRQ_PRIO); listen_pcb = tcp_listen(pcb); if (listen_pcb) tcp_accept(listen_pcb, accept_callback); IRQJJNPROTECT(x) ; Pliki tcp_server.h i tcp_server.c Plik tcp_server.h zaw iera sygnaturę funkcji TCPserverStart, która urucham ia ser-:i'ij w er TCP. .lej im plem entacja znajduje się w pliku lcp_servenc. A rgum entem funkcji'-,? TCPserverStart je s t num er portu, na którym serw er m a nasłuchiw ać. Funkcja ta jfjj zw raca zero, gdy uruchom ienie pow iodło się, a w artość ujem ną, gdy nie udało się-żłj| uruchom ić serw era. Funkcja TCPserve r S t a r t działa zgodnie z diagram em serwera,śj przedstaw ionym w poprzednim ro zdziale na rysunku 4.4, a dodatkow o sprawdza: w artości zw racane przez poszczególne funkcje z biblioteki lw IP i obsługuje błędy. Funkcja ta je s t przeznaczona do w yw ołania z program u głów nego, a więc spoza ■ biblioteki lwIP, dlatego w yw ołania funkcji bibliotecznych odbyw ają się przy zablo­ kow anych przerw aniach biblioteki. Funkcja tcp_listen w ykonuje pasyw ne otwar-: cie - aktyw uje nasłuchiw anie połączeń od klientów . F unkcja tcp_accept rejestruje funkcję zw rotną obsługującą faktyczne otw ieranie połączenia. M iędzy wywołaniem . tcp_listen a tcp_accept stos lw IP nie m oże odebrać połączenia, ale ponieważ przerw ania są zablokow ane, to ew entualne odebrane w tym czasie pakiety sieciov Tab. 5.3. Pliki przykładu 5a board_conl.c boardJ n il.c boardJ e d .c „ tcp_server.li } return 0; ) Stan autom atu serw era przechow ujem y w strukturze typu s t a t e . Składow a ti­ meout tej struktury zaw iera liczbę sekund, przez które serw er m a jeszcze czekać na polecenie od klienta, patrz rysunek 5.9. Składow a function tej struktury je st adresem funkcji, która ma być w yw ołana w celu obsłużenia kolejnego odebranego znaku. struct state { err t (* function) (struct state *, struct tcp_pcb *,..uint8__t); int timeout; ■■ Źródłowe i biblioteczne e x jc p d .c startup_stm 32j:ld . c tcp_server.c if (listen pcb == NULL) { IRQ__PROTECT(x, LWIP_IRQ_PRI0); tcp_abandon(pcb, 0); IRQJJNPROTECT(x); return -1; util_delay.c util_eth_nc.c u li/Je d .c u tiljw ip .c ulil tim e.c Nagłówkowe board_conf.h board_de!.h board_de!s.h boardjn it.h board led.h util_delay.h * util_eth.li u tilje d .li u tiljw ip .h util time.ti tibiwip4.a iibstm32f10x.a ■ ■ : i 1; 1 i i iS ■ V . CC./) cortex-m3, h lwipopts.li stm 32!10x_conf.h 1111 ;JjV ’ ■7’5'i T D la każdego stanu definiujem y osobną funkcję, której nazw a je s t taka sam a jak nazw a tego stanu. Zm iana stanu odbyw a się przez zm ianę w artości składow ej function. W szystkie funkcje m ają tę sam ą sygnaturę. Pierw szym argum entem jest w skaźnik do struktury typu state, co um ożliw ia obsługę w ielu klientów (połą­ czeń T C P ) za pom ocą tych sam ych funkcji - funkcja dostaje w skaźnik do struktury zw iązanej z klientem (połączeniem T C P ), którego m a obsłużyć. D rugim argum enlem ijast y |k |a ź n ik do deskryptora T C P opisującego połączenie, z którego odebrano dane. Trzccjin argum entem je s t odebrany znak. Funkcje obsługujące stany zw racają 5.2. Przykład 5a - pierwsza wersja serwera 'PCP state = mein__malloc (sizeof (struct state)); if (state == NULL) return ERR_MEM; state->function = InitState; state->timeout = SERVER_TIMEOUT; tcp_arg(pcb, state); tcp_err (pcb, conn__err_callback) ; tcp_recv (pcb, recv__callback) ; tcp_poli (pcb, poU__callback, POLL_PER__SECOND) ; return tcp_write_from_rom(pcb, invitation); w artości typu e r r _ t zgodnie z konw encją przyjętą w bibliotece lwlP, czyli ERR_; y przy popraw nym zakończeniu lub w łaściw y kod błędu. D odatkow o m ogą zwrócier w artość ERRJLXIT, która oznacza, że funkcja zakończyła się popraw nie, ale n a le n zam knąć połączenie TCP. łdefine ERRJ1XIT 100 Funkcje obsługujące poszczególne stany autom atu serw era są następujące: static static static static static err__t err_t err t err_t err_t static err_t static err_t static err_t static err t static err_t static err_t InitState (struct state *, struct tcp_pcb *, uint8_t); lACState(struct state *, struct tcp_pcb *, uint8_t); OptionState(struct state *, struct tcp_pcb *, uint8_t); HelpState(struct state *, struct tcp_pcb *, uint8_t); OnGreenLedState(struct state * struct tcp_pcb *, uint8_t); struct tcp_pcb * OffGreenLedState(struct state uint8_t); OnRedLedState(struct state * struct tcpjpcb *, uint8_t); OffRedLedState(struct state , struct tcp_pcb *, uint8_t); struct tcp__pcb GetLocalTimeState(struct state uint8_t); ExitState(struct state *, struct tcp_pcb *, uint8_t); ErrorState(struct state *, struct tcp_pcb *, uint8_t); W iększość odpow iedzi udzielanych przez serwer, zam ieszczonych w tabeli 5.2,. to stale napisy, które znajdują się w pam ięci tylko do odczytu (R O M lub racz oi ■ Flash). A by skrócić tekst program u, do ich w ysyłania definiujem y m akro tc p ^ te_from _rora. A rgum ent p je st w skaźnikiem do deskryptora T C P opisującego polą-i^ czenie, przez które ma być w ysłana odpow iedź. A rgum ent x je st nazw ą tablicy typu.fjj c h a r zaw ierającej napis do w ysiania zakończony zerow ym bajtem , który nie jest;1 w ysyłany. M akro nie działa popraw nie, jeśli x je st w skaźnikiem typu c h ar* . Należy też zw rócić uw agę, że jeśli używ am y sterow nika util_eth_zc.c, to dane do wysłania'! trzeba skopiow ać do pam ięci biblioteki - ostatni argum ent funkcji tc p _ w r ite m usi$ m ieć w tedy w artość TCP_WRITEJTLAG_COPY. jjdefine tcp_write__from_rom(p, x) tcp_write(p, x, sizeof(x) - 1, 0) Funkcja zw rotna accept_c a l l b a c k je s t w yw ołana, gdy zostanie odebrane nowći^jf połączenie. Funkcja ta realizuje p ozostałą część diagram u serw era z rysunku 4.4.''-|; N ajpierw alokujem y now ą strukturę typu s t a t e i inicjujem y jej składow e. Struktura; s t a t e je s t zw iązana z now ym połączeniem (klientem ), a je j adres będzie przeka-jd zyw any funkcjom zw rotnym obsługującym to połączenie. N a koniec w ysyłam y doljij klienta tekst pow itania i znak zachęty. ’ static const char invitation!} » "\r\n" "This is TCP server running on top of the lwlP stack.\r\n" "Press h or ? to get help.\r\n" "\r\n" idefine SERVER_TIMEOUT '30 idefine POLL PER SECOND 2 static errjt accept_caUback(void *arg, struct tcp_pcb *pcb, err_t err) { struct state *state; 181 } G dy połączenie zostanie zam knięte aw aryjnie lub z pow odu w ystąpienia błędu, bi­ blioteka lw lP w yw ołuje funkcję zw rotną c o n n _ e rr_ c a llb a c k . Zadaniem tej funkcji je st zw olnienie pam ięci przydzielonej strukturze typu s t a t e w funkcji a c c e p t_ c a llb a c k . A dres struktury typu s t a t e , która m a być usunięta z pam ięci, jest pierw ­ szym argum entem funkcji c o n n _ e rr_ c a llb a c k . static void conn_err_callback(void *arg, err_t err) ( mem_free(arg); i W kilku m iejscach w program ie serw era w ystępuje potrzeba zam knięcia połącze­ nia T C R T rzeba w tedy zw olnić pam ięć przydzieloną strukturze typu s t a t e oraz w yw ołać funkcję tc p _ c lo s e z biblioteki lwlP. A by nie pow tarzać tych sam ych se­ kw encji instrukcji, im plem entujem y funkcję tc p _ e x i t zam ykającą połączenie TCP. Pam iętajm y, że po w yw ołaniu tc p _ c lo s e m ogą jeszcze przyjść dane, ale nie bę­ dziem y m ogli ich obsłużyć, gdy w cześniej zw olnim y pam ięć przechow ującą stan połączenia. Z kolei, jeśli nie zw olnim y tej pam ięci, to po zakończeniu funkcji tc p _ e x i t nie będzie ju ż okazji do jej zw olnienia. D latego na początku funkcji tc p _ e x i t w yrejestrow ujem y funkcję zw rotną służącą do odbierania danych, w yw ołując funk­ cję tc p _ re c v . static void tcp_exit(struct state ‘ state, struct tcp_pcb *pcb) ( tcp_recv(pcb, NULL); if (state) ( mesi_free (state) ; tcp_arg(pcb, NULL); I tcp_close(pcb); I P rzetw arzanie odebranych danych i w ysyłanie odpow iedzi odbyw a się w funkcji zw rotnej recv_callback. N ajpierw spraw dzam y, czy w yw ołanie tej funkcji jest skutkiem odebrania now ych danych, czy też zostało zainicjow ane zam ykanie połą­ czenia TCP. Jeśli w skaźnik p je st niezerow y, to ożhiicza, że odebrane zostały dane. N ajpierw w yw ołujem y funkcję tcp_recved, która inform uje stos lwlP, że aplikacja odebrała dane. W łaściw e przetw arzanie delegujem y do funkcji StateAutomaton. Jeśli funkcja StateAutomaton zakończy się sukcesem i funkcja zw rotna recv_calIback m a zw rócić w artość ERR_OK, to należy zw olnić łańcuch buforów w skazyw any przez p. Jeśli funkcja StateAutomaton zw róci w artość ERR_EXIT lub w skaźnik p je st rów ny zeru (druga strona zam knęła połączenie od swojej strony), to należy zam knąć połączenie T C P za pom ocą funkcji tcp_exit. errjjt recv_callback(void *arg, struct tcpjpcb *pcb, * I struct pbuf *p, err_t err) ( if (p) t )'i 5.2. Przykład 5a ~ pierwsza wersja serwera TCP tcp_recved(pcb, p->Łot_len); err = StateAutomaton(arg, pcb, p ) ; if {err == ERR_OK j| err == ERR_EXIT) pbuf_free(p); if (err == ERR_EXIT) { tcp_exit(arg, pcb); err * ERR_OK; case 'h ' : case '?': state->function return ERRJ3K; case 1G ': state->function return ERR_0K; case 'g': state->function return ERR_OK; case *R * : state->function return ERR_0K; case 'r1: state->function return ERR_0K; case 11': state->function return ERR_0K; case 1x ' : state->function return ERR OK; case for {;;); default: state->function return ERR_0K; 1 ) else { tcp^exit(arg, pcb); err"~= ERR__OK; ) return err; i Funkcja S tateA utom aton obsługuje autom at stanow y serwera. N ajpierw ponownie' inicjujem y składow ą ti m e o u t - klienent je st aktywny, więc czas połączenia wydłu­ żam y o kolejne 30 sekund. N astępnie przeglądam y w skazyw any przez p łańcuch buforów zaw ierający odebrane dane i dla każdego znaku w yw ołujem y funkcję wska­ zyw aną przez składow ą f u n c t i o n struktury s t a t e . Pam iętajm y, że ta funkcja mo/e zm ienić w artość składowej f u n c t i o n - autom at m oże przejść do innego stanu. static err_t StateAutomaton(struct state *s, struct tcp_pcb *pcb, struct pbuf *p) I s->timeouŁ = SERVER_TIMEOUT; for {;;) ( uint8_t *c = (uint8_t *)p->payload; uint!6_t i; err__t err; j = OnGreenLedState; » OffGreenLedState; = OnRedLedState; = OffRedLedState; = GetLocalTimeState; - ExitState; = ErrorState; } F unkcje obsługujące kolejne stany są bardzo podobne. D latego prezentuję tylko nie­ które z nich. N ajpierw jed n a z funkcji zajm ujących się obsługą diod św iecących. D ziała ona zgodnie z diagram em z rysunku 5.4. static err_t OnGreenLedState(struct State *state, struct tcp_pcb *pcb, uint8_t c) { switch (c) ( case ' ': case '\t': case '\r': return ERR_0K; case '\nł: state->function » InitState; GreenLEDon{) ; return tcp write from_rom{pcb, prompt); % default: state->function = ErrorState; return ERR OK; ~ * } return ERR_OK; } Przetw arzaniem w stanie I n i t S t a t e zajm uje się funkcja o tej sam ej nazw ie. Funkcja ta działa zgodnie z diagram em z rysunku 5.2. static const char promptf] = "\r\n" ' ' *"*' static err_t InitState(struct state *state, struct tcp_pcb *pcb, uint8_t c) ( switch (c) { case IAC: state->function = IACState; return ERR_0K; case ' ': " / case *\ t 1: t case 1\r': return ERR_OK; case '\n *: return tcp write from rom(pcb, prompt); » HelpState; ! for (i = 0; i < p->len; ++i) if (ERR_OK != (err = s->function(s, pcb, c (iJ))) return err; if (p~>len == p->tot_len) break; else p = p->next; "> "; 183 J-fir „ W ysłaniem inform acji z czasem , który upłynął od w łączenia m ikrokontrolera, zaj­ m uje się funkcja G etL o calT im eS tate. Funkcja ta działa zgodnie z diagram em z ry­ sunku 5.5. N apis m ożna sform atow ać za pom ocą funkcji s n p r i n t f , która należy do standardow ej biblioteki C, ale nie je s t w spółużyw alna. Z am iast niej lepiej jest użyć funkcji s n p r i n t f r, która je s t w spółużyw alna i je s t dostarczana przez bibliotekę Newj-ib. O bie funkcje tw orzą napis, który zgodnie z konw encją obow iązującą w ję zyRirfc zM dńczony je s t zerow ym bajtem . Im plem entow any protokół, ja k w iększość protokołów fintersieci, nie w ysyła w napisach tego term inalnego zera. 18 4 5.2. Przykład 5a - pierwsza wersja serwera TCP 5. Serwer T( p; "> static const char timefrml) = "\r\n" "%u ^02u:ł02u:%02u.%03u\r\n" "\r\n" static err t ErrorState{struct state ‘state, struct tcp_pcb *pcb, uint8_t c) { switch {c) { case '\n': state->function = InitState; return tcp_write_from_rom{pcb, error); default: return ERR OK; "> static err_t GetLocalTimeState{struct state ‘state, struct tcp_pcb *pcb, uint8_t c) { switch (c) { case ' ’: case ’ \t'; case *\r': return ERR_OK; case *\n *: { char buf[TIME_BUF_SIZE]; unsigned d, h, m, s, ms; int size; struct _reent reent; ) i F unkcja zw rotna p o ll _ c a ll b a c k im plem entuje fragm ent diagram u z rysun­ ku 5.9 obsługujący zdarzenie budzika. Pozostałe fragm enty tego diagram u, ini­ cjujące zm ienną tim e o u t, są zaim plem entow ane w funkcjach a c c e p t_ c a llb a c k i S tateA u tom aton. Jeśli w skaźnik s t a t e m a w artość NULL, m oże to oznaczać, że w ystąpił problem z zam knięciem połączenia - struktura s t a t e została zw olniona, a w yw ołanie tc p _ c lo s e nie pow iodło się i połączenie nadal jest otw arte. T rzeba spróbow ać zam knąć je ponow nie. state->function = InitState; GetLocalTime{&d, &h, &m, &s, &ms); size = _snprintf_r{6reent, buf, TIME_BUF__SIZE, timefrm, d, h, m, s, ms); if (size <- 0) return tcp_write_from_rom{pcb, error); if {size >= T IME__BUF_SIZE) size = TIME_BU?_SIZE - 1; return tcp_write(pcb, buf, size, TCP_WRITE_E,LAG_COPY); static const char timeout U = "\r\n" "TIMEOUT\r\n"; static err_t poll_callback{void *arg, struct tcp_pcb *pcb) { struct state ‘state = arg; ) default: state->function return ERR OK; 185 if (State == NULL) ' tcp_exit{arg, pcb); else if {— (state->timeout) <= 0) { tcp_write_from_rom(pcb, timeout); tcp_exit(arg, pcb); ErrorState; ) I ) return ERR_OK; Polecenie, które klient w ysyła do serw era, chcąc zakończyć z nim połączenie, < sługuje funkcja Exitstate, działająca zgodnie z diagram em z rysunku 5.6. Aby -f zakończyć działanie autom atu i zam knąć połączenie z klientem , funkcja ta zwraca 1 w artość ERR_EXIT. static err_t Exitstate{struct state ‘state, struct tcp_pcb ‘ pcb, uint8_t c) ( switch {c ) { case ‘ ': case *\t *: case *\ r 1: — return ERR— OK; t •r-Ł-łtr case '\ n ': return ERR_EXIT; default: state->function = ErrorState; return ERR OK; 1 static const char error[] = "\r\n" a "ERROR\r\n" "\r\n" 2. ■ , • 'fir ' , P -- 1 Poinform ow aniem klienta o błędnym poląceniu zajm uje się funkcja E r r orSt działająca zgodnie z diagram em po k azan y ń i na rysunku 5.8. ) "'¿i. gPP ta j l l Plik e x jc p d .c Plik e x jc p d .c zaw iera funkcję main przykładu. W funkcji tej urucham iam y ko­ lejne potrzebne układy m ikrokontrolera i stos lw IP oraz konfigurujem y ustaw ienia sieciow e, analogicznie ja k w opisanym w cześniej przykładzie 3a. N a zakończe­ nie urucham iam y serw er TCP. Serw er nasłuchuje na standardow ym porcie usługi Telnet, czyli na porcie 23. M ożna w ybrać dow olny num er portu z przedziału od 1 do 65 535. N ie pow inno się jed n ak używ ać portów pow szechnie znanych usług w brew ich przeznaczeniu. Podczas urucham iania-św ieci się czerw ona dioda. Jej zgaśnięcie sygnalizuje zakończenie urucham iania serw era. M iganie czerw onej dio­ dy w rytm ie zdefiniow anym drugim argum entem m akra e rr o r_ c h e c k oznacza, że w yw ołanie funkcji, um ieszczone jak o pierw szy argum ent tego makra, zakończyło się niepow odzeniem . int main{) { static struct netif netif; static struct ethnetif ethnetif = {PHYJVDDRESS}; uiqt8_t confBit; Deii^dSjdoO); confBit ,= ffetConfBit{); 186 5. Serwer TCl\ AllPinsDisable{); LEDconfigureO ; RedLEDonf); SET__IRG_PROTECTION {) ; error_check(CLKconfigure(), 1); error_check(LocalTimeConfigure(), 2); error_check(ETHconfigureMII{), 4); netif.hwaddr(O) - 2; netif.hwaddr[l] = (BOARDJTYPE » 8) & Oxff; netif.hwaddr[2] = BOARD_TYPE & Oxff; netif.hwaddr[3J «= (ETHJ30ARD » 8) & Oxff; netif.hwaddr[4] = ETH_BOARD & Oxff; netif.hwaddr[5] = 1 + confBit; if (iconfBit) | IP4_ADDR(Snetif.ip_addr, 192, 168, 51, 84}; IP4__ADDR(&netif.netmask, 255, 255, 255, 240); IP4_ADDRf&netif.gw, 192, 168, 51, 81); 5.2. Przykład 5a - pierwsza wersja serwera TCP 187 Jako h o s t m ożna też podać nazw ę w ęzła. W L inuksie w pliku /etc/h o sts m ożem y zdefiniow ać nazw y w ęzłów w naszej sieci lokalnej. Jeśli um ieścim y w tym pliku w pis 192.168.51.89 local-89.localdomain local-89 to będziem y m ogli połączyć się z serw erem za pom ocą polecenia telnet local-89 lub telnet local-89.localdomain Przykładow ą sesję, w której w ypróbow ano w szystkie polecenia, przedstaw iono w ta b e li 5.4. Podczas tej sesji pow inniśm y zaobserw ow ać w łączanie i w yłączanie diod św iecących. W trakcie połączenia m ożem y za pom ocą kom binacji klaw iszy C trl+] przełączyć program telnet w tryb w ydaw ania lokalnych poleceń. O pis pole- } else { IP4_ADDR(&netif.ip^addr, IP4_ADDR(finetif.netmask, IP4_ADDR(&neti f .gw, 0, 0, 0, 0) ; 0, 0, 0, 0); 0, 0, 0, 0); 1 error_check(LWIPinterfacelnit(Snetif, Sethnetif), 5); LWIPtimersStart(); error__check(TCPserverSŁart(23), 7); RedLEDoff{); return 0; | ! Z w róćm y uw agę, że funkcja main kończy się instrukcją r e t u r n . Jest to dopuszczal­ ne, gdy używ am y pliku startup_stm 32_cld.c. Procedura startow a zaim plem entow a­ na w tym pliku w chodzi w nieskończoną pętlę, gdy funkcja main zakończy działa­ nie. Jeśli używ am y innej procedury startow ej, bezpieczniejszym rozw iązaniem jest zastąpienie instrukcji r e t u r n nieskończoną pętlą: for 5.2.3. Testowanie przykładu U rucham iając przykład w zestaw ie Z L 29A R M , w ybieram y za pom ocą zworki BOOT1 sposób skonfigurow ania ustaw ień sieciow ych. Jeśli zw orka je st w pozy­ cji 0, użyte zostaną ustaw ienia zdefiniow ane statycznie w funkcji main. Jeśli jest w pozycji 1, to zostanie uruchom iony klient D H CR "Serw er przystosow any je s t do w spółpracy z program em telnet. W najprostszym przypadku urucham iam y go z linii poleceń system u W indow s lub konsoli L inuksa, pisząc Jako h o s t podajem y adres IP przydzielony zestaw ow i uruchom ieniow em u, uży­ w ając notacji z kropkam i. Jako p o r t podajem y num er portu, na którym nasłuchu­ je serwer. Jeśli nie podam y num eru portu, Jo zostanie użyty dom yślny port usłu­ gi Telnet, czyli port 23. Z atem zakładając, że zestaw uruchom ieniow y ma adres 192.168.5U 89, m ożem y połączyć się z nim za pom ocą polecenia telnet 192.168.51.89 Test poleceń serwera Linux $ telnet 192.168.51.89 Trying 192.168.51.89... Connected to local-89.localdomain (192.168.51.89). Escape character is , A] ' . This is TCP server running on top of the lwlP stack. Press h or ? to get help. > h h or ? print this help g' turn on the green led turn off the green led g R turn on the red led r turn off the red led t get microcontroller running time X exit Windows C:\>telnet 192.168.51.89 This is TCP server running on top of the lwlP stack. Press h or ? to get help. > h h or ? print this help G turn on the green led turn off the green led g R turn on the red led r turn off the red led t get microcontroller running time X exit > G > g > G > R > g > r > R > t > r 0 00:05:01.990 > t > a 0 00:07 CO «sr telnet host port T ab . 5 .4 . ERROR > a > X ERROR Connection to host lost. > xÆ Connect io^fei-osed by foreign host. $ . Ù C:\> 189 5.3. Przykład 5b - serwer TCP z nadz,orcą Tab. 5.7. Pliki przykładu 5b Tab. 5.5. Test zamknięcia połączenia Linux $ telnet 192.168.51.89 Trying 192.168.51.89... Connected to local-89.localdomain (192.168.51.89). Escape character is ’ W indows C:\>telnet 192.168.51.89 This is TCP server running on top of the lwIP stack. Press h or ? to get help. > t 0 00:06:22.210 > t > A3 0 00:08:57.230 Welcome to Microsoft Telnet Client > A1 telnet> quit Connection closed. e9 Escape Character is 'CTRL+}* lf: S Źródłowe i biblioteczne This is TCP server running on top of the lwIP stack. Press h or ? to get help. r C:\> Tab. 5.6. Test przekroczenia czasu Windows C:\>telnet 192.168.51.89 This is TCP server running on top of the lwIP stack. Press h or ? to get help. > t > t This is TCP server running on top of the lwIP stack. Press h or ? to get help. 0 00:08:45 200 > TIMEOUT 0 00:11:59.220 Connection to host lost. TIMEOUT Connection closed by foreign host. $ C:\> ceń dostępnych w tym trybie m ożna uzyskać, w ydając polecenie h e lp . Połączenie m ożna zam knąć poleceniem c lo s e . Połączenie m ożna też zam knąć, kończąc jedno­ cześnie działanie program u telnet, poleceniem q u i£ f a w L inuksie dodatkow o kom­ binacją klaw iszy C trl-D . O dpow iedni przykład pokazano w tabeli 5.5. Z naczki ' ' oznaczają w ciśnięcie klaw iszy C trl-]. W tabeli 5.6 zam ieszczono test zam knięcia połączenia T C P w w yniku przekroczenia czasu oczekiw ania na polecenie. Przykład 5b - serwer TCP z nadzorcą b o a rd jo n l.c b o a rd jn it.c boardJed. c tc p je r m .h b o a rd jo n f.h board_dei.li board_dels.li b o a rd jn ith b o a rd je d .li : Microsoft Telnet> quit Linux $ telnet 192.168.51.89 Trying 192.168.51.89... Connected to local-89.localdomain (192.168.51.89). Escape character is ,A3'. e x jc p d _ w d g .c startup_stm 32_cld. c tc p je rv e r.c * Serw er z poprzedniego przykładu m a pew ną w adę. Jeśli w ystąpi problem podczas jeg o urucham iania, to program kręci się w nieskończonej pętli w ew nątrz m akra ei ro r_ c h e c k . N iezłym pom ysłem je s t w tej sytuacji w yzerow anie m ikrokontrolera util_delay.c u t iljth jic .c ulUJedTc u tiljw ip .c u tiljim e .c u lf j/d g .c Iiblwip4.a Iibstm32t10x.a Nagłówkowe util_delay.h u t iljth .il u tilje d .h u tiljw ip .li u liljim e .h util wdg.h CC.Il cortex-m 3.li lwipopts.li s tm 3 2 t1 0 x jo n t.h i ponow ienie próby uruchom ienia serw era. Ponadto sam serw er je s t dość skom pli­ kow aną aplikacją i trudno w ykluczyć w ystąpienie w jeg o im plem entacji jakiegoś błędu, który doprow adzi do zaw ieszenia. W im plem entacji serw era w prow adzili­ śm y celow o taki błąd. A plikacje urucham iane na m ikrokontrolerach m ają działać bezobsługow o i aby radzić sobie z takim i problem am i, m ikrokontrolery w yposaża­ ne są w układ nadzorcy (ang. watchclog). W tym przykładzie dodajem y do serw era T C P obsługę układu nadzorcy. N azw y plików potrzebnych do jeg o skom pilow ania zam ieszczone są w tabeli 5.7. Są to w w iększości te sam e pliki co w poprzednim przykładzie. W dalszyńt ciągu opisuję tylko różnice m iędzy tymi przykładam i. Pliki util_wdg.h i utiljw dg.c M ikrokontrolery ST M 32 w yposażone są w dw a układy nadzorców : IW DG (ang. independent w atchdog) i W W D G (ang. witulow wcitchdog). U kład IW D G jest ty­ pow ym układem nadzorcy, jak i znajduje się w w iększości m ikrokontrolerów i dla­ tego w ykorzystam y w łaśnie ten układ. U kład IW D G zaw iera 12-bitowy licznik zli­ czający od zadanej w artości początkow ej do zera. Taktow any je s t przez dzielnik w stępny (ang. prescaler) w łasnym generatorem LSI (ang. Iow speed internal) RC 0 nom inalnej częstotliw ości 40 kHz. G enerator ten m a spory rozrzut produkcyjny 1 w edług danych katalogow ych [8, 9] je g o rzeczyw ista częstotliw ość w aha się m ię­ dzy 30 a 60 kHz. W pliku util__wgd.h deklarujem y m akro WatchdogReset, które restartuje licznik nad­ zorcy. W tym celu w yw ołuje funkcję IWDG_ReloadCounter z biblioteki STM 32. łdefine WatchdogReset IWDG_ReloadCounter Funkcja IWDG_ReloadCounter je st bezparam etrow a, ustaw ia początkow ą wartość licznika układu nadzorcy i nie zw raca żadnej w artości. A by zapobiec w yzerow aniu m ikrokontrolera przez układ nadzorcy, funkcja ta pow inna być w yw ołana w re­ gularnych odstępach czasu. Do inicjow ania układu nadzorcy deklarujem y w pliku util_w gd.h funkcję WatchdogStart. Jej im plem entacja znajduje się w pliku util_ wgd.c. N a początku tego pliku definiujem y tablicę prescalerTbl dopuszczalnych w artości dzielnika w stępnego. 't liii li I static conirc'jgint8__t prescalerTbl [] = { IWDG_Presciiłer_4, 5.3. Przykład 5b - serwer TCP z nadzorcą 5. Seerwer 190 Zakładając nom inalną częstotliw ość LSI, m aksym alny czas m ożliw y do uzyskania za pom ocą układu IW D G w ynosi ok. 26 sekund. Interw al restartow ania licznika nadzorcy pow inien być odpow iednio m niejszy - m usi uw zględniać rozrzut częstot­ liwości taktow ania. IWDG_Prescaler_8, IWDG_Prescaler_16, IWDG_Prescaler_32, IWDG_Prescaler_64, IWDG_Prescaier__128, IWDG_Prescaler 256 i; static const int maxldx = sizeof(prescalerTbl) / sizeof(prescalerTbl[0]) - 1; Testowanie przykładu Ten przykład pow inien pozytyw nie przejść te sam e testy, które przeszedł poprzedni przykład. D odatkow o należy przetestow ać nadzorcę. P rzykładow e w ydruki z term i­ nalu pokazane są w ta b e li 5 .8 . W celu zaw ieszenia serw era w ysyłam y znak dolara. P oniew aż w w yniku zaw ieszenia oprogram ow anie stosu lw IP nie działa, w ysłany do serw era segm ent T C P ze znakiem dolara nie zostanie nigdy potw ierdzony i opro­ gram ow anie T C P po stronie klienta retransm ituje ten segm ent. Po restarcie serw era stos lw IP dostaje taki relransm itow any segm ent, który nie należy do żadnego ak­ tyw nego połączenia, w ięc odsyła segm ent z ustaw ionym znacznikiem RST, aby po­ inform ow ać o tym drugą stronę kom unikacji. W ten sposób klient m oże dow iedzieć się, że połączenia ju ż nie ma. N iestety program telnet z system u W indow s nie roz- A rgum entem funkcji W a tc h d o g S ta rt jest czas, po którym licznik układu nai ina osiągnąć w artość zero i w yzerow ać m ikrokontroler. W artość tego czasu podaj my w m ilisekundach. D okładnej w artości nie uda się uzyskać, choćby ze wz na niedokładność częstotliw ości taktow ania. W ybieram y w artość dzielnika nego i początkow ą w artość licznika, aby ja k o ś przybliżyć ten czas. Do obliczeprzyjm ujem y nom inalną częstotliw ość taktow ania 40 kH z. U kład IW D G konfjgu'. rujem y za pom ocą funkcji z biblioteki STM 32. N azw y tych funkcji rozpoczynaj się prefiksem IWDG. Funkcja IWDG_WriteAccessCmd uaktyw nia zapis do rejestrókonfiguracyjnych układu nadzorcy. Funkcja IW D G _SetPrescaler ustaw ia dzielni w stępny układu nadzorcy. F unkcja lWDG__SetReload ustaw ia w artość, którą jest Ini cjow any licznik nadzorcy po w yw ołaniu funkcji IWDG_ReloadCounter. N a koni układ nadzorcy uaktyw niam y za pom ocą funkcji IWDG_Enable, która włącza tążgenerator LSI. T ab . Linux This is TCP server running on top of the lwIP stack. Press h or ? to get help. Plik ex_tcpd_wdg.c Plik ex_tcpd_w dg.c zaw iera funkcję main tego przykładu. F unkcja ta je st bardzo podobna do funkcji main z poprzedniego przykładu. R óżnice są następujące. Na sam ym początku funkcji main urucham iam y układ nadzorcy: WatchdogStart (WDG_TIMEOUT__MS| ; Po uruchom ieniu serw era konfigurujem y regularne w yw ołanie funkcji restartującej licznik nadzorcy: ( ^ LWIPsetAppTimer(WatchdogReset, WDG_RESET_IN'#ERVAL_MS); N a początku pliku ex_tcpd_jvdg.c m usim y jeszcze zdefiniow ać stale czasow e: This is TCP server running on top of the IwIP stack. Press h or ? to get help. > t > t > $ 0 00:11:08.800 0 00:17:59.980 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(prescalerTbl(idx)); IWDG_SetReload{timeout - 1); IWDG_ReloadCounter(); IWDG Enable(); łdefine WDG_TIMEOUT_MS 26000 idefine WDG RESET INTERVAL MS 13000 Windows C:\>telnet 192.168.51.89 ' ) 5.3.2. 5.8. Test nadzorcy $ telnet 192.168.51.89 Trying 192.168.51.89... Connected to local-89.localdomain (192.168.51.89). Escape character is ,A)’. void WatchdogStart(unsigned timeout) { int idx; timeout *= 10U; for (idx = 0; timeout > OxlOOOU && idx <= maxldx; timeout » = 1, ++idx); if (idx > maxldx) { idx = maxldx; timeout = OxlOOOU; 191 Welcome to Microsoft Telnet Client > $ Connection closed by foreign host. 'i $ telnet 192.168.51.89 Trying 192.168.51.89... Connected to local-89.localdomain (192.168.51.89) .* Escape character is ,Aj'. This is TCP server running on top of the IwIP stack. Press h or ? to get help. Escape Character is 'CTRL+J Microsoft Telnet> quit C:\>telnet 192.168.51.89 This is TCP server running on top of the IwIP stack. Press h or ? to get help. > t > t 0 00:00:53.550 0 00:00:48.350 > X Connection to host lost. Con^^ftioi^losed by foreign host. $ ‘ C:\> poznaje popraw nie tej sytuacji. T rzeba go zakończyć poleceniem q u it . O poprav.. nym działaniu, czyli zrestartow aniu układu przez nadzorcę, m ożna się p rzek o n ać1, obserw ując diody św iecące. Św iadczy o tym rów nież to, że m ikrokontroler zaczyna' odm ierzać czas od początku. W idzim y to, w ysyłając polecenie t po ponow nym po.-: łączeniu się z serw erem . R estartow anie serw era zaobserw ujem y rów nież, gdy nie pow iedzie sie jeg o uruchom ienie, np. gdy odłączym y kabel ethernetow y. Klient TCP 194 6. Klient Tl /> 6.1, Projekt protokołu 195 Tem atem tego rozdziału je s t klient używ ający protokołu transportow ego TCl1 R ozdział zaw iera dw a przykłady. W pierw szym z nich pokazuję klienta, którego',! zadaniem je s t okresow e łączenie się z serw erem w celu przesłania danych p o c h o ij dzących na przykład z czujników . W przerw ach m iędzy połączeniam i kłient p rz ę ś l chodzi w tryb czuw ania (ang. standby), który zapew nia najm niejszy pobór prądu'-; przez m ikrokontroler. C zas przebyw ania w trybie czuw ania odm ierza zegar czastiw rzeczyw istego (RTC, ang. real tim e clock). Po w ejściu w ten tryb utracona zostaje;* zaw artość pam ięci operacyjnej (R A M ) i w iększości rejestrów. Z achow yw ana jest-Jj jed y n ie zaw artość rejestrów zapasow ych (ang. backup regisłers), w których moż­ na przechow ać niezbędne ustaw ienia program u. D rugi przykład rozszerza klientaH 0 obsługę rejestrów zapasow ych. Podobnie ja k serw er z poprzedniego rozdziału;-, klient prezentow any w tym rozdziale też pow inien działać bezobslugow o i radzićfl sobie z sytuacjam i aw aryjnym i. S erw er z poprzedniego rozdziału używ ał w typ celu układu nadzorcy. W tym ro zdziale pokazuję inne m etody zerow ania mikrokon­ trolera i restartow ania program u. Przedstaw iony klient je s t w zasadzie tylko szkie­ letem aplikacji, nie obsługuje żadnych czujników , ale łatw o m ożna go rozbudować ^ 1 zaim plem entow ać obsługę potrzebnych peryferii, co pozostaw iam Czytelnikow i ja k o ćw iczenie. 6.1. Projekt protokołu K om unikaty w ym ieniane m iędzy klientem a serw erem opisane są w ta b e li 6.1. K om unikaty są kodow ane ja k o teksty A SCII. K om unikat składa się ze słow a klu­ czow ego, po którym m ogą w ystępow ać param etry! oddzielone spacją. Parametry W m ogą być opcjonalne. K ażdy kom unikat kończy się znakiem końca w iersza, czyli iists i.py'' sekw encją znaków C R i LF. Protokół je s t stanowy. Stanow ość tego protokołu została niejako w ym uszona prze/ to, że interpretacja kom unikatu S E T zależy od typu kom unikatu, na który je st od- -y pow iedzią. A utom at dla klienta je s t przedstaw iony na ry s u n k u 6.1. N ie będziemy ' im plem entow ać serw era, ale dla pełności opisu potrzebny je st rów nież jeg o aui m at. Jedna z wielu m ożliw ych w ersji autom atu serw era je s t przedstaw iona na ry ­ s u n k u 6.2. Jak w idać, autom aty te różnią się, w szczególności m ają różne zl stanów. Po otw arciu połączenia T C P klient w ysyła kom unikat H EL L O i przechodzi do sta­ nu H elloState, w którym oczekuje na o d p o w ie d z ie ć serw era. Jeśli w tym stanie klient odbierze kom unikat O K, czyli pozytyw ne-potw ierdzenie, to w ysyła kom uni­ kat PARAM i przechodzi do stanu P aram State, w którym oczekuje na odpowiedź od serw era. Jeśli w stanie H elloS tate k lient odbierze kom unikat SET, czyli prośbę 0 zsynchronizow anie zegara czasu rzeczyw istego, to próbuje go ustaw ić. Jeśli pr; siane data i czas m ają popraw ny form at i prośba pow iedzie się, to klient odsyła kom unikat O K ze zm ienionym czasem , a po nim kom unikat PARAM i przechud/: do stanu Param State. „W przeciw nym przypadku klient w ysyła kom unikat ERROK 1 zam yka połączenie TCP. Jeśli w stanie Param State klient odbierze kom unikat OK. to w ysyła kom unikat B Y E i zam yka połączenie TCP. Jeśli w tym stanie odb rze kom uńikat SE T i przesłane param etry m ają popraw ne w artości, to ustaw ia je, co potw ierdza kom unikatem O K z now ym i w artościam i param etrów , a nasti .i Rys. 6.1. Automat stanowy protokołu po stronie klienta w ysyła kom unikat B Y E i zam yka połączenie TCP. Jeśli param etry w odebranym k om unikacie S E T m ają niepopraw ne w artości, to klient w ysyła kom unikat ERR O R i zam yka połączenie TCP. H. . ,■ !. Przejście do stanu końcow ego oznacza zam knięcie połączenia TCP. K lient zam y­ ka 'rlw n ip j (połączenie T C P zaw sze po odebraniu kom unikatu E R R O R lub BYE. Zam knięcierpołączenia T C P przez drugą stronę należy traktow ać ja k odebranie ko- 6.2. Przykhul 6a - pierwsza wersja klienta TCP 197 Tab. 6.1. Komunikaty Komunikat Opis HELLO Jest to pierwszy komunikat wysyłany przez klienta do serwera po zestawieniu połączenia TCP w celu zainicjowania komunikacji. Parametrami są data i czas, odczytane z zegara czasu rzeczywistego klienta, w formacie RRRR.M M .DD gg:mm:ss (rok, miesiąc, dzień, go­ dzina, minuta, sekunda). Serwer powinien odpowiedzieć komunikatem OK lub SET PARAM Komunikat ten jest wysyłany przez klienta do serwera w celu przesłania swojej konfiguracji. M a dwa parametry. Parametr C 0 N N E C T I0 N J IM E 0 U T jest czasem, po którym klient, nie do­ czekawszy się na odpowiedź od serwera, zamyka połączenie TCP Parametr STANDBY_TIME jest czasem przebywania klienta w uśpieniu. Oba parametry są podawane w sekundach jako liczby przy podstawie dziesięć. Serwer powinien odpowiedzieć komunikatem OK lub SET SET Komunikat ten jest wysyłany przez serwer do klienta w celu zmiany ustawień przesłanych za pomocą komunikatu HELLO lub PARAM. Parametry tego komunikatu mają taki sam format jak parametry komunikatów HELLO i PARAM. Na ten komunikat klient odpowiada komunikatem OK, jeśli dokonał zmiany ustawień zgodnie z intencją serwera. W przeciwnym przypadku klient odpowiada komunikatem ERROR OK Komunikat ten jest wysyłany przez klienta lub serwer w celu potwierdzenia odebrania komunikatu. Jeśli jest odpowiedzią na komunikat SET, to zawiera parametry, które zostały ustawione. W innych przypadkach parametry po tym komunikacie są opcjonalne i mogą być ignorowane. Na ten komunikat się nie odpowiada ERROR Komunikat ten jest wysyłany przez klienta lub serwer w celu poinformowania, że odebrany komunikat nie może być zinterpretowany. Parametry po tym komunikacie są opcjonalne i mogą być ignorowane. Na ten komunikat nie odpowiada się, a strona, która go wysiała, natychmiast po jego wysianiu zamyka połączenie TCP BYE Komunikat ten jest wysyłany przez klienta lub serwer w celu zakończenia komunikacji. Pa­ rametry po tym komunikacie są opcjonalne i mogą być ignorowane. Na ten komunikat nie odpowiadajsię, a strona, która go wysiała, natychmiast po jego wysianiu zamyka połączenie TCP tent SE T. W ybór m iędzy tymi dw iem a m ożliw ościam i zależy od strategii działania serw era i nie musi być częścią specyfikacji, która tylko opisuje m ożliw e działania. 2. Przykład 6a - pierwsza wersja klienta TCP N azw y plików przykładu sałem ju ż w poprzednich przykład korzysta z trybu obniżonego poboru m ocy 6a zam ieszczone są w tabeli 6.2. W iększość z nich opi­ rozdziałach. Poniżej om aw iam now e pliki, ale poniew aż czuw ania, zaczynam od krótkiego przedstaw ienia trybów w m ikrokontrolerach STM 32. Tab. 6.2. Pliki przykładu 6a Źródłowe i biblioteczne Rys. 6.2. Automat stanowy protokołu po stronie serwera ■ m unikatu BYE. Jeśli k lient nie otrzym a żadnego kom unikaty przez określony c 2.is lub odbierze błędny kom unikat, to w ysyła kom unikat E R R O R i zam yka połączę-, a l l nie. D om yślny czas oczekiw ania na odpow iedź w ynosi 30 sekund. Jego wartość BIS nie m oże być m niejsza niż 5 sekund, aby kom unikaty zdążyły dotrzeć do odbiorcy i serw er miał dostatecznie dużo czasu na w ysianie odpow iedzi. Po zam knięciu połą-, czenia klient przechq/Jzi w stan uśpienia, p o m y śln y czas przebyw ania w tym stanie w ynosi 20 sekund. Takie początkow e w artości tych czasów m ają ułatw ić testowanie, program u. W autom acie serw era nie je s t określone, kiedy na kom unikat H EL L O lub PARAM serw er m a odpow iedzieć kom unikatem O K , a kiedy zm ienić ustaw ienia komunika- ex jc p _clie n t.c startup_stm 32_cld.c tcp_client.c bo a rd jto n l.c b o a rd jn iic b o a rd je d .c tcp_client.h board_conf.h b o a rd J e l.ti board_dels.il bo a rd jn it.h boardJed. h util_delay.c util_elh_nc.c utilJ e d . c u tiljw ip .c u tiljtc .c u tiljim e .c Iiblwip4.a libstm 32M0x.a Nagfri wkowe « li _ ..... iii .... util_delay.li util_error.h u tije th .h u tilje d .h u tiljw ip .h u tiijtc .h util lime.h cc.h cortex-m 3.li Im popts.h stm 32l10x_conl.h 6.2. Przykład 6a - pierwsza wersja klienta TCP int RTCconfigure(void) 1 £XTI_InitTypeDef EXTI_InitStructure; NVIC_Ini.tTypeDef NVIC_InitStructure; Tryby o obniżonym poborze mocy 6 .2 .1 . M ikrokontrolery S T M 32 w yposażono w kilka trybów o obniżonym poborze W trybie uśpienia (ang. sleep m ode) w strzym yw ane je s t taktow anie rdzenia j4 m ięci, w szystkie układy peryferyjne pozostają taktow ane. W trybach głębokie uśpienia (ang. deep sleep m ode) w strzym yw ane je s t taktow anie rdzenia, pamji i w iększości peryferii. Są dw a tryby głębokiego uśpienia: tryb zatrzym ania (ąt stop m ode) i tryb czuw ania (ang. standby). RCC_APBlPeriphClockCmd(RCC_APBiPeriph_PWR | RCC_APBlPeriph_BKP, ENABLE) ; PWR_BackupAccessCmd(ENABLE) ; if (PNR_GetFlagStatus(PWR_FLAG_SB) PWR_ClearFlag(PWR_FLAG_SB); RTC_WaitForSynchro () ; Rdzeń m ikrokontrolera zasilany je s t napięciem 1,8 V. W trybie zatrzym ania wyj" czone są w szystkie sygnały taktujące w dom enie 1,8 V. W strzym ane są oscy łat RC HS1, oscylator kw arcow y H S E i w szystkie pętle fazow e - patrz rysunek ż.jf W ew nętrzny regulator napięcia 1,8 V może pozostać w stanie norm alnej pracy al zostać przełączony w stan niskiego poboru m ocy (ang. low p o w e r m ode). W trybf zatrzym ania zaw artość rejestrów i pam ięci pozostaje niezm ieniona. Mikrokontrotó’ m ożna w ybudzić z tego trybu za pom ocą jed n eg o z 16 przerw ań zewnętrznyc EXTI (ang. external interrupt), przerw ania w ygenerow anego przez programową!' ny detektor napięcia zasilania P V D (ang. program m able voltage detector), alarm'' zegara czasu rzeczyw istego lub sygnału budzenia (ang. w ake-up) w y g en ero w an e/ przez interfejs USB albo E thernet. ^ ) ! EXTI_StructInit(6EXTI_InitStructure); EXTI_InitStructure.EXTI_Line = EXTI_Linel7; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCrad = ENABLE; EXTI_InitStructure.EXTI_Mode » EXTI_Mode_Interrupt; EXTI_Init(SEXTI_InitStructure); NVXC_InitStructure.NVIC_IRQChannelPreemptionPrior.ity = L0W_IRQ_PRI0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd “ ENABLE; NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_Init(SNVIC_InitStructure); NVIC InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; NVIC~Init(SNVIC_InitStructure); return 0; We w szystkicli trybach o obniżonym poborze mocy m ogą pozostaw ać włączone: .;;f - 6.2.2. w ew nętrzny oscylator RC LSI (ang. Iow speodr internal) o częstotliw ości nomi nalnej 40 kH z, zw ykle taktujący układ nadzorcy IW D G; zew nętrzny oscylator kw arcow y L S E (ang. low sp eed external), którego częstot- i. liwość w ynosi zw ykle 32 768 Hz i który taktuje zegar czasu rzeczyw istego. Pliki u t iljtc .h i u t iljt c .c Pliki util_rtc.h i util_rtc.c zaw ierają im plem entację obsługi zegara czasu rzeczyw istego oraz trybu ęzuw ania. U m aw iam y się, że zegar odlicza sekundy od początku dnia 1 stycznia 1970 roku, czyli zgodnie z konw encją obow iązującą w systcmach uniksow ych. Funkcja R T C c o nfigure konfiguruje zegar czasu rzeczywistego, Fu n k cja'ta zw raca zero, gdy konfigurow anie pow iodło się, a w przeciw nym przypadku w artość ujem ną. != RESET) { else ( BKP_DeInit(); RCC_LSEConf ig (RCC_LSE_0N) ; active_check(RCC_GetFlagStatus(RCC_FLAG_LSERDY), 10000000); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); RTC_SetPrescaier(32767); RTC_WaitForLasŁTask(); W trybie czuw ania w ew nętrzny reg u lato r napięcia 1,8 V je s t w yłączony. Oscylatory H SI, H SE i w szystkie pętle fazow e są rów nież w yłączone. Z aw artość pamięć’ i w iększości rejestrów zostaje utracona. Z achow yw ana je s t jed y n ie zawartość re­ jestrów zapasow ych. M ik rokontroler z trybu czu w ania m ożna w ybudzić na kilk’ sposobów : zerując go za pom ocą w yprow adzenia R E SE T , zerując go za pomo4; cą nadzorcy, podając narastające zbocze na w yprow adzenie WKUP-PAO lub zgla' szając alarm zegara czasu rzeczyw istego. Tryb czuw ania różni się od pozostałych jeszcze tym, że po w ybudzeniu z niego w ykonyw anie program u rozpoczyna się od1 początku. W pozostałych trybach w ykonyw anie program u je s t w znaw iane od miej, sca, gdzie nastąpiło uśnięcie. Jeśli odłączym y głów ne zasilanie m ikrokontrolera, tc zegar czasu rzeczyw istego i rejestry zapasow e są zasilane przez wyprowadzenL, V bat* c*° którego m ożna podłączyć baterię podtrzym ującą zasilanie tych układów,’Program w ykorzystujący tryb czuw ania pow inien spraw dzić, czy przyczyną rozpo­ częcia w ykonyw ania jest w ybudzenie, czy w łączenie zasilania. - 199 . ■. ; 1 Poniew aż zegar czasu rzeczyw istego je s t sprzętow o zw iązany z układem zarzą­ dzającym trybam i obniżonego poboru m ocy (PW R ), a je g o rejestry znajdują się w tej sam ej dom enie zasilania i taktow ania co rejestry zapasow e (B K P), w funkcji RTCconfigure najpierw uaktyw niam y taktow anie tych układów i dostęp do reje­ strów zapasow ych. N astępnie spraw dzam y za pom ocą funkcji PWR GetFlagStatus, czy m ikrokontroler obudził się ze stanu czuw ania - czy ustaw iony je st bit PWR_ FLAG_SB. Jeśli się obudził, to zegar czasu rzeczyw istego działa i nie trzeba go kon­ figurow ać. T rzeba tylko w yzerow ać znacznik PWR_FLAG_SB i poczekać za pom ocą funkcji R T C _ W a i tForSynchro na zsynchronizow anie zegarów . Jest konieczne, gdyż układy zegara czasu rzeczyw istego są taktow ane z dw óch źródeł: z oscylatora kw ar­ cow ego L SE i sygnałem PCLK1 z w yjścia dzielnika A B P I. Synchronizację nale­ ży przeprow adzić po każdym w łączeniu któregoś z tych sygnałów, np. za pom ocą funkcji RCC_APBlPeriphClockCmd. Jeśli ^przyczyną rozpoczęcia w ykonyw ania program u nie je s t obudzenie ze stanu c z u w h ia j Ji | w łączenie zasilania m ikrokontrolera, to trzeba skonfigurow ać zegar czasu rzeczyw istego. N ajpierw jed n ak za pom ocą funkcji BKP_DeInit zerujem y 6.2. Przykład 6a - pierwsza wersja klienta TCP układ sterujący rejestram i zapasow ym i. Z a pom ocą funkcji RCC_LSEConfig* tyw niam y oscylator LSE, który używ a zew nętrznego kw arcu 32 768 Hz. Fm R C C _G etFlagStatus spraw dza, czy oscylator ten w ystartow ał. Funkcja ta jesllfj w olyw ana m aksym alnie 10 m ilionów razy przez m akro a c tiv e _ c h e c k . Makro je s t zdefiniow ane w pliku board_ init.h i pow oduje, że jeśli w tym czasie osćfl tor się nie uruchom ił, to funkcja R TC configure kończy działanie i zw raca warfe1 ujem ną. Funkcje RCC_RTCCLKConfig i RCC_RTCCLKCmd w łączają taktow anie zeg' czasu rzeczyw istego oscylatorem L SE. Funkcja R T C _ S e tP re sca le r ustawia dzie nik w stępny, tak aby licznik zegara czasu rzeczyw istego byl zw iększany z częst' tliw ością 1 Hz. W spółczynnik podziału je s t o jed en w iększy od w artości argumeii tej funkcji. F unkcje biblioteki S T M 32 m odyfikujące rejestry konfiguracyjne zeg ‘ czasu rzeczyw istego tylko inicjują tę operację. Z apis do rejestrów RTC trwa śt* sunkow o długo (kilka taktów zegara LSE) i przed kolejnym zapisem lub odcz tern, aby upew nić się, że poprzedni zapis się zakończył, trzeba w yw ołać funkii RTC_W aitForLastTask. N a koniec w funkcji R TC configure konfigurujem y przerw ania zegara czasu rzec>/? w istego. Przerw anie RTC_IRQn je s t zgłaszane po każdym zw iększeniu licznika /.'' gara czasu rzeczyw istego, czyli w naszym przypadku co jed n ą sekundę. Przerwanie alarm u RTCAlarm_IRQn jest zgłaszane przez licznik zegara czasu rzeczywistego, po osiągnięciu zadanej w artości. Przerw ania konfigurujem y z niskim prioryteteiS! w yw łaszczania, niższym niż biblioteka lwIP. N a razie nie aktyw ujem y przerw ali Z ostaną uaktyw nione przez kolejne funkcje. '. Funkcja R T C setC allback ustaw ia funkcję zw rotną, która m a być w yw ołana po ka^I dym w ystąpieniu przerw ania RTC_IRQn. Jej jed y n y m argum entem je s t adres funkęjlij zw rotnej, która je s t bezparam etrow a i nie zw raca żadnej w artości. Jeśli argum ent ten m a w artość NULL, to blokujem y przerw anie RTC_IRQn za pom ocą funkcji RTCji.' IT C onfig - zerow any je st bil RTC__IT_SEC. W przeciw nym przypadku adres funkcji;' zw rotnej zapisujem y w zm iennej globalnej c a llb a c k , a następnie aktyw ujem y prze* rw anie RTC_IRQn - ustaw iany je s t bit RTC_IT_SEC. , static void (*callback)(void) = NULL; void RTCsetCallback(void (*f) (void)) ( if (f == NULL) ( RTC_WaitForLastTask(); RTC_ITConfig(RTC_IT_SEC, DISABLE); callback = £; if (f) I RTC_WaitForLastTask(); RTC_ITCon£ig(RTC_IT_SEC, ENABLE); ,,.... 1 ) O bsługą przerw ania RTC_IRQn zajm uje się funkcja RTC_IRQHandler. Zeruje ona' znacznik przerw ania (bit RTC_IT_SEC) i w yw ołuje funkcję zw rotną, jeśli została ona skonfigurow ana. " £ void RTC_IRQHandler(void) ( if (RTCLGetITStatus(RTC_IT_SEC) != RESET) ( RTC_WaitForLastTask(); RTC ClearITPendingBit(RTC IT SEC); 201 if (callback) callback (); } ) Licznik zegara czasu rzeczyw istego odczytujem y i m odyfikujem y odpow iednio za pom ocą funkcji G etR ealT im eC lock i SetR ealT im eC łock. uint32_t GetRealTimeClock(void) ( RTC_WaitForLastTask(); return RTC_GetCounter(); } void SetRealTimeCłock(uint32_t t) ( RTC_WaitForLastTask(}; RTC_SetCounter(t); } Funkcja S tandby w prow adza m ikrokontroler w tryb czuw ania. A rgum entem tej funkcji je s t czas, po którym m ikrokontroler m a się obudzić. Czas podajem y w se­ kundach. M ikrokontroler w ybudzi się, gdy w ystąpi zdarzenie alarm u, czyli gdy licznik zegara czasu rzeczyw istego osiągnie w artość ustaw ioną za pom ocą funkcji RTC_SetAlarm. N ie ma potrzeby aktyw ow ania przerw ania zw iązanego z alarmem . Podanie jak o argum entu funkcji S tandby w artości 0 spow oduje uśpienie na 232 se­ kund, czyli w praktyce na czas nieograniczony. M ikrokontroler w tryb czuw ania w prow adza funkcja PWR_EnterSTANDBYMode. Przedtem jednak za pom ocą funkcji ETHpowerDown w stan; obniżonego poboru m ocy przełączam y rów nież interfejs ethernetow y. void Standby(uint32_t time) ( RTC_Wa i t ForLas tTa s k (); RTC_SetAłarm(RTC_GetCounter{) + time); RTC_WaitForLastTask{); ETHpowerDown(); PWR_EnterSTANDBYMode(); } A larm zegara czasu rzeczy w istego je st zgłaszany w ostatnim cyklu oscylatora LSE, taktującego RTC, odpow iadającego sekundzie, w której alarm należy zgłosić. Zatem rzeczyw isty czas do zgłoszenia alarm u m oże być nieco dłuższy od zadanego, w naj­ gorszym przypadku o niecałą sekundę. C zasem pożądane m oże być przejście w tryb czuw ania z pew nym opóźnieniem . Zajm uje się tym funkcja D elayedStandby. Pierw szym je j argum entem jest żądane opóźnienie. D rugim argum entem je s t czas, po którym m ikrokontroler m a się obu­ dzić. O ba czasy podajem y w sekundach. C zas uśpienia zapam iętujem y w zmiennej globalnej standbyT im e. O późnienie realizujem y za pom ocą alarm u zegara czasu rzeczyw istego. A larm w yw ołuje przerw anie RTCAlarm_IRQn, które aktyw ujem y za pom ocą funkcji RTC_ITConfig - ustaw iam y bit RTC_IT_ALR. A by zabezpieczyć się przed fałszyw ym alarm em - rejestr alarm u m a zaw sze jak ąś w artość - w zmiennej globalnej magicNumber ustaw iam y pew ną ustaloną w artość MAGIC_NUMBER. Jest bar­ dzo m ało praw dopodobne, że taka w artość znajdzie się tam przypadkow o, idefine MAGIC_NUMBER 1836547290 stat^jL uint3£_t magicNumber; stat‘ iSAurtL$fe|t standbyTime; void Delayódiftandby (uint32_t delay, uint32_t time) 1 6.2. P rzykła d 6 a ~ p ierw sza w ersja klienta TCP 6. Klient TY.'/" 202 uint32_t pa r a m (PARAM_NUMBER); uint32_t timer; unsigned idx; char msg[MSG_SIZE]; if (delay > 0) ( magicNumber = MAGIC_NUMBER; standbyTime = time; RTC_WaitForLastTask(); RTC SetAlarm(RTC_GetCounter() + delay); RTC_WaitForLastTask(); RTC~ITConfig(RTC_IT__ALR, ENABLE); 1; Składow a fu n c tio n struktury typu s t a t e je s t adresem funkcji, która m a być w yw o­ łana w celu obsłużenia odebranego kom unikatu. Pierw szym argum entem tej funkcji je st w skaźnik do struktury typu s t a t e . D rugim argum entem je st w skaźnik do deskryptora T C P opisującego połączenie, z którego odbieram y kom unikaty. Składow a param struktury typu s t a t e je s t tablicą param etrów klienta. W tej tablicy pod in­ deksem CONNECTIONJTIMEOUT przechow ujem y czas oczekiw ania na kom unikat. Po przekroczeniu tego czasu klient, nie otrzym aw szy żadnego kom unikatu, zam yka połączenie TCP. W tablicy param pod indeksem STANDBYJTIME przechow ujem y czas przebyw ania klienta w trybie czuw ania. Składow a tim e r odlicza czas, przez który klient będzie jeszcze czekał na kolejny kom unikat i po którego upłynięciu, nie otrzym aw szy kom unikatu, zam knie połączenie. W artości czasów są w sekundach. S kładow a msg służy do zgrom adzenia odbieranego kom unikat. Składow a id x je st indeksem pierw szego w olnego znaku w tablicy msg, czyli je s t to liczba dotychczas odebranych znaków kom unikatu. Stała MSG SIZE określa m aksym alną długość ko­ m unikatu pow iększoną o jed en , tak żeby w buforze zm ieściło się jeszcze term inalne zero, zw ykle kończące napisy w języku C. ) else Standby(time); ) V, Przerw anie RTCAlarm_IRQn jest obsługiw ane przez funkcję RTCAlarm_IRQHandle:t;;ji która w prow adza m ikrokontroler w tryb czuw ania, gdy w artość zm iennej magic-ijj' Number zgadza się z w artością u staw ianą przez funkcję D elayedS tandby. void RTCAlarmJRQHandler (void) ( if (RTC_GetITStatus(RTC_IT_ALR) != RESET) EXTI_ClearITPendingBit(EXTI_Linel7); RTC_WaitForLastTask(); RTC_ClearITPendingBit(RTC_IT_ALR); if TraagicNumber == MAGICJtUMBER) 1 magicNumber = 0; SŁandby(standbyTime); ( ) K lienta urucham ia się za pom ocą funkcji T C P c lie n tS ta r t. Jej sygnatura znajduje się w pliku tcp_client.h. Ta funkcja je s t przeznaczona do w yw ołania z program u głów nego, dlatego w ołane w niej funkcje z biblioteki lw IP otoczone są m akram i chroniącym i przed w spółbieżnym w ykonyw aniem kodu tej biblioteki. Pierw szy ar­ gum ent a d d r funkcji T C P c lie n tS ta r t je s t adresem IP serw era, z którym m a być naw iązane połączenie TCP. D rugi argum ent p o r t je s t num erem portu, na którym nasłuchuje serwer. Funkcja ta działa w edług diagram u klienta przedstaw ionego na rysunku 4.4. Z w raca zero, gdy zostało zainicjow ane urucham ianie klienta, czyli gdy udało się w ysiać segm ent SY N , a w artość ujem ną w przeciw nym przypadku. N a początku alokujem y i inicjujem y strukturę typu s t a t e . N a razie param etry inicjuje­ my w artościam i dom yślnym i. Im plem entację czytania tych param etrów z rejestrów zapasow ych odkładam y do następnego przykładu. ) 6.2.3. Pliki tcp_client.h i tcpjclient.c < W pliku tcp_client.c znajduje się im plem entacja klienta realizującego protokół < sany w rozdziale 6.1. Z aczynam y od zdefiniow ania stałych reprezentujących ko- - ■■ m unikaty, które odbiera klient. D efiniujem y też form aty kom unikatów , które kiieni w ysyła. Ponadto definiujem y form aty param etrów kom unikatu SET. »define TIME_FRM "%Y.%m.%d %H:%M:%S" Idefine PARAM_FRM "%"U32_F" %"U32_F static const char ok_msg(] static const char s e tjn s g f] static const char b y e jn s g U static const char error_msg(] static const char heilo_msg_frm{| static const char param_msg_frm(] static const char ok_time_msg__frm( ] static const char ok_param_msg_frm(] static const char bye_msg_frm(] static const char error_msg_frm[] static const char set_time_frm[] static const char setj?aram_frmU "OK"; "SET"; "BYE"; "ERROR"; "HELLO ” TIME_FRM”\r\n"; "PARAM "PARAM_FRM"\r\n"; "OK "TIME_FRM"-YFYn"; "OK "PARAM_FRM»U\n"; "BYE "TIME_FRM"\r\n"; "ERROR "TIME_FRM"\r\n"; TIME_FRM; PARAM FRM; w 32 0 1 2 p ; * f.«i struct state { err_t (* function)(struct state struct tcp_pcb *); idefine DEFAULT_CONNECTION_TIMEOUT Idefine DEFAULT_STANDBY_TIME idefine POLL_PER_SECOND 30 20 2 int TCPclientStart (struct ip_addr *addr, uint!6_t port] ( struct tcp pcb *pcb; struct state *state; err_t err; IRQ_DECL_PROTECT(x); Stan klienta przechow ujem y w strukturze typu s t a t e . łdefine MSG_SIZE »define CONNECTIONJTIMEOUT »define STANDBYJTIME »define PARAM NUMBER 203 state = mem_malloc(sizeof(struct state)); if (state == NULL) return -1; state->function = HelloState; /SlfcpO: Jj&zeczytać ustawienia z rejestrów zapasowych. */ staif->piifirltCONKęCTION_TIMEOUT) = DEFAULT_CONNECTION_TIM£OUT; state->paraflli[STANDBY TIME] = DEFAULT STANDBY TIME; 205 6.2. Przykład 6a - pierwsza wersja klienta TCP Jeśli zostaną odebrane dane lub połączenie zostanie norm alnie zam knięte przez ser­ wer, to biblioteka lw IP w yw ołuje funkcję zw rotną recv_callback. D ziałanie tej funkcji je s t analogiczne ja k w przykładach 5a i 5b. state->timer = state->param(CONNECTION_TXMEOUT]; state->idx = 0; IRQ_PROTECT(x, LWIP_IRQ_PRIO) ; pcb = tcp_new{); IRQJJNPROTECT(x); if {pcb « NULL) { mem_free(state); return -1; #define ERR_£XIT 100 static err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf ‘p, err_t err) ( if ip) ( tcp_recved(pcb, p->tot_len); err = StateAutomaton(arg, pcb, p ) ; if (err == ERR_OK !| err == ERR_EXIT) pbuf_free(p); if (err == ERR_EXIT) { tcp_ex.it(arg, pcb); err~= ERR_OK; i IRQ_PROTECT(x, LWIP_IRQ_PRIO); tcp_arg(pcb, state); tcp_err(pcb, conn_err_callback); tcp_recv(pcb, recv_całlback); tcp_poii(pcb, poll_callback, POLL_P£R_SECOND); IRQ UNPROTECT(x); m } ) else ( tcp_exit(arg, pcb); IRQ_PRO?ECT(x, LWIP_IRQ_PRIO); err = ERR_0K; err = tcp_connect{pcb, addr, port, connect callback); IRQ_UNPROTECT(x); if (err != ERR_OK) { return err; ) mem_free(state); IRQ_PROTECT(x, LWIP_IRQ_PRIO) ; tcp_abandon(pcb, 0); IRQ_UNPROTECT(x); return -1; ) return 0; Jeśli połączenie T C P do serw era zostanie ustanow ione, to biblioteka lw IP wywołuję:'1 funkcję zw rotną c o n n e c t_ c a łlb a c k , w której klient w ysyła do serw era komunią: kat H ELLO . Funkcję tc p _ w rite _ tim e _ ra sg , w ysyłającą do serw era kom unikaty znacznikiem czasu, opisuję nieco dalej. static err_t connect_callback(void *arg, struct tcp_pcb *pcb, err_t err) ( return tcp_write_time msg(pcb, hello_msg_frm); i Jeśli połączenie T C P nie zostanie otw arte lub zostanie zam knięte aw aryjnie (sl.i-ow ane), to biblioteka lw IP w yw ołuje funkcję zw rotną c o n n _ e rr_ c a llb a c k . W funltr cji tej pow inniśm y zapisać do rejestrów zapasow ych param etry klienta, co zaimple­ m entujem y w następnym przykładzie. R eakcją ritr skasow anie połączenia T C P jest w prow adzenie m ikrokontrolera w tryb czuw ania na czas określony przez parametr/ p aram [ STA N D B Y _ T I M E ] . Z aśnięcie opóźniam y o 2 sekundy, aby dać bibliotece Iv.lP ■ i interfejsow i E thernet szansę w ysiania kom unikatu kasującego połączenie TCP. Je to potrzebne w sytuacji, gdy kasow anie połączenia je s t inicjow ane przez bibliotekę lw IP po stronie klienta, co m oże być skutkiem w ystąpienia ja k ieg o ś błędu. static void conn_errjsallback(void struct state *statę =,arg; ) arg, erf t err) /* TODG: Zapisać ustawienia do rejestrów zapasowych. DelayedStandby(2, state->param[STANDBY_TIME)); Połączenie T C P zam yka funkcja tcp_exit. N ie m usim y w niej zw alniać pam ięci przydzielonej strukturze typu state, gdyż po zam knięciu połączenia m ikrokontro­ ler je s t w prow adzany w tryb czuw ania, a po obudzeniu rozpocznie w ykonyw anie program u od początku, jakby został w yzerow any. Jeśli nie pow iodło się w yw oła­ nie funkcji tcp_close, to w yw ołujem y funkcję tcp_abort, która z kolei w yw ołuje funkcję conn_err_callback. Jeśli w yw ołanie funkcji tcp_close zakończy się suk­ cesem , to w prow adzam y m ikrokontroler w tryb czuw ania na czas określony przez param etr p a r a m [ S T A N D B Y _ T I M E ] . Jak poprzednio zaśnięcie opóźniam y o 2 sekundy, aby dać bibliotece lw IP szansę dokończenia procedury zam ykania połączenia TCP. Przed zaśnięciem pow inniśm y zapisać do rejestrów zapasow ych param etry klienta, co zaim plem entujem y w następnym przykładzie. static void tcp_exit(struct state *state, struct tcp pcb *pcb) if (tcp_close(pcb) != ERR_OK ) ( tcp ab o r t (pcb); ( 1 else { /* TODO: Zapisać ustawienia do rejestrów zapasowych. */ DelayedStandby (2, state->paramiSTANDBY_TIME] ); I i Przekroczenie czasu oczekiw ania na kom unikat obsługuje funkcja zw rotna p o ll _ c a llb a c k . Jeśli czas upłynie, czyli licznik tim e r zm niejszy się do zera, to w ysyła­ my kom unikat o błędzie i zam ykam y połączenie TCP. static err_t polł_callback(void *arg, struct tcp_pcb *pcb) struct state *state = arg; if (— (state->tirner) <= 0) { tcp_write_time_jnsg(pcb/ error_msg_frm); tcp_exit(arg, pcb); { 6.2. Przykład 6a - pierwsza wersja klienta TCP Funkcja tc p _ w rite _ tim e_ m sg w ysyła kom unikat zaw ierający znacznik czasu ( i czas w ysłania kom unikatu). P rotokół nakazuje w ysyłać znacznik czasu tylko w m unikacie H ELLO , ale nie zabrania w ysyłania go w innych kom unikatach, Dlateg w szystkie kom unikaty w ysyłane przez klienta, jeśli to tylko m ożliw e, zawieraj znacznik czasu, co ułatw ia testow anie program u. Pierw szy argum ent pcb funkcj tc p _ w rite _ tim e _ m sg je st w skaźnikiem do deskryptora T C P opisującego połączenie przez które ma być w ysłany kom unikat. D rugi argum ent fo rm a t je s t wskaźnikiem* do stałego napisu zaw ierającego form at kom unikatu do w ysłania. Funkcja zwraoa kod zakończenia typu e r r _ t zgodnie z konw encją stosow aną w bibliotece IwIP, ‘ static err_t tcp__write_time_msg (struct tcp_pcb *pcb, const char ‘format) { char msg(MSG_SIZE]; time_t rtime; struct tm tm; size_t size; SYS_ARCH_DECL_PROTECT(x); rtime = GetRealTimeClock(); if (localtime_rf&rtime, &tm) == NULL) return ERR__OK; SYS_ARCH_PROTECT(x ); size = strftime(msg, MSG_SIZE, format, &tm); SYS_ARCH_UNPROTECT(x); return tcp__write (pcb, msg, size, TCP_WRITE_FLAG_COPY); struktury typu s t a t e , w której są przechow yw ane param etry klienta. Trzeci argu­ m ent fo rm a t je s t w skaźnikiem do stałego napisu zaw ierającego form at kom unikatu do w ysłania. Funkcja zw raca kod zakończenia typu e r r t zgodnie z konw encją stosow aną w bibliotece IwIP. static err_t tcp_write_param_msg(struct tcp_pcb *pcb, s t ruct State *s, c onst char ‘formatl ( char msg(MSG_SIZEJ; size_t size; SYS_ARCH_DECL_PROTECT(x); S m 'J? SYS_ARCH_PROTECT(x); size = snprintf(msg, MSG_SIZB, format, s->param(CONNECTION_TIMEOUT], s->param(STANDBY_TIME)); SYS_ARCH_UNPROTECT(x); i f T size >= MSG_SIZE) s i z e = MSG_SIZE - 1; r e tu rn tcp _write (pcb, msg, s i z e , TCP_WRITE_F1,AG_C0PY) ; '% i ,fi ) Funkcja tcp_w rite_param _m sg korzysta z funkcji s n p r i n t f , która nie je s t w spół­ używ alna i dlatego jej w yw ołanie otoczone je s t m akram i blokującym i przerw ania. F unkcja s n p r i n t f um ieszcza w buforze msg m aksym alnie MSG_SIZE znaków, w łą­ czając term inalne zero. N atom iast zw raca liczbę bajtów, które zostałyby um iesz­ czone w buforze, gdyby miał on dostateczny rozm iar, ale nie w łączając term inal­ nego zera. D latego jeśli w artość zm iennej s i z e je s t w iększa lub rów na MSG_SIZE, to oznacza, że napis nie zm ieścił się w buforze msg i został obcięty. K om unikat w ysyłam y za pom ocą funkcji tc p _ w r ite , naw et jeśli nie zm ieścił się w buforze. N ie w ysyłam y term inalnego zera. . -'i \ ; } ~ 4 W funkcji tc p _ w rite_ tim e _ m sg najpierw za pom ocą funkcji GetRealTimeClc.-.' odczytujem y liczbę sekund, które upłynęły od pdczątku epoki U niksa, czyli odj 1 stycznia 1970 roku, a następnie konw ertujem y ją na datę i czas za pom ocą funk“, cji lo c a ltim e r z biblioteki standardow ej C. Jeśli konw ersja się nie powiedzie;'1, to nie m ożna nic rozsądnego zrobić i funkcja kończy działanie, zw racając ERR_'d,„; Funkcja s t r f t i m e z biblioteki standardow ej C form atuje kom unikat i umieszcza;, go w buforze msg, ale kopiuje do tego bufora nie w ięcej niż MSG_SIZE bajtów, wli­ czając term inalne zero. N atom iast zw raca liczbę bajtów um ieszczonych w bufoi/.e, nie w liczając w to term inalnego zera. P oniew aż funkcja ta nie je s t współużywalna, jej w yw ołanie otoczone je s t m akram i blokującym i przerw ania. F unkcja tcp _ w rit e w ysyła kom unikat, zgodnie ze specyfikacją protokołu, bez term inalnego zeia. Struktura tm jest zdefiniow ana w bibliotece standardow ej C. struct tm { int tm_sec; int tmjnin; int tm_hour; int tmjnday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm isdst; /* 207 Funkcja S tateA utom aton obsługuje autom at stanow y klienta. Jej pierw szy argu­ m ent s je s t w skaźnikieni do struktury zaw ierającej stan autom atu. D rugi argum ent pcb je s t w skaźnikiem do deskryptora T C P opisującego połączenie, z którego ode­ brano kom unikat. Trzeci argum ent p je s t w skaźnikiem do łańcucha buforów, któ­ re zaw ierają odebrane dane. Funkcja zw raca kod zakończenia typu e r r _ t zgodnie z konw encją stosow aną w bibliotece Iw IP lub w artość ERR_EXIT, gdy połączenie T C P m a zostać zam knięte. static err_t StateAutomaton(struct state *s, struct tcp_pcb *pcb, struct pbuf *p) { s->timer » s->param[C0NNECTI0N_TIME0UT]; for {;;) { uint8_t *c = (uint8_t *)p->payload; uintl6_t i; err_t err; sekunda */ minuta */ godzina */ dzień miesiąca */ miesiąc */ rok */ dzień tygodnia */ dzień roku */ znącznik czasu letniego 7 ); Funkcja tcp_w rite_j>aram _m sg w ysyła kom unikat PARAM z param etram i klienta. Pierw szy argum ent pcb je st w skaźnikiem do deskryptora T C P opisującego połącze­ nie, przez które m a być w ysłany kom unikat. D rugi argum ent s je s t w skaźnikiem do Ht ‘ ff, for (i = 0; i < p->łen; ++i) ( i f (c [i ] == ,\n/) { s->msg(s->idx++) = cji]; s->msg[s->idx) = '\0'; s->idx = 0; . err = s->function (s, pcb); 'iw ii M v 'c != ERR_0K) • r e t u r n err; ; . iń 208 6. Klient l e p ' else if (s->idx < MSG_SIZE - 2) s->msg[s->idxt+J = c [i }; } if (p->len == p->tot_len) break; else p = p->next; ) return ERR_OK; ! W funkcji S tateA u to raato n przeglądam y odebrany kom unikat znak po znakuj D opóki nie napotkam y znaku L F (w języ k u C zapisyw anego ja k o ' \ n '), kopiujemyj kolejne znaki kom unikatu do bufora msg, który je s t składow ą struktury typu s ta te r K opiujem y m aksym alnie MSG SIZE - 2 znaków , aby w buforze pozostało jeszcze m iejsce na znak LF i term inalne zero. Jeśli napotkam y znak LF, w staw iam y go'; w raz z term inalnym zerem do bufora msg i w yw ołujem y funkcję w skazyw aną pi/oz składow ą f u n c tio n struktury typu s t a t e . D la każdego stanu je st zdefiniowaną, funkcja, której nazw a je s t taka sam a ja k nazw a stanu i która obsługuje komunikaty' odebrane w tym stanie. A utom at klienta m a dw a stany, w ięc są dw ie takie funkcje, H e llo S ta te i P aram S tate. Pierw szy argum ent s t a t e tych funkcji je s t wskaźnikier/. do struktury typu s t a t e . D rugi argum ent pcb je s t w skaźnikiem do deskryplora T( 'P opisującego połączenie. Funkcje te zw racają kod zakończenia typu e r r _ t zgodnie: z konw encją stosow aną przez bibliotekę lw IP lub w artość ERR_EXIT, gdy połączenie T C P ma zostać zam knięte. fdefine msglen(s) (sizeof(s) - 1) Idefine msgncmp(sl, s2, n) \ (strncmp(sł, s2, n) == 0 && isspace((int)sl[nj)) 6.2. Przykład 6a - pierwsza wersja klietita TCP else if {msgncmp(state->msg, bye_msg, msglen(byejnsg)) i i msgncmp{state->msg, errorjnsg, msglen(errorjnsg))) return ERR_EXIT; else { tcp_write_time__msg (pcb, error_msg__frm); return ERR__EXIT; ) } Funkcja H e llo S ta te realizuje górną część diagram u z rysunku 6.1. Funkcja s t r p ­ tim e z biblioteki standardow ej C konw ertuje datę i czas reprezentow ane za pom ocą napisu do postaci struktury typu tm. Z w raca zero, gdy konw ersja się nie pow iodła. F unkcja mktime też z biblioteki standardow ej C konw ertuje datę i czas reprezento­ wane za pom ocą struktury tm na liczbę sekund, które upłynęły od początku 1 stycz­ nia 1970 roku. Z w raca w artość -1 zrzutow aną na typ tim e _ t, gdy konw ersja się nie pow iodła. łdefine idefine łdefine łdefine 1 if (!strptime(state->msg + msglen{setjnsg), set_time_frm, &tm)) { tcp_write_timejnsg(pcb, error_msg_frm); — return ERR_ EXIT; ".,v j 1 else ( state->param[CONNECTION_TIMEOUT] = timeout; state->param(STANDBY_TIME3 = sleep_time; tcp_write__param_msg (pcb, state, ok_param_msg_f rm); tcp_write_time_msg (pcb, bye_msg_frm); I } ~ SYS_ARCHJ?HOTECT(x); ret = sscanf(state->msg + msglen(setjnsg), set_param_frm, &timeout, &sleep__time); SYS_ARCHJJNPROTECT(x) ; if (ret != 2 H timeout < MIN_CONNECTIOK_TIMEOOT || timeout > MAX_CONNECTIONJfIMEOUT |[ sleep_time < MIH_STANDBY_TIME 1| sleep_time > MAX_STANDBY_TIME) { tcp_write_time_msg(pcb, error_msg_frm); } ! 5 600 1 1800 else if (msgncmp(stateu >msg, setjnsg, msglen(setjnsg))) { uint32_t timeout, sleep time; int ret; SYS_ARCH_DECL_PROTECT(x); else if {msgncmp{state->msg, setjnsg, msglen(setjnsg))) { err_t err; time_t t; struct tm tm; SetRealTimeClock(t); err = tcp_write_timejnsg(pcb, ok_timejnsgjfrm); if (err != ERR_OK) > return err; state->jfunction = ParamState; return tcp__write_param_msg (pcb, state, paramjnsg_f rm); MXN_C0NNECTI0N_TIME0UT MAX_CONNECTION_TIMEOUT MIN_STANDBY_TIME MAX_STANDBY_TIME static err_t ParamState(struct state *state, struct tcp_pcb *pcb) { if (msgncmp(state->msg, okjnsg, msglen(ok_msg))} 1 tcp_write time_msg(pcb, byejnsg_frm); static err_t HelloState{struct state ‘state, struct tcp_pcb *pcb) { if {msgncmp(state->msg, okjnsg, msglen(okjnsg))) { state->function = ParamState/ return tcp write__paramjnsg (pcb, state, paramjnsg_frm) / t = mktime(&tm); if {t == (time_J:)-l) ( tcp_write_time_msg(pcb, error jnsg_frm); return ERR_EXIT; 20 9 i ) else if (¡msgncmp(state->msg, byejnsg, msglen(byejnsg)) && !msgncmp(state->msg, errorjnsg, msglen(errorjnsg))) tcp_write_time_msg(pcb, errorjnsg_frm); return ERR_EXIT; Fuńfeja#sf6):an>State realizuje dolną część diagram u zam ieszczonego na rysun­ ku 6.1. N ajiparam etry czasow e nakładam y pew ne ograniczenia. D olne ograniczę- 210 łdefine error_temporary(expr, err) \ if ((expr) < 0 ) 1 \ int i; \ for (i = 0; i < 3; ++i) ( \ Error(err); \ nie na czas oczekiw ania na kom unikat zabezpiecza klienta przed ustaw ienie krótkiego czasu, który uniem ożliw iłby odebranie kom unikatu. D olne ogranie ż e n ili na czas uśpienia zabezpiecza przed zerow ą w artością tego czasu, co oznaczałoby? w praktyce uśpienie na zaw sze - patrz opis funkcji Standby. G órne ograniczenia ngj param etry klienta m ają ułatw ić je g o testow anie. O dczyt param etrów z komunikatij| SE T w ykonujem y za pom ocą funkcji s s c a n f z biblioteki standardow ej C. Funkćjai ta nie je s t w spółużyw alna. «|'i| I Standby(10); Plik utiljerror.h „V -j fdefine error_permanent(expr, err) error_check(expr, err) ) \ \ \ \ ► \ I Błędy, których przyczyna m oże ustąpić po w yzerow aniu m ikrokontrolera, obsługuje m akro e r r o r _ r e s e t a b l e . Za pom ocą tego m akra najpierw inform ujem y o rodzaju błędu, trzykrotnie w yw ołując funkcję E rro r , a następnie zerujem y mikrokontrolci za pom ocą funkcji NVIC_SystemReset z biblioteki STM 32. M ikrokontroler STM32 podczas zerow ania w ym usza stan niski na w yprow adzeniu R E S E T , dzięki czemu cale urządzenie je st restartow ane. f fdefine error_resetable(expr, err) if {(expr) < 0) i int i; for (i = 0 ; i < 3; ++i) ( Error(err); int main{) { static struct netif netif; static struct ethnetif ethnetif = {PHY_ADDRESS}; static struct ip_addr addr; uint8_t confBit; il ■' | Delay(1000000); confBit = GetConfBit{); AllPin s D i s a b l e O ; LEDconfigure(); RedLEDonO; SET_IRQ_PROTECTION{); error_resetable(CLKconfigure{), 1); error_permanent(LocalTimeConfigure{), 2); error_resetable(RTCconfigure{), 3); error_resetable (ETHconfigureMII (), 4); .ty 1 NVIC_SystemReset(); D o obsługi błędów, których przyczyna m oże ustąpić po pew nym czasie, przezna­ czone je s t m akro e rrq r_ te m p o ra ry . N ajpiąrw inform ujem y o rodzaju błędu, trzy­ krotnie w yw ołując funkcję E rro r , a następnie w prow adzam y m ikrokontroler w stan czuw ania na 10 sekund. C zas czuw ania m ożna oczyw iście w ydłużyć lub uczynić go param etrem makra. Po w ybudzeniu m ikrokontroler rozpoczyna wykonywanie program u od początku. Plik ex_tcp_client.c Plik ex_tcp_client.c zaw iera funkcję main przykładu. F unkcja ta je s t w sw ojej struk­ turze bardzo podobna do funkcji main z poprzednich przykładów . G łów na różni­ ca polega na tym , że używ am y m akr z pliku util_error.h. B łędy zgłaszane przez funkcje urucham iające układy sprzętow e zaklasyfikow ano jak o takie, które m ogą ustąpić po w yzerow aniu m ikrokontrolera i restarcie urządzenia. D latego funkcje urucham iające układy sprzętow e w ołane są za pom ocą m akra e r r o r _ r e s e t a b l e , które zeruje m ikrokontroler, gdy funkcja zasygnalizuje błąd. W yjątkiem jest funk­ cja L o calT im eC onfigurę, gdyż analiza jej tekstu źródłow ego w skazuje, że je d y ­ nym pow odem jej błędnego działania m oże być funkcja S ysT ick_C onfig, która zakończy się niepow odzeniem tylko wtedy, gdy otrzym a niepopraw ną w artość param etru. Taki błąd nie ustąpi po w yzerow aniu m ikrokontrolera. D latego funk­ cję L o calT im eC onfigure w yw ołujem y za pom ocą m akra e rro r_ p e rm a n e n t. Błędy zgłaszane przez funkcje urucham iające protokoły sieciow e zaklasyfikow ano jako chw ilow e problem y z siecią, które najpraw dopodobniej ustąpią po pew nym czasie. D latego te funkcje w yw ołujem y za pom ocą m akra e r r o r tem porary. D otychczas na w szystkie błędy pod czas urucham iania program u reagow aliśm yn je g o zaw ieszeniem w nieskończonej pętli - m akro e rro r_ c h e c k . W poprzeddjfajfl rozdziale w celu w y prow adzenia m ikrokontrolera z tego stanu używ aliśm y nàd»';;f| zorcy. W tym podrozdziale p o kazuję inne rozw iązanie tego problem u. W pliku'ï*! util_error.h zdefiniow ane są m akra służące do obsługi błędów . P ierw szym argU-*$l m entem każdego z tych m akr je s t w yw ołanie funkcji, która zw raca w artość zeró,® przy popraw nym zakończeniu, a w artość ujem ną, gdy w ystąpi! błąd. R odzaj błędCF sygnalizuje funkcja E rro r , która m iga czerw oną d iodą św iecącą. D rugi argu . m akra określa liczbę m ignięć. D o obsługi błędów , których przyczyna w ydaje mc nieusuw alna, przeznaczone je s t m akro e r r o r jo e r m a n e n t. M akro to zaw iesza pro- ;V. gram i tak napraw dę je s t przem ianow anym m akrem e rr o r_ c h e c k zdefiniow anym '3 w pliku util_led.h. łdefine error_check(expr, errl if ((expr) < 0) { for (;;) { Error(err); \ \ 1 6.2.5. 6.2.4. 211 6.2. Przykład 6a - pierwsza wersja klienta TCP 6- Klient / q J SijJ •■ netif.hwaddr[0] = 2; netif.hwaddrdJ = (BOARDJTYPE » 8) 6 0xff; netif.hwaddr[2] = BOARD TYPE & Oxff; netif,hwaddr(3] - {ETH_BOARD » 0) & 0xff; netif.hwaddr|4) = ETH_BOARD & Oxff; netif.hwaddr(5] * 1 + confBit; if (¡confBit) { IP4_ADDR(&netif.ip_addr, 192, 168, 51, 84); IP4__ADDR(&netif .netmask, 255, 255,255, 240); .jli|^_ADD^(Snetif ,gw, 192, 168, 51, 81); else i , jil - 212 6. Klient T( p IP4_ADDR(&netif.ip_addr, IP4_ADDR(6netif.netmask, IP4_ADDR(&netif.gw, O, O, O, O, O, O, O, 0); O, 0); O, O J ; ) error_temporary(LWIPinterfacelnit(&netif, Łethnetif), 5); LWIPtimersStart(}; error_temporary(DHCPwait(&netif, 10, 4), 6); IP4_ADDR{&addr, 192, 168, 51, 88); error_temporary{TCPclientStart Uaddr, 22222), 7); RedLEDoff () ; for W zestaw ie Z L29A R M sposób uzyskania ustaw ień sieciow ych w ybieram y jak po­ przednio za pom ocą zw orki B O O T1. Po uruchom ieniu biblioteki lw IP i skonfipu- J row aniu ustaw ień sieciow ych urucham iam y klienta. Łączy się on z serw erem , który Ć nasłuchuje pod adresem 192.168.51.88 na porcie 22222. Podczas całego procesu ,»3 konfigurow ania św ieci się czerw ona dioda. Jej zgaśnięcie oznacza koniec urucha- ■; m iania, a m iganie sygnalizuje w ystąpienie problem u. 6.2.6. Testowanie przykładu Do przetestow ania przykładu je st potrzebny serw er TCP. M ożna w tym celu uz program u netcat, który je s t standardow o um ieszczany w dystrybucjach L im iku i urucham iany poleceniem nc. Jest też dostępna w Internecie je g o darm ow a w sja przeznaczona dla system ów W indow s. P rogram netca t, którego używałem _ do testow ania przykładów w środow isku W indow s, zn ajduje się w pliku n c lh zip w archiw um z przykładam i w katalogu ./m ain/netcat. N etcat je s t narzędziem ■ używ anym z linii poleceń (ang. co m m a n d linę). C zyta ze standardow ego wejść i pisze na standardow e w yjście. Ł atw o daje się go użyć w skrypcie. W ta b e li a * zam ieszczone są przykładow e sposoby je g o uruchom ienia. W p ierw szym wii jest polecenie urucham iające serw er tylko na je d n o połączenie - netcat końc. d ziałanie po zam knięciu p o łączenia. W drugim w ierszu je s t polecenie umożliw ją c e odbieranie w ielu kolejnych połączeń od klienta. Jeśli nie będzie ono dzii popraw nie, to m ożna użyć, zam ieszczonych w o statnim w ierszu tabeli, poleceń . -/i u rucham iających serw er w nieskończonej pętli.. ,Wr przypadku L inuksa całą sekw encję poleceń m ożna po prostu w pisać w linii poleceń. W przypadku Window trzeba utw orzyć plik w sadow y (z rozszerzeniem bat) z podaną w tabeli sekwen« poleceń. Tab. 6.3. Uruchamienie serwera Linux nc -1 22222 nc -lk 22222 while truei do nc -1 22222; done W indows nc -1 -p 22222 nc -L -p 2^222 Secho off :forever nc -i -p 22222 goto forever 3 6.2. P rzykład 6a - pierwsza wersja klienta TCP 213 Pierw szy test polega na ogólnym spraw dzeniu działania klienta oraz działania ze­ gara czasu rzeczyw istego i trybu czuw ania. N a w szystkich poniższych w ydrukach kom unikaty bez param etrów i kom unikaty S E T są w ysyłane przez serwer, czyli są w pisyw ane z konsoli, a pozostałe kom unikaty pochodzą od klienta. HELLO 1970.01.01 00:00:03 OK PARAM 30 20 OK BYE 1970.01.01 00:00:11 HELLO 1970.01.01 00:00:38 SET 2010.08.05 12:00:00 OK 2010.08.05 12:00:00 PARAM 30 20 OK BYE 2010.08.05 12:00:01 Po w łączeniu zasilania zegar czasu rzeczyw istego zaczyna odliczanie od północy 1 stycznia 1970 roku. M iędzy kom unikatem B Y E a H E L L O upłynęło 27 sekund. M ikrokontroler spal przez 20 sekund, a pozostałe 7 sekund zajęło ponow ne uru­ chom ienie klienta. Przekroczenie czasu m ożna przetestow ać, nie odpow iadając na kom unikat H ELLO . HELLO ERROR HELLO ERROR 2010.08.05 2010.08,05 2010.08.05 2010.08.05 12:00:28 12:00:58 12:01:25 1 2 :01:5Ś M iędzy kom unikatem H EL L O a E R R O R upłynęło zgodnie z oczekiw aniem 30 se­ kund. M iędzy kom unikatem E R R O R a H EL L O upłynęło ja k poprzednio 27 sekund. K olejny test polega na próbie zm iany param etrów. HELLO 2010.08.05 12:10:51 OK PARAM 30 20 SET 10 10 OK 10 10 BYE 2010.08.05 12:10:57 HELLO 2010.08.05 12:11:14 OK PARAM 30 20 OK BYE 2010.08.05 12:11:20 O ba param etry czasow e klienta zostały zm ienione na 10 dzy kom unikatem B Y E a H EL L O upłynęło 17 sekund, 10 sekund i urucham iał się ponow nie przez następne 7 przyw rócono dom yślne w artości param etrów . N a koniec w ać, czy klient popraw nie reaguje na błędne kom unikaty. HELLO 2010.08.05 12:16:28 KO ERROR 2010.08.05 12:16:30 HELLO 2010.08.05 12:16:57 I ERROR 2010-.0$j05 12:17:03 sekund. Tym razem m ię­ czyli klient spał zadane sekund. Po w ybudzeniu należałoby też przetesto­ 6.3. Przykład 6b - klient TCP z. obsługą rejestrów zapasowych Przykład 6b - klient TCP z obsługą rejestrów zapasowych 215 strów zapasow ych ja k o pam ięć 21 słów czterobajtow ych (ang. words). Jedno z tych słów rezerw ujem y na sum ę kontrolną (C R C , ang. cyclic redundancy check), o czym poniżej. Z atem w ST M 32F107 do dyspozycji pozostaje nam 20 słów pam ięci za­ pasow ej. A by uczynić oprogram ow anie m ożliw ie przenośnym , definiujem y stałą BKPwords, która oznacza liczbę stów m ożliw ych do zapisania w pam ięci zapaso­ wej. N azw y plików przykładu 6b zam ieszczone są w ta b e li <5.4. W dalszym ciągu opisu^ ję tylko różnice w stosunku do przykładu 6a. Pliki util_bkp.h i util_bkp.c static const int BKPwords = (sizeof(BKPdataReg) / (2 * sizeof(BKPdataReg[0]))) - 1; Pliki ulil_bkp.li i util_bkp.c zaw ierają im plem entację funkcji obsługujących reje- , stry zapasow e. Poszczególne m odele m ikrokontrolerów z rodziny STM 32 mają! różną liczbę rejestrów zapasow ych. N iektóre m ają ich tylko 10. M ikrokontroler ST M 32F107 w yposażono w 4 2 dw ubajtow e rejestry, których zaw artość je st pod-"' trzy m yw ana przez zasilanie podłączone do w yprow adzenia V BAT. R ejestry te nieste-:' ty nie zajm ują ciągłego obszaru pam ięci w przestrzeni adresow ej m ikro k o n tro ler. Ż eby łatwiej było się nim i posługiw ać, w bibliotece S T M 32 zdefiniow ano stale BKP_DR1 do BKP_DR42. K ażdej z tych stałych przypisano w artość przesunięcia (an g ,1 offset), pod którym znajduje się odpow iedni rejestr zapasow y. Przesunięcia są wy-A znaczane w zględem adresu 0x40006C 00. Ż eby m ożna było traktow ać rejestry za- 1 pasow e jak o ciągły obszar pam ięci o rozm iarze 84 bajtów, będziem y je adresować-; pośrednio za pom ocą tablicy BKPdataReg. Podukład m ikrokontrolera odpow iedzialny za obsługę rejestrów zapasow ych kon­ figurujem y za pom ocą funkcji B K Pconfigure, która w łącza potrzebne sygnały tak­ tujące i uaktyw nia dostęp do tych rejestrów . U aktyw nia też układ liczący sprzę­ tow o sum ę kontrolną. D o je j obliczania je s t używ any ten sam w ielom ian, który je s t stosow any do w yliczania sekw encji kontrolnej ram ki ethernetow ej. Z aw artość rejestrów zapasow ych m ożna skasow ać za pom ocą w yprow adzenia PC 13 m ikro­ ko n tro lera (ang. tam per). W zestaw ie Z L 29A R M do tego w yprow adzenia podłą­ czony je s t przycisk SW 4, który po w ciśnięciu w ym usza na tym w yprow adzeniu stan niski. static const uintl6_t BKP_DR1, BKP_DR2, BKP_DR7, BKP_DR8, BKP_DR13, BKP_DR14, BKP_DR19, BKP_DR20, BKP_DR25, BKP_DR26, BKP_DR31, BKP_DR32, BKP DR37, BKP DR38, BKPdataReg|] = { BKPJDR3, BKP__DR4, BKP_DR9, BKPJJR10, BKP_DR15, BKP_DR16, BKP_DR21, BKP_DR22, BKP_DR27, BKP_DR28, BKP_DR33, BKP_DR34, BKP_DR39, BKP_DR40, BKP_DR5, BKP_DRll, BKP_DR17, BKP_DR23, BKP_DR29, BKP_DR35, BKP_DR41, void BKPconfigure(void) ( RCC_APBlPeriphClockCmd(RCC_APBlPeriph_PWR | RCC_APBlPeriph_BKP, ENABLE|; RCC_AHBPeriphClockCmd(RCC__AHBPeriph_CRC, ENABLE); PWR BackupAccessCmd(ENABLE); BKP_ClearFlag(); BKP TamperPinLevelConfig(BKP_TamperPinLevel_Low); BKP_DR6, 8KPJ)R12, BKP_1)R1B, BKPJ3R24, BKP_DR30, BKP_DR36, BKP_DR42 BKPJTamperPinCmd(ENABLE); ) Stała BKPwords je st w idoczna tylko w ew nątrz jednostki translacji util_bkp.c. A by uzyskać do niej dostęp z innych jed n o stek translacji, definiujem y funkcję BKPnumberWords. 1; Poniew aż m ikrokontrolery S T M 32 są 32-bitow e, w ygodnie i efektyw nie je st p r/e sylać dane w porcjach czterobajtow ych. D latego będziem y traktow ać pam ięć rejeTab. int BKPnumberWords(void) { return BKPwords; - V ) Funkcja BKPwrite zapisuje dane do pom ięci zapasow ej. Pierw szy argum ent d a ta je s t w skaźnikiem do tablicy słów, które m ają być zapisane. Drugi argum ent co u n t je st liczbą słów do zapisania. F unkcja zw raca liczbę faktycznie zapisanych słów. K ażde słow o zapisujem y w dw óch kolejnych rejestrach zapasow ych. N a końcu za­ pisujem y sum ę kontrolną, która pozw ala zw eryfikow ać popraw ność późniejszego odczytu i co być m oże w ażniejsze, pozw ala leż stw ierdzić, czy odczytane zerow e dane są w ynikiem w yzerow ania zaw artości rejestrów zapasow ych, czy rzeczyw iście takie dane w nich zapisano. cc.h cortex-m3.h Iwipopts.h stm 32t10x cont.h int BKPwrite (const uint32__t ‘ data, int count) { int idx; uint32_t crc; 6.4. Pliki przykładu 6b Źródłowe i biblioteczne ex tcp clnt bkp.c startup stm 32 cld.c tcp_client_bkp.c board conf.c board init.c boardJe d .c tcp client, h board cont.h board def.h boarfi dets.h board init.h b o a rd je d .h u til bkp.c u til delay, c util_etli_nc.c u til J e d .c u tiljw ip .c u t iljtc . c u til tim e.c Iiblwip4.a ■Iibsten32i10x.a Nagłówkowe - u til bkp.h u til delay.h u til error.h u til eth.h t u tilje d .li u tiljw ip .li u t iljt c . li u til time.h i m ■at v * if®,county > BKPwords) ^unt^*P &KPwords; CRC ResetP${}; 6.3. Przykład 6h - klient TCP z obsługą rejestrów zapasowych Pozostałe różnice polegają na zapam iętaniu param etrów klienta w rejestrach za­ pasow ych przed uśpieniem m ikrokontrolera w funkcjach, które kończą działanie klienta, czyli co n n _ _ err_ callb ack i tc p _ e x it. for (idx = 0; idx < count; ł+idx) { BKP__WriteBackupRegister(BKPdataReg(2 * idx], data[idx] & 0xffff); BKP_WriteBackupRegister(BKPdataReg[2 * idx + 1 ] , static void conn_err_callback(void *arg, err_t err) ( struct state ‘ state = arg; data{idx] >> 16); CRC^CalcCRC{data[idx]); BKPwrite(state->param, PARAM_NUMBER); DelayedStandby(2, state->param(STANDBY_TIME)); } crc = CRC__GetCRC () ; BKP_WriteBackupRegister(BKPdataReg[2 * idx], crc £ Qxffff); BKP_WriteBackupRegister(BKPdataReg(2 * idx + ł], crc » 16); return idx; ) static void tcp_exit(struct state ‘ state, struct tcp_pcb *pcb) { if (tcp_close(pcb) != ERR_OK) | tcp_abort(pcb); ) ) Funkcja BKPread odczytuje dane z pam ięci zapasow ej. Pierw szy argum ent data jest w skaźnikiem do tablicy słów, gdzie m ają być um ieszczone odczytane dane. Drugi1 argum ent c o u n t je s t liczbą słów do odczytania. F unkcja zw raca liczbę odczytanych słów albo w artość ujem ną, gdy nie zgadza się sum a kontrolna. int BKPread(uint32_t *data, int count) else { BKPwrite(state->param, PARAM_NUMBER); DelayedStandby(2, state->param(STANDBY_TIME]); ) 1 1 int idx; uint32_J: crc; 6.3.3. data(idx] = BKP_ReadBackupRegister(BKPdataReg(2 * idxj) f (BKP_ReadBackupRegister(BKPdataReg[2 * idx + 1 ] ) « 16); crc = BKP_ReadBackupRegister(BKPdataReg [2 * idx}) | (BKP^ReadBackupRegister(BKPdataReg[2 * idx + 1]) « 16); BKPconfigure{); 6.3.4. i Testowanie przykładu P rzykład pow inien najpierw przejść pozytyw nie w szystkie testy, którym i byl te­ stow any poprzedni przykład. N astępnie m ożna przystąpić do testow ania rejestrów zapasow ych. N ajpierw próbujem y zm ienić w artości param etrów klienta. CRC_ResetDR{); if (crc !- CRC_CalcBłockCRC(data, idx)) return -1; return idx; HELLO 2010.08.05 12:25:29 OK PARAM 30 20 SET 10 10 OK 10 10 BYE 2010.08.05 12:25:35 Plik tcp_client_bkp.c Plik tcp_client_bkp.c zaw iera im plem entację klienta realizującego rozw ażany w tym rozdziale protokół i dodatkow o w yposażonego W .flbsługę rejestrów zapasowych. W stosunku do im plem entacji klienta z pliku tc p ^ lie n t.c są tylko trzy różnice. Pierw sza różnica w ystępuje w funkcji T C P c łie n tS ta r t. Spraw dzam y, czy rejestry zapasow e zaw ierają param etry klienta i jeśli zaw ierają, to je czytam y. Jeśli nie uda się odczytać param etrów , to są one inicjow ane w artościam i dom yślnym i. Spraw dzam y, czy rzeczyw iście param etry zapisano. HELLO 2010.08.05 12:25:51 OK PARAM 10 10 OK BYE 2010.08.05 12:25:54 HELLO 2010.08.05 12:26:10 ERROR 2010.08.05 12:26:20 int TCPcłientStart(struct ip_addr *addr, uintl6_t port) ( if (BKPread(state->param, PARAMJ1UMBER) != P^RAM_NUMBER) { state->param(CONNECTION_TIMEOUT) = DEFAUL%CONNECTION_TIMEOUT; state->param[STANDBY_TIME] = DEFAULT_STANDBY_TIME; Plik ex_tcp_clnt_bkp.c Plik ex_tcp_client_bkp.c zaw iera funkcję main przykładu. Funkcja ta jest praw ie identyczna ja k w poprzednim przykładzie. Jedyna różnica polega na w yw ołaniu na jej początku funkcji B K Pconfigure konfigurującej rejestry zapasow e. if (count > BKPwords) count - BKPwords; for (idx = 0; idx < count; ++idx) I 217 H. M iędzy kom unikatem B Y E a H EL L O upłynęło 16 sekund, a m iędzy kom unikatem H EL L O a E R R O R m inęło 10 sekund, co św iadczy o tym , że param etry zm ieniono, zapisano w rejestrach zapasow ych i odczytano z nich po w ybudzeniu mikrok o n tfo le rą N a s tę p n ie , gdy m ikrokontroler śpi, w ciskam y przycisk tam per (SW 4 w ZL29ARNii). 218 6. Klient TCI' HELLO 2010.08.05 12:28:46 OK PARAM 30 20 OK BYE 2010.08.05 12:20:49 HELLO 2010.08.05 12:29:15 ERROR 2010.08.05 12:29:45 W idać, że przyw rócono dom yślne w artości param etrów. M iędzy kom unikatem BYH ■' a H EL L O upłynęło 26 sekund, a m iędzy kom unikatem H E L L O a E R R O R m inęło' .< 30 sekund. Serwer UDP 220 7.2. Przykład 7 - prosty serw er UDP 7. Serwer U lf iB Sl W tym rozdziale przedstaw iam prosty serw er używ ający protokołu transportowego UDP. Serw er ten um ożliw ia zdalne m anipulow anie rejestram i w ejścia-w yjścia1rrilv krokontrolera (przedstaw ionym i na rysunku 1.3 i opisanym i w rozdziale 1.5), alg“ m ożna go łatw o rozbudow ać, aby um ożliw ia! sterow anie dow olnym i peryferiam i m ikrokontrolera, co pozostaw iam C zytelnikow i jak o ćw iczenie. Przykład bardziej; skom plikow anego serw era korzystającego z protokołu transportow ego U DP moi na' znaleźć w nocie aplikacyjnej [5]. Jest lam opisany serw er T F T P (ang. Trivial File Transfer P rotocol), czyli serw er prostego protokołu do przesyłania plików. ■ ! 7.1. Projekt protokołu T ab . 7 .1 . w tym polu są przesyłane w porządku sieciow ym (ang. big-endian), czyli najbar­ dziej znaczący bit pola D A N E m a num er 16, a najm niej znaczący je s t bit 31. Protokół działa w edług zasady żądanie-odpow iedź. K lient w ysyła polecenie, serw er je w ykonuje i odsyła w łaściw ą odpow iedź. Jeśli serw er nie m oże popraw nie zinter­ pretow ać polecenia, to odpow iada kom unikatem , w którym pole O PER A C JA m a w artość PD U _E R R O R (ang. protocol data unit error). 7.2. | Tym razem zaprojektujem y protokół bezstanow y, w którym kom unikaty będą mied postać binarną. Form at kom unikatu je s t w idoczny na ry s u n k u 7.1. Wszystkie kom unikaty m ają 32 bity. P oczątkow e 4 bity zaw ierają num er w ersji protokolu;J' W prow adzenie w kom unikatach pola inform ującego o w ersji protokołu je st bafi$ dzo pow szechną praktyką. U łatw ia rozw ijanie protokołu i w prow adzanie jego noi? w ych w ersji z zachow aniem kom patybilności z w ersjam i poprzednim i. Opisywaną^ tu w ersja protokołu m a w polu W E R S JA w artość 1. K olejne czterobitow e pole';6 O PE R A C JA w kom unikatach w ysyłanych przez klienta zaw iera polecenie do wy* konania, a w kom unikatach w ysyłanych przez serw er zaw iera odpow iedź. Poleceniair m ają w artości od 0 do 7, a odpow iedzi od 8 do 15. A ktualnie zdefiniow ane operacje) opisane są w ta b e li 7.1. W artości nieuw zględnienie w tabeli są zarezerw ow ane dof przyszłego w ykorzystania. O śm iobitow e pole PO RT zaw iera num er portu wejścia-!.---w yjścia m ikrokontrolera. N um er 1 oznacza port A, num er 2 port B itd. Numeryi,^. które nie odpow iadają żadnem u fizycznem u portow i m ikrokontrolera, są zarezer- j| w ow ane do przyszłego w ykorzystania. O statnie 16 bilów kom unikatu zajm uje pole';! D A N E. Jego interpretacja zależy od operacji i je s t opisana w tabeli 7.1. W artośoil| Wartość T a b . 7 .2 . 1 READ_OUTPUT_BITS 2 Polecenie - odczytaj rejestr wyjściowy o d r .Zawartość pola DANE jest nieistotna. Serwer. odpowiada komunikatem z operacją OUTPUT BITS RESET_BITS 3 Polecenie - wyzeruj w rejestrze wyjściowym o d r bity, które mają wartość 1 w polu DANE. Serwer odpowiada komunikatem z operacją OUTPUT BITS SET_BITS 4 Polecenie - ustaw w rejestrze wyjściowym ODtyBity, które mają wartość 1 w polu DANE. Serwer odpowiada komunikatem z operacją OUTPUT BITS WRITE_BITS 5 Polecenie - zapisz do rejestru wyjściowego o d r wartość pola DANE. Serwer odpowiada _ komunikatem z operacją OUTPUT BITS PDU ERROR 8 Odpowiedź serwera informująca o błędnym poleceniu. Pola PORT i DANE zawierają zera INPUT BITS 9 Odpowiedź serwera - pole DANE zawiera wartość odczytaną z rejestru wejściowego lim OUTPUT BITS 10 Odpowiedź serwera - pole DANE zawiera wartość odczytaną z rejestru wyjściowego opi«. OPERACJA - [4:7] ' ' PORT [8:15] DANE [16:31] e x jid p d .c startup_stm 32_cld.c udpjserver.c board_con!.c boardJ n it.c board J e d .c udp_server.h board_conU i boardjJef.h b o a rd je ts .h b o a rd jn it.h boardJe d .h 7.2.1. Iiblwip4.a Iibstm32t10x.a .:■! w- *>1, uliljdelay.h util_error.h util_eth.h u tilJed.h u tiljw ip .b U tiljlC .il u til time.h cc.h cortex-m3.h Iwipopts.h stm32i10x_conf.h Pliki udp_server.h i udp_server.c Pliki udp_server.h i udp_server.c zaw ierają im plem entację serwera, który realizuje opisany w yżej protokół. Serw er urucham ia się za pom ocą funkcji UDPserverStart. Jej argum entem je s t num er portu, na którym serw er m a nasłuchiw ać. Funkcja ta zw raca zero, gdy uruchom ienie serw era pow iodło się, a w artość ujem ną w prze­ ciw nym przypadku. Funkcja UDPserverStart realizuje diagram serw era przedsta­ w iony na rysunku 4.9. D odatkow o spraw dzam y w artości zw racane przez funkcje biblioteki lw IP i stosow nie reagujem y, jeśli któraś funkcja zw róci błąd. Funkcja UDPserverStart je st przeznaczona do w yw ołania z program u głów nego, dlatego w yw ołania funkcji z biblioteki lw IP otoczone są m akiam i, które zabezpieczają przed ich w spółbieżnym w ykonyw aniem . Za pom ocą-funkcji udp_recv ustawiam y funkcję zw rotną recv_callback, która będzie w yw ołana po odebraniu przez serw er danych. O statni argum ent w w yw ołaniu funkcji udp_recv m a w artość NULL, gdyż nasz serw er je st bezstanow y i nie m a potrzeby przechow yw ania żadnych informacji m iędzy kolejnym i je g o w yw ołaniam i. int UDPserverStart(uint!6_t port) { struct udp_pcb *pcb; err t err; IH0~|ECL_PH0TECT (x); —^ I R Q _ r e O T llć l( |( , Rys. 7.1. Format komunikatu u tiljte la y .c util_eth_nc.c util J e d .c u liljw ip .c util time, c Nagłów kowe ■> WERSJA [0:3] Pliki przykładu 7 Źródłowe i biblioteczne opis ,.2 i2 B Polecenie - odczytaj rejestr wejściowy i d r .Zawartość pola DANE jest nieistotna. Serwer-odpowiada komunikatem z operacją INPUT BITS READJNPUTJ3ITS Przykład 7 - prosty serwer UDP N azw y plików przykładu 7 zam ieszczone są w ta b e li 7.2. W iększość z nich opisa­ łem ju ż w poprzednich rozdziałach. Poniżej om aw iam tylko now e pliki. Pole OPERACJA Operacja 221 L W IP _IR Q _P R IO ); pcb = udp<_n(j/w{); 7. Serwer Uft 222 łdefine PDU ERROR łdefine INPUT_BITS łdefine OUTPUT_BITS IRQ_UNPROTECT(x); if (pcb == HÜLL) return -1; IRQ_PROTECT(x, LWIP_IRQ_PRIO) ; err = udp_bind(pcb, IP_ADDR_ANY, port); IRQJJNPROTECT(x); if (err != ERR_OK) { IRQ_PROTECT(x, LWXP_IRQ_PRIO); udp_remove(pcb); IRQ_ÜNPROTECT(x); return -1; ) ) Form at kom unikatu, przedstaw iony na rysunku 7.1, definiujem y ja k o strukturę I pdu t (ang. protocol data unit type), Pola kom unikatu W E R SJA i OPERACJA definiujem y ja k o w spólną składow ą v e r s io n _ o p e r a tio n . A lternatyw nie można je zdefiniow ać ja k o dostępne w języ k u C pola bitowe. Jednak pola bitow e nie są prze­ nośne - sposób ich realizacji zależy od konkretnej im plem entacji jęz y k a C. Dlatego;, należy ich unikać w definicjach struktur, których postać binarna je s t ustalona. PACK_STRUCT_BEGIN struct pdu_t { PACK_STRUCT_FIELD(u8_t version_operation); PACK_STRUCT_FIELD(u8~t port); PACK_STRUCT_FIELD{ul6_t pins); ) PACK_STRUCT_STRUCT; PACK__STRUCT_END : ■1 ■ * ‘ K om pilator nie m a obow iązku um ieszczania składow ych struktury w ciągłym ob­ szarze pam ięci. Z e w zględu na szybkość realizacji operacji na składow ych struk­ tury, kom pilator m oże zoptym alizow ać ich rozm ieszczenie w pam ięci, zostawiając m iędzy kolejnym i składow ym i puste, niew ykorzystane m iejsce. A by w yłączyć takie optym alizacje, w bibliotece IwIP zdefiniow ano m akra, których nazw a zaczyna się od przedrostka PACK. W iększość kom pilatorów pozw ala program iście decydow ać o rozm ieszczeniu składow ych struktury w pam ięci, ale nie je s t to ujęte w standardzie języ k a C. Poszczególne kom pilatory oferują w tym celu różne rozszerzenia. Poniżej przedstaw iam realizację m akr PACK dla GCC. Te definicje oraz definicje dla innych kom pilatorów znajdują się w pliku cc.h. PACK__STRUCT__BEGIN PACK_STRUCT_STRUCT _ a t t r i b u t e _ (( _ p a c k e d _ ) ) PACK_STRUCT_END PACK_STRUCT_FIELD(x) x N um er wersji protokołu oraz operacje i odpowiedzi protokołu definiujem y jako stale. PDU_VERSION * READ_INPUT_BITS READ_OUTPUT_BITS RESET_BITS SET_BITS WRITE BITS 1 1 '2 3 4 5 , 8 9 10 łdefine pdu_version(pdu) ((pdu)->version_operation >> 4) łdefine pdu_operation(pdu) ((pdu)->version_operation &0xf) łdefine pdu_port(pdu) ((pdu)->port) łdefine pdu_data(pdu) ntohs((pdu)->data) łdefine set_pdu_version_operation(pdu, v, c) \ ((pdu)->version_operation = ((v) << 4) i ((c) & 0xf)) łdefine set_pdu_port(pdu, x) ((pdu)->port = (x)) łdefine set_pdu_data(pdu, x) ((pdu)->data - htons(x)) return 0; łdefine łdefine łdefine łdefine łdefine łdefine 223 A by tekst źródłow y byl przejrzysty, definiujem y m akra odczytujące i zapisujące poszczególne pola w strukturze typu p d u _ t. A rgum ent pdu jest w skaźnikiem do struktury tego typu. Zauw ażm y, że dostęp do pola DATA je s t zrealizow any za po­ m ocą funkcji n to h s i h to n s . Jest to potrzebne, gdyż pole DATA jest w porządku sieciow ym . IRQ__PROTECT (x, LWIP_IRQ_PRIO); udp__recv (pcb, recv_callback, HULL); IRQ_ÜNPROTECT(x); łdefine łdefine łdefine łdefine 7.2. Przykład 7 - prosty serwer U DP I * Z asadniczą obsługę protokołu im plem entujem y w funkcji zw rotnej re c v c a llb a c k . N a początku za pom ocą funkcji p b u f _ a llo c przydzielam y bufor, w którym serw er um ieści sw oją odpow iedź. Poniew aż potrzebny je s t bufor o bardzo m ałym rozm ia­ rze, alokujem y go na stercie (param etr PBUF_RAM), a nie z puli buforów. Faktyczny rozm iar przydzielonego bufora będzie w iększy niż rozm iar struktury typu pdu t, w yspecyfikow any ja k o drugi argum ent funkcji p b u f a l l o c . N a początku bufora zostanie pozostaw ione m iejsce na w staw ienie nagłów ków protokołów w arstw y do­ stępu do sieci, sieciow ej i transportow ej (param etr PBUF_TRANSPORT). Jednak, dla ułatw ienia posługiw ania się buforem , składow a p a y lo a d w przydzielonej strukturze typu p b u f w skazuje na początek m iejsca w buforze, gdzie m ają być um ieszczone dane w arstw y transportow ej. void tecv_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, uint!6_t port) { struct pbuf *q; struct pdu_t *src, *dst; q = pbuf alloc (PBUF TRANSPORT, sizeof (struct pdu_t), PBUF__RAM); if (q =»~NULL) { pbuf_free(p); return; ) sre = p->payload; dst * q->payload; if (p->len < sizeof(struct pdu_t) II pdu_version(sre) != PDU_VERSION II pdu_port(sre) < 1 II pdu_port(sre) > gpioCount) { set_pdu version_operation(dst, PDU_VERSION, PDU_ERR0R); set_pdu_port(dst, 0); set_pdu data(dst, 0); I else { GPIO_TypeDef *io * gpio|pdu_port(src) - 1}; ^^tchi(^du_operation (sre)) ( case JiE^)_IKPUT_BITS: 224 7.2. Przykład 7 - prosty serwer UDP 7. Serwer (Jl)p set_pdu_version_operation (dst, PDU__VERSION, set_pdu_port(dst, pdu_port(src))/ set_pdu_data(dst, GPIO_ReadInputData(io)); break; case READ__OUTPUT__BITS: set_pdu_version_operation(dst, PDU__VERSION, set_pdu_port(dst, pdu_port(src)); set_pdu_data(dst, GPIO_ReadOutputData(io)); break; case RESET_BITS: GPIOJlesetBits (io, pdu_data (src)); set_pdu__version operation (dst, PDIM/ERSION, set_pdu__port (dst, pdu_port (src)); set_pdu_data(dst, GPIO_ReadOutputData(io)); break; case SET_BITS: GPIO_SetBits(io, pdu_data(src)); setj?du__versionjDperation (dst, PDU_VERSION, set_pdu__port (dst, pdu_port(src)); set_pdu_data(dst, GPIO_ReadOutputData(io)); break; case WRITE_BITS: GPIO_Write(io, pdu_data(src)); set_pdu_version_operation(dst, PDUJflSRSION, set_pdu_port(dst, pdu_port(src)); set_pdu_data(dst, GPIO_ReadOutputData(io)); break; default: set_pdu_version_operation(dst, PDU_VERSION, set_pdu_port(dst, 0); set_pdu_data(dst, 0); INPUT_BITS) ; 225 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_12 | GPI0_Pin_13; GPIO_InitStruct,GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO__Init (GPIOC, SGPIO_InitStruct) ; ) OUTPUT_BITS); W funkcji main inicjujem y poszczególne potrzebne w tym przykładzie układy m i­ krokontrolera, m oduły biblioteki IwlP, a następnie konfigurujem y ustaw ienia sie­ ciow e, podobnie jak w poprzednich przykładach. Na końcu za pom ocą funkcji UDPserverStart urucham iam y serw er U D P na porcie 33333, a za pom ocą funkcji PORTCconf igure konfigurujem y port C. OUTPUT_BITS) ; int m a i n {) ( static struct netif netif; static struct ethnetif ethnetif = (PHY_ADDRESS); uint8_t confBit; OUTPUT_BITS); Delay(1000000); confBit “ GetConfBit(); AllPinsDisable(); LEDconfigure {); RedLEDon{); SET_IRQ_PROTECTION(); OUTPUT_BXTS); error_resetable(CLKconfigure(), 1); error_permanent(LocalTimeConfigure{), 2); error_resetable (ETHconf igureMII (), 4); PDU_ERROR); netif.hwaddr(0] = 2 ; ? netif.hwaddrflj = (BOARDJFYPE » 8) S 0xff; netif.hwaddr[2] = BOARDJFYPE fi 0xff; netif.hwaddr[3) = (ETHJ30ARD » 8) & 0xff; netif,hwaddr[4) = ETHJ30ARD & 0xff; netif.hwaddr|5) = 1 + confBit; if (¡confBit) { IP4_ADDR(finetif.ip__addr, 192, 168, 51, 84); IP4_ADDR i&netif.netmask, 255, 255, 255, 240); IP4_ADDR(&netif.gw, 192, 168, 51, 81); ! 1 pbuf_free(p); udp_sendto(pcb, q, addr, port); pbuf_free(q); ) Jeśli bufor zostanie przydzielony, to d alsza część funkcji recv__callback je st dość typow a. N ajpierw spraw dzam y popraw ność odebranego kom unikatu. Jeśli komuni­ kat je s t popraw ny, to w ykonujem y zaw arte w nim polecenie i odsyłam y odpowiedź. N a koniec trzeba też zw olnić przydzielone bufory. S else { IP4_ADDR(inetif.ip_addr, IP4__ADDR(Łnetif.netmask, IP4_ADDR (Snetif .gw, 0, 0, 0, 0, 0, 0, 0, 0); 0, 0); 0, 0); ) 7.2.2. error_resetable(LWIPinterfacelnit(Snetif, Sethnetif), 5); LWIPtimersStart(); error_resetabie(DHCPwait(Snetif, 10, 4), 6); error resetabłe(UDPserverStart(33333), 7); Plik ex_udpd.c Plik ex_udpd.c zaw iera funkcję main przykładu. Z aw iera też funkcję PORTCconf igure, która konfiguruje niektóre w yprow adzenia portu C ja k o w ejścia, żebyśm y mieli co testow ać. W zestaw ie Z L 29A R M d o w yprow adzeń P C 5 ...P C 9 je st podłączony dżojstik (m g . jo ystick), do w yprow adzenia P C I 2 - przycisk SW 3, a do w yprowa­ dzenia PC 13 - przycisk SW 4. Jako w yjść użyjem y diod św iecących podłączonych w zestaw ie Z L29A R M do w yprow adzeń PE 14 i PE15. static void PORTCconf icjure (void) { t GPIO_InitTypeDef GPIO_InitStruct; * RCC_APB2EeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_StructInit(SGPIO_InitStruct); GPIO InitStruct.GPIO Pin = GPIO Pin 5 I GPIO Pin 6 I GPIO Pin 7 I RedLEDoff{); PORTCconfigure(); for {;;}; } 7.2.3. ' .w' Testowanie przykładu D o przetestow ania przykładu w ykorzystam y program netcat. K om unikat do serwera można wysłać za pom ocą poleceń z tabeli 7.3. W dalszym ciągu zakładam, że ser­ w er ijjfcywa adresu 192.168.51.89. N ajpierw rozw ażm y polecenie dla system u Linux. Za pćim odppjolecenia echo m ożna wysiać napis na standardow e wyjście. Parametry -ne powoduj'4, że po w ysianiu tego napisu nie jest w ysyłany znak końca wiersza, 7. Serwer U D p ~ ' Tab. 7.3. Uruchamianie klienta echo -ne i nc -u -wł 192,168.51.89 33333 I hexdump -C "nc" -u -wl 192.168.51.09 33333 < infile > outfile ____ Tab. 7.4. Przykładowe testy w zestawie ZL29ARM Poleconie Odpowiedź Wciśnięty przycisk SW 3 ii 03 00 00 19 03 23 eO Wciśnięty przycisk SW4 ii 03 00 00 19 03 13 e8 Oba przyciski wciśnięte ii 03 00 00 19 03 03 e8 Sprawdzenie stanu diod 12 05 00 00 la 05 cO 00 Włączenie zielonej diody 13 05 40 00 la 05 80 00 Włączenie czerwonej diody 13 05 80 00 la 05 00 00 Wyłączenie zielonej diody 14 05 40 00 la 05 40 00 Wyłączenie czerwonej diody 14 05 80 00 la 05 cO 00 Włączenie obu diod 15 05 00 00 la 05 00 00 Błędne polecenie 20 00 00 00 18 00 00 00 Test a znak lew ego ukośnika (ang, backslash) je st traktow any jak o znak rozpoczynający sekw encję specjalną, co um ożliw ia w ysyłanie napisów, które zaw ierają dane binarne. A by wysiać znak (bajt) o w artości szesnastkow ej hh, należy w pisać \xhh. Dane do. w ysiania umieszczam y w cudzysłow ach. W yjście polecenia echo przekierowujemy na w ejście program u netcat (polecenie nc). Param etr -u oznacza w ysyłanie danych za pom ocą UDP. Param etr -w l nakazuje program ow i neicat czekać m aksym alnie jedną sekundę na odpow iedź. K olejnym i argum entam i polecenia nc są adres IP i num er por­ tu serwera. Program netcat po odebraniu odpow iedzi od serw era w ypisuje ją na stan­ dardow ym wyjściu, które przekierow ujem y na w ejście polecenia hexdump. Program hexdum p um ożliw ia w ypisyw anie danych w różnych formatach. Param etr -C ozna­ cza w yświetlanie szesnastkow o każdego bajta oddzielnie. Polecenie echo w syste­ m ie W indow s nie jest tak elastyczne ja k w Linuksie. N ajprostszym rozw iązaniem jest przygotow anie polecenia, które chcem y w ysiać, w pliku i n f i l e za pom ocą edytora binarnego. Zawartość pliku i n f i l e w ysyłam y na w ejście polecenia nc, a odpowiedz zapisujem y w pliku o u t f i l e . D obrym pom ysłem je st przygotow anie sobie całego ze­ stawu plików z poszczególnym i potrzebnym i poleceniami. W następującym przykładzie odczytujem y stan w ejść.portu C w zestaw ie ZL29ARM . czyli w ysyłam y kom unikat zapisany szesnastko\yo. U 030000. 5 echo -ne "\xll\x03\x00\x00" | nc -u -wl 192.168.51.89 33333 | hexdump -C 00000000 19 03 33 eO 00000004 O trzym aliśm y odpow iedź 190333e0, co oznacza, że wejścia PC 13, PC 12, PC9, PC8, PC7, PC6 i PC5 są w stanie w ysokim , a pozostałe w stanie niskim , czyli oba przy­ ciski i dżojstik nie są- wciśnięte. K olejne przykłady zam ieszczone są w tabeli 7.4. Zauważm y, że w niektórych odpow iedziach W ejście PC3 m a poziom wysoki. D o wej­ ścia tego je st podłączony sygnał zegara M 1I_TX_CLK z m odułu ethernetow ego, dla­ tego m ożem y się spodziew ać odczytu dość przypadkow ych wartości na tym wejściu. Klient UDP 8.2. SNTP 229 T em atem tego rozdziału są klienty protokołów D NS i SNTP. O ba używ ają protoko'^ łu transportow ego UDP. Przykładem ich użycia będzie program , który komunikuje'’ się z internetow ym serw erem czasu i synchronizuje zegar czasu rzeczyw istego rfuijt krokontrolera. nikiern do struktury zaw ierającej przetłum aczony adres IP lub m a wartość NULL, gdy w ystąpił błąd, np. nazw a nie m oże być przetłum aczona lub nie istnieje. Trzeci argum ent a rg je st w skaźnikiem przekazanym jak o czw arty argum ent w yw ołania funkcji d n s_g ethostbynam e. Funkcja zw rotna je st typu v o id , czyli nie zw raca żad­ nej w artości. DNS O pis konfigurow ania adresów serw erów D N S znajduje się rozdziale 3.2.2. A dresam i serw erów DNS m ożna też zarządzać za pom ocą dw óch poniższych funkcji. D NS (ang. D om ain Narne System ), czyli system nazw dom enow ych, je s t je d ri|l z podstaw ow ych usług w intersieciach. Z apew nia tłum aczenie nazw domenowych? w ęzłów sieci, znanych użytkow nikom sieci, czyli nazw takich ja k www.niema.pl :nat, adresy IP. U m ożliw ia też tłum aczenie odw rotne, czyli spraw dzenie, ja k a nazw a do'y nienow a odpow iada danem u adresow i IP. D NS składa się z protokołu kom unikacyj-' nego i hierarchicznego system u serw erów . D NS używ a protokołu transportowego? UDP, choć serw ery m iędzy sobą m ogą kom unikow ać się rów nież za pom ocą TCP.!; Serw er nasłuchuje na porcie 53. Z asadnicze elem enty D N S są opisane w dokumem ; tach RFC 1034 i RFC 1035, które razem tw orzą standard intersieci ST D 13. void dns_setserver(u8_t numdns, struct ip_addr *dnsserver); Funkcja d n s _ s e ts e r v e r ustaw ia adres serw era D N S. Pierw szy argum ent numdns je s t indeksem w w ew nętrznej tablicy m odułu D NS przechow ującej adresy serw erów i m usi być m niejszy niż stała DNS_MAX_SERVERS zdefiniow ana w pliku Iwipopts.h. Drugi argum ent d n s s e r v e r je s t w skaźnikiem do struktury zaw ierającej adres IP ser­ w era DNS. W bibliotece lw lP zaim plem entow ano prostego klienta D NS - pliki clns.h i dns.c,' K onfiguruje się go w pliku Iw ipopts.h, co opisałem w rozdziale 3.2.2. D o obsługi , klienta protokołu D NS biblioteka lw lP dostarcza kilku funkcji. errj: dns__gethostbyname (const char *name, struct ip_addr *addr, dns_found_callback found, void *arg); » struct ip_addr dns_getserver(u8_t numdns); Funkcja d n s _ g e ts e r v e r zw raca adres IP serw era D NS o indeksie numdns. Jeśli in­ deks m a niepopraw ną w artość lub pod tym indeksem nie został skonfigurow any żaden serw er, to zw raca adres składający się z sam ych zer. 8.2. SN TP (ang. Sim ple N etw ork Time Protocol) to protokół um ożliw iający synchroni­ zację zegarów w intersieciach, je st opisany w R FC 4330. SN TP jest uproszczoną w ersją N TP (ang. N etw ork Time P rotocol), ale zupełnie w ystarcza do precyzyjnej synchronizacji zegara czasu rzeczyw istego w dow olnym urządzeniu, które ma d o ­ stęp do Internetu. SN TP używ a protokołu transportow ego UDP. Serw ery czasu na­ słuchują na porcie 123. SN TP jest protokołem bezstanow ym . K lient w ysyła do ser­ w era żądanie (ang. request) podania aktualnego czasu, a serw er odsyła odpow iedź (ang. reply) z czasem . SN TP je st kom patybilny z N T P w tym sensie, że serw ery N T P odpow iadają na żądania SNTP. Funkcja d n s_ g eth o stb y n am e odw zorow uje nazw ę dom enow ą na adres IP. Pierw-,/> jej argum ent name je s t w skaźnikiem d o napisu zaw ierającego nazw ę, która ma być. przetłum aczona. D rugi argum ent a d d r je st w skaźnikiem do struktury, w której m a ‘; być um ieszczony przetłum aczony adres IP, jeśli został on ju ż pozyskany wcześniej przez klienta D NS i znajduje się w je g o lokalnej pam ięci. W tym przypadku funk-, cja zw raca w artość ERR_0K. L iczbę pam iętanych lokalnie odw zorow ań określa stała DNS_TABLE_SIZE zdefiniow ana w pliku Iw ipopts.h. Jeśli adres IP nie je s t jeszcze /n.iny, to funkcja w ysyła prośbę do serw era D NS i kończy działanie, zw racając wartość . ERR_INPROGRESS. W tym przypadku aplikacja zostanie pow iadom iona o odebraniu,, odpow iedzi od serw era za pom ocą funkcji zw rotnej^której adres found je s t trzecim, argum entem . C zw arty argum ent a rg je s t wskaź.nijdem, który zostanie przekazany funkcji zw rotnej, co um ożliw ia obsługę w szystkich odw zorow ań za pom ocą wspók, nej funkcji zw rotnej. W przypadku w ystąpienia problem u funkcja m oże też zwrócić inny kod błędu typu e r r _ t , zgodnie z konw encją stosow aną w bibliotece lwlP. typedef void (* dns_found_callback)(const char *name, struct ip_addr *addr, 1 void *arg); ^ I Jeśli klient D NS odbierze o d pow iedź od serw era, to biblioteka lw lP wywołuje funkcję zw rotną typu d n s_ fo u n d _ c a llb a c k . Pierw szy jej argum ent name wskazuje nazw ę w ęzła, którego adres IP chcem y poznać. D rugi jej argum ent ad d r je st wskaź- SNTP ‘"I C zas w N T P i SN TP je st reprezentow any za pom ocą 64-bitow ego znacznika cza­ su (ang. tim estam p). Z nacznik czasu je s t zapisyw any w sieciow ym porządku okte­ tów i zaw iera liczbę sekund, które upłynęły od dnia 1 stycznia 1900 roku czasu uniw ersalnego (U TC, ang. U niversal Time Clock). Początkow e 32 bity znacznika zaw ierają część całkow itą, a kolejne 32 bity to część ułam kow a. Taki form at za­ pisu czasu zapew nia rozdzielczość około 233 pikosekundy. Jeśli taka precyzja nie je st potrzebna, to nieużyw ane, najm niej znaczące bity znacznika czasu w ypełnia się zeram i. Z nacznik czasu rów ny zeru oznacza niepraw idłow y lub nieosiągalny czas. Z nacznik czasu przepełnia się co 232 sekund, czyli co około 136 lat, lecz nie pow inno to pow odow ać w iększych problem ów , gdyż je st to na tyle długi okres, że mozrni z ś ^ j e g o źródła łatw o określić, którego 136-lelniego okresu czasu dotyczy dany znacznik. D robnym problem em je s t w ystępow anie raz na 136 lat niereprezen- 8.2. SNTP tow alnego okresu o długości 233 pikosekund, gdy znacznik czasu musiałby , w artość zero. Ż ądanie i odpow iedź m ają w spólny form at, taki sam ja k w NTP. Jest on staw iony na ry s u n k u 8.1. W szystkie liczby w ielooktetow e zapisuje się w ku sieciow ym . D w ubitow e pole LI zaw iera ostrzeżenie o sekundach przestępn (ang. leap im licator). W artość 0 oznacza brak ostrzeżenia. W artości 1 i 2 oznaczają że ostatnia m inuta bieżącego d nia będzie m iała odpow iednio 61 lub 59 sekund! W artość 3 oznacza, że zegar serw era nie został jeszcze zsynchronizow any. To pjest istotne tylko w kom unikatach zaw ierających odpow iedź od serw era. Klient'.w sze w staw ia w nim w artość 0. T rzybitow e pole V N zaw iera num er wersji pr0; tokołu. O pisyw ana tu w ersja m a num er 4. T rzybitow e pole M ode zaw iera rod/ operacji. Klient, w ysyłając żądanie, ustaw ia w artość 3, a serw er w odpow iedzi usta*» wia w artość 4. S erw er pracujący w trybie rozgloszeniow ym , w ysyłający cyklicznie" w ustalonych odstępach czasu inform ację o aktualnym czasie, um ieszcza w tvn> polu w artość 5. Inne m ożliw e w artości tego p ola opisane są szczegółow o w doku-', m encie R FC 4330. II [0:1] VN [2:4] Mode [5:7] Stratum [8:15] Root Delay [32 bity] Root Dispersion [32 bity] Reference Indentifier [32 bity] Reference Timestamp [64 bity] Originate Timestamp [64 bity] Receive Timestamp [64 bity] Transmit Timestamp [64 bity] Key Identifier (opcjonalne) [32 bity] Message Digest (opcjonalne) [1284>itów] Rys. 8.1. Format komunikatu NTP Poll [16:23] Precision [24:311 231 Pole Stratum inform uje o położeniu (num erze warstwy) serwera w hierarchii synchro­ nizacji. Klient zaw sze ustawia w nim wartość 0. Jest ono istotne tylko w odpowiedzi udzielonej przez serwer. Wartość 0 w tym polu oznacza kom unikat „kiss-o’-death”, który informuje, że serw er nie chce udzielić odpow iedzi, gdyż np. jest przeciążony. Klient, otrzym aw szy taki kom unikat, pow inien przestać wysyłać żądania do tego ser­ wera i zw rócić się do innego serwera. Jeśli żaden alternatywny serw er nie jest dostęp­ ny, to klient może ponaw iać żądanie do tego serwera, zwiększając wykładniczo od­ stęp czasu między kolejnymi żądaniami, jeśli serw er nadal nie odpowiada. Wartość 1 w polu Stratum w ysyłają serwery pierwotne (pierwszej warstwy), najczęściej synchro­ nizow ane własnym zegarem atom owym . Wartości od 2 do 15 wysyłają serwery w tór­ ne, synchronizow ane za pom ocą N TP do serwerów, które należą do warstwy o jeden mniejszej. Wartości od 16 do 255 są zarezerw ow ane do przyszłego wykorzystania. Pole Poll zaw iera inform ację o m aksym alnym interw ale m iędzy kolejnym i kom uni­ katam i serw era, gdy działa on w trybie okresow ego rozgłaszania. Pole Precision za­ w iera inform ację o dokładności zegara, którego używ a serwer. C zasy te określa się ja k o 2X sekund, gdzie x jest w artością um ieszczoną w danym polu, interpretow aną ja k o ośm iobitow a liczba ze znakiem w kodzie uzupełnieniow ym do dw ójki. K lient zaw sze zeruje w szystkie bity w tych polach i m oże ignorow ać w artości otrzym ane od serw era, jeśli ich nie potrzebuje. Pole R oot D elay zaw iera różnicę czasu w sekundach m iędzy tym serw erem a ser­ w erem pierw otnym , z którym się on synchronizuje, w ynikającą m .in. z opóźnień przesyłania kom unikatów w sieci. W artość w tym polu interpretuje się ja k o liczbę ułam kow ą slalopozycyjną ze znakiem w kodzie uzupełnieniow ym do dw ójki, gdzie przecinek je s t postaw iony m iędzy 15. a 16. bitem . W artość w tym polu m oże być ujem na. Pole to je s t istotne tylko w kom unikatach w ysyłanych przez serwer. K lient ustaw ia w nim zaw sze zero. Pole R oot D ispersion zaw iera m aksym alny błąd czasu w sekundach, w ynikający z tolerancji częstotliw ości zastosow anego w serw erze zegara. W artość w tym polu interpretuje się ja k o liczbę ułam kow ą bez znaku, gdzie przecinek je s t postaw iony m iędzy 15. a 16. bitem . Pole to je s t istotne tylko w kom unikatach w ysyłanych przez serwer. K lient ustaw ia w nim zaw sze zero. W polu R eference Identifier serw er pierw otny um ieszcza sw ój identyfikator, zaw ie­ rający m aksym alnie cztery znaki A SC II i dopełniony zerow ym i oktetam i. Serw ery w arstw 2. do 15. um ieszczają w tym polu adres IP serw era, do którego się synchro­ nizują. Pole to je s t istotne tylko w kom unikatach w ysyłanych przez serwer. Klient ustaw ia w nim zaw sze zero. K olejne cztery pola zaw ierają znaczniki czasu. R eference T im estam p inform uje, kiedy zegar serw era byl po raz ostatni synchronizow any. K lient um ieszcza w tym polu zero. W polu O riginate T im estam p klient um ieszcza zero, a serw er kopiuje do niego zaw artość pola T ransm it T im estam p z żądania klienta. W polu R eceive Tim estam p klient um ieszcza zero, a serw er um ieszcza w nim czas odebrania żąda­ nia od klienta w edług sw ojego zegara. W polu T ransm it T im estam p klient i serw er um ieszczają czas w ysiania kom unikatu, posługując się sw oim lokalnym zegarem . WaiTOŚci tt f pozw alają oszacow ać czas podróży kom unikatów , co um ożliw ia do­ kładniejszą Synchronizację. O znaczm y O riginate T im estam p, R eceive T im estam p 232 8.3. Przykład 8 - automatyczna synchronizacja zegara czasu rzeczywistego & Klient U pp - ► T ab . 8 .1 . C zas klienta 233 Pliki przykładu 8 Źródłowe i biblioteczne Żądanie \ / O dpow iedź - ► R ys. C zas serw era font5x8.h sntp_client.h board_cont.li board_del.lt board_dels.h board_init.il board_lcd.li b o a rd je d .h Przykład 8 - automatyczna synchronizacja zegara czasu rzeczywistego ■ N azw y plików przykładu 8 zam ieszczone są w ta b e li 8.1. W iększość z nich opis; lem ju ż w poprzednich rozdziałach. Poniżej opisuję tylko now e pliki. Pliki sntp_clienł.h i sntpjclient.c Pliki sntp_client.h i sn tp jc lie n t.c zaw ierają im plem entację klienta protokołu SN'I P Z aczynam y od zdefiniow ania stałych i struktur tego protokołu. Pow inniśm y zdf niow ać stałą NTP_P0RT reprezentującą num er portu, na którym nasłuchują serwery W N T P czas odm ierza się w sekundach od 1 stycznia 1900 roku, a nasz zegar czast rzeczyw istego liczy sekundy od 1 stycznia 1970-ruku. Do przeliczania deiiniujem j stalą NTP_T0_UNIX, której w artością je s t liczba sekund m iędzy tym i datam i. łdefine N T P J O R T łdefine NTP_TOJJNIX Iiblwip4.a Iibstm 32tl0x.a ■. util_delay.h util_error.h utit_eth.h u tiljc d .h u tiijc d _ e x .il u tfje d .h u tiljw ip .h util_rtc.li util tinie.h cc.h cortex-m3.h lwipopts.li stm32t10x_cont.h dziale, czyli nieprzenośności pól bitow ych języ k a C, trzy pierw sze pola kom unikatu definiujem y ja k o w spólną ośm iobitow ą składow ą LI_VN_Mode. PACK_STRUCT_BEGIN struct ntpjnsg { PACK_STRUCT__FIELD(uint;'8_t LI_VN Mode); PACK_STRUCT_FIELD(uint8_t Stratum); PACK_STRUCT_FIELD(uint8_t Poll); PACK_STRUCT_FIELD(int8_t Precision); PACK_STRUCT_FIELD(uint32_t RoofcDeiayi; PACK_STRUCT_FIELD(uint32_t RootDispersion); PACK_STRUCT_FIELD(uint8_t Referenceldentifier[4}); PACK_STRUCT_FIELD(struct ntp_timestamp ReferenceTimestamp); PACK_STRUCT_FIELD(struct ntp_timestamp OriginateTimestamp); PACK_STRUCT_FIELD(struct ntp_timestamp ReceiveTimestamp); PACK_STRUCT_FIELD(struct ntp_timestamp TransmitTimestamp); l PACK_STRUCT_STRUCT; PACK_STRUCT_END W artości, które pojaw iają się w polach w ysyłanych i odbieranych kom unikatów , też trzeba zdefiniow ać jak o stałe. łdefine idefine łdefine łdefine łdefine łdefine łdefine 123 2208988800U Z nacznik czasu reprezentujem y ja k o strukturę typu n tp _ tim esta m p . PACK_STRUCT_BEGIN struct ntp_timestamp ( PACK_STRUCT_FIELD(uint32_t Secondsl; PACK STRUCTJ?IELD(uint32_Ł SecondsFraction/; util_delay.c u til_ e llijic .c u iiijc d .c u tiljc d _ e x .c u til Je d .c u tiljw ip .c u tiijtc .c u tiljim e .c Natjlówk owe Pola K ey Identifier i M essage D igest są opcjonalne i nie są używ ane w uproś/ ,r czonej w ersji protokołu, czyli w SNTP. Podsum ow ując, w najprostszym przypadki 1 klient w prośbie ustaw ia w polu V N w artość 4, w polu M ode w artość 3, a w po/o stałych polach w artość 0. M oże też ustaw ić sw ój czas w polu T ransm it Timestamp W odpow iedzi uzyskanej od serw era klient spraw dza popraw ność pól LI, VN M ode i Stratum . D o korekty sw ojego czasu korzysta z w artości w polu Transmi T im estam p, ew entualnie też z czasów O riginate T im estam p i R eceive Timestamp a zaw artość pozostałych pól ignoruje. K lient pow inien też spraw dzać, czy otrzyma-! ne znaczniki czasow e-są praw idłow e, czyli niezerow e. 8.3.1. board_con!.c boardJ n it.c boardJ c d J s 0 108. c boardJe d .c 8.2. Wymiana komunikatów NTP między klientem a serwerem i T ransm it T im estam p z odebranej od serw era odpow iedzi odpow iednio przez 'I I T2 i T 3. Przez T4 oznaczm y czas odebrania odpow iedzi przez klienta w edług jego lokalnego zegara, patrz ry s u n e k 8.2. W tedy łączny czas podróży komunikatów w obie strony szacuje się ja k o T 4 - T l - T3 + T2, a korektę czasu klienta, czyli różnicę m iędzy czasem serw era a klienta, ja k o (T2 + T3 - T l - T 4) / 2. 8.3. ex_sntp.c iont5x8.c sntp_ciient.c startupjtm 3 2 _ c ld . c .■ „ i PACiTsTRUCTJBTRUCT; . , PACK_STRUCT__END O bow iązkow ą część kom unikatu NTP, zam ieszczoną na rysunku 8.1, reprezenti my ja k o strukturę typu n tp jn s g . Z tych sam ych pow odów co w poprzednim r<>/- NTP_LI_NO_WARNING NTP_LI_ĄLARM_CONDITION NTP_VERSI0N NTP_MODE_CLIENT NTP_HODE_SERVER NTP_STRATUM_KISS_OF_DEATH NTP STRATUM MAX 0 3 4 3 4 0 15 Pola LI, V N, M ode kom unikatu zdefiniow aliśm y jak o składow ą LI_VN_Mode struk­ tury typu n tp jn s g . Do obsługi tych pól służą poniższe makra. M akro n tp _ le a p _ in d i c a t o r daje w artość pola LI. M akro n tp _ v e r s io n daje w artość pola VN. M akro ntp_raode daje w artość pola M ode. A rgum entem tych m akr jest w skaźnik pdu do struktury typu n tp jn s g . M akro n tp _ co m p o se_ li_ v n jn o d e pom aga w ypełnić sklad o w if Li Mm Mode tej struktury. A rgum entam i są odpow iednio w artości pól LI, VN i M ode. . i,li' 8. Klient UDp 234 fdefine Sdefine idefine fdefine ({(li) ntp_leap_indicator(pdu) ((uint8_t)((pdu)->LI_VN_Mode >> 6)) ntp_version(pdu) {(uint8_t){((pdu)~>LI_VN_Mode » 3) & 0x7)) ntp_mode (pdu) ((uint8_t)((pdu)->LI_VN_Mode & 0x7)) ntp_compose_li_vn_mode(li, vn, mode) \ « 6} | ({(vn) « 3) & 0x38) | {(mode) & 0x7}) K lienta urucham ia się za pom ocą funkcji S N T P c lie n tS ta rt. Jej pierw szy argument serverN am e je st nazw ą serw era, do k tórego m a być w ysiane żądanie SNTP. Funkcja ta je s t przeznaczona do w yw ołania z program u głów nego i tylko inicjuje klienta, który następnie działa w przerw aniu biblioteki lwIP, czyli w tle w stosunku do pro­ gram u głów nego. D latego funkcja S N T P c lie n tS ta rt nie zw raca żadnej wartości, a drugi jej argum ent s t a t u s je s t w skaźnikiem do zm iennej typu i n t , w której klient um ieszcza status, czyli inform ację o w yniku sw ojego działania. W artości, które m oże przyjm ow ać status, są opisane w ta b e li 8.2. O dpow iednie stale definiujemy za pom ocą dyrektyw i d e f i n e w pliku sntp_client.h. W yw ołania funkcji bibliote­ ki lw IP w ew nątrz funkcji S N T P c lie n tS ta rt są otoczone m akram i wykluczającym i w spółbieżne w ykonyw anie kodu tej biblioteki. void SNTPclientStart(const char ‘serverName, int ‘status) { struct ip_addr serverIP; err_t err; IRQ_DECL_PROTECT(x) ; IRQ__PROTECT {x , LWIP_IRQ_PRIO); err = dns_gethostbyname(serverName, SserverlP, SNTPrequest, (void*)status); IRQJJNPROTECT(x); ¡, if (err == ERR_OK) { IRQ_PROTECT(x, LWIP_IRQ_PRIO) ; SNTPrequest(serverName, &serverIP, (void*)status); IRQJJNPROTECT(x) ; ‘ status = SNTP_IN_PROGRESS; ) else if (err =* ERR_INPROGRESS) ‘ status = SNTP_IN_PROGRESS; else ‘status = SNTP DNS ERROR; T ab . 8 .2 . Status klienta SNTP Slata SNTP NOT RUNNING W artość ' " U p ls 2 Klient nie został jeszcze uruchbrtllóny SNTP_SYNC!1R0NIZED 1 Klient uzyskał czas od serwera, zsynchronizował zegar czasu rzeczywi­ stego i zakończył działanie SNTP IN PROGRESS 0 Klient wysłał żądanie do serwera DNS lub SNTP i oczekuje na odpowiedź 8.3. Przykład 8 - automatyczna synchronizacja zegara czasu rzeczywistego 235 Funkcja S N T P c lie n tS ta rt zaczyna od przetłum aczenia nazw y serw era na adres IP. Jeśli funkcja d ns_gethostbynam e zw róci w artość ERR_0K, to struktura s e r v e r I P za­ w iera adres IP i w yw ołana je s t funkcja SN TPrequest, której zadaniem je s t w ysianie żądania SNTP. Jeśli funkcja d n s_ g eth o stb y n am e zw róci w artość ERR_INPROGRESS, co oznacza, że żądanie D NS zostało w ysłane, to po otrzym aniu odpow iedzi zosta­ nie w yw ołana funkcja SN TPrequest, której adres je st trzecim argum entem w yw o­ łania funkcji dns__gethostbynarae. C zw arty argum ent s t a t u s funkcji d n s_ g e th o stbynam e je s t w skaźnikiem , który m a być przekazany ja k o trzeci argum ent funkcji SN TPrequest. Przed zakończeniem funkcja S N T P c lie n tS ta rt ustaw ia status klienta w zm iennej w skazyw anej przez w skaźnik s t a t u s . O pisyw ana im plem entacja um ożliw ia urucham ianie w iele (sic!) klientów rów nocześ­ nie. D la każdego klienta alokujem y strukturę typu s n tp c l i e n t . Struktury klientów tw orzą listę. N a pierw szy elem ent listy w skazuje zm ienna globalna f i r s t C l i e n t . Składow a n e x t w skazuje na następny elem ent na liście. Składow a pcb jest w skaźni­ kiem do deskryptora UDP, używ anego do w ysłania żądania i odebrania odpow iedzi. Składow a tim e r je s t licznikiem odm ierzającym czas, przez który klient będzie je s z ­ cze czekał na odpow iedź serw era. G dy w artość tej składow ej zm niejszy się do zera, klient zakończy działanie, a je g o dane zostaną usunięte z pam ięci. Składow a s t a t u s w skazuje na zm ienną, w której m a być um ieszczony status klienta. struct sntp_client { struct sntp__client ‘next; struct udp_pcb *pcb; int timer; int ‘status; }; static struct sntp_client ‘firstClient = NULL; Po otrzym aniu odpow iedzi od serw era D NS w celu w ysiania żądania do serw era S N T P w yw ołujem y funkcję SN TPrequest. Jej pierw szy argum ent w skazuje nazw ę serw era SN T P i nie jest używ any. A rgum ent ten je s t potrzebny, gdyż adres tej funk­ cji je st przekazyw any do funkcji dns_ g eth o stb y n am e jak o adres funkcji zw rotnej, co w ym aga zgodności sygnatur funkcji. D rugi argum ent s e r v e r I P je s t w skaźnikiem do struktury zaw ierającej adres IP serw era. Jeśli w skaźnik ten ma w artość NULL, to w ystąpił ja k iś błąd podczas kom unikacji z serw erem D N S. Przyczyną m oże być p odanie błędnej nazw y serw era SN TP lub aw aria sieci. Trzeci argum ent s t a t u s je s t w skaźnikiem do zm iennej, w której klient m a um ieścić sw ój status. static void SNTPrequest(const char ‘serverName, struct ip_addr ‘serverIP, void*‘status) { struct sntp__client ‘client; if (NULL ” serverIP) { * (int*)status = SNTP_DNS_ERROR; return; SNTP_DNS_ERROR -1 Klient zakończył działanie, gdyż nie udało się przetłumaczyć nazwy ser­ wera na adres IP SNTP MEMORY ERROR -2 Klient zakończył działanie z powodu błędu alokacji pamięci SNTP UDP ERROR - '3 Klient zakończył dzialańie, gdyż nie udało się wysłać żądania do serwera SNTP_NO_RESPONSE -4 ' Serwer SNTP nie odpowiedział w przewidzianym czasie ł klient zakończył działanie client = mem_malloc(sizeof(struct sntp_client)); if (client == NULL) f * (int*)status - SNTPJ4EMORY_ERROR; return; SNTP_RESPONSE_ERROR -5 Serwer SNTP odpowiedział, ale odpowiedź jest błędna i nie można na jej podstawie zsynchronizować zegara. Klient zakończył działanie ciient->pctffi“ NULL; ) ) Ulr ¡ j |j 8.3. Przykład 8 - automatyczna synchronizacja zegara czasu rzeczywistego client->timer = SNTPJfIMEOUT; client->status = (in Ł * )s ta t u s i client->next * firstClient; firstClient = client; if (NULL != (client->pcb = udp_new()) &£ ERR OK == udp__bind (client->pcb, IP_ADDR_ANY, 0} £fi ERR_OK == udp_connect(client->pcb, serverIP, NTP^PORT)) struct pbuf *p; 1 p = pbuf alloc(PBUFJTRANSPORT, sizeof{struct ntpjnsg), PBUF_RAM); if tp) r struct ntpjnsg *msg = p->payload; memset(msg, 0, sizeof(struct ntpjnsg)); m s g - > U _VN_Mode = ntp_compose_li vn inode(NTP_U_NO_WARNING, NTP_VERSION, NTP_MODE__CLIENT); udp_recv(client->pcb, SNTPrepiy, client); if (ERR_OK != udp send(client->pcb, p>) { * (intMstatus =“SNTP_UDP_ERR0R; client->timer = 0; 237 Po otrzym aniu odpow iedzi od serw era SN TP biblioteka w yw ołuje funkcję zw rot­ ną SNTPrepiy. Pierw szym argum entem tej funkcji je s t w skaźnik do struktury typu sntp_client. Drugi argum ent pcb je st deskryptorem UDP. Trzeci argum ent p jest w skaźnikiem do bufora, który zaw iera odpow iedź serw era. C zw arty argum ent s e ­ rverIP je s t w skaźnikiem do struktury zaw ierającej adres IP serw era. Piąty argu­ m ent serverPort je s t num erem portu, którego serw er użył do w ysłania odpow iedzi. W dalszym ciągu potrzebne nam są tylko w skaźniki arg i p. Po zw eryfikow aniu popraw ności odebranego kom unikatu uaktualniam y licznik zegara czasu rzeczy­ w istego za pom ocą funkcji SetRealTimeClock. Z w róćm y uw agę na odw racanie kolejności bajtów za pom ocą funkcji ntohl i konw ersję czasu za pom ocą stałej NTP_TO_UNIX. N a koniec w funkcji S NTPrepiy ustaw iam y odpow iedni status klien­ ta, zw alniam y bufor zaw ierający odebrany kom unikat i zerujem y składow ą timer struktury client, aby natychm iast usunąć niepotrzebnego ju ż klienta. static void SNTPrepiy(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *serverIP, ul6_t serverPort) ( struct sntp_client *client = arg; struct ntpjnsg *msg; i pbuf_free(p); msg = p->payload; if (p->len >= sizeof(struct ntpjnsg) ££ ntp_leap__.indicator (msg) !~ NTP LI_ALARM_CONDITION ££ ntp_version(msg) == NTPJ/ERSION ££ ntpjnode(msg) =*= Ni;P_MODE_SERVER ££ msg->Stratum != NTP_STRATUM_KISS_0F_DEAT1I ££ msg->Stratum <= NTP_STRATUM_MAX ££ (msg->TransmitTimestamp.Seconds != 0 |j msg->Transmit?imestamp.SecondsFraction != 0)) { SetRealTimeCiock{ntohl(msg->TransmitTimestarap.Seconds) NTP_TO_UNIX); Mciient->status) = SNTP__SYNCHRONIZED; } else { * (int*)status = SNTP_MEMORY_ERROR; client->timer = 0; ) i else { * (intMstatus = SNTp_UDP_ERROR; client->timer = 0; } I W funkcji SNTPreguest próbujem y przydzielić klientow i now ą strukturę typu sntp_client i jeśli alokacja się pow iodła, inicjujem y składow e tej struktury ora/ w staw iam y ją na początek listy klientów . N astępnie próbujem y uzyskać deskryptoi U D P za pom ocą funkcji udp new. Jeśli się pow iodło, próbujem y za pom ocą funkcji udp_bind uzyskać port, który posłuży do w ysiania żądania i na którym będziemy oczekiw ać odpow iedzi od serw era. Jeśli dostaliśm y port, w yw ołujem y funkcję udp_ connect, aby przypisać do deskryptora U D P adres i num er portu serw era. Dzięki tem u odebrana zostanie tylko o d pow iedź od tego serw era, do którego wysialiśm y żądanie, a w szelkie inne datagram y U D P będą ignóiTRrane. Jeśli pow yższe się uda­ ło, próbujem y przydzielić za pom ocą funkcji pbu'fJ l l o c bufor, w którym zosta­ nie um ieszczone żądanie SNTP. Po przydzieleniu bufora w ypełniam y pola żądania; SNTP. N astępnie ustaw iam y funkcję zw rotną udp_recv, która zostanie w yw ołana1 po odebraniu odpow iedzi od serw era. Funkcja zw rotna ja k o argum ent dostanie; w skaźnik client do struktury typu sntp_client opisującej klienta. W reszcie cale: żądanie w ysyłam y za pom ocą funkcji udp_send. N a koniec, po w ysłaniu żądania zw alniam y bufor z niepotrzebnym ju ż kom unikatem . Jeśli w pow yższej procedu­ rze napotkaliśm y ja k iś problem , ustaw iam y*odpow iedni status klienta i zerujemy składow ą timer struktury client, aby przyspieszyć usunięcie klienta z pamięci, o czym dalej. Przed usunięciem klienta zostanie też zw olniony przydzielony mu deskryptor UDP. } else * (client->status) = SNTPJiESPONSEJSRROR; pbuf_free(p); client->timer = 0; i D o obsługi przekroczenia czasu oczekiw ania na odpow iedź serw era im plem entuje­ my budzik. Przyjm ijm y, że będzie on w ołany co 200 m ilisekund oraz że klient bę­ dzie czekał na odpow iedź m aksym alnie 4 sekundy. Z apew ne w ystarczyłoby czekać krócej, bo zw ykle serw ery N T P odpow iadają szybko, a nie m a sensu synchronizo­ wać się do serw era, na którego odpow iedź trzeba 'długo czekać, ale - aby ułatwić testow anie - dobrze jest jed n ak ustaw ić odpow iednio długi czas oczekiw ania. O kres budzika i liczbę okresów, które klient ma czekać na odpow iedź od serw era, definiu­ jem y odpow iednio jak o stale SNTP_TIMER_MS i SNTP_TIMEOUT. łdefine SNTP_TIMER_MS 200 Idefine SNTPJTIMEOUT 20 Z darzenie budzika obsługiw ane jest przez funkcję SNTPtimer, w której przegląda­ my liptę klientów . Z listy usuw am y te klienty, które działają ju ż zbyt długo. Jeśli ldieimiwit ¡¡tiy.ydzielono deskryptor UDP, to zw alniam y ten deskryptor przed usunię­ ciem z pamjięci danych klienta. 238 8. Klient Ul)/* 8.3. Przykład 8 - automatyczna synchronizacja zegara czasu rzeczywistego static void ClockCallback(void) static int f = 0; int i; void SNTPtimer(void) { struct sntp_client *curr, *prev, *next; curr = firstCIient; prev = NULL; while (curr) { if (— (curr->timer) 0) { if (curr->pcb) udp_remove(curr->pcb); if (prev) next = prev->next = curr->next; else next = firstCIient = curr->next; if {*(curr~>status) == SNTP_IN_PROGRESS) * (curr->status) - SNTP_NO_RESPONSE; mem_free(curr); curr = next; else { prev 8.3.2. { LCDgoto(0, 1); LCDwriteTime(GetRealTimeCiock()); for (i = 0; i < COUNT; ++i) i LCDgoto(2 + i, 0); if (f == 0) ( LCDwrite(serverTbl(i]); LCDwritet" "); ) else if (f == 2 j| f 3) f switch (status(i}) { case SNTP_N0T_RUNNING: LCDwrite("SNTP not running break; case SNTP__S YNCHR0NI ZED: LCDwrite("Time synchronized break; case SNTP_IN_PR0GRESS: LCDwrite("SNTP in progress break; case SNTP_DNSJERR0R: LCDwrite("DNS error break; case SNTP_MEM0RY_ERR0R: LCDwrite("Memory error break; case SNTP_UDP_ERR0R: LCDwrite("UDP error break; case SNTPJ10_RESP0NSE: LCDwrite("SNTP no response break; case SNTP_RESP0NSE_ERR0R: LCDwrite("SNTP response error break; curr; curr->next; Plik ex_sntp.c Plik ex_siitp.c zaw iera im plem entację testów klienta SNTP. N ajpierw deklarujem y ' tablicę s e r v e rT b ł w skaźników do nazw serwerów . W śród tych nazw je st serwer nieoferujący usługi SNTP. Jego nazw a w ystępuje dw ukrotnie, aby przetestować pam ięć lokalną D N S. Żeby przetestow ać D N S, na drugiej pozycji je s t nazw a, któ­ ra nie istnieje w Internecie. D w ie o statnie pozycje w tablicy w skazują na nazwy oficjalnych serw erów czasu, synchronizow anych zegarem atom ow ym i zainstalo­ w anych w G łów nym U rzędzie M iar. D la każdego serw era urucham iam y osobnego klienta. Statusy klientów przechow ujem y w tablicy s t a t u s . ffdefine COUNT 5 static const char * const serverTbl(COUNT] = j "wikipedia.org", "nie.ma.takiego.serwera", "wikipedia.org", "tempusł.gum.gov.pl", "tempus2.gum.gov.pi" 239 "); "); "); "); "); "); "); } i } f = (f + 1) & 3; } •-,**. 1; static int status[COUNT] = ( SNTP_NOT_RUNNING, SNTP__NOT_RUNNING, SNTP_NOT_RUNNING, SNTP_NOT_RUNNING, SNTP_NOT_RUNNING ); W przerw aniu zegara czasu rzeczyw istego, /zgłaszanym co sekundę, w yw ołujem y funkcję zw rotną C lo c k C a llb ac k , której zadhniem je st w yśw ietlenie na LCD aktu­ alnego czasu oraz inform acji o działaniu poszczególnych klientów . N a przem ian przez dw ie sekundy w yśw ietlam y nazw y serw erów , a przez kolejne dw ie sekundy - statusy klientów , które uruchom iliśm y. W funkcji main inicjujem y poszczególne układy m ikrokontrolera, ustaw iam y funk­ cję zw rotną C lo c k C a llb a c k w ołaną w przerw aniu zegara czasu rzeczyw istego, kon­ figurujem y ustaw ienia sieciow e, ustaw iam y budzik SNTPtimer dla klientów SNTP, a na koniec urucham iam y po kolei, w niew ielkich odstępach czasu, klienty SN TP za pom ocą funkcji S N T P c lie n tS ta rt. int main() { static struct netif netif; static struct ethnetif ethnetif = (PHY^ADDRESS}; int i; uint8_t confBit; Dehy (1%Ł&00); confBit .= ¿btConfBit(); 240 8. Klient UDP AllPinsDisable(); LEDconfigure(); R e d LEDonO ; LCDconfigure ( } ; SET_IRQ_PROTECTION(}; netif.hwaddr[0] = 2; netif.hwaddr[l] = (BOARDJl'YPE » 8) & Oxff; netif.hwaddr[2} = BOARDJTYPE & Oxff; netif.hwaddr[3J = (ETH_BOARD » 8) & Oxff; netif.hwaddr[41 = ETH_BOARD & Oxff; netif.hwaddr[5) = 1 + confBit; if (¡confBit) { IP4_ADDR(6netif.ip_addr, 192, 168, 51, 84); IP4_ADDR(&netif.netmask, 255, 255, 255, 240); IP4_ADDR(&netif.gw, 192, 168, 51, 81); 1 0, 0, 0, 0); 0, Ö, 0, 0); 0, 0, 0, 0); I error_resetable(LWIPinterfacelnit(&netif, Sethnetif), 5); LWIPtimersStart(}; LWIPsetAppTimer(SNTPtimer, SNTP_TIMER_MS); error_resetable(DHCPwait{&netif, 10, 4), 6); RedLEDoff (); tem pus2.gum .gov.pl, 212.244.36.228, cezow y zegar atom owy, G łów ny U rząd M iar, oficjalny serw er dostarczający czas urzędow y w Polsce; - vega.cbk.poznan.pl, 150.254.183.15, cezow y zegar atom owy, Polska A kadem ia N auk, C entrum B adań K osm icznych, O bserw atorium A strogeodynam iczne w B orow cu k. Poznania; - ntp.itLw aw .pl, 193.110.137.171, cezow y zegar atom owy, Instytut Łączności w W arszaw ie; - ntp.elprom a.cotn.pl, 83.19.137.3, rtibidow y zegar atom owy, laboratorium porów ­ nujące w zorce czasu, Ł om ianki k. W arszawy; - L pl.po ol.ntp.org, pula serw erów rozm ieszczonych na terenie Polski; - Leurope.pool.ntp.org, pula serw erów rozm ieszczonych w Europie; L pool.ntp.org, ogólnośw iatow a pula serwerów . Do testow ania sam ego protokołu SNTP, w archiw um z przykładam i w katalogu ./m ake/ex8_udp_clnt znajduje się plik linux_sntp_clnt.c, który zaw iera im plem enta­ cję prostego klienta SN TP dla system u Linux. Program ten w yśw ietla szczegółow e inform acje zaw arte w odpow iedzi otrzym anej od serw era. U rucham ia się go, po­ dając ja k o argum ent nazw ę serw era SNTP. K lient ten nie obsługuje przekroczenia czasu - jeśli nie dostaniem y odpow iedzi, trzeba usunąć program za pom ocą kom ­ binacji klaw iszy Ctrl-C. Uwagi końcowe N iew łaściw ie używ ane i skonfigurow ane klienty SN TP m ogą niepotrzebnie zw ięk­ szyć ruch w sieci i bardzo obciążyć serwery czasu. N ależy bezw zględnie stosow ać się do dobrych praktyk (ang. best practlces) podanych w RFC 4330, a w szczególności: - I - Jeśli nazw a lub adres IP serw era SN T P są zapisane w pam ięci stałej urządzenia, które jest w ytw arzane w celach kom ercyjnych, to musi to być serw er zarządzany przez producenta lub sprzedaw cę tego urządzenia. - Jeśli nie je s t w ym agana dokładność oferow ana przez zegar atom owy, nie należy korzystać z serw erów pierw otnych, a raczej z puli serwerów , które są synchroni­ zow ane do serw erów pierw otnych. Testowanie przykładu Po uruchom ieniu program u w zestaw ie Z L 29A R M ‘w pierw szym w ierszu LC D po­ w inny pojaw ić się data i czas. N a początku je s t to godzina 00:00:00 dnia 1 stycz­ nia 1970 roku. Po zsynchronizow aniu zegara pow inny pojaw ić się aktualna data i aktualny czas U TC. C zas ten, zależnie od pory roku, spóźnia się w stosunku do czasu polskiego o jed n ą lub dw ie godziny. W w ierszach od trzeciego do siódm ego w yśw ietlane są na przem ian nazw y serw erów i statusy klientów. O prócz serw erów , których nazw y są um ieszczone w pliku źródłow ym ex_sntp. c, m ożna w ypróbow ać inne serw ery N TP.j N astępujące serw ery są wymienione w W ikipedii: - N ie w olno w ysyłać żądań do serw era częściej niż co 15 sekund. K lient pow inien zw iększać w ykładniczo odstęp czasu m iędzy kolejnym i żąda­ niam i, jeśli serw er nie odpow iada w rozsądnym czasie. N ależy używ ać serwerów , które są w sieci położone m ożliw ie najbliżej klienta. for (i = 0; i < COUNT; ++i) { Delay (10000000); SNTPclientStart(serverTbl(i), &status[i }); for {;;); 8.3.3. 241 - error_resetable(CLKconfigure{), 1) ; error_permanent (Locall’ imeConfigure (), 2); error_resetable(RTCconfigure(), 3); RTCsetCaliback(CiockCallback); error_resetable(ETHconfigureMII(), 4); else { IP4_ADDR(&netif.ip_addr, IP4_ADDR(£netif.netmask, IP4_ADDR(finetif.gw, 8.3. Przykład 8 - automatyczna synchronizacja zegara czasu rzeczywistego tem pusL gum .gov.pl, 212.244.36.227, cezow y zegar atom ow y, G łów ny Urząd M iar, oficjalny serw er dostarczający czas urzędow y w Polsce; P rzedstaw iona w yżej im plem entacja je s t bardzo uproszczona. N ie uw zględnia opóźnień w transm isji pakietów sieciow ych. N ie obsługuje stref czasow ych ani zm ian czasu na letni i zim owy. Form uły um ożliw iające oszacow anie czasu podróży pakietów i w yznaczenie korekty czasu klienta zam ieściłem w podrozdziale opisu­ jący m SNTP. Strefy czasow e oraz czas letni i zim ow y są w spierane przez standar­ dow ą bibliotekę języ k a C i dość łatw o m ożna dodać ich obsługę. Jeśli potrzebu­ jem y precyzyjnie określić czas zdarzenia w przeszłości lub różnicę czasu między zdarzęniam i, trzeba uw zględnić sekundy przestępne, w staw iane od czasu do czasu dla tsKoryąjjo>vania zegara z położeniem Z iem i w zględem Słońca. Ponadto, m ając jeszcze św iężo w pam ięci zam ieszanie z „problem em roku 2000” , należy zastano- 242 8. Klient UDI' wić się nad „problem em roku 2036”, kiedy to 7 lutego o godzinie 6:28:16 1 | ( ' przepełni się znacznik czasu NTP. Z am ieszczona tu im plem entacja w ydaje się naVW ' ten problem odporna. K olejnego problem u m ożem y spodziew ać się w roku 2038, gdy czas uniksow y w system ach 32-bitow ych stanie się ujem ny. Typ time__t zwy- n-®; kle definiuje się ja k o liczbę ze znakiem i po doliczeniu do m aksym alnej wartości 231 - 1 następuje warlos'ć ujem na - 2 31, czyli dnia 19 stycznia 2038 roku po godzinie !'!$ i 3:14:07 nastąpi godzina 20:45:52 d nia 13 grudnia 1901 roku. Tak włas'nie zadziała i’ biblioteka N ew lib, użyta do napisania przykładów prezentow anych w tej książce, v C hoć zapew ne do tego czasu w szystkie kom putery będą ju ż reprezentow ać czas w arytm etyce co najm niej 64-bitow ej i ich ten problem nie dotknie, to w ciąż mogą ■■ jeszcze pozostaw ać w użyciu 32-bitow e m ikrokontrolery. Pow yższe uw agi należy uw zględnić, jeśli w ym agam y bardzo dokładnego odm ierzania czasu. Odpowiednie m odyfikacje program u pozostaw iani C zytelnikow i ja k o am bitne ćw iczenie. Rozgłaszanie 244 9. Rozgłaszanie UDp U D P um ożliw ia rozgłoszenie (ang. broadcast) datagram u, czyli w ysianie go je d - ' noczcsnie do w szystkich odbiorców w danej podsieci. W tym rozdziale prezentuję1 dw a przykładow e program y. P ierw szy rozgłasza datagram y U D P i w zasadzie jest. prostym klientem UDP. D rugi je s t prostym serw erem U D P i je s t przeznaczony do testow ania tego pierw szego - w yśw ietla na L C D w szystkie odebrane datagram y' UDP. Z asady działania klienta i serw era U D P w yjaśniłem ju ż w poprzednich 10 / . działach, w ięc bez zbędnego w stępu teoretycznego przystępuję od razu do opisuprzykładów. 9.1. Przykład 9a - rozgłaszanie datagramów UDP N azw y plików przykładu 9a zam ieszczone są w ta b e li 9.1. W śród nich je s t tylko jeden now y plik, który opisuję w następnym podrozdziale. T ab . 9 .1 . Pliki przykładu 9a Źródłowe i biblioteczne ex_send_bcast.c tonl5x8.c slarlup_stm 32_cld. c board_conl.c boardJn i t c b o a rd jcd_ ks0 1 0 8.c board Je d . c iont5x8.h board_conl.il board_del.li board_defs.li boardJnit.h b o a rd jc d .h b o a rd je d .h u tiljle la y .c util_eth_nc.c u til Je d . c u lilje d .c u liljw ip .c util lime.c Iiblwip4.a Iibstm32l10x.a Nagłówkowe 9.1.1. util_delay.h util_error.h u iiijih . b u liljc d .li u tilje d .li u tiijw ip .il U iiljtC .il u til lim e.li CC.Il cortex-m 3.li lwipopts.li slm 32f10x_conf.l) Plik ex_send_bcast.c Plik ex_send_bcast.c zaw iera im plem entację prostego klienta UDP, rozsyłającego cyklicznie datagram y U D P do w szystkich w ęzłów w sw ojej podsieci. W opisanych dotychczas klientach pozostaw ialiśm y bibliotece lwj.P w ybór portu źródłowego i w tym celu podaw aliśm y zero ja k o n u m er portu w .jrzecim argum encie wywołania funkcji udp_bind. W odróżnieniu od tam tych, w tym kliencie używ am y ustalonego portu źródłow ego, którego num er definiujem y ja k o stalą SRC_PORT. N um er portu, na który będą w ysyłane datagram y UDP, definiujem y jak o stalą DST_PORT. Stała. BCAST_TIMER_MS określa okres pow tarzania transm isji w m ilisekundach. Stała BUF_ SI ZE definiuje rozm iar pom ocniczego bufora. łdefine SRC_PORT 5001 łdefine DST_P0RT 5002 łdefine BCAST_TIMER_MS 2666 łdefine BUF ŚI2E 64 ł 245 9.1. Przykład 9a - roz.glasz.anie datagramów UDP R ozgłoszenie datagram u realizuje funkcja SendBroadcast. W ysyła ona p oje­ dynczy datagram na przem ian na adres ukierunkow anego rozgłaszania i adres rozg łaszania w bieżącej podsieci, czyli 255.255.255.255. Podsieć testow a ma przy d zieloną pulę adresów 192.168.51.80/28, a zatem adresem ukierunkow ane­ go ro zg łaszania w niej je s t 192.168.51.95. Funkcje z biblioteki lw lP przecho­ w ują adres IP w strukturze typu ip_addr, a funkcje z biblioteki standardow ej C w stru k tu rze typu in_addr. W ysyłany datagram U D P zaw iera krótki tekst A SCII. T ekst ten zaw iera num er kolejny datagram u, potem adres 1P rozgłaszania i num er portu, na który datagram je s t w ysyłany. T ekst kończy się znakiem końca w ier­ sza, czyli sekw encją znaków CR i LF. W ysyłany datagram U D P w yśw ietlam y też na L C D - każdy datagram w osobnym w ierszu. U żyty LC D m oże w yśw ietlić tylko 8 w ierszy tekstu, w ięc po w yśw ietleniu każdych kolejnych 8 datagram ów czyścim y ekran L C D . N ależy pam iętać, że funkcja s nprintf i funkcje o bsługu­ ją c e w y św ietlacz ciekłokrystaliczny nie są w spółużyw alne, co spraw ia, że rów ­ nież funkcja SendBroadcast, w której są one w ołane, nie jest w spółużyw alna. W tym przykładzie w ykonanie funkcji S en d B r o a d c a s t nie zostanie je d n a k nigdy w yw łaszczone przez przerw anie, w którym m ogłaby zostać ponow nie w yw ołana, w ięc nie m a problem u. static void SendBroadcast(void) ( static unsigned count = 0; struct udp_pcb *pcb; struct pbuf *p; 1 struct ip_addr broadcast_ip; struct in_addr ip; int size; char b u f fBUF_SIZKJ; count++; if (count & 1) IP4_ADDR(&broadcast_ip, 192, 168, 51, 95); else IP4_ADDR(&broadcast_ip, 255, 255, 255, 255); ip.s_addr = broadcast_ip.addr; size - snprintf (buf, BUF_SIZE, "%u %s:%u\r\n", count, inet_ntoa(ip), DST_PORT); if (size <= 0 J! size >= BUFJJIZE) return; pcb = udp_new(); if (pcb == NULL) return; *• * if (ERR_0K != udp_bind (pcb, IP_ADDR_ANY, SRC_P0RT) j) NULL == (p » pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM))} { udp_remove(pcb); \- 'Ili-'-,Vi * ;■£ i ':-'v 9. Rozgłaszanie UI)P 246 udp_sendto(pcb, p, &broadcast_ip, DST_PORT); pbuf_free(p); udp_remove(pcb); 9.1.2. Testowanie przykładu Do przetestow ania tego przykładu m ożna użyć prostego serw era, który prezentuję w przykładzie 9b. W ym aga to jed n ak posiadania dw óch zestaw ów uruchom ienio­ w ych. Innym rozw iązaniem jest uruchom ienie prostego serw era na kom puterze, któ­ rego używ a się do program ow ania m ikrokontrolera. Prosty serw er U D P dla system u L inux, um ożliw iający testow anie tego przykładu, znajduje się w archiw um z przy­ kładam i w pliku U nux_recv_bcast.c, który je s t w katalogu ./m ake/ex9a_send_bcast. Program ten w yw ołuje się z linii poleceń, podając ja k o argum ent num er portu, na którym m a nasłuchiw ać serwer. D la każdego odebranego datagram u U D P w yśw iet­ la on inform ację o adresie IP i num erze portu źródłow ego, z którego ten datagram został w ysłany. W yśw ietla też zaw artość otrzym anego datagram u UDP, zakładając, że je s t to tekst A SCII. Po skom pilow aniu i uruchom ieniu tego program u, a na­ stępnie uruchom ieniu układu z m ikrokontrolerem , pow inniśm y zobaczyć w ydruk podobny do poniższego. if {(count & 7> =— 1> LCDclear (); LCDwrite(buf); ) Funkcja raain nie różni się istotnie od analogicznych funkcji z poprzednich przykła­ dów. Z asadnicza różnica polega na tym , że przed w ejściem w nieskończoną pętlę ustaw iam y funkcję S en d B ro ad cast ja k o budzik w ołany okresow o co BCAST_TIMER_ MS m ilisekund. int main () 1 static struct netif netif; static struct ethnetif ethnetif = (PHY_ADDRESS); uint8_t confBit; $ ./linux recv_bcast.elf 5002 Listening on port 5002 Delay(1000000); confBit = GetConfBit(); AIlPinsDisabłeO; LEDconfigure(); RedLEDon(); LCDconfigure(); SET_IRQ_PROTECTION(); From:192.168.51.89:5001 Content:! 192.168.51.95:5002 From:192.168.51.89:5001 Content:2 255.255.255.255:5002 error_resetable(CLKconfigure(), 1); error_permanent(LocalTimeConfigure(), 2); errorjresetable(ETHconfigureMII{), 4); t 9.2. netif.hwaddr[Q) - 2; netif.hwaddr[l) *= (BOARDJFYPE » 8) & 0xff; netif.hwaddr(2) = BOARD__TYPE fi 0xff; netif.hwaddr{3} = (ETH_B0ARD » 8) & 0xff; netif.hwaddr{41 = ETH_BOARD & Oxff; netif.hwaddr(5] = 1 + confBit; if {!confBit) ( IP4_ADDRfŁnetif.ip_addr, 192, 168, 51, 84); IP4_ADDR(&netif.netmask, 255, 255, 255, 240); IP4_ADDR(&netif.gw, 192, 168, 51, 81); 1 else 1 IP4_ADDR(fi.netif.ip_addr, 0, 0, 0, 0); IP4_ADDR(&netif.netmask, 0, 0, 0, 0); IP4_ADDR(&netif.gw, 0, 0, 0, 0); Przykład 9b - odbieranie datagramów UDP N azw y plików przykładu 9b zam ieszczone są w ta b e li 9.2. Jedyny now y plik opi­ suję w następnym podrozdziale. Tab. 9.2. Pliki przykładu 9b Źródłowo i biblioteczna ex recv bcast.c lont5x8.c startup_stm32_cld. c board cont.c board init.c boardJcd_ks0108.c boardJed.o font5x8.h board conf.h board det.h board dets.h b o a rd jn it.h b o a rd jc d .h b o a rd je d .h ^ - •***■ RedLEDoffO; > LWIPsetAppTimer(SendBroadcast, BCAST_TIMER_MS); for (;;); util delay. c u til eth nc.c u tiljc d .c utilJod_ex.c u tilje d .c u tiljw ip .c util time.c Nagłówkowe 1 error_resetable(LWIPinterfaceInit(&netif, fiethnetif), 5); LWIPŁimersStart(); error_resetable{DHCPwait(Snetif, 10, 4), 6); ) 247 9.2. Przykład 9b - odbieranie datagramów U DP } - 4 - 4 * --------------- util delay.h u til error.h u til eth.h u ffljc d .h util_lcd_ex.h u tilje d .h u tiljw ip .h u tiljtc .h u til time.h Iiblwip4.a Ubstm32t10x.a ....... cc.h cortex~m3.h Iwipopts.h stm 32/10x_conUi 248 9,2.1. 9.2. Przykład 9b - odbieranie datagramów UDP 9. Rozgłaszanie UDl' SET_IRQ_PROTECTION(); Plik ex_recv_bcast.c error_resetable(CLKconfigure(), 1}; error_permanent(LocalTimeConfigure(), 2); error_resetable (ETHconfigureMII (), *1); Plik ex_recv_bcast.c zaw iera im plem entację prostego serw era U D P przeznaczonego do w spółpracy z klientem z przykładu 9a. S erw er urucham iam y za pom ocą funk­ cji U D P se rv e rS ta rt. A rgum entem tej funkcji je s t num er portu, na którym serwer m a nasłuchiw ać. Funkcja ta zw raca zero, gdy uruchom ienie serw era pow iodło się. a w artość ujem ną w przeciw nym przypadku. Jest ona identyczna ja k funkcja o tej sam ej nazw ie z przykładu 7. netif.hwaddr[0} = 2; netif.hwaddr(l) = (BOARD_TYPE » 8) & Oxff; netif.hwaddr[2] = BOARD_TYPE £ Oxff; netif.hwaddr[3] = (ETH_BOARD » 8) & Oxff; netif,hwaddr[4] = ETH_BOARD & Oxff; netif.hwaddr[5) = 3 + confBit; if (¡confBit) { IP4_ADDR(£netif.ip^addr, 192, 168, 51, 85); IP4__ADDR(£netif .netmask, 255, 255, 255, 240); IP4_ADDR(£netif.gw, 192, 168, 51, 81); static int UDPserverStart(uintl6_t port); Funkcja U D P se rv e rS ta rt ustaw ia funkcję zw rotną re c v _ c a llb a c k , która obsługuje odbierane datagram y. W funkcji r e c v _ c a llb a c k w yśw ietlam y w pierw szym wier­ szu L C D adres IP i num er portu źródłow ego, z k tórego został w ysłany datagram UDP, a w pozostałych w ierszach zaw artość odebranego datagram u, zakładając, że je s t to tekst A SCII. P rzed w yśw ietlen iem kolejnego datagram u czyścim y ekran LCD. \ else { IP4_ADDR(£netif.ip_addr, IP4 ADDRiinetif.netmask, IP4_ADDR(£netif.gw, static void recv_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, uintl6_t port) ( struct pbuf *q; uint!6__t len; ) ) error_resetable(UDPserverStart(UDP_PORT), 7); RedLEDoff(); for (;;); 2. A by ten program m ógł odbierać datagram y w ysyłane przez program z przykładu 9a, serw er musi nasłuchiw ać na porcie 5002. 5002 Funkcja main je s t bardzo podobna do analogicznej funkcji z poprzedniego przykła­ du. Są dw ie istotne różnice. K onfigurujem y inne adresy M A C i IP, aby program y z przykładów 9a i 9b m ogły być uruchom ione rów nocześnie w tej sam ej sieci testo­ w ej. N a końcu zam iast klienta urucham iam y serw er'U D P. int main () { static struct netif netif; static struct ethnetif ethnetif « (PHY_ADDRESS); uint8_t confBit; Delay(1000000); confBit = GetConfBit(); AllPinsDisable(); " LEDconfigure(}; RedLEDonO ; LCDconfigureO / * 0, 0, 0, 0); 0, 0, 0, 0); 0, 0, 0, 0); error_resetable(LWIPinterfacelnit(Snetif, £ethnetif), 5); LWIPtimersStart(); error_resetable (DHCPwait (Snetif, 10, *1), 6); LCDclear(); LCDwriteIPport(addr, port); LCDputchar(,\n'); for (len = 0, q = p; len < p->Łot_len; len += q->łen, q = q->next) LCDwriteLenWrap(q->payload, q->len); pbuf_free(p); »define UDP_P0RT 249 Testowanie przykładu P rzykład ten zasadniczo m a ch arak ter pom ocniczy. A le aby móc go przetestow ać sam odzielnie, w archiw um z przykładam i um ieszczony je s t prosty klient U D P dla L inuksa, w ysyłający cyklicznie co 4 sekundy datagram na podany adres 1P i nu­ m er portu. Im plem entacja tego klienta znajduje się w pliku linux_send_bcast.c, który znajduje się w katalogu ,/m ake/ex9b_recv_bcast w archiw um z p rzykłada­ mi. P rogram ten w yw ołujem y, podając dw a argum enty: docelow y adres IP i nu­ m er portu. Program w ysyła takie sam e datagram y U D P jak program z przykładu 9a. Z aw artość w ysłanych datagram ów U D P w ypisuje na standardow e w yjście. Z a po m o cą tego program u m ożna w ysyłać je n a ”adres rozgłaszania w bieżącej podsieci: $ ./łinux_send_bcast.elf 255.255.255.255 5002 1 255.255.255.255:5002 2 255.255.255.255:5002 M ożna też w ysyłać datagram y U D P na adres ukierunkow anego rozgłaszania: $ ./linux_send_bcast.elf 192.168.51.95 5002 1 192^.68.51.95:5002 2 19i|i68.$ 1 ^ 5 : 5 0 0 2 250 9. Rozgłaszanie UDP Ponadto w celach testow ych m ożna rów nież w ysyłać datagram y U DP po prostu na adres jednostkow y: $ ,/linux___send_bcast.elf 192.168.51.90 5002 1 192.168.51.90:5002 2 192.168.51.90:5002 Serwis WWW 10.1. Komunikacja między klientem a serwerem WWW Jedną z bardzo ważnych usług w Internecie, a być m oże w ręcz usługą najw ażn iej-' szą, jest W W W (ang. worlcl wide web). N ajpraw dopodobniej w iększość internau- ■, tów utożsam ia Internet z WWW. U sługa W W W działa w m odelu klient-serwer. Serw ery udostępniają różnego rodzaju w itryny i portale, a klientam i są przeglądarki1 internetow e, instalow ane w każdym urządzeniu m ającym dostęp do intersieci, obec­ nie rów nież w telefonach kom órkow ych. W iele urządzeń sieciow ych, np. rutery do­ m ow e, w yposaża się w serw ery W W W , um ożliw iające zarządzanie nim i za pomocą • przeglądarki internetow ej. Popularność W W W w ynika z atrakcyjnego i intuicyjne­ go interfejsu graficznego. R ów nież konstruow ane przez nas urządzenia sterowane m ikrokontroleram i chcielibyśm y w yposażać w taki interfejs, dlatego w tym ro z d zia -1 le przedstaw iam przykład bardzo prostego serw isu W W W , który zajm uje mniej niż 1 80 KiB pam ięci Flash. Jak przystało na ostatni rozdział książki, jest to najbardziej skom plikow any z prezentow anych w niej przykładów. < sch em a t> ://< w ęze i> :< p o rt> /< śc ież k a> ? < z ap y ta m e> if< IY u g m en t> Pole <w ęzeł> je s t nazw ą dom enow ą w ęzła lub adresem IP w notacji dziesiętnej z kropkam i. Pole <port> je s t num erem portu usługi sieciow ej, zapisanym jako liczba przy podstaw ie dziesięć. Pole to um ożliw ia określenie niestandardow ego num eru portu, innego niż dom yślny dla danego schem atu. O ddziela się go od poprzedzającej części U RI dw ukropkiem . Pole <ścieżka> określa zw ykle nazw ę pliku zaw ierającego zasób. Jest oddzielone od poprzedzającej części U RI uko­ śnikiem . Pole < zapytanie> zaw iera dodatkow e param etry, w ysyłane do serw era usługi i m ające w pływ na udzieloną przez niego odpow iedź. M a to na przykład zastosow anie przy dynam icznym generow aniu stron W W W . K ażdy param etr składa się z nazw y i w artości oddzielonych znakiem rów ności. Pole <zapytanie> je s t o d dzielone od poprzedzającej je części U R I pytajnikiem . K olejne param etry o ddziela się od siebie znakiem et (ang. am persaiul), czyli &. Pole <fragm ent> specyfikuje fragm ent zasobu. Jest oddzielone od poprzedzającej je części URI krzyżykiem . P oszczególne pola identyfikatora są opcjonalne i nie m uszą w ystę­ pow ać. Jeśli jak ieś pole nie w ystępuje, to nie w ystępuje też znak oddzielający to pole od poprzedniej części URI, przy czym nie dotyczy to znaków oddzielających schem at od dalszej części URI. Te znaki przynależą do schem atu i m uszą się pojaw ić, jeśli podany je s t schem at. A plikacja m oże określić schem at dom yślny. D la przeglądarki internetow ej dom yślnym schem atem je s t http. K ażdy schem at ma zw ykle przypisany dom yślny port. Jeśli używ any je s t port dom yślny, to pole <port> nie m usi w ystępow ać. D la http dom yślnym num erem portu je s t 80. W ięcej na tem at U RI m ożna przeczytać w dokum encie R FC 3986. Poniżej zam ieszczone są przykładow e URI. 10.1. Komunikacja między klientem a serwerem WWW K om unikację m iędzy użytkow nikiem oraz reprezentującym go klientem a serwe­ rem W W W m ożna podzielić na trzy fazy: - U żytkow nik, posługujący się przeglądarką internetow ą, w pisuje nazw ę serwisu albo klika na odnośnik lub przycisk. W w yniku tego przeglądarka generuje iden­ tyfikator zasobu, który ma być w yśw ietlony użytkow nikow i. - Przeglądarka w ysyła do serw era żądanie dostarczenia zasobu. Serw er odsyła żądany zasób lub inform ację o błędzie. Z w ykle zasobów form acji zasobów 253 w yśw ietlenie strony internetow ej w ym aga ściągnięcia wielu kolejnych zaw ierających tekst i grafikę. N a podstaw ie otrzym anych dotychczas in­ przeglądarka autom atycznie generuje kolejne identyfikatory potrzebnych i dla każdego z nich pow tarza dw ie ostatnie fezy kom unikacji. fi!e :///k a ta lo g l/k a ta lo g 2 /p !ik ftp://ftp.is.co.za/ric/rrc3y86.txt URI (ang. U niform R esource Identifier) je st ustandaryzow anym sposobem identy­ fikow ania różnego rodzaju zasobów , w tym przede w szystkim zasobów interneto­ wych. Szczególnym i przypadkam i U RI są U RN (ang. U niform R esource Name) i U R L (ang. Uniform R esource Locator). U RN określa tylko nazw ę zasobu, a URL oprócz identyfikacji zasobu w skazuje rów nież sposSb'dostępu do niego. Podzbiory U RN i U RL nie są rozłączne, konkretny identyfikator m oże być zaklasyfikow any jednocześnie jak o U RN i URL. Identyfikator U RI rozpoczyna się od pola <schemat>, które określa form at pozostałej części identyfikatora, protokół kom unikacyjny itd. Po tym polu następuje dw ukropek i część specyficzna dla danego schem atu. B ardzo często spotykanym i schem atam i są: file , ftp , http, m ailto itd. < sc h e m u t> :< c z ę & sp ecy ficr.u a d la sc h e m a tu > W śród w szystkich form atów URI, ze w zględu na zastosow anie w W W W , najbar­ dziej dla nas interesujący jest schem at hierarchiczny, w którym część specyficzna schem atu rozpoczyna się dw om a ukośnikam i. h ttp ://w w w .ietf.o rg /rfc/3 9 8 6 .tx t h ttp ://w w w ,se rw e r:8 0 8 0 /k a ta lo g /in d e x .lu m l? p a ra m e trl= a b c & p a ra m e tr2 = i2 3 # ro z iiz ia l-l U lap ://[2 0 0 I:cib 8 ::7 ]/c-G B 7 o b je ctC lass? o n e n u iilto :J o h n .D o e@ e x am p le.co m n ew .s:co m p .in fo sy sien is.w w w .serv ers.u n ix ie i:- f l - 8 16-555 -1 2 1 2 te ln e t://! 9 2 .0 .2 .1 6 :8 0 / u rn :o a sis:n a m e s:sp e c ific a tio n :d o c b o o k :d td :x m ł:4 .1 .2 1 2 7 .0 .0 .1 :8 0 8 0 1.1.2. HTTP H TTP (ang. H ypertext Transfer Protocol) je s t protokołem , za pom ocą którego prze­ glądarka internetow a kom unikuje się z serw erem WWW. A ktualna w ersja tego pro­ tokołu, czyli w ersja L I, jest opisana w dokum encie RFC 2616. H TT P używ a proto­ kołu transportow ego TCP. Serw er standardow o nasłuchuje na porcie 80. H TTP jest protqkolem bezstanow ym - w ym iana kom unikatów składa się z żądania w ysyłane­ go [t®ez k,|tąnta i odpow iedzi odsyłanej przez serwer. W yśw ietlenie strony W W W w ym aga zw ykle ściągnięcia wielu zasobów (tekst, obrazki), a dla każdego z nich 10.1. Komunikacja między klientem a serwerem WWW musi zostać w ysiane osobne żądanie. W wersji 1.0 H TTP każda taka komunikacją odbyw a się w osobnym połączeniu TCP. W wersji 1.1 HTTP, w celu zmniejszenia narzutu zw iązanego z budow aniem i rozłączaniem połączenia, w pojedynczym po- : łączeniu T C P m ożna przesłać w iele kolejnych żądań i odpow iedzi. Protokół H TT P je s t d o ić ro zbudow any i nie m a tu m iejsca, aby przedstaw ić go 4, w całości. P okażę tylko k ilk a przykładów . K om unikaty kodow ane są tekstowo.;';!: W niektórych m iejscach w ielkość liter nie m a znaczenia (ang. case insensiti ve), w innych zaś je s t istotna (ang. case sen sitive) - je s t to szczegółow o opisi ne w specyfikacji p rotokołu. K ażdy w iersz kończy się sek w en cją znaków CK i LF. Ż ądan ie w ysyłane p rz e z k lien ta składa się z nagłów ka (ang. header), I ry kończy się pustym w ierszem , czy li dod atk o w ą sekw encją znaków CR i LI-. ■' Po nagłów ku m oże w ystępow ać o p cjo n aln e ciało (ang. body) żądania. Pierw: w iersz nagłów ka zaw iera nazw ę m etody, U RI oraz w ersję p rotokołu używi przez klienta. P oszczególne sk ład n ik i p ierw szego w iersza o d d ziela się pojedy czym i spacjam i. N ajczęściej uży w a się m etody GET, któ ra ozn acza żądanie do­ starczenia zasobu. U RI żądanego zasobu m ożna podać w cało ści, ale m ożna pom inąć pola < schem at> , < w ęzeł> i < port> , g dyż żądanie je s t k ierow ane przi połączenie TCP, któ re w łaśnie zo stało otw arte do serw era o k reślo n eg o w polat < w ęzeł> i <port>, a pole < sch em at> je s t w tym p rzypadku nadm iarow e, bo w ia­ dom o, że p rzesyła się k o m unikaty pro to k o łu HTTP. K olejne w iersze nagłów ka U um ożliw iają przekazanie d o d atk o w y ch param etrów . W iersze z param etram i skła­ dają się z nazw y param etru, d w u k ro p k a i w artości param etru. W artość param etru ,, m oże być po p rzed zo n a białym i znakam i - p referpw ana je s t po jed y n cza spacja. ' B iałe znaki na końcu w iersza są ignorow ane. Ż ąd an ie z m etodą G E T nie zaw ie -1 .. ra ciała. Z atem n ajp ro stsze m ożliw e żąd an ie w ygląda następ u jąco (pusty w ie rv kończący żądanie je s t istotny): G E T / H T T P / 1 .0 C zęsto zdarza się, że jeden fizyczny serw er pod tym sam ym adresem IP obsługuje w iele nazw dom enow ych. Z punktu w idzenia klientów w ygląda to ja k w iele wirtu­ alnych serwerów. A by to um ożliw ić, klient um ieszcza nazw ę serw era ja k o parametr H ost, który jest obow iązkow y od w ersji 1.1 HTTP. G E T /pub/index.html H T T P / 1 .! Host: www.nazwa.serwera ••• “ *1 Zw ykle przeglądarka internetow a w ysyła w żądaniu więcej inform acji. Popatrzmy na poniższy przykład. Param etr U ser-A gent identyfikuje przeglądarkę, a czasem też system operacyjny zainstalow any na kom puterze użytkow nika. K olejne parametry A ccept inform ują serw er o akceptow anych przez przeglądarkę form atach danych, obsługiw anych językach, m etodach kom presow ania danych, obsługiw anych rodza­ jach kodow ania znaków narodow ych ild. Płiramelr C onnection inform uje, czy po­ łączenie ma być zam knięte (w artość close) natychm iast po odesłaniu odpowiedzi, czy utrzym yw ane (w artość keep-alive) przez serwer, gdyż będą w nim przesyłane kolejne żądania. 255 G E T / l e d ? L E D = R & L E D = G H T T P / 1 .1 Host: localhost User-Agent: Firevox/1.0 (Operating Systcm/3.0) Accept: text/html.text/plain,image/png Accept-Language: pl,en-us,en Accept-Encoding: gzip,deflate Acccpt-Charsct: ISO-8859-2,UTF-8 Connection: close Zauw ażm y, że w pow yższym przykładzie w URI przesyłane są param etry zapyta­ nia. Jeśli tych param etrów je s t dużo, jeśli pochodzą z rozbudow anego formularza, w ygodniej je st użyć w tym celu m etody POST. W tedy param etry zapytania zostaną um ieszczone w ciele kom unikatu, ja k w poniższym przykładzie. Param etr C ontenl-Type inform uje, że kom unikat zaw iera ciało i podaje sposób jeg o kodow ania. N atom iast w artość param etru C ontent-L ength inform uje o długości ciała w okte­ tach. Zw róćm y uw agę, że ciało kom unikatu nie kończy się znakiem końca w iersza (czego nie w idać na w ydruku). Z w róćm y też uw agę na pusty w iersz oddzielający nagłów ek od ciała kom unikatu. P O S T /led H T T P / 1 .1 1-Iost: localhost User-Agent: Firevox/1.0 (Operating System/3.0) Connection: close Cnntent-Typc: application/x-www-fonn-urlencoded Content-Length: 11 LED=R&LED=G O dpow iedź serw era składa się z nagłów ka, który kończy się pustym w ierszem . Po nagłów ku m oże w ystępow ać ciało zaw ierające zasób, o który prosił klient. Pierwszy w iersz nagłów ka zaw iera w ersję protokołu używ aną przez serwer, kod statusu (ang. status code) i jego opis tekstow y (ang. reason phrase). Poszczególne składniki pierw szego w iersza oddziela się pojedynczym i spacjam i. K od statusu inform u­ je o w yniku działania serw era. Jest to trzycyfrow a liczba dziesiętna. Interpretacja poszczególnych zakresów w artości je st zam ieszczona w tab eli 10.1. O pis teksto­ wy nie je s t interpretow any przez oprogram ow anie klienta i je s t przeznaczony dla T ab . 1 0 .1 . Niektóre kody statusu HTTP 1 0 0 ...1 9 9 Informacje o postąpię przetwarzania żądania, np.: 100 — cząść żądania została odebrana i zaakceptowana 2 0 0 ...2 9 9 Żądanie klienta zostało poprawnie odebrane, zrozumiane i zaakceptowane, np.: 20 0 - odpowiedź zawiera żądany zasób 3 0 0 ...3 9 9 Klient musi podjąć dodatkową akcją w celu uzyskania zasobu, np.: 301 - żądany zasób został przeniesiony na stale i znajduje sią pod innym adresem 4 0 0 ...4 9 9 Wystąpił błąd po stronie klienta, np.: 4 0 0 - przestane żądanie ma niepoprawną składnią, 40 4 - żądany zasób nie istnieje Wystąpił błąd po stronie serwera, np.: 500'.ł .% 9 9 i Siffl - nie można obsłużyć żądania z powodu nieoczekiwanego problemu, 5 0 S i- serwer nie obsługuje wersji HTTP podanej w żądaniu 256 użytkow nika. Podobnie ja k w żądaniu, kolejne w iersze nagłów ka odpow iedzi i opcjonalne i um ożliw iają przekazanie dodatkow ych param etrów. W iersze z pari metram i składają się z nazw y param etru, dw ukropka i wartos'ci param etru. Warto: param etru m oże być poprzedzona białym i znakam i - preferow ana je st pojedyn< spacja. Białe znaki na końcu w iersza są ignorow ane. W poniższym przykłai param etr D ate inform uje o dacie i czasie w ysłania odpow iedzi. P aram etr Server identyfikuje serw er i system operacyjny. Param etr Last-M odified inform uje o da< i czasie ostatniej m odyfikacji przesyłanego zasobu. Param etr Connection o w tości close inform uje, że serw er zam knie połączenie po w ysłaniu tej odpow ied/i W artość param etru C ontent-Length określa długość ciała w iadom ości w oktetach, czyli rozm iar przesyłanego zasobu. P aram etr Content-Type określa rodzaj zasobi i sposób jego kodow ania. C zęsto spotykanym i w artościam i tego param etru są: lex htm l, text/plain, text/xm l, text/css, application/octet-stream , application/pdf, image' gif, im age/jpeg, im age/png, im age/svg+xm l, im age/tiff, im age/vnd.m icrosoft.ici itd. N azw y te jednoznacznie identyfikują rodzaj zasobu i nie w ym agają objaśnienia. D odatkow e pole charset specyfikuje sposób kodow ania zasobu, inform uje o sposi bie kodow ania znaków. W poniższym przykładzie ciało odpow iedzi zaw iera teksi zapisany w H TM L z użyciem kodow ania U TF-8. Z asadniczą część ciała odpowie­ dzi tu pom inięto i zastąpiona w ielokropkiem . H T T P / 1.1 200 O K Dale: Fri, 20 A u g 2010 10:38:34 G M T Server: Apacz/i.O (Operating Sys(em/3.0) Last-Modified: Fri, 20 A u g 2010 10:11:55 G M T Connection: close Content-Length: 937 Content-Type: text/html; charset=UTF-8 <h tm l> 10.1.3. 10.1. Komunikacja między klientem a serwerem WWW 10. Serwis VVU II HTML H TM L (ang. H ypertext M arkup Language) jest podstaw ow ym językiem opisu stron WWW. O pisuje strukturę dokum entu W W W za pom ocą znaczników (ang. tags). N azw a znacznika jest otoczona naw iasam i ostrokątpym i. W iększość znaczników w ystępuje w parach: znacznik otw ierający i z.naczni^zam ykający. W znaczniku za­ m ykającym jeg o nazw a poprzedzona je s t ukośnikiem . N a przykład cały dokument rozpoczyna się znacznikiem <htm l>, a kończy znacznikiem </htm l>. Znaczniki <head> i </head> otaczają nagłów ek dokum entu. Znaczniki <title> i </title> iden­ tyfikują tekst, który przeglądarka pow inna w yśw ietlić na pasku tytułow ym swojego okna. Znaczniki <body> i </body> otaczają opis strony, która m a być w yśw ietlo­ na w ew nątrz okna przeglądarki. Z naczniki < h ł> , < /h l> , <h2>, </h2> itd. służą do w skazania nagłów ków poszczególnych rozdziałów i sekcji w tekście. H TM L um ożliw ia też zdefiniow anie sposobu prezentacji dokum entu w przeglą­ darce internetowej. Znaczniki <center> i </center> nakazują w ycentrow anie treści, którą otaczają. Z nacznik <p> rozpoczyna nowy paragraf, a znacznik </p> kończy ,, 257 go. N iektóre znaczniki nie m ają pary, w ystępują sam odzielnie, np. znacznik <hr /> w yśw ietla poziom ą linię. Takie znaczniki, w edług najnow szej specyfikacji, mają po nazw ie spację i ukośnik. Z nacznik m oże też mieć param etry, które um ieszcza się w znaczniku otw ierającym po nazw ie i oddziela białym i znakam i. Param etry mają zw ykle postać: nazw a param etru, znak rów ności, wartość param etru w cu ­ dzysłow ach. Przykładow o znacznik <font size= ”6”> nakazuje zm ianę rozm iaru czcionki. O dpow iadający mu znacznik dom ykający </font> przyw raca poprzed­ ni rozm iar czcionki. N ow oczesne serw isy W W W nie korzystają z tej możliwości H TM L-u i opisują w ygląd strony za pom ocą arkuszy stylów CSS (ang. Cascading Style Sheets). H TM L pozw ala na osadzanie w tekście rysunków, filmów, odnośników do innych dokum entów itp. Na przykład znacznik <im g src=” ...” alt=”...” /> nakazuje um iesz­ czenie obrazka. Param etr sre w skazuje URI zasobu, który zaw iera ten obrazek i któ­ ry trzeba ściągnąć. Param etr alt określa tekst, który m a być w yświetlony, gdy tego zasobu nie udało się ściągnąć lub gdy przeglądarka pracuje w trybie tekstow ym i nie um ożliw ia w yśw ietlenia grafiki. Znaczniki <a href=” ...”> i </a> otaczają tekst odnośnika, zw ykle podkreślony i w yśw ietlany w kolorze niebieskim . Param etr href określa U RI zasobu, którego przeglądarka m a zażądać po kliknięciu na ten tekst. H TT P pozw ala też na osadzanie w dokum entach ciągów instrukcji języków skryp­ towych. H TM L um ożliw ia tw orzenie interaktyw nych formularzy. Znacznik <form action= ”...” m ethod=”...”> rozpoczyna definicję form ularza. P aram etr action definiuje URI, który ma być w ysłany do serwera. Param etr m ethod określa m etodę (zw ykle POST), która ma być użyta. Z nacznik </lbrm > kończy definicję formularza. W ewnątrz for­ m ularza m ożna zdefiniow ać kontrolki za pom ocą znacznika <input />. Param etr type określa typ kontrolki. Przykładow o w artość checkbox oznacza pole wyboru, a w artość subm it - przycisk, na który trzeba kliknąć, aby przeglądarka wykonała akcję opisaną w param etrach action i m ethod znacznika <form >. Interpretacja para­ metrów znacznika kontrolki zależy od typu kontrolki. Param etr value w kontrolce typu subm it określa tekst, który ma być w yśw ietlany na przycisku. Param etry name i value kontrolki typu checkbox oznaczają odpow iednio nazw ę i wartość param etru w ysyłanego w zapytaniu, które dla m etody G E T je st um ieszczane w polu <zapytanie> URI, a dla metody PO ST w ciele żądania, jak to przedstaw iono w przykładach w rozdziale 10.1.2. Nie ma tu miejsca na szczegółowy opis składni i \yszystkich elementów HTML-u. Czytelnik zainteresowany poznaniem tego języka bez problemu znajdzie w Internecie jakiś samouczek. Zamiast kontynuować jego opis, obejrzyjmy następujący przykład strony wygenerowanej przez serwer z prezentowanego w tym rozdziale przykładu 10. <himl> <headxtitle>Przykladowy Serwer HTTP</litlex/head> <bodyxcenler> < p x i m g src=”slm32_logo.gif”alt=”S T M 3 2 L O G O " / x / p > < p x f i § i t s iy ^ F |’6” > 0 0 0 : 0 9 : 0 2 . 4 7 0 < / f o n t x / p x h r /> < f o r m action=’ l/led”melhod="post”> 259 10.2. Przykład 10 - prosty serwis WWW < p > C z e r w o n a dioda świecąca <inpul type=”chcckbox”n a m e = ”L E D ”value=”R ”/></p> <p>Ziclona dioda świecąca cinput type="chcckbox”n a m e = " L E D ”value=”G ”checked /></p> | f .. 10 2 Prezentow any w tym podrozdziale przykład serw isu W W W składa się z serw era H TT P i aplikacji WWW. Serw er jest bardzo prosty, obsługuje tylko fragm ent proto­ kołu H TT P i nie je s t w pełni zgodny ze specyfikacją zaw artą w RFC 2616, ale jest w ystarczająco funkcjonalny, aby m ożna było oprzeć na nim aplikację kom unikują­ cą się z m ikrokontrolerem za pom ocą przeglądarki internetowej. Serw er ten może też być podstaw ą do w łasnej, pełniejszej im plem entacji HTTP. N azw y plików tego przykładu zebrano w ta b e li 10.2. W iększość z nich opisałem ju ż w poprzednich rozdziałach. W kolejnych podrozdziałach om aw iam szczegółow o pliki specyficzne dla tego przykładu. < p x i n p u t type=”submit”valuc=”Z m i e ń ”/></p> < / f o r m x h r /> <p>iwIP/i.3.2 C M S i S / i . 3 0 S T M 3 2 F 1 0 x Standard Periplicrals Library/3.3.0 ncwlib/i.!8.0</p> </ccntcrx/body> </html> Na podstaw ie pow yższego opisu przeglądarka internetow a w yśw ietla stronę poka­ zaną na ry s u n k u 10.1. N a górze je s t w yśw ietlany obrazek, a poniżej niego czas, który upłyną! od uruchom ienia m ikrokontrolera. Pom iędzy poziom ym i liniami znaj­ duj;) się pola w yboru i przycisk Z m ień um ożliw iające sterow anie diodam i świecący-; mi w zestaw ie ZL29A R M . N a dole w yśw ietlane są inform acje o w ersjach bibliotek użytych do skom pilow ania przykładu. ; <3 Przykładowy Serwer HTTP - Microsoft In te l net rnplm er File Edit g )B a c k - View Favorites - ¿ j) Tools jj| M B Help _ . ■ x ') |y P Address | ÿ | h ttp :// 192. l 68. 51.B9/ s” reh Favorites _ . s ___ _____ _ [ f, j j - ,;v @ - iJ k £ j Go „ l Unl^ r " -Tv' ■•-S T M . ' ■$ ..." A ■U33 OfG. niiam al, duel CAN. ;u';'.c i. ¡'ss Is! 0 00 :09 :02.470 Przykład 10 - prosty serwis WWW ... 10 2 1 Pliki http_parser.h i http_parser.c H TTP je st protokołem tekstow ym , więc serw er m usi przetłum aczyć odebrany ko­ m unikat na postać lepiej nadającą się do dalszego przetw arzania, zw ykle na postać binarną. Proces ten nazyw a się parsow anie i obejm uje analizę leksykalną oraz skła­ dniow ą tekstu. N ie w dając się w szczegóły, chodzi w skrócie o pom inięcie nieistot­ nych fragm entów tekstu (białych znaków, kom entarzy), w yszukanie słów kluczo­ w ych, specjalnych sekw encji znaków (operatorów ), nazw (identyfikatorów ), stałych (literałów ), a następnie spraw dzenie popraw ności składni i stw orzenie struktury da­ nych, którą będzie m ożna dalej w ygodnie przetw arzać. K om unikaty H TTP są dość skom plikow ane i napisanie pcinego parsera H TT P je s t zadaniem czasochłonnym . Z w ykle nie pisze się parserów od podstaw. Istnieją dobre darm ow e narzędzia, ta­ kie ja k na przykład Flex i Bison, um ożliw iające przyspieszenie i zautom atyzow a­ nie procesu im plem entow ania parsera. Poniew aż jed n ak przykładow y serw er ma być bardzo prosty, napiszem y też prosty parser. Jego interfejs definiujem y w pliku h ttp jm rse r .h , a im plem entację um ieszczam y w pliku http_jmrser.c. Zaczynam y od zdefiniow ania typu w yliczeniow ego m ethod_t dla m etod, które parser m a rozpo­ znaw ać. typedef enum (GET_METHOD = 1, POST__METHOD = 2| method_t; Tab. 10.2. Pliki przykładu 10 Źródłowe 1 biblioteczne C z e r w o n a dioda świecąca JH_. Zielona dioda świecąca * ‘Zmień ex_httpd.c http_application.c http_parser.c htlp_server.c startup_stm32_cld.c board_conl.c boardJ n il.c boardJe d .c http.h http_applicalion.li http_parser.h http_serm .h stm32_logo.h board_conf.h board_del.h board_dels.h boardJnit.h bo a rd je d .h util_delay.c util_eth_nc.c u tilje d .c u liljw ip .c util time.c Iiblwip4.a Iibstm32l10x.a Nagłówkowe lwIP/1.3.2 C M S I S / 1 . 3 0 S T M 3 2 F 1 0 x Standard Peripherals Library/3.3.0 newlib/1.18.0 .¿J [ ¿ j Done Rys. 10.1. Główna strona serwisu WWW z przykładu 10 | $ Internet - ..------------------------------------- ulil_delay.h util_error.h ulil_elh.li u lilje d .h u tiljw ip .h u tiljtc .h u til tim e.li cc.h cortex-m3.h Iwipopts.h stm32t10x_conf.h 260 10. Serwis WWW D efiniujem y też typ w yliczeniow y s t a t u s _ t dla kodów statusu odsyłanych klien­ towi przez serwer. Są to tylko niektóre, w ybrane kody statusu, spośród zdefinio-F w anych w RFC 2616. N asz serw er je s t bardzo uproszczony i w iększość b łę d ó w : w żądaniu otrzym anym od klienta kw ituje statusem „400 Bad R equest” . Naton napotkaw szy problem z udzieleniem odpow iedzi, w ysyła klientow i status „51 Internal Server E rror” . D odatkow o serw er rozpoznaje błędną nazw ę zasobu i nieoh- '■ sługiw aną w ersję HTTP, w ysyłając odpow iednio status „404 N ot Found” lub „51 ■' . H TTP Version N ot Supported” . Status „100 C ontinue” je st używ any wewnętrznie, •>.; przez serw er i oznacza, że analiza żądania jeszcze się nie zakończyła. Jeśli żądl klienta je s t popraw ne, to serw er odsyła żądany przez niego zasób i w odpowied ■ um ieszcza status „200 O K ” . typedef enum (Continue_X00 = OK_200 ~ = Bad_Request_400 = Not_Found_404 = Internal_Server_Error_500 = HTfP_Version_Not_Supported_505 = 10.2. Przykład 10 - prosty serwis W W W ' 261 p aram _len. Jeśli param etr zostanie znaleziony, to pod odpow iednim indeksem w tej tablicy parser um ieszcza wartość 1. struct http_parser * http_parser_new(char const * const * const res_tbl, int res_len, char const * const * const prm_tbl, int prm_len) { struct http_parser *s; s = memjnailoc(sizeof(struct http_parser) + prm_len - 1); if (s) ( s->state « METHOD_STATE; s->method = 0; s->buffer_idx = 0; s->resource_tbl = res tbl; s->resource__len = res_len; s->resource_idx = -ł; s->content_len = 0; s->param_tbl = prm_tbl; s->param_len = prm__len; memset(s->param_flag, 0, prm_len); 100, 200, 100, 404, 500, 505) status_t; } return s; W ew nętrzny stan parsera przechow ujem y w strukturze typu h ttp _ p a r s e r . i łdefine BUFFER_SIZE 32 struct http_parser { state; state_t method; method t buffer[BUETER_SIZE]; char buffer idx; int char const * const * resource_tbl; resource len; int resource idx; int content len; int char const * const * param tbl; param len; int param flag 11j; char Funkcja p arser_ n ew tw orzy now y parser, czyli alokuje nową strukturę typu h ttp _ p a r s e r i inicjuje jej składow e. Jej pierw szy argum ent r e s _ t b l je st wskaźnikiem do tablicy w skaźników do nazw zasobów, które parser m a rozpoznaw ać. Drugi argum ent re s _ le n zaw iera rozm iar tablicy r e s _ tb l. Trzeci argum ent prm _tbl je st w skaźnikiem do tablicy w skaźników do napisów z param etram i, które parser ma rozpoznaw ać. C zw arty argum ent prm _len zaw iera rozm iar tablicy prra_tbl. Funkcja ta zw raca w skaźnik do struktury typu h tt p _ p a r s e r , która identyfikuje par­ ser. W skaźnik ten je s t przekazyw any ja k o pierw szy argum ent pozostałych funkcji m odułu parsera. Dzięki tem u m ożna utw orzyć w iele parserów - każde odebrane przez serw er połączenie T C P m a przydzielony w łasny parser. Funkcja zw raca N U L L , gdy nie udało się przydzielić pam ięci. Parser im plem entujem y jak o autom at stanowy. Stan parsera przechow ujem y w skła­ dow ej s t a t e . D efinicja typu s t a t e _ t znajduje się w dalszej części tego podrozdzia­ łu, przy opisie autom atu. W składow ej raethod parser zapisuje identyfikator rozpo­ znanej metody. W składow ej b u f f e r parser przechow uje fragm ent analizowanego kom unikatu. Składow a b u f f e r _ id x zaw iera liezfię,-znaków zapisanych aktualnie w tym buforze. Składow a r e s o u r c e _ tb ł jest w skaźnikiem do tablicy wskaźników do nazw zasobów, które parser m a rozpoznaw ać. Składow a re s o u rc e _ łe n zawiera , rozm iar tej tablicy, czyli liczbę zasobów , które m ają być analizow ane. W składowe) resource__idx parser um ieszcza indeks znalezionego zasobu. Składow a contc:v__ le n zaw iera liczbę znaków , które pozostały jeszcze do przeanalizow ania w ciele żądania. Składow a p a ra m _ tb l je st w skaźnikiem do tablicy w skaźników do napisów zaw ierających param ęjry, które parser ma rozpoznaw ać w ciele żądania. Każdy na­ pis składa się z nazw y param etru, znaku rów ności i w artości param etru. Składowa p aram _len zaw iera rozm iar tej tablicy w skaźników . Składow a p a ram _ flag je st ta­ blicą, w kfórej parser um ieszcza inform acje o znalezionych param etrach. Tablica ta jest alokow ana dynam icznie i inicjow ana zeram i, a jej rzeczyw isty rozm iar wynosi void http_parser_delete(struct http_parser *s) { mem free(s); i Funkcja p a r s e r _ d e le t e usuw a parser i zw alnia zajm ow aną przez niego pamięć. Jej argum entem jest w skaźnik do struktury opisującej parser, który m a być usunięty. K olejne trzy funkcje um ożliw iają odczytanie w yniku parsowania. method_t http_parser_method(const struct http_parser return s ? s->method : -1; 1 Funkcja h ttp _ p a rse r_ m e th o d zw raca identyfikator rozpoznanej w żądaniu metody. Jej argum entem je st w skaźnik do struktury opisującej parser. Popraw ny identyfika­ tor m etody nigdy nie je st liczbą ujem ną. int http_parser_resource(const struct http_parser *s) ( return s ? s->resource_idx : -1/ F unlJlja h |t)p _ p a rser_ _ reso u rce zw raca indeks rozpoznanego zasobu. Jej argu­ m entem jestji'wskaznik do struktury opisującej parser. Z w rócenie w artości ujem nej 262 10. Serwis WWW1 oznacza, że nie znaleziono zasobu - składow a re s o u rc e _ id x je s t inicjow ana w ar-’, tością -1 . int http_parser_param(const struct http_parser *s, int idx) { return s SS idx >= 0 ss idx < s->param_len ? s->param_£laq[idx) : 0; I Funkcja h ttp _ p a rs e r_ p a ra m zw raca w artość 1, gdy parser znalazł param etr o in—; deksie id x , a w artość 0 w przeciw nym przypadku. Jej pierw szym argum entem jest w skaźnik do struktury opisującej parser. Drugi argum ent id x je st indeksem spraw ­ dzanego param etru. status_t http_parser_do(struct http_parser *s, char x) 1 if (! s) return Internal_Server_Error_500; else if {s->bu£fer_idx < BUFFER_SIZE) s->buffer[s->buffer_idx+t-] = x; switch (s->state) { ) } W łaściw ym parsow aniem żądania zajm uje się funkcja h ttp _ p a rs e r _ d o . Jej pierw­ szym argum entem je st w skaźnik do struktury opisującej parser. Funkcja ta jest w yw oływ ana po kolei dla każdego znaku analizow anego kom unikatu. Jej drugi argum ent x zaw iera kolejny analizow any znak. Funkcja zw raca status procesu parsow ania. Jeśli zw róci w artość C ontinue_100, oznacza to, że parsow anie nie zostało jeszcze zakończone, a funkcja w yw ołująca parser pow inna kontynuow ać odbieranie znaków ze strum ienia T C P i przekazyw anie ich parserow i. Jeśli parser zw róci inny status, to oznacza, że parsow anie zostało zakończone i funkcja w yw ołująca parser pow inna podjąć akcję stosow ną do otrzym anego statusu oraz przestać wywoływać parser. A nalizow ane znaki grom adzim y w pom ocniczym buforze b u f f e r . Zakładamy przy tym , że żaden poszukiw any U RI ani param etr (w raz ze znakiem końca wier­ sza) nie je st dłuższy niż BUFFER_SIZE znaków. L iczbę dotychczas zgrom adzonych znaków przechow ujem y w składow ej b u ff e r_ id x . Parser im plem entujem y jak o au­ tom at stanowy. Instrukcja sw itc h rozdziela sterow anie zależnie od aktualnego sta-, nu s t a t e . D la każdego stanu im plem entujem y sekcję c a se . Identyfikatory stanów autom atu definiujem y ja k o typ w yliczeniow y s t a t e _ t . typedef enum {METHOD_STATE, URI_STATE, VERSION_STATE,,,p*RAM_STATE, CONTENT_STATE, END_STATE, ERROR__STATE) state_t; Parser zaczyna od stanu METHOD_STATE (patrz funkcja h ttp _ p a rse r_ n e w ) i jeśli, zm ienia stan, to zaw sze na stan o w yższym num erze. Stan ERROR_STATE oznacza w ystąpienie błędu i parser ju ż nigdy nie w ychodzi z tego stanu. Poniżej opisuję kolejne sekcje ca se , czyli działanie parsera w poszczególnych stanach. W stanie M ETHOD_STATE parser próbuje rozpoznać m etodę żądania. A ktualnie parser rozpo­ znaje tylko dw ie metody, ale dodanie kolejnych nie pow inno spraw ić kłopotu. case METHOD_STATE: > if {s->buffer_idx == 4 strncmp(s->buffer, "GET ", 4) == 0) { s~>method = GET_METHOD; s->buffer idx = 0; ¡0.2. Przykład 10 - prosty serwis WWW 263 s->state = URI_STATE; i else if {s->buffer_idx == 5 && strncmp(s~>buffer, "POST ", 5) == 0} { s->method = P0ST_METH0D; s->buf fer__idx = 0; s->state * URI_STATE; ) else if (s->buffer_idx >= 5) { s~>state = ERROR__STATE; return Bad_Request 400; } return Continue_100; Po rozpoznaniu m etody przechodzim y do stanu URI STATE. W tym stanie analizu­ jem y URI żądania. Parsow anie U RI jest bardzo uproszczone. Zaim plem entow anie pełnego parsera U RI je st trudne, gdyż ten sam identyfikator m oże być zapisany na wiele sposobów, dopuszczalne jest szesnastkow e kodow anie znaków (sekw encja roz­ poczynająca się od znaku procentu) itd. Spacja nie je st popraw nym znakiem w URI - jest zapisyw ana jako sekw encja %20. D latego koniec U RI rozpoznajem y po otrzy­ maniu spacji oddzielającej U RI od pola zaw ierającego w ersję HTTP. Poniew aż spa­ cja nie jest częścią URI, przed dalszym i spraw dzeniam i trzeba ją usunąć z bufora. O trzym any U RI porów nujem y po kolei ze w szystkim i U RI um ieszczonym i w tabli­ cy re s o u r c e _ tb l. Po w ykryciu zgodności zapam iętujem y indeks znalezionego URI w składowej re s o u rc e _ id x i przechodzim y do stanu VERSION_STATE. case URI_STATE: if (x = = ' ' ) ! int i; if (s->bufferis->buffer_idx - 1 ] == 1 '} s->buffer_idx— ; for (i = 0; i < s->resource_len; ++i) ( if {strncmp(s->buffer, s->resource_tbifi], s->bu£fer_idx) =« 0) { s->resource_idx = i; s->buffer_idx = 0; s->state = VERSION_STAT£; return Continue_100; } ) s->state = ERROR__STATE; return Not_Found_404; ) else if {s->buffer_idx >= BUFFER_SIZE) { s->state = ERROR__STATE; return Bad_Request_400; } return Continue_100; W stanie VERSION_STATE sprawdzamy, czy n u m e r wersji w o t r z y m a n y m żądaniu zgadza się z obsługiwanymi wersjami HTTP. D o p u s z c z a m y obie istniejące aktu­ alnie wersje protokołu. Po p o p r a w n y m zweryfikowaniu wersji przechodzimy d o stanuj,PARAM STATE. * lt case VESS^ON_STATE: if (S“2ttfuffer idx == 10 && 10.2. Przykład 10 - prosty serwis WWW (strncmp(s->bu£fer, "HTTR/l.0\r\n", 10) = = 0 1 1 strncmp(3->buffer, "HTTP/l.l\r\n", 10) == 0)) ( s->buf fer_.idx = 0; s->state = PARAM_STATE; i ełse if {s->buffer_idx >= 10) { s->state = ERROR_STATE; return HTTP_Version_Not_Supported_505; 265 czonym i w tablicy p arara_ tb l. Inform ację o wykryciu zgodności zapam iętujem y w tablicy p aram _ flag . Jeśli cala zaw artość ciała kom unikatu została ju ż przetw o­ rzona, to przechodzim y do stanu końcow ego END_STATE. case CONTENT_STATE: s->content_len— ; if (x == *6' |j s->content_len == 0) { int i; ) return Continue_100; W stanie PARAM_STATE analizujem y pozostałą część nagłów ka HTTP, zawierającą param etry żądania. W ykryw am y dw ie sytuacje: koniec nagłów ka (bufor zawiera ' tylko znaki C R i LF) i w ystąpienie param etru Content-Length. W artość tego para­ m etru oznacza długość ciała w iadom ości. Jeśli kom unikat nie m a ciała, to przecho­ dzim y do stanu końcow ego END_STATE, a jeśli ciało w ystępuje (param etr Conte:.- Length m a dodatnią w artość), to przechodzim y do stanu CONTENT_STATE. case PARAM_STATE: if (x == <\ n ') t if (s->buffer__idx == 2 66 s->bu£fer(0) == *\ r * 66 s->bufferilj == '\n'} ( if (s->content__len > 0) s~>state = CONTENT_STATE; else { 5->state o END_STATE; return OK_20Q; i } else if (s->buffer_idx >= 19 66 strncmp(s->buffer, "Content-Length: ", 16) == 0 66 s->buffer[s->bu£fer_idx - 2) == '\r' 66 s->buffer{s->buffer_idx - 1] == *\ n 1) { int i; for (i = 16; i < s->buffer_idx - 2; ił-i) { if (isdigit{(int)s->bufferti])) { s->content_len *= 10; s->content_len += s->buffer(ij - *0'; ) else 1 s->5tate = ERROR_STATE; return Bad_Request 400; , i i s->buffer_idx = 0; } return Continue_100; W stanie CONTENT_STATE analizujem y zaw artość ciała kom unikatu i poszukujem y pa-; ram etrów z form ularza H TM L. Parsow anie je s t bardzo uproszczone. Przyjmujemy, że param etry rozdzielane są znakiem &. K oniec param etru rozpoznajem y po otrzy­ m aniu tego znaku lub gdy nie m a ju ż więcej znaków do przetw orzenia. Z nak & nie je st częścią param etru, dlatego przed dalszym i spraw dzeniam i usuw am y go z bufo­ ra. O trzym any param etr porów nujem y po kolei ze w szystkim i param etram i umiesz- if (s->buffer{s->bu£fer_idx - 1] == '6') s->buffer_idx— ; for (i = 0 ; i < s->param_len; ++i) if (strncmp(s->buffer, s->param_tbl(i), s->buffer_idx) == 0) s->param flag(i] = 1; s->buffer_idx = 0; ) if (s->content_len == 0) { s->state = END_STATE; return OK_200; } return Continue_100; Jeśli co ś poszło źle, np, funkcja http__parser_do została ponow nie wywołana, m im o że w cześniej zw róciła status różny od C ontinue_100, to w ykonujem y sekcję d e f a u l t. Jedyne co można zrobić w tej sytuacji, to zw rócić inform ację o błędzie. default: s->state = ERROR_STATE; return Internal_Server_Error_500; Pliki http_server.h, http.h i http_application.h Plik http_server.h zaw iera definicję dom yślnego num eru portu H TTP oraz deklara­ cję funkcji H T T P serv erS tart, która urucham ia serw er HTTP. Funkcja ta jest zaim ­ plem entow ana w pliku http_server.c i je st identyczna ja k funkcja T C P s e rv e rS ta rt z przykładów 5a i 5b, zaim plem entow ana w pliku tcp_servei:c. A rgum entem tych funkcji je st num er portu, na którym serw er m a nasłuchiw ać. Funkcje te zw racają zero, gdy uruchom ienie serw era pow iedzie się, a w artość ujem ną w przeciwnym przypadku. idefine HTTP_RORT 80 int HTTPserverStart (uint!6__t); W pliku http.h zadeklarow ana jest struktura typu h tt p . D efinicja tej struktury znaj­ duje się w pliku http_server.c. Struktura h t t p przechow uje w szystkie niezbędne inform acje zw iązane z obsługą żądania i w ysyłaniem odpow iedzi HTTP. struct http; Ponadto w pliku http.h zadeklarow ane są poniższe funkcje operujące na strukturze typu h t t p i używ ane w pliku http_application.c\ który opisuję w jednym z następ­ nych podrozdziałów. Im plem entacja tych funkcji znajduje się w pliku http__server,c. charjj|phttpj|data_new{struct http *, size_Ł); void http_dat^_len(struct http *, size_t); void http_dat!a_rom(struct http *, const char *, size t); 10. Serwis WFiy 266 W pliku http_application.h znajdują się deklaracje pozw alające w sposób ogólny zdefiniow ać algorytm działania prostego serwisu WW W . W tablicy r e s o u r c e _ tb l należy um ieścić w skaźniki do napisów reprezentujących URI, które m ają być ob­ sługiw ane przez serw is. Z m ienna r e s o u r c e _ tb l_ le n m usi zaw ierać rozm iar tej ta­ blicy, czyli liczbę obsługiw anych URI. W tablicy p a ra r a e te r_ tb l należy umieścić w skaźniki do napisów zaw ierających param etry, które są generow ane przez for­ m ularze generow ane przez nasz serw is. Z m ienna p a ra m e te r _ tb l_ le n musi zaw ie­ rać rozm iar tej tablicy, czyli liczbę obsługiw anych param etrów. Pow yższe tablice i zm ienne definiujem y w pliku http_applicałion.c. extern extern extern extern const const const const char * const resource_tbi(j; int resource_tbl_len; char * const parameter_tbl(j; int parameter_tbl_len; size_t size_t uint32 Sam ą logikę działania serw isu im plem entujem y też w pliku http_application.c w funkcji m ake_http_answ er. A rgum entam i tej funkcji są w skaźniki do struktur opisujących stan obsługi żądania H T T P oraz parser. Funkcja ta na podstaw ie in­ formacji uzyskanych od parsera m usi w ygenerow ać odpow iedź H TT P i zwrócić status HTTP. Z w rócenie w artości OK_200 oznacza, że w ygenerow anie odpowiedzi pow iodło się i należy ją w ysiać klientow i. Inny status oznacza w ystąpienie proble­ mu. W tedy funkcja, która w yw ołała funkcję m ake_http_answ er, musi obsłużyć ten problem - w tej sytuacji najlepiej je s t w ysiać klientow i inform ację zaw ierającą ten status. ); Składow a d a ta _ f la g s struktury typu h t t p przechow uje znaczniki potrzebne do obsługi bufora danych. A ktualnie zdefiniow any je st tylko jeden w skaźnik F L A G _ NEEDS__FREE. M usi być on ustawiony, gdy bufor d a ta został przydzielony na stercie za pom ocą funkcji m em jnalloc i przed usunięciem z pam ięci struktury typu h t t p musi zostać zw olniony za pom ocą funkcji mem_f re e . Jeśli składow a d a ta w skazuje na dane w pam ięci stałej (w naszym przypadku Flash), to nie zw alnia się pam ięci zajm ow anej przez te dane i znacznika F L A G _ N E E D S _ F R E E nie ustawiamy. static struct http * http_new(void) ( struct http parser *parser; struct http *bttp; parser = http_parser_n e w (resource_tbl, resource_tbl_len, parameter_tbl, parameter__tbl_len); if (parser == NULL) return NULL; http = memjnałloc(sizeof(struct http)); if (http) { http->parser = parser; http->data = NULL; http->data_flags = 0; http->data_idx = 0; hfctp->data_left = 0; http~>status = Continue_100; http->timeout * SERVERJFIMEOUT; Plik http_server.c - obsługa HTTP 1 10 Serw er przechow uje dane niezbędne do obsłużenia klienta w strukturze typu h ttp . Składow a p a r s e r je s t w skaźnikiem do struktury opisującej parser przypisany temu klientow i. Składow a s t a t u s zaw iera aktualny statuę»absługi żądania H TTP zgodnie z tabelą 10.1. Składow a tim e o u t zaw iera liczbę sekund, które pozostały jeszcze do zakończenia obsługi klienta. Składow a d a ta jest w skaźnikiem do bufora z od­ pow iedzią, która m a być w ysłana klientow i. O dpow iedź często je st zbyt duża, aby m ogła być w ysiana w jed n y m segm encie TCP. D latego m usim y zaim plem entow ać w ysyłanie odpow iedzi w kaw ałkach. Składow a d a ta _ id x w skazuje pozycję pierw ­ szego jeszcze niew ysłanego bajtu w buforze w skazyw anym przez d a ta . Składow a d a ta l e f t zaw iera liczbę bajtów, które pozostają jeszcze do w ysiania. struct http { struct http_parser status_t * int char * *parser; status; timeout; *data; 1 N ie należy bezpośrednio m anipulow ać składow ym i struktury typu h tt p . D o obsługi tej struktury im plem entujem y szereg funkcji. Funkcja h t t p new przydziela nową strukturę typu h t t p i inicjuje jej składow e. Z w raca w skaźnik do tej struktury lub w artość NULL, gdy w ystąpił problem z alokacją pam ięci. Funkcja ta tw orzy też nową instancję parsera. Plik http_server.c zaw iera im plem entację serw era HTTP. N ajpierw zajm ijm y się obsługą żądania HTTP. A by serw er nie został zaw ieszony przez złośliw ego klien­ ta, ustalam y, że połączenie z klientem m oże trw ać m aksym alnie 10 sekund. Jest to czas zupełnie w ystarczający, aby odebrać i przeanalizow ać żądanie oraz wysłać odpow iedź. łdefine SERVER_TIMEOUT t 267 data_idx; data_left; data_flags; Idefine FLAG_NEEDS_FREE status_t make__http_answer (struct http *, const struct http_parser *); 10.2.3. 10.2. Przykład 10 - prosty serwis VkWW else http_parser_delete(parser); return http; ) Funkcja h tt p _ d e le t e usuw a z pam ięci strukturę typu h tt p . N ajpierw jednak usu­ w am y parser i ew entualnie zw alniam y bufor w skazyw any przez składow ą d a ta . A rgum entem tej funkcji je st w skaźnik do zw alnianej struktury typu h ttp . static void http_delete(struct http *http) ( http_parser_delete(http->parser); if (http->data_flags S FLAG_NEEDS_FREE) meą_free(http->data); mem free(httpl; 1 Funkcja h t t p d a ta new alokuje bufor, w którym m a być um ieszczona odpow iedź udłfclanu$p|rzez serwer. Pierw szym argum entem tej funkcji jest w skaźnik do struk­ tury typu h & p , do której m a być przypisany alokow any bufor. Drugi argum ent s i z e 268 10. Serwis WWW zaw iera żądany rozm iar tego bufora. Funkcja ta zw raca w skaźnik do przydzieli go bufora lub w artość NULŁ, gdy przydzielenie pam ięci się nie pow iodło. Funkcja h ttp _ d ata_ n ew je st przew idziana do w yw ołania przez aplikację W W W zaim m entow aną w pliku http_application.c. char * http_data_new(struct http *http, size_t size) { http->data = memjnalloc(size); if (http->data) { http->data_idx = 0; http->data_left = size; http~>data_flags = FLAG_NEEDS_FREE; ) return http->data; ) Funkcja h tt p _ d a ta _ d e łe te zw alnia bufor przypisany do składow ej d a ta struktury typu h tt p . Jej argum entem je st w skaźnik do struktury typu h tt p , do której przypi­ sany je s t zw alniany bufor. static void http_data_delete(struct http *http) ( if (http->data_flags & FLAG_NEEDS_FREE) { mem_free(http->data); http->data = NULL; http->data__idx = 0; http~>data_left - 0; http->data_flags » 0; ■ 10.2. Przykład 10 - prosty serwis WWW' static int http_sent(struct http *http) { return http->data_left == 0; ! F unkcja h ttp _ tim e o u t zm niejsza licznik czasu, który pozostał jeszcze do zakoń­ czenia obsługi klienta. Z w raca zero, gdy obsługa klienta m a być kontynuow ana, a jeden w przeciw nym przypadku, czyli gdy należy zakończyć obsługę klienta. Jej pierw szym argum entem jest w skaźnik do struktury typu h ttp . static int http_timeout(struct http *http) ( return — (http->timeout) <= 0; 1 F unkcja h ttp _ s e n d w ysyła porcję danych z odpow iedzią serwera. Jej pierwszym argum entem je s t w skaźnik do struktury typu h tt p . Drugi argum ent pcb jest w skaź­ nikiem do deskryptora T C P opisującego połączenie TCP, przez które dane mają zostać w ysiane. Funkcja ta najpierw spraw dza za pom ocą funkcji tc p _ sn d b u f ilość w olnego m iejsca w buforze nadaw czym TCP. Jeśli jest w nim dostatecznie dużo m iejsca, aby w ysiać w szystkie dane, to w ysyłam y je w całości. Jeśli bufor nadaw ­ czy je st zbyt mały, to w ysyłam y tylko fragm ent danych i ustaw iam y znacznik TCP_ WRITE_FLAG_MORE oznaczający, że będą jeszcze w ysiane kolejne fragmenty. static void http_send(struct http ‘ http, struct tcp_pcb *pcb) | uintl6_t len; uint8 t flag; len = Łcp_sndbuf (pcb) ;* if (len > 0 SS http~>data && http->data_Ieft > 0) ( if (len >= http->data_left) ( len = http->data__left; flag => 0; ) 1 Funkcja h ttp _ d a ta _ łe n m odyfikuje rozm iar danych, które pozostały jeszcze do wysiania. Jej pierw szym argum entem je st w skaźnik do struktury typu h tt p . Drugi argum ent s i z e zaw iera nowy rozm iar danych. Funkcja h tt p _ d a ta _ le n je s t przew i­ dziana do w yw ołania przez aplikację W W W zaim plem entow aną w pliku http_applicalion.c. ) else flag * TCP_WRITE_FLAG__MORE; if (ERR_OK == tcp_write(pcb, http->data + http->data_idx, len, flag)) { http->data_idx i= len; http->data_JLeft -= len; void http_data_len(struct http *http, size_t size) { http->data_ieft = size; ) Funkcja h ttp _ d a ta _ ro ra przypisuje do struktury typu h t t p odpow iedź serw era znaj­ dującą się w pam ięci stałej. Jej pierw szym argum entem je s t w skaźnik do struktury typu h tt p . Drugi argum ent d a ta je st w skaźnikiem do m iejsca w pam ięci, gdzie znajduje się odpow iedź serw era. Trzeci argum ent s i a e zaw iera rozm iar tej odpo­ w iedzi. Funkcja h ttp _ d a ta _ ro m je st przew idziana d e w yw ołania przez aplikację W W W zaim plem entow aną w pliku http_application.c. void http_data_rom(struct http *http, const char *data, size_t size) ( http->data = (char *)data; http->data_idx = 0; http->data_left = size; http->data_flags = 0; •* i > Funkcja h tt p _ s e n t spraw dza, czy w szystkie dane zostały ju ż w ysiane. Z w raca zero, gdy jeszcze jakieś' dane pozostały do w ysłania, a jeden w przeciw nym przypadku. Jej pierw szym argum entem je st w skaźnik do struktury typu h ttp . 269 } ) I Funkcja h ttp _ e n g in e obsługuje żądanie klienta. Jej pierw szym argum entem jest w skaźnik do struktury typu h tt p . Drugi argum ent pcb je st w skaźnikiem do de­ skryptora T C P opisującego połączenie TCP, z którego odebrano żądanie. Trzeci ar­ gum ent p je st w skaźnikiem do łańcucha buforów, które zaw ierają odebrane dane. D opóki status H TTP ma w artość C ontinue_100, czyli serw er oczekuje na kolejne porcje żądania, to funkcja ta dla każdego odebranego znaku w yw ołuje funkcję parsera h ttp _ p a rs e r_ d o . Jeśli status H TTP zm ieni się na OK_200, co oznacza, że zosta­ ło odebrane popraw ne żądanie, to w yw ołujem y funkcję m ake_http_answ er, której zadaniem jest przygotow anie odpow iedzi dla klienta. W trakcie przygotow yw ania odpow iedzi status H TTP może się zm ienić. Jeśli się zm ienił, to usuw am y ew entualnąjprzygotow aną przez funkcję m ake_http_answ er odpow iedź za pom ocą funkcji h t t ^ d a t # J d e l e t e . N astępnie, jeśli status H TTP jest różny od OK_200, w yw ołuje­ my funkcjęi|lh ttp _ e r r o r _ r e s p o n s e , której zadaniem jest przygotow anie odpowiedzi 10.2. Przykład ¡0 - prosty serwis 10. Serwis lVW\y 270 "Content-Type: text/html\r\n" "\r\n" "<html>" "<headxtitie>£rror</titlex/head>" "<bodyxhl>404 Not Found</hlx/body>" "</html>"; static const char internai_server_error_500_htmł{) = "HTTP/1.1 500 Internal Server Error\r\n" "Connection: close\r\n" "Content-Type: text/htmł\r\n" "\r\n" "<html>" "<headxtitłe>Error</titlex/head>" "<bodyxhl>500 Internal Server Error</hlx/body>" "</html>"; static const char version_not_supported_505_html[] = "HTTP/1.1 505 HTTP Version Not Supported\r\n" "Connection: close\r\n" "Content-Type: text/html\r\n" "\r\n" "<html>" "<headxtitle>Error</title></head>" "<body><hl>505 HTTP Version Not Supported</hlx/body>" "</html>"; inform ującej o błędzie. N a koniec w yw ołujem y funkcję h ttp _ s e n d , która inicjuje w ysłanie odpow iedzi. static void http_engine{struct http *http, struct tcp_pcb *pcb, struct pbuf *p) { struct pbuf *q; if {http->status == Continue_100) { for (q = p;; q = q->next) { uint8_t *c = (uint8_t *)q->payload; uint!6__t i; for (i = 0 ; i < q->len; ++i) { http->status = http_parser_do{http->parser, c[i]); if (http->status == Continue_100) continue; else if {http->status *= OK_200) { http->status = make_http_answer{http, http->parser); if {http->status != OK_200) http_data delete{http); 1 if {http->status != OK__200) http_error_response{http); http_send{http, pcb); return; switch{http->status) { case Bad_Request_400: http data_rom(http, bad_request 400_html, sizeof(bad_request_400_html) - 1); return; case Not_Found_404: http_data_rom{http, not_found_404_html, sizeof{not_found_404_html) - ł); return; case HTTP Version_Not_Supported_505: http_data_rom(http, version_not_supported_505_html, sizeof{version_not_supported_505_html) - 1); return; default: http data_rom{http, internal_server_error_500_html, sizeof{internal_server_error_500_html) - 1); return; ! if {q->len == q->tot_len) break; } ) ) Funkcja h ttp _ e r r o r _ r e s p o n s e przygotow uje odpow iedź inform ującą o w ystąpieniu błędu. Jej pierw szym argum entem je s t w skaźnik do struktury typu h tt p . Kom pletne odpow iedzi serw era dla poszczególnych kodów statusu H TT P definiujem y jak o sta­ łe napisy - kom pilator um ieści je w pam ięci Flash. W ydaje się to m arnotraw stw em pam ięci, bo w szystkie te odpow iedzi m ają w spólny w zorzec i m ożna by je genero­ wać dynam icznie. Pam iętajm y jed n ak , że fragm enty kodu obsługujące błędy pow in­ ny być m ożliw ie odporne na w ystąpienie kolejnych błędów, np. zw iązanych z alo­ kacją pam ięci. W ystąpienie problem u podczas obsługi sytuacji, która je st wynikiem innego problem u, m oże doprow adzić do załam ania się aplikacji, a pam ięci Flash m am y pod dostatkiem . D om yślną odpow iedzią jes.t^,5.00 Internal S erver E rror”, co jest dość rozsądnym rozw iązaniem . . static void http_error_response(struct http *http) ( static const char bad_request_400_html(] = "HTTP/1.1 400 Bad Request\r\n" "Connection: ciose\r\n" "Content-Type: Łext/html\r\n" "\r\n" "<html>" "<headxtitle>Error</titłeX/head>" "<bodyxhl>400 Bad..Request</hlx/body>" * "</html>"; static conkt char not_found_404_html() = "HTTP/1.1 404 Not Found\r\n" "Connection: close\r\n" 271 i } 10.2.4. Plik httpjserver.c - obsługa połączenia TCP' ' W pliku http_server.c znajduje się im plem entacja funkcji HTTPserverStart, która urucham ia serw er HTTP. Pisałem ju ż o niej w jednym z poprzednich podrozdzia­ łów. Pozostało om ów ienie funkcji zw rotnych obsługujących połączenie TCP. Ich im plem entacja bazuje na funkcjach serw era TCP, który opisałem w przykładach 5a i 5b. Funkcja zw rotna a ccept_callback je s t w yw ołana przez bibliotekę lw IP po odebraniu połączenia TCP. Jej zadaniem je s t przydzielenie do tego połączenia no­ wej struktury typu http i ustaw ienie pozostałych funkcji zw rotnych. W artość stałej P O M W p ę r | $EC O N D dobieram y tak, aby funkcja zw rotna tcp_poll była w yw ołana co sekundę. |i*i 272 10.2. Przykład 10 - prosty serwis WWW 10. Serwis WWW Sdefine POLL_PER_SECOND 273 if (http_timeout(http)) close_connection(http, pcb); /* Można też wysyłać tu. else http_send(http, pcb); 2 static err_t accept_callback(void *arg, struct tcp_pcb *pcb, err_t err) { struct http *http; */ return ERR OK; http = http__new(); if (http ==~NULL) return ERR_MEM; tcp_arg(pcb, http); tcp_err(pcb, conn_err_callback)/ tcp_recv(pcb, recv_callback); tcp_sent(pcb, sent_callback); tc p j> o ll( p c b , poll_callbaek, POLL_PER_SECOND); return ERR_OK; i Funkcja zw rotna c o n n _ e rr_ c a llb a c k je s t w yw ołana przez bibliotekę lwlP, gdy po­ łączenie T C P zostanie zam knięte aw aryjnie. Jej zadaniem jest zw olnienie pamięci przydzielonej przez serw er do obsługi klienta. W tym celu w yw ołujem y funkcję h tt p _ d e le t e . static void conn_err_callback(void *http, err_t err) ( http_delete (http); } Funkcja zw rotna re c v _ c a lib a c k je s t w yw ołana przez bibliotekę lw lP po odebraniu danych z połączenia T C P lub po zam knięciu tego połączenia. W celu przetw orzenia odebranych danych w yw ołujem y funkcję h ttp _ e n g in e . W reakcji na zam knięcie połączenia T C P przez klienta w yw ołujem y funkcję c lo s e _ c o n n e c tio n , którą opi­ suję na końcu tego podrozdziału. } P om ocnicza funkcja c lo s e _ c o n n e c tio n zw alnia w szystkie zasoby przydzielone przez serw er do obsługi klienta i zam yka połączenie TCP. static void close_connection(struct http *http, struct tcp_pcb *pcb) { tcp_recv(pcb, NULL); tcp_sent(pcb, NULL); tcp_polł(pcb, NULL, 0); http_delete(http); tcp_arg(pcb, NULL); , tcp_close(pcb); ’ static err_t recv_callback(void *http, struct tcp_pcb *pcb, struct pbuf *p, err_t err) ( if (p) I tcp_recved(pcb, p->tot__len); http_engine(http, pcb, p); pbuf_free(p); ) 1 else close connection(http, pcb); return ERR_OK; .2.5. Plik http_application.c i F unkcja zw rotna s e n t c a llb a c k jest w yw ołana przez bibliotekę lw lP po odebra­ niu potw ierdzenia dostarczenia danych. Z a pom ocą funkcji h tt p _ s e n t spraw dza­ my, czy cała odpow iedź została ju ż w ysłana. Jeśli w szystkie dane zostały wysłane, kończym y połączenie TCP, w yw ołując funkcję c lo s e _ c o n n e c tio n . Jeśli pozostały jak ieś dane do w ysłania, w yw ołujem y funkcję h ttp _ s e n d , która w ysyła kolejną ich porcję. Plik http_application.c zaw iera im plem entację logiki działania aplikacji WWW. Przerobienie prezentow anego w tym rozdziale przykładu na potrzeby innego ser­ wisu W W W w ym aga tylko m odyfikacji tego pliku. Zaczynam y od zdefiniow ania tablicy w skaźników r e s o u r c e _ tb l do napisów zaw ierających URI, które serw er ma rozpoznaw ać. M usim y rów nież zdefiniow ać rozm iar r e s o u r c e _ tb l_ le n tej tablicy. A by kod źródłow y był przejrzysty, definiujem y też za pom ocą dyrektyw S d efin e identyfikatory indeksów w tej tablicy. static err_t sent_callback(void *http, struct tcp_pcb *pcb, ul6_t len) { if (http_sent(http)) , close_connection(http, pcb); else http_send(http, pcb); return ERR_OK; »define MAIN_PAGE »define STM32_LOGO »define DONE_PAGE ) Funkcja zw rotna p o ll _ c a ll b a c k je s t w yw ołana cyklicznie przez bibliotekę lwlP. Z a pom ocą funkcji h ttp _ tim e o u t zm niejszam y licznik czasu, który pozostał do zakończenia obsługi klienta i jeśli czas ten ^ p ły n ą ł, zam ykam y połączenie TCP, w yw ołując funkcję c lo s e jc o n n e c tio n . W funkcji p o ll _ c a ll b a c k m ożem y też w y­ w ołać funkcję h ttp _ s e n d , ale nie w ydaje się to potrzebne. static err_t poll_callback(void *http, struct tcp_pcb *pcb) ( 0 1 2 const char * const resource_tbl[] = { *7", "/stm32_1ogo.gi f ” , "/led" i; const int resource_tbl_ien = sizeof(resource_tbl) / sizeof(resource_tbl[0]); Jeśli używ am y form ularzy H TM L, m usim y zdefiniow ać tablicę w skaźników p a ra m e te p _ tb l do napisów zaw ierających param etry form ularzy oraz rozm iar pararaeteiW bl*|l<ąn tej tablicy. A by zw iększyć czytelność kodu źródłow ego, definiujem y też za pom pcą dyrektyw lld e fin e identyfikatory indeksów w tej tablicy. 274 10. Serwis WWW ((define LED G Idefine LED_R 10.2. Przykład 10 - prosty serwis WWW O ł "Content-Type: text/html; charset=UTF-8\r\n” "\r\n" "<html>" "<headxtitle>Przykładowy Serwer HTTP</titlex/head>" "<body>" "<center>" " < p x i m g src=\"stm32__logo.gif\" altÄ\nSTM32 L0G0\" / x / p > " "<pXf o n t size=\"6\">%u %02u:%02u:%02u.%03u</fontx/p>" f'<hr />" "<form acfcion=V71ed\" method=\"post\">" "<p>" "Czerwona dioda świecąca " "<input type=\"checkbox\" name=V'LED\" value=\"R\" %s/>" "</p>" "<p>" "Zielona dioda świecąca " "<input type^'checkboxX" name=\"LED\" value=\"G\" %s/>" "</p>" " <pxinput type=\"submit\" value=X"Zmień\" /></p>" "</form>" "<hr />" const char * const parameter_tbl{3 = { "LE0=G", "LED-R" I; const int parameter tbl_len = sizeof (parameter__tbl) / sizeof (parameter_tbl(Oj); Serw er w celu w ygenerow ania odpow iedzi w yw ołuje funkcję raake_http_answ er. W funkcji tej najpierw w yw ołujem y funkcje parsera: h ttp _ p a rse r_ m e th o d i h tt p p a r s e r re s o u rc e , aby poznać m etodę i URI, które znajdow ały się w żądaniu przy­ słanym przez klienta. N astępnie, zależnie od U RI i metody, w ygenerow anie odpo­ wiedzi delegujem y do w łaściw ej funkcji lub zw racam y status „404 N ot Found” . status_t make_http_answer(struct http *http, const struct http_parser *parser) { method_t method; int idx; method = http_parser_method(parser); idx = http_parser resource(parser); if (idx == MAIN_PAGE &6 method == GET_METHOD) return http_main_page(http); else if (idx == STM32_LOGO && method == GET__METHOD) return http_stm32_logo(http); else if (idx == D0NE_PAGE method =»* P0ST_METH0D) return http_done_page(http, parser); else return Not_Foundj304; "<P>" "lwIP/%u.%u.%u CMSIS/%x.%x " "STM32F10x Standard Peripherals ŁibraryAu.%u.%u" łifdef NEWLIB_VERSION " newlib/" _NEWLIB_VERSION lendif "</p>" "</center>" "</body>" "</html>"; static const size_t main_page_2en = sizeof (main__page_html) + 12; , i O dpow iedź zaw ierającą głów ną stronę serw isu, przedstaw ioną na rysunku 10.1, ge­ nerujem y za pom ocą funkcji h ttp _ m ain _ p ag e. O pis strony tw orzym y dynam icznie. Stały w zorzec całej odpow iedzi znajduje się w statycznej tablicy m ain_page_htm l. Stała raain_page_len zaw iera rozm iar bufora, w którym m a być um ieszczona od­ pow iedź i który alokujem y za pom ocą funkcji h ttp _ d a ta _ n e w . R ozm iar bufora jest nieco w iększy niż długość napisu raain_page_htral, gdyż trzeba zapew nić miejsce na w staw iane w artości. S erw er m oże sym ultanicznie obsługiw ać w iele klientów. D latego do form atow ania odpow iedzi używ am y funkcji s n p r i n t f r , która jest w spółużyw alna. Z a pom ocą funkcji R edLED state i G reenL ED state odczytujem y stan diod św iecących i ustaw iam y odpow iednio stan pól w yboru w form ularzu. Jeśli nie pow iedzie się przydział bufora lub funkcja _ s n p r i n t f _ r zw róci błąd, to zw ra­ cam y status „500 Internal S erver E rror” . Po popraw nym sform atow aniu odpow iedzi ustawiam y za pom ocą funkcji h ttp _ d a ta _ le n w łaściw ą długość odpow iedzi, bez term inalnego zera, którego nie należy w ysyłać. Jeśli cala odpow iedź nie mieści się w buforze (choć nie w idać do lego realnego pow odu), to w ysyłam y część, która się zm ieściła, w nadziei żc je s t to lepsze rozw iązanie niż niew ysłanie żadnej odpow ie­ dzi. N a koniec, jeśli w sźystko poszło dobrze,^zw racam y status „200 O K ” . static status_t httpjnairTpa'ge (struct http *http) ( static const char main_page_html{] = "HTTP/1.1 200 0K\r\n" "Connection: close\r\n" int data_size; unsigned d, h, m, s, ms; char *data; struct _reent reent; H data = http_data_new(http, main_page_len); if (data == NULLT return Internal_Server_Error_500; GetLocalTime(&d, &h, &m, &s, &ms); data_size = _snprintf_r(&reent, data, main__page_len, main_page_html, d, h, m, s, ms, RedLEDstate() ? "checked " GreenLEDstate() ? "checked " : LWI PJfERS I0NJ4A JOR, LWI P_VERSI0N_MINOR, LWIP~VERSION_REVISION, CM3_CMS IS_VERSION_MAIN, _CM3_CMSIS_VERSI0N_SUB, _STM32F10X_STDPERIPH_VERSION_MAIN, __STM32F1OX_STDPERIP h " v ERSION_SÜ01, STM32 FI 0X__STDPERI PH_VERSION_SUB2} ; if (data_size <= 0) return Internal_Server_Error_500; if Jl{size_t)data_size < main_page_len) http_WtL_len (http, (size_t)data_size); else )'• 275 276 10.2. Przykład 10 - prosty serwis WWW 10. Serwis WWW http_data_len(http, main_page_len - 1); return OK_200; danie z m etodą POST. O bsługą tego żądania zajm uje się funkcja http_done_page, w której najpierw spraw dzam y za pom ocą funkcji h ttp _ p a rse r_ p a ra m , jakie pa­ ram etry zaw ierało to żądanie i stosow nie do tego w łączam y lub w yłączam y od­ pow iednią diodę św iecącą. N astępnie odsyłam y odpow iedź zaw artą w tablicy done_page_htm l. D ługość odpow iedzi określa stała done__page_len. Po otrzym aniu odpow iedzi przeglądarka w yśw ietla, przedstaw ioną na ry s u n k u 10.2, stronę infor­ m ującą o w ykonaniu zmiany. Po kliknięciu na tej stronie w odnośnik Powrót w ra­ cam y do głów nej strony serw isu WWW. Funkcja h ttp _ d o n e_ p ag e zawsze zw raca status „200 O K ”. I Na głów nej stronie serw isu W W W osadzony jest obrazek z logo m ikrokontrole­ rów ST M 32 - zasób stm 3 2 J o g o .g if. G dy klient zażąda tego zasobu, w yw ołujem y funkcję h ttp _ stm 3 2 _ lo g o . Sam obrazek oraz je g o rozm iar zdefiniow ane są w pliku stm 32_logo.h, który opisuję w następnym podrozdziale. Funkcja http__stm32__logo je st bardzo prosta, um ieszcza w łaściw e dane w strukturze typu h t t p za pom ocą funkcji http_data__rom i kończy działanie, zw racając status „200 O K ”. atatic status_t http_stm32_logo(struct http *http) ( łinclude <stm32_logo,h> static status_t http_done_page(struct http *http, const struct http_parser *parser) { static const char done_page__html [] = "HTTP/1.1 200 0K\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "\r\n" "<html>" "<headxtitle>Przykładowy Serwer HTTP</titlex/head>" "<body>" "<center>" "<font size=\M\">" "<p>Wykonano</p>" " < p x a href=\"/\">Powrót</ax/p>" ”</font>" "</center>" ” </body>" "</html>"; static const size_t done_page_len = sizeof(done_page_html) - 1; http_data_rom(http, stra32_Iogo_gif, atffl32_logo_gif_len) ; return OK_200; 1 G łów na strona serw isu zaw iera też form ularz służący do sterow ania diodam i św ie­ cącym i. Po kliknięciu na przycisk Zm ień tego form ularza przeglądarka w ysyła żąI ' 5 P rz y k ła d o w y S e rw e r HTTP - M ic ro s o ft In t e r n e t E nplorer File Edit Q üack View Favorites -r ( J ) - (W ) Tools | S ‘| (;•,') Help '»i1’ J>.'> Search S ^ - ' Favorites | |V m J Address j.jÿ | h ttp :// 192. 168.51 .89/led Go 277 I Unta' » • Wykonano Powrôt if (http_parser_param(parser, LED_G)) GreenLEDon () ; else GreenLEDoff(); if (http_parser_param(parser, LED_R)} RedLEDon (); else RedLEDoff (); http_data_rom(http, done_page_html, done_page_len); return OK 200/ - ,Ti 10.2.6. Plik stm 32Jogo.h Plik stm 32_logo.h zaw iera kom pletną odpow iedź serw era na żądanie przesiania ob­ razka, który ma się w yśw ietlić na głów nej stronie serw isu. O dpow iedź znajduje się w tablicy stm 3 2 _ lo g o _ g if. Stała stm 32_łogo_gif__len zaw iera długość odpow ie­ dzi. D efinicje te um ieściłem w osobnym pliku, a nie bezpośrednio w pliku http_application.c, gdyż zajm ują dużo m iejsca (poniżej je s t w ydrukowany tylko mały frag­ m ent pliku stm 32_logo.li), co bardzo zm niejszyłoby czytelność tekstu źródłowego. > |:y, ' ■: I ® internet Rys. 10.2. Strona WWW informująca o zmianie stanu diod świecących U static const char stm32_logo_gif(] = "HTTP/ł.l 200 0K\r\n" "(JcsuiectaJn: close\r\n" "Conten^łype: image/gif\r\n" "\r\n" t‘ i 278 JO. Serwis WWW "GIF89a\xfa\x00\xa0\xG0\xf7\xQ0\x00\xf4\xfb\xfe" "\xe7\xf7\xf c:\xb6\xdl\x78\x6c\xb3\x91\xf c:\xc5\x31\x00\xa3\xba\xb6" Konwersji pliku binarnego z obrazkiem do postaci akceptow anej przez kom pilator C w ykonałem za pom ocą prościutkiego program u, którego tekst źródłow y je st w ar­ chiw um z przykładam i w pliku im age2c.c w katalogu ,/m ake/exlO _httpd. Plik ex_htłpd.c Plik ex_httpd.c zaw iera funkcję main przykładu. Jest ona bardzo podobna do funkcji main z przykładu 5a. int main{) ( static struct netif netif; static struct ethnetif ethnetif = {PHY_ADDRESS); uint8_t confBit/ , Delay(1000000); confBit = GetConfBit(); Al l P i n sDisableO; LEDconfigure(); RedLEDon(); SET_IRQ_PROTECTION{); error_resetable(CLKconfigure(), ł); error_permanent(LocalTimeConfigure(), 2); error_resetable(ETHconfigureMII{), 4); netif.hwaddr[0] = 2; netif.hwaddr[l] = (BOARDJTYPE » 8) & 0xff; netif-hwaddr[2] = BOARDJTYPE & 0xff; netif.hwaddr|31 = (ETH__BOARD » 8) 6 0xff; netif.hwaddr[4J = ETH_BOARD & 0xff; netif.hwaddr[5j = 1 + confBit; if (iconfBit) { IP4_ADDR(finetif.ip_addr, 192, 168, 51, 84); IP4_ADDR(finetif.netmask, 255, 255, 255, 240); IP4__ADDR (finetif .gw, 192, 168, 51, 81); $ echo -en "GET / HTTP/1.l\r\n\r\n" | nc 192.168.51.89 80 HTTP/1.1 200 OK Connection: close Content-Type: text/html; charset=UTF-8 <html><headxtitle>Przykładowy Serwer HTTP</title></headxbody><cente r X p X i m g src="stm32_logo.gif" alt="STM32 LOGO" / x / p x p x f o n t size=" 6">0 01:37:22.610</fontx/p><hr / x f o r m action="/led" method="post"X p>Czerwona dioda świecąca <input type="checkbox" name="LED" value="R" checked / x / p X p > Z i e l o n a dioda świecąca cinput type="checkbox" name= "LED" value="G" / x / p > < p x i n p u t type="subn\it" value="Zmień" / x / p x / f o r m X h r /Xp>lwIP/1.3.2 CMSIS/1.30 STM32F10x Standard Peripherals Lib rary/3.3.0 newlib/l.18.0</pX/center></bodyx/html> S echo -en "POST /led HTTP/1.l\r\nContent-Length: 5\r\n\r\nLED=G" \ i nc 192.168.51.89 80 HTTP/1.1 200 OK Connection: close Content-Type: text/html; charset=UTF~8 <html><headxtitle>Przykladowy Serwer H T T P C / t i t l e X / h e a d x b o d y X c e n t e r x f o n t size-"4"xp>Wykonano</p><p><a h r e f = " / " > P o w r ó t < / a x / p x / f o n t x /centerx/body></html> W ysłanie błędnego żądania. $ echo -en "PET / HTTP/1.l\r\n\r\n" I nc 192.168.51.89 80 HTTP/1.1 400 Bad Request Connection: close Content-Type: text/html <html><head><title>Error</titlex/headxbodyXhl>400 Bad Request</hl> </bodyx/html> -,»■*' ) error_resetable(LWIPinterfacelnit(finetif, fiethnetif), 5); LWIPtimersStart(); error_resetable(DHCPwait(finetif, 10, 4), 6); error_resetable (HTTPserverStart (HTTP__PORT), 7) ; RedLEDoff (); for(;;); 5 > 10.2.8. Ś ciągnięcie głów nej strony serw isu. Ze zw róconej odpow iedzi w ynika, że czerw ona dioda św iecąca jest w łączona, a zielona w yłączona. W yłączenie czerw onej diody św iecącej i w łączenie zielonej. } else { IP4_ADDR(&netif,ip_addr, 0, 0, 0, 0); IP4_ADDR(&netif.netmask, 0, 0, 0, 0); IP4_ADDRffinetif.gw, 0, 0, 0, 0); 279 wad. W szczególności trudno je st w ten sposób w ysiać błędne żądanie. O dporność serw era na różnego rodzaju błędy najlepiej testuje się za pom ocą program u netcat lub telnet. Poniżej zam ieszczam kilka przykładow ych testów w ykonanych z konsoli Linuksa. Podczas tych testów serw er używ ał adresu IP 192.168.51.89 uzyskanego za pom ocą DHCP. "\x5b\x03\x00\x0b\x78\xc0\x40\xl6\xf2\x90\xl7\xcc\xa6\x06\xd7\xl3" "\x70\x01\x01\x00\x3b"; static const s iz e _ t stm 32_logo_gil_len = sizeof(stm32_logo__gif) - 1; 10.2.7. 10.2. Przykład 10 —prosty serwis WWW Testowanie przykładu Prezentow any w tym rozdziale przykład pow inien w spółpracow ać z dow olną prze­ glądarką internetową. Jednak nie w szystko da się za pom ocą przeglądarki przetesto- Prośba o nieistniejący zasób. $ echo -en "GET /abc HTTP/1.l\r\n\r\n" 1 nc 192.168.5-1.89 80 HTTP/1.1 404 Not Found Connection: close Content-Type: text/html < h t m l x b e a d x t i t l e > E r r o r < / t i t l e x / h e a d x b o d y x h l > 4 0 4 Not Found</hl></ bodyx/html> W ysłanie błędnej w ersji HTTP. $ echo -en "GET / HTTP/2.0\r\n\r\n” | nc 192.168.51.89 80 HT’ iJldU.i 595 HTTP Version Not Supported ConnectiJm (close • Content-Typfii text/html 280 10. Serwis WWW < h t m l x h e a d x t i t i e > E r r o r < / t i t l e x / h e a d x b o d y x h l > 5 G 5 HTTP Version Not Supported</hlx/body></htmi> Tesr przekroczenia czasu. Połączenie pow inno zostać zam knięte przez serw er po 10 sekundach. $ telnet 192.168.51.89 80 Trying 192.168.51.89... Connected to local-89.localdomain (192,168.51.89}. Escape character is ,AJ*. Connection closed by foreign host. Narzędzia GNU 282 Dodatek. Narzędzia GNU Dodatek. Narzędzia GNU 283 Przykłady um ieszczone w lej książce kom pilow ałem w środow isku system u ope­ racyjnego Linux za pom ocą darm ow ego zestaw u narzędzi (ang. toolchain) G NU z w ykorzystaniem darm ow ej biblioteki N ew lib. W tym dodatku dokum entuję proces instalow ania środow iska program istycznego i kom pilow ania przykładów. O pis ten je st przeznaczony dla C zytelników , którzy ju ż m ają pew ne dośw iadczenie w uży­ w aniu narzędzi GNU. M ikroprocesory A RM używ ają trzech zestaw ów instrukcji: ARM , Thum b i Thum b-2. D la każdego z tych zestaw ów trzeba m ieć oddzielny zestaw biblio­ tek. U m ożliw ia to opcja —e n a b le - m u l ti li b . Opcji tej jed n ak nie trzeba podaw ać podczas konfigurow ania zestaw u narzędzi, gdyż je st dom yślna. N atom iast w pliku Jgcc/config/arm /t-arm -elf m usim y zdefiniow ać, jakie w ersje bibliotek m ają zostać skom pilow ane. N ależy w yedytow ać w nim następujące wiersze: Instalow anie środow iska program istycznego należy rozpocząć od pakietu Binutils. Jego najnow szą w ersję m ożna znaleźć na stronie http://ftp.gnu.org/gnu/binutils. W trakcie przygotow yw ania książki najnow sza w ersja tego pakietu m iała num er 2.20.1. Jej instalow anie przebiega następująco: MULTILIB_OPTIONS = mthumb mcpu=cortex-m3 MULTILIBJJIRNAMES = thumb coi:tex-m3 MULTILIB_EXCEPTIONS = mcpu=cortex-m3 MULTILIB_MATCHES tar -zxf binutils-2.20.1.tar.gz cd binutils-2.20.1 mkdir build cd build ../configure --target=arm-elf — prefix=/usr/iocal/arm make su make install exit cd ../.. Instalujem y kom pilator skrośny (ang. cross com piler) - kom pilacja je st w ykony­ wana na kom puterze o innej architekturze niż architektura procesora, na której ma być w ykonyw any skom pilow any program . Param etr — t a r g e t określa docelow ą ar­ chitekturę, na którą będą generow ane pliki w ynikow e. P aram etr - - p r e f i x określa m iejsce, gdzie będą um ieszczane pliki w ykonyw alnę zestaw u narzędzi. A by mieć do nich dostęp, trzeba ustaw ić ścieżkę poszukiw ania plików. N ajprościej m ożna to zrobić w pliku .bash_profile (w niektórych dystrybujcach .profile), który znajduje się w katalogu dom ow ym użytkow nika. Przykładow y w pis w tym pliku w ygląda następująco: PATI!=$PATH:$H0ME/bin:/usr/local/arm/bin:/usr/local/msptSO/bin export PATH N a czas instalow ania kolejnych składników środow iska program istycznego w ystar­ czy w ykonać polecenie: export PATH=$PATH:/usr/local/arm/bin Pamiętajmy o dodaniu we w szystkich ścieżkach podkatalogu /bin. Polecenie make i n s t a l l pow inno w ykonyw ać się z upraw nienianii^ifdm inistratora, dlatego przed jego w ykonaniem przełączam y się w tryb adm inistratora za pom ocą polecenia su, a po jego wykonaniu w racam y do trybu użytkow nika za pom ocą polecenia e x it . K olejnym pakietem , który trzeba zainstalow ać, je s t GCC. A dresy serw erów oferu­ jących G CC dostępne są na stronie http://gcc.gnu.org/m irrors.htm l. Ze względu na w ystępujący w rdzeniach C ortex-M 3 drobny błąd w niektórych w ariantach instrukcji ld r d , należy użyć wersji co najm niej 4.4.0. Od tej wersji dla C ortex-M 3 dom yślnie je st ustaw iona opcja -m fix - c o rte x -m 3 - ld rd , która zapobiega używ aniu przez kom ­ pilator w adliw ie działających instrukcji. W trakcie przygotow yw ania książki najnow ­ sza w ersja G CC miała num er 4.4.3. Po ściągnięciu pakietu należy go rozpakow ać: tar -zxf gcc-4.4.3.fcar.gz cd gcc-4.4.3 Pow yższe param etry oznaczają, że w dom yślnym dla bibliotek katalogu znajdą się w ersje bibliotek używ ające zestaw u instrukcji ARM , w jeg o podkatalogu thum b - w ersje używ ające zestaw u T hum b, a w podkatalogu thum b/cortex-m 3 - w ersje używ ające zestawu Thum b-2. K onsolidator będzie dołączał w łaściw e biblioteki na podstaw ie argum entów podanych w linii poleceń (konsolidatora lub kom pilatora). D om yślnie dołączane będą biblioteki używ ające zestaw u instrukcji ARM . O pcja -mthumb będzie w ym uszać dołączanie bibliotek używ ających zestaw u instrukcji Thum b. Z astosow anie łącznie opcji -mthumb oraz -m cpu=cortex-m 3 będzie pow o­ dow ać dołączanie bibliotek używ ających zestaw u instrukcji T hum b-2. N azw y opcji kom pilatora (z pom inięciem początkow ego m yślnika) specyfikuje się za pom ocą param etru M0LTILIB_OPTIONS. N azw y podkatalogów , w których m ają być um iesz­ czane odpow iadające im w ersje bibliotek, w ym ienia się w param etrze MULTILIB_ DIRNAMES. Param etr MULTILIB_EXCEPTIONS służy do opisania zabronionych kom ­ binacji opcji kom pilatora. G CC nie dopuszcza użycia sam ej opcji -m cpu= cortex-m3, bez opcji -mthumb. Po skonfigurow aniu w ersji bibliotek m ożem y przystąpić do skom pilow ania kom pilatora skrośnego: mkdir build cd build ../configure — target=arm-elf — prefix=/usr/local/arm \ — enabie-languages=c,c++ — with-newlib — without-headers \ — disable-shared — with-mpfr=/usr/local O pcja —e n a b łe -la n g u a g e s określa języki program ow ania, dla których mają zostać zbudow ane kom pilatory. U staw ienie łącznie opcji —w ith -n e w lib i —w ith o u t-h e ­ a d e rs spraw ia, że biblioteka L IB G C C zostanie zbudow ana bez w sparcia jakichkol­ w iek plików nagłów kow ych, czyli nie będzie ona korzystać z żadnej innej biblio­ teki, natom iast pozostałe biblioteki będą m ogły korzystać z biblioteki N ew lib i jej plików nagłów kow ych. Takie ustaw ienia są typow e; gdy buduje się kom pilator dla system ów w budow anych. O pcja — d i s a b le - s h a r e d w yłącza używ anie bibliotek dzielonych, ładow anych dynam icznie, co w przypadku m ikrokontrolerów nie m ia­ łoby po prostu sensu. O pcja —w ith - m p f r = /u s r /lo c a l okazała się konieczna, gdyż konfigurator nie znalazł położenia biblioteki M PFR, potrzebnej do skom pilow ania GCC. Za pom ocą tej opcji w skazuje się ścieżkę, gdzie ta biblioteka je st zainstalo­ w ana. W konkretnym środow isku opcja ta m oże być zbędna, ale m oże okazać się potrzebne użycie innych opcji. Sam proces kom pilow ania przebiega następująco: make instaljlrgcc 284 Dodatek. Narzędzia GNU exit cd ../.. Popraw ność dotychczasow ych etapów instalacji m ożna spraw dzić za pom ocą dw óch poniższych poleceń. Polecenie a rm - e lf - g c c -v pow inno w ypisać coś na­ stępującego: Using built-in specs. Target: arm-elf Configured with: ../configure — target=arm-eif — prefi.x=/usr/local/ann — enable-languages=c, C++ — with-newlib — without-headers — disable-shared — with-mpfr=/usr/local Thread model: single gcc version 4.4.3 (GCC) Natomiast polecenie arm-elf-gcc -print-multi-lib powinno wypisać coś takiego: thumb;Gmthumb thumb/cortex-m3;@mthumb@mcpu=cortex-m3 W kolejnym kroku instalujem y biblioteki. Potrzebujem y standardow ej biblioteki języ k a C. Jedną z najpow szechniej stosow anych dla system ów w budow anych jest biblioteka N ewlib. M ożna ją ściągnąć z serw era ftp://sources.redhat.com /pub/new lib/index.htm l. W trakcie przygotow yw ania książki najnow sza w ersja m iała num er 1.18.0. Jej instalow anie przebiega następująco: tar -zxf newiib-1.18.0.tar.gz cd newlib-1.18.0 mkdir build cd build ../configure — target=arm-elf — prefix=/usr/local/arm — disable-shared make CFLAGS_FOR_TARGET= \ ''-02 -ffunction-sections -fdata-sections -D BUFSIZ =256" su make install exit cd ../.. Param etr C FLAGS_FOR_TARGET polecenia make określa opcje, które m ają być uży­ te podczas kom pilow ania biblioteki. Pierw sze trzy spośród tych opcji w yjaśniłem w rozdziale 1. N atom iast opcja -D B U FSIZ je st specyficzna dla biblioteki N ew lib i określa dom yślny rozm iar bufora przydzielanego dla plików otw ieranych za p o ­ m ocą funkcji fopen. Pozostało jeszcze dokończenie instalow ania G CC. W tym kroku instalujem y po­ m ocnicze biblioteki dostarczane w raz z G CC. N ajw ażniejszą z nich jest biblioteka libgcc. Ich instalow anie w ygląda następująco: cd gcc-4.4.3/build make all CFLAGS_F0R_TARGET="-02 -ffunction-sections -fdata-sections" su make install exit „ cd ../.. > Teraz m ożna w reszcie rozpakow ać archiw um z przykładam i. W tym archiw um w katalogu ./m ake znajdują się podkatalogi dla poszczególnych przykładów : e x la _ led, exlb _ lcd , ex2_eth, ex3a_ip, ex3b_ip_nc, ex3c_ip_zc, ex5a_tcpd, ex5b_tcpd_ Dodatek. Narzędzia GNU 285 wdg, exóa_tcp_clnt, ex6b_tcp_clnt_bkp, ex7_udpd, ex8_udp jo in t, ex9a_send_bcast, ex9b_recv_bcast, exIO JU tpd. Każdy z tych podkatalogów zaw iera plik m akefile urucham iający kom pilow anie odpow iedniego przykładu. W pliku m akefile specyfikujem y tylko nazw y plików źródłow ych i w ynikow ych, a w celu uruchom ienia w ła­ ściwej kom pilacji w łączam y plik m akefile.in, który znajduje się w katalogu ./m ake/ scripts. Plik m akefile, in zaw iera polecenia w spólne dla w szystkich przykładów. W katalogu Jm ake/scripts znajduje się też głów ny plik m akefile, który urucham ia kom pilow anie w szystkich przykładów. Z m ienna TARGETS (patrz pliki J m a ke/ex*/ m akefile) determ inuje form at produkow anych plików w ynikow ych. Jeśli podam y plik w ynikow y z rozszerzeniem elf, zostanie zw rócony plik w form acie ELF. Jeśli podam y plik w ynikow y z rozszerzeniem bin, zostanie w ygenerow any plik z binar­ nym obrazem pam ięci Flash. Jeśli podam y plik w ynikow y z rozszerzeniem hex, zo­ stanie w yprodukow any plik w form acie Intel HEX. M ożna podać więcej niż jedną nazw ę, każdą z innym rozszerzeniem . Pliki w ynikow e dla poszczególnych przykła­ dów są um ieszczane w odpow iednich katalogach ./m ake/ex*. D om yślnie przykłady kom pilow ane są na zestaw ZL29A R M z m odułem ethernetow ym ZL3ETH , a nazw y plików w ynikow ych poprzedzane są prefiksem z.l29arm+z.l3eth, natom iast pliki pośrednie i biblioteczne są um ieszczane w katalogu ./ m ake/lib/zl29arm + zl3eth. Przykłady m ożna łatw o dostosow ać do różriyeh w arian­ tów sprzętu za pom ocą dyrektyw kom pilacji w arunkow ej. Steruje tym zm ienna h a r ­ dware w pliku m akefile.in, który znajduje się w katalogu ,/m ake/scripts. D om yślną w artością zm iennej hardw are je s t z l2 9 arra+ zl3 eth . M ożna to zm ienić, podając inną w artość tej zm iennej bezpośrednio jak o param etr polecenia make, na przykład: make hardware=prototype Z ostanie w tedy użyty plik nagłów kow y board_def.il z katalogu ./exam ples/include/ prototype, nazwy plików w ynikow ych zostaną poprzedzone prefiksem prototype, a pliki pośrednie i biblioteczne będą um ieszczane w katalogu Jm ake/lib/prototype. D la każdej wersji sprzętu trzeba zdefiniow ać odpow iedni podkatalog w katalogu ./exam ples/include, a w tym podkatalogu należy um ieścić odpow iedni plik board_ def.h. Ponadto należy zdefiniow ać odpow iednią sekcję w pliku makefile.in. Na koniec pozostaje jeszcze zaprogram ow anie pam ięci m ikrokontrolera. R óżnorodność program atorów i program ów do ich obsługi sprawia, że trudno jest podać jak ąś zw ięzłą instrukcję. W archiw um z przykładam i w katalogu ./m ake/ scripts znajduje się skrypt fla sh .sh dla O penO C D . U rucham ia się go, podając jako argum ent nazw ę pliku w form acie binarnym . Jeśli nie podam y argum entu, to w bie­ żącym katalogu poszukiw any je s t plik z rozszerzeniem bin i zaw artość tego pliku jest używ ana do zaprogram ow ania pam ięci m ikrokontrolera. Literatura Literatura [I] 12] [3] [4] 15} |6 j [7] [8] 19] [10] [II] [12] [13] [14] [15] Corner D.E., Sieci kom puterow e TCP/IP. Zasady, protokoły i architektura, tom 1, WNT, W arszaw a 1997, 1998. K ernighan B.W., R itchie D .M ., Język A N S I C, WNT, W arszawa 2002. Spurgeon C h.E., E thernet - podręcznik adm inistratora, RM , W arszawa 2000. A N 3000 A pplication note, C onfiguring the N icheLite™ T C P/IP stack for the S T M 32F 107xx m icrocontroller, http://w w w .st. com /stonline/products/literature/an/15903. pdfA N 3102 A pplication note, lw lP T C P /IP stack dem onstration for STM 32F107xx connec­ tivity line m icrocontrollers, http://w w w .st.com /stonline/products/literature/an/J6620.pdf, http://w w w .st.com /stonline/products/support/m icro/fU es/an3I02.zip. A R M -based 32-bit M CU ST M 32F10xxx standard peripheral library, w ersja 3.3.0, h ttp:// w w w .st.com /stonline/products/support/inicro/files/stm 32fl0x_stdperiph_lib.zip. PM 0056 Program m ing m anual, ST M 32F10xxx C ortex-M 3 program m ing m anual, h ttp:// w w w .st.com /stonline/products/literature/pm /J5491.pdf. RM 0008 R eference m anual, ST M 32F101xx, ST M 32F102xx, ST M 32F103xx, ST M 32F105xx and STM 32F107xx advanced A RM -based 32-bit M C U s, http://w w w . st. com /stonline/products/literature/rm /13902.pdf. ST M 32F105xx, ST M 32F107xx, C onnectivity line, A RM -based 32-bit M CU with 64/256 KB Flash, USB O TG , Ethernet, 10 tim ers, 2 C A N s, 2 A DCs, 14 com m unication interfa­ ces, http://w w w .st. com /stonline/products/literature/ds/15274.pdf. Postel J., U ser D atagram Protocol, STD 6, RFC 768, sierpień 1980, http://tools.ietf.org/ htm l/ifc768, http://w w w .rfc-editor.org/std/std6.txt. Postel J., Internet Protocol, ST D 5, RFC 791, w rzesień 1981, http://tools.ietf.org/htm l/ rfc791, http://w w w . rfc-editor. org/std/std5. txt. Postel J., Internet Control M essage Protocol, STD 5, RFC 792, w rzesień 1981 http://tools.ietf.org/htm l/rfc792, http://w w w .rfc-editor.org/std/std5.txt. Postel J., Transmission C ontrol Protocol, STD 7, RFC 793, w rzesień 1981, h ttp M o o ls. ietf.org/htm l/rfc793, http://w w w.rfc-editor.org/std/std7.txt . Plum m er D., E thernet A ddress R esolution Protocol: O r Converting N etw ork Protocol A ddresses to 48.bit E thernet A ddress f o r Transm ission on E thernet H ardware, STD 37, RFC 826, listopad 1982, http://lools.ietforg/htm l/rfc8264 ^http://w w w .rfc-editor.org/std/ std37.txt. M ockapetris P., D omain nam es - concepts a n d fa cilities, STD 13, RFC 1034, listopad 1987, http://tools.ietf.org/htm l/rfc10 3 4 , http://w w w .rfc-editor.org/std/stdJ3.txt. 116] M ockapetris P., Domain nam es - im plem entation a n d specification, STD 13, RFC 1035, listopad 1987, http://tools.ietf.org/htm l/rfcl035, http://w w w .rfc-editor.org/std/stdJ3.txt. [17] D rom s R., D ynam ic H ost C opfiguration Protocol, RFC 2131, m arzec 1997, http://tools. ietf. org/htm l/rfc213 J. > [18] Fielding R., G etlys J., M ogul J., F rystyk H., M asinter L., Leach P., B erners-Lee T., H ypertext Transfer Protocol - H T T P /J .l, R FC 2616, czerw iec 1999, http://tools.ietf.org/ htm l/rfc2616. 287 [19] Paxson V., A llm an M ., Com puting T C P ’s R etransm ission Timer, RFC 2988, listopad 2000, http://tools.ietf.org/htm l/rfc2988. [20] C heshire S., A boba B., G uttm an E., D ynam ic C onfiguration o f IP v4 Link-L ocal Addresses, RFC 3927, maj 2005, http://tools.ietf.org/htm l/rfc3927. [21] B erners-L ee T., Fielding R., M asinter L., U niform R esource Identifier (U RI): G eneric Syntax, STD 66, R FC 3986, styczeń 2005, http://tools.ietf.org/htm l/rfc3986, http://www. rfc-editor. org/std/std66. txt. [22] M ills D., Sim ple N etw ork Time Protocol (SN TP ) Version 4 fo r IPv4, IP v6 and OSI, RFC 4330, styczeń 2006, http://tools.ietf.org/htm l/rfc4330.