Ethernet i AVR–y, cz 3


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<br> fprintf(f, "Ten napis jest <br>LED ów.<br>
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 testowa

waż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