K U R S
Ethernet i AVR y
Ethernut od podstaw, część 3
Kontynuujemy rozpoczęty miesiąc temu opis serwera
WWW wbudowanego w system Nut/OS. Jego najprostsza
aplikacja pokazana w poprzednim odcinku pozwalała
na wyświetlenie statycznej strony internetowej. W tej
części pokażę, jak budować strony interaktywne
z formularzami i dynamicznie generowaną
zawartością.
W tej części cyklu pokażę, jak ślaną jako funk-
zbudować prostą aplikację Ethernu- cja zwrotna. Obsługę
ta sterowaną za pomocą przeglądar- mechanizmu generacji dyna-
ki internetowej (rys. 4). Jej zada- micznej zawartości stron, nazwanego
niem jest zapalanie i gaszenie diody w Ethernucie ASP (Active Server Pa-
LED po kliknięciu przycisku oraz ges nie należy mylić z technologią
pokazywanie stanu przełączników ASP Microsoftu) należy zainicjalizo-
znajdujących się na płytce z uru- wać w następujący sposób: ASP bardziej rozbudowany
NutRegisterAsp(); // uruchomienie
chomionym w Ethernutem w oknie przykład
mechanizmu ASP
przeglądarki (rys. 5). Aby taka apli- Opisany poniżej przykład będzie
NutRegisterAspCallback(ASP
_callback); // wybór funkcji
kacja mogła działać, ethernutowy generował dwie tabelki, zawierające
wywoływanej
serwer WWW wyposażono w 2 me- stan diod oraz przełączników na
// przy napotkaniu
znacznika <%znacznik%>
chanizmy: płytce ZL9AVR oraz zestaw odno-
dynamiczne generowanie zawar- Funkcja callback w najprostszym śników, których kliknięcie będzie
przypadku wygląda następująco:
tości stron, które wykorzysta- powodowało zapalanie/gaszenie
my do wypisywania stanu diod static int ASP_callback (char *tag_ LED ów. Szkielet strony w języku
name, FILE *f)
i przycisków, HTML jest następujący (plik in-
{
if(!strcmp(tag_
skrypty CGI, których będziemy dex.asp):
name,"napis"))
używać do zapalania i gaszenia
{
Kurs Ethernut EP część 3
fprintf(f, "Ten napis jest
LED ów.
wygenerowany dynamicznie!");
return 0;
}
Strony WWW z dynamiczną
Stan przełączników na płytce
Ethernut: zawartością return 1;
}
W dużych serwerach WWW do <%przelaczniki%>
tego generacji stron z dynamiczną Parametr tag_name to nazwa
Diody LED: zawartością wykorzystuje się zwykle napotkanego w kodzie strony znacz- <%diody%>
rozbudowane języki skryptowe, jak nika ASP, natomiast f to strumień
np. PHP, serwlety w Javie czy ASP. (FILE), do którego możemy zapi-
Wersja Nut/OS:<%nut_version%>
Ponieważ Nut/OS działa na bardzo sać dane, które zostaną przesłane
skromnym sprzęcie, mechanizm ge- do klienta zamiast znacznika ASP.
neracji stron z dynamiczną zawarto- A więc powyższy kod,
ścią jest bardzo uproszczony i ogra- w miejsce znacznika
nicza się do wywołania wybranej <%napis%> umieści
funkcji programu w języku C przy tekst Ten napis jest
napotkaniu odpowiedniego znaczni- wygenerowany dyna-
ka w kodzie strony w HTML u: micznie! .
Wspomnę tu o jesz-
c z e j e d n e j b a r d z o
Strona testowaważnej rzeczy: aby
Napis poniżej będzie
mechanizm dynamicz-
wygenerowany dynamicznie:
<%napis%>
nej generacji zawarto-
ści stron WWW mógł
Po napotkaniu znacznika <%na- działać, plik z kodem
pis%>, serwer HTTP wbudowany strony musi mieć roz- Rys. 4. Okno przeglądarki z przykładową aplikacją
w Nut/OS wywoła wybraną funkcję szerzenie . a s p (np. uruchomioną na płytce ZL9AVR z modułem ZL1ETH
callback, w polskiej terminologii okre- index.asp) firmy Kamami
Elektronika Praktyczna 2/2007
109
K U R S
spowoduje (w systemie Ethernut) wy-
List. 4.
static int CGI_callback(FILE *f, REQUEST *r) wołanie funkcji odpowiadającej skryp-
{
towi diody.cgi z parametrem zapal
// kod HTML przekierowujacy do pliku index.asp
static prog_char webpage_code[] = "
o wartości 1.
"refresh\" content=\"0;url=../index.asp\">";
Stworzymy teraz skrypt diody.
// wysylamy naglowek protokolu HTTP 200 OK wszystko w porzadku
cgi, który umożliwi sterowanie dio-
NutHttpSendHeaderTop(f, r, 200, "Ok");
dami LED na płytce ZL9AVR. Będzie
// wysylamy "Content Type" rodzaj danych, czyli plik tekstowy w formacie
on przyjmował parmetry o postaci
HTML (text/html)
zapal=numer_diody i zgas=nu-
NutHttpSendHeaderBot(f, "text/html", 1);
mer_diody, gdzie numer_diody
// wysylamy kod strony w HTMLu
fputs_P(webpage_code, f); to numer diody LED (0& 3), która ma
być zapalona lub zgaszona. Skrypt
// upewniamy sie, ze wszystko zostalo juz wyslane do klienta
fflush(f);
ten będzie musiał także wygenerować
poprawną stronę WWW. W naszym
// sprawdzamy, czy skrypt zostal wywolany z parametrami
if (r >req_query) {
przypadku po ustawieniu odpowied-
char *name;
niego stanu LED ów, skrypt będzie
char *value;
int i;
przekierowywał przeglądarkę interne-
int count;
tową do pliku index.asp.
// pobieramy liczbe parametrow
Kod funkcji w języku C przypisa-
count = NutHttpGetParameterCount(r);
nej do skryptu diody.cgi przedsta-
for (i = 0; i < count; i++) {
wiono na list. 5. Funkcja CGI_call-
// pobieramy nazwe i wartosc kolejnego parametru
back przyjmuje 2 parametry: FILE
name = NutHttpGetParameterName(r, i);
*f strumień, do którego zapis po-
value = NutHttpGetParameterValue(r, i);
woduje wysłanie zapisanych danych
// analizujemy go i podejmujemy odpowiednie czynnosci
do przeglądarki klienta i REQUEST
if(!strcmp(name,"zapal"))
led_state |= (1<
*req strukturę opisującą żądanie
else if(!strcmp(name,"zgas"))
led_state &= ~(1< }
m.in. adres do którego odwołuje się
}
klient oraz listę parametrów (tekst po
znaku ? w adresie strony)
// aktualizujemy stan diod LED przez zapis do Portu F
PORTF&=0xf0;
W odróżnieniu od opisanego wcze-
PORTF|=(led_state)&0xf;
śniej mechanizmu ASP zastępującego
return 0;
określone miejsca w szablonie strony,
}
funkcja obsługująca skrypt CGI musi
oprócz kodu strony w HTML u wy-
Kod funkcji ASP_callback oraz darce internetowej wydawanie roz- syłać klientowi nagłówki protokołu
funkcji pomocniczych dla tej strony kazów dla naszej aplikacji. Do tego HTTP. Odpowiadają za to funkcje:
NutHttpSendHeaderTop(FILE *f, REQU-
przedstawiono na list. 4. Obsługuje celu posłuży my się mechanizmem
EST *req, int status, char *title);
on dwa znaczniki: <%przelaczni- CGI (Common Gateway Interface).
ki%> i <%diody%>, umieszczając W kodzie HTML generowanym przez oraz
NutHttpSendHeaderBot(FILE *f, char
w ich miejscu tabelki zawierające funkcję ASP_callback() pojawiają
*mime_type, long bytes);
odpowiednio stan przełączników (od- się następujące odnośniki do pliku
czytany bezpośrednio z portu D mi- cgi bin/diody.cgi: Pierwsza z nich wysyła kod sta-
krokontrolera) oraz diod LED (prze- tusu (status) serwera HTML i od-
s=1">Zgas
chowywany w zmiennej led_state).
l=1">Zapal
Dodatkowo w tabelce Diody LED oraz informację o rodzaju i wersji
znajdą się odnośniki umożliwiające W przypadku dużych serwe- oprogramowania serwera WWW. W na-
ich zapalanie lub gaszenie. W pliku rów WWW, taki plik fizycznie ist- szym przypadku wysyłany kod to 200
index.asp występuje także znacz- nieje i jest zwykle skryptem w Per- ( OK ). Oznacza on, że otrzymane po-
nik: <%nut_version%> jest on lu. Skrypty CGI są przechowywane lecenie jest poprawne i żądane dane
wbudowany w system Nut/OS i w je- w oddzielnym katalogu o nazwie zostaną wysłane. Często spotykanymi
go miejsce serwer WWW wstawia cgi bin. W systemie Nut/OS plik kodami statusu są np. 404 (Not Fo-
wersję używanego Ethernuta. skryptu jest zastąpiony funkcją und strona nie istnieje) albo 403
Aby sprawdzić, czy program po- w języku C. (Forbidden dostęp zabroniony).
prawnie działa należy przytrzymać Cechą mechanizmu CGI pozwala- Druga z wymienionych funkcji wy-
przycisk na płytce, a następnie (cały jącą na przekazywanie poleceń dla syła klientowi informację o typie ser-
czas trzymając przycisk wciśnięty) serwera przez przeglądarkę interne- wowanych danych (parametr mime_
kliknąć Odśwież w przeglądarce in- tową jest możliwość wywoływania type) w naszym przypadku "text/
ternetowej. skryptów z parametrami podanymi html", czyli dane tekstowe w formacie
w ich adresie po znaku ? . Na HTML oraz (jeżeli parametr bytes
Skrypty CGI przykład wpisanie w pasku adresu jest liczbą nieujemną) długość prze-
Mamy już opanowane wysyłanie przeglądarki: syłanych danych, przydatną zwłasz-
http://jakis_serwer/cgi bin/diody.
dynamicznie generowanych stron do cza przy przesyłaniu dużych plików
cgi?zapal=1
klienta. Teraz umożliwimy przeglą- (przeglądarka może wówczas podać
Elektronika Praktyczna 2/2007
110
K U R S
HTTP/1.0 200 Ok
List. 5.
static int ASP_callback (char *tag_name, FILE *f)
nagłówki protokołu HTTP
{
Server: Ethernut 4.2.1
if(!strcmp(tag_name,"przelaczniki"))
{
Content type: text/html
tabelka_przelaczniki(f);
return 0;
1 pusta linia
} else if(!strcmp(tag_name,"diody"))
(.....) kod
{
tabelka_diody(f);
HTML zawarty w stałej webpage_
return 0;
} code
Następnie sprawdzamy, czy skrypt
return 1;
}
CGI został wywołany z parametrami
(element req_query struktury REQU-
void tabelka_przelaczniki(FILE *f)
{
EST jest wskaznikiem do listy argu-
int i;
mentów, ich brak powoduje przyjęcie
// wysylamy do klienta kod zwyczajnej tablelki w HTMLu
wartości NULL). Jeśli mamy jakieś pa-
fprintf(f,"Przycisk:"); rametry, sprawdzamy ich liczbę (funk- for(i=0;i<4;i++) fprintf(f," | S%d", i+2); // nazwa przycisku na plytce cja NutHttpGetParameterCount()), a następnie w pętli pobieramy ich na- fprintf(f," |
Stan:"); zwy i wartości za pomocą funkcji: for(i=0;i<4;i++) char *NutHttpGetParameterName(REQU- { EST *req, int index); char stan = PIND & (1<<(i+4)); // odczytujemy stan przycisku char *NutHttpGetParameterValue(REQU- z portu D EST *req, int index); // ... i wypisujemy w tabelce czy wlaczony, czy nie gdzie index jest numerem inte- if(!stan) fprintf(f," | wcisniety"); resującego nas parametru. else fprintf(f," | wycisniety"); Mając nazwy i wartości argu- } mentów, możemy je przeanalizować fprintf(f," |
"); // koniec tabelki
i podjąć stosowne czynności. W opisy-
}
wanym przykładzie, napotkanie para-
static unsigned char stan_led = 0;
metru o nazwie zapal (lub zgas) po-
void tabelka_diody(FILE *f)
woduje ustawienie (lub wyzerowanie)
{
bitu w zmiennej led_state o nume-
int i;
rze podanym w wartości parametru.
fprintf(f,"Dioda:"); Na końcu funkcji CGI_call- for(i=0;i<4;i++) b a c k przepisujemy 4 najmłodsze fprintf(f," | D%d", i+1); // nazwa diody LED na płytce bity zmiennej led_state do rejestru fprintf(f," |
Stan:"); PORTF, aby zaktualizować stan diod for(i=0;i<4;i++) LED. { // sprawdzamy, czy dioda powinna byc zapalona: Pozostało nam jeszcze zarejestro- char stan = stan_led & (1<wać skrypt CGI w systemie i przypi- // ... i wypisujemy w tabelce jej stan sać mu wybraną funkcję w języku C. if(stan) { Należy to wykonać przed uruchomie- fprintf(f," | zapalona "); niem głównej pętli serwera WWW za // oraz odnosnik pozwalajacy na zmiane stanu diody: fprintf(f,"Zgas", i); pomocą funkcji: } int NutRegisterCgi (char *name, in- else { t(*func)(FILE *, REQUEST *)); fprintf(f," | zgaszona "); fprintf(f,"Zapal", podając jako name nazwę skryptu i); (w naszym przypadku diody.cgi) i adres } } obsługującej go funkcji jaki func. fprintf(f," |
"); // koniec tabelki
}
Co dalej?
Opisany przykład serwera może
procentową wartość objętości ściąga- dwóch wariantów funkcji w bibliotece w danym momencie obsługiwać tylko
nego pliku). standardowej. Funkcje z sufiksem _P jedno połączenie. Przeglądarki inter-
Następnie wysyłamy kod strony w nazwie przyjmują dane z pamięci netowe potrafią wysyłać kilka żądań
(webpage_code) za pomocą funkcji Flash, bez _P z pamięci RAM. Kod jednocześnie, których nasz serwer nie
fputs_P(). Jak wiemy mikrokontro- HTML wysyłany w funkcji CGI_call- będzie w stanie obsłużyć. Taka sytu-
lery AVR mają oddzielne przestrze- back jest przechowywany w pamięci acja zakończy się błędem connection
nie adresowe pamięci Flash i RAM, Flash (typ danych prog_char), aby refused połączenie odrzucone. Na
konieczne więc było wprowadzenie zaoszczędzić pamięć RAM (kompila- szczęście dzięki wbudowanej w Nut/
tor AVR GCC domyślnie umieszcza OS obsłudze wątków, można ten pro-
Przykłady przedstawione w artykule zostały
wszystkie ciągi znaków w pamięci blem rozwiązać uruchamiając kilka
uruchomione na zestawie składającym się
RAM). kopii serwera działających jednocze-
z płytki ewaluacyjnej ZL9AVR, interfejsu Ethernet
W wyniku działania powyższych śnie. Ale o tym za miesiąc!
z RTL8019 ZL1ETH oraz modułu dipAVR
ZL7AVR, które udostępniła redakcji firma funkcji, przeglądarka klienta odbie- Tomasz Włostowski, EP
Kamami (www.kamami.pl).
rze od serwera następujące dane: tomasz.wlostowski@ep.com.pl
Elektronika Praktyczna 2/2007
111
Wyszukiwarka
Podobne podstrony:
Ethernet i AVR–y, cz 1
Ethernet i AVR–y, cz 5
Ethernet i AVR–y, cz 2
Bootloader AVR cz 2
Kurs AVR GCC cz 5
Zestaw uruchomieniowy do procesorow rodziny AVR i 51, cz 2
Kurs AVR GCC, cz 3
Kurs AVR GCC cz 2
Kurs AVR GCC cz 3
Kurs AVR GCC cz 1
Kurs AVR GCC, cz 1
AVR owe fusy cz 2
Kurs AVR GCC, cz 5
Kurs AVR GCC, cz 4
Kurs AVR GCC, cz 2
Kurs AVR GCC cz 4
więcej podobnych podstron