K U R S
Ethernet i AVR y
Ethernut od podstaw, część 2
Miesiąc temu opisałem sposoby kompilacji i instalacji
bibliotek systemu Nut/OS oraz pokazałem, jak
stworzyć najprostszy program pracujący pod jego
kontrolą. W drugiej części omówię funkcje pełnione
przez poszczególne biblioteki Nut/OS oraz
integrację Ethernuta z AVR Studio.
Biblioteki Nut/OS a libnutpro.a ob-
System Ethernut składa się sługa popularnych protokołów
z kilku bibliotek i specjalnego kodu sieciowych: DNS (resolvowanie
startowego, dołączanych do progra- nazw hostów), DHCP (automatycz- mu plików (nutfs)
mu użytkownika znajdujących się na konfiguracja sieci), HTTP, FTP. są opcjonalne.
(w przypadku korzystania z NutBu- Dołączenie kodu startowego oraz
ilda) w katalogu winavr\NutOS\ bibliotek: nutarch, nutos, nutdev O makefile'ach raz jeszcze
lib\avr. Oto one: i nutcrt jest konieczne do prawidło- Makefile to skrypty sterujące
nutinit.o kod startowy wej kompilacji programów, biblioteki kompilacją programów. O tym, jak
systemu, uruchamiany po zerowa- sieciowe (nutnet i nutpro) oraz syste- je samodzielnie tworzyć, można do-
niu mikorkontrolera. Jego główne
zadania to: inicjalizacja peryferiów
List. 1. Kod inicjujący kontroler Ethernet i parametry TCP/IP
mikrokontrolera (m.in. zewnętrznej // statyczny adres IP naszego urządzenia
#define MY_IP_ADDR "10.1.108.222"
pamięci RAM), ustawienie stosu,
// statyczna maska podsieci
uruchomienie zarządzania wątkami. #define MY_NETMASK "255.255.0.0"
// statyczny adres domyślnej bramy
Po wykonaniu powyższych czynno-
#define MY_GATEWAY "10.1.0.1"
// czy konfigurować sieć statycznie (wykomentować linię niżej), czy z użyciem
ści, kod startowy skacze do funkcji
DHCP?
main() programu użytkownika.
#define USE_DHCP
libnutarch.a funkcje spe-
void init_network()
cyficzne dla używanej platformy
{
NutRegisterDevice(&DEV_ETHER, 0, 0);
sprzętowej (np. przełączanie kon-
tekstu mikrokontrolera) oraz sterow- #ifdef USE_DHCP
if(NutDhcpIfConfig("eth0", 0, 20000))
niki urządzeń przeznaczone wyłącz-
#endif
{
nie dla konkretnej architektury (np.
NutNetIfConfig("eth0", NULL,
UART wbudowany w mikrokontro-
inet_addr(MY_IP_ADDR),
inet_addr(MY_NETMASK));
ler, kontroler Ethernet RTL8019).
libnutdev.a pozostałe ste-
NutIpRouteAdd(0, 0, inet_addr(MY_GATEWAY), &DEV_ETHER);
}
rowniki urządzeń.
}
libnutfs.a funkcje obsługi
systemów plików UROM i FAT.
Ethernut i AVR Studio
libnutcrt.a miniaturowa
Aplikacje dla systemu Ethernut można również kompilować w popularnym środowisku AVR Studio.
wersja standardowej biblioteki ję-
Aby utworzyć projekt wykorzystujący Nut/OS:
zyka C. Zawiera takie funkcje jak
1. Tworzymy nowy projekt AVR GCC.
printf(), malloc(), fopen() itd.
2. Kopiujemy pliki Makefile i Sources z jednego z przykładów do katalogu, w którym założyli-
libnutos.a zarządzanie
śmy nowy projekt.
wątkami, obsługa komunikacji mię- 3. Modyfikujemy plik Sources w następujący sposób:
w linii SOURCES umieszczamy listę plików zródłowych projektu,
dzyprocesowej oraz funkcje dyna-
w linii OUTPUT wpisujemy nazwę projektu, która musi być dokładnie taka sama jak nazwa
micznej alokacji pamięci.
w AVR Studio,
libnutnet.a stos TCP/IP,
w linii MY_CFLAGS podajemy dodatkowe opcje dla kompilatora GCC (np. tryb optymalizacji,
funkcje obsługi gniazd sieciowych dodatkowe ścieżki poszukiwania plików nagłówkowych, itp.) lub zostawiamy ją pustą,
w linii LIBS podajemy biblioteki, które będą dołączone do programu (także biblioteki Nut/OS),
(socketów).
w linii CRUROM_DIR można ustawić ścieżkę do katalogu, którego zawartość znajdzie się
w pamięci Flash mikrokontrolera (np. wbudowanej w urządzenie strony WWW).
Komplet kodów zródłowych przykładów z kursu
4. W menu Project >Configuration options zaznaczamy pole Use external Makefile i wybieramy
Ethernut znajdują się na płycie CD EP1/2007B
skopiowany przed chwilą plik Makefile.
razem z najnowszą dystrybucją systemu
Po wykonaniu powyższych czynności, z aplikacją dla Nut/OS można pracować tak jak ze zwykłymi
Ethernut (4.2.1) i odpowiednimi skryptami
projektami AVR Studio. Przykładowe programy przedstawione w tym i następnych odcinkach kursu
konfiguracyjnymi.
będą zawierały także gotowe projekty dla AVR Studio.
Elektronika Praktyczna 1/2007
93
K U R S
wiedzieć się np. na stronie http://
Wyjaśnienie niektórych pojęć i terminów pojawiających się w tekście artykułu
www.eng.hawaii.edu/Tutor/Make/. Je-
DHCP (Dynamic Host Configuration Protocol) to protokół komunikacyjny umożliwiający kompu-
śli korzystamy z plików makefile
terom w sieci uzyskanie od serwera danych konfiguracyjnych, np. adresu IP hosta, adresu IP
pochodzących z przykładowych pro-
bramy sieciowej, adresu serwera DNS, maski podsieci. Protokół DHCP jest zdefiniowany w RFC
gramów z niniejszego kursu, linko-
2131 i jest następcą BOOTP. DHCP został opublikowany jako standard w roku 1993.
wane biblioteki ustawia się w pli-
Protokół DHCP opisuje trzy techniki przydzielania adresów IP:
ku Sources w linii LIBS. Np.
przydzielanie ręczne oparte na tablicy adresów MAC oraz odpowiednich dla nich adresów
aby dołączyć libnutpro.a należy IP. Jest ona tworzona przez administratora serwera DHCP. W takiej sytuacji prawo do pracy
w sieci mają tylko komputery zarejestrowane wcześniej przez obsługę systemu,
dopisać do linii LIBS lnutpro.
przydzielanie automatyczne, gdzie wolne adresy IP z zakresu ustalonego przez administratora
Istotna jest też kolejność biblio-
są przydzielane kolejnym zgłaszającym się po nie klientom,
tek na liście, a w pewnych przypad-
przydzielanie dynamiczne, pozwalające na ponowne użycie adresów IP. Administrator sieci
kach konieczne jest powtórzenie tej
nadaje zakres adresów IP do rozdzielenia. Wszyscy klienci mają tak skonfigurowane inter-
samej biblioteki (wynika to ze spo-
fejsy sieciowe, że po starcie systemu automatycznie pobierają swoje adresy. Każdy adres
sobu działania linkera ld w przy-
przydzielany jest na pewien czas. Taka konfiguracja powoduje, że zwykły użytkownik ma
padku, gdy biblioteki odwołują się
ułatwioną pracę z siecią.
do siebie wzajemnie), np: Routing jest to wyznaczenie trasy dla pakietu danych w sieci komputerowej, a następnie
wysłanie go tą trasą. W sieciach opartych na protokole TCP/IP do wyznaczania trasy pakietów
LIBS = lnutarch lnutos
służy specjalna struktura zwana tablicą routingu. Zawiera ona adresy sieci IP (w postaci par
lnutdev lnutarch lnutcrt
adres maska) skojarzone z prowadzącymi do nich fizycznymi interfejsami i/lub routerami. W przy-
kładzie opisanym w artykule tablica routingu wygląda następująco:
Inicjalizacja i konfiguracja
Network Gateway Netmask Iface
interfejsu sieciowego
10.1.0.0 0.0.0.0 255.255.0.0 eth0
Zanim napiszemy jakikolwiek
127.0.0.0 127.0.0.1 255.0.0.0 lo
program wykorzystujący sieciowe
0.0.0.0 10.1.0.1 0.0.0.0 eth0 > wpis
możliwości systemu Nut/OS, musi- dodany przez funkcję NutIpRouteAdd()
Wyznaczanie trasy dla pakietu polega na porównaniu jego adresu z kolejnymi wpisami tablicy
my zainicjalizować kontroler Ether-
routingu:
net i skonfigurować parametry sieci
Jeśli (Adres_docelowy_pakietu AND Netmask) == Network to:
TCP/IP. Uproszczony kod (bez ob-
jeśli nie jest ustawiony gateway > wyślij pakiet bezpośrednio do interfejsu Iface,
sługi błędów i listy plików nagłów-
jeśli jest ustawiony gateway > przekaż pakiet komputerowi o adresie gateway.
kowych), który wykonuje te czyn-
Ostatni wpis w tablicy routingu pasuje do każdego adresu pakietu i przekazuje pakiety do do-
ności przedstawiono na list. 1.
myślnej bramy, czyli komputera łączącego nas z zewnętrzną siecią.
Znana z poprzedniego odcinka
Adres 127.0.0.1 jest adresem zwrotnym urządzenia, czyli samego siebie .
kursu funkcja NutRegisterDevi- HTTP (Hyper Text Transfer Protocol) to protokół sieci WWW (World Wide Web). Właśnie za
pomocą protokołu HTTP przesyła się żądania udostępnienia dokumentów WWW, informacje
ce rejestruje w systemie i inicjuje
o kliknięciu odnośnika oraz informacje z formularzy.
kontroler Ethernet (RTL8019AS).
Pojawiają się też 4 nowe funkcje,
opisane w ramce.
Program pokazany na list. 1 (DHCP/statycznie) za pomocą zmia- korzystamy z DHCP, a urządzeniu
pozwala wybrać rodzaj konfiguracji ny makrodefinicji USE_DHCP. Jeśli nie uda się pobrać adresu z ser-
Funkcje zastosowane w przykładach
int NutDhcpIfConfig(CONST char
ip_addr adres IP urządzenia. int NutTcpAccept(TCPSOCKET *sock, u_short port);
*name, u_char * mac, u_long
ip_mask maska podsieci, w której pracuje Oczekuje na połączenie przychodzące TCP na
timeout);
urządzenie. porcie port, po odebraniu połączenia przypisuje
Próbuje pobrać ustawienia sieci TCP/IP z ser-
je do gniazda siecowego sock. W razie niepo-
wera DHCP i jeśli to się uda, konfiguruje z ich
int NutIpRouteAdd(u_long ip, wodzenia, zwracana wartość jest niezerowa.
użyciem interfejs sieciowy oraz zwraca wartość
u_long mask, u_long gate,
0. W przypadku niepowodzenia, zwracana war-
NUTDEVICE * dev); FILE *_fdopen(int fd, CONST char *mode);
tość jest niezerowa.
Dodanie wpisu do tablicy routingu. Tworzy strukturę FILE wirtualnego pliku połą-
Parametry:
Parametry: czonego z deskryptorem fd w trybie mode. Tryb
name nazwa interfejsu sieciowego, który
ip adres sieci docelowej. r+b użyty w przykładach oznacza odczyt
ma być konfigurowany. W naszym przypadku
mask maska sieci docelowej. i uzupełnianie (r+) binarne (b). Deskryptorem fd
"eth0".
gate brama do sieci docelowej. może być np. wskaznik do gniazda sieciowego
mac adres sprzętowy (MAC) interfejsu
dev interfejs sieciowy, na który kierowane TCPSOCKET. Zwraca wskaznik do nowo utworzo-
sieciowego. Podanie NULL powoduje użycie
będą pakiety o adresach pasujących do wpisu. nej struktury FILE lub NULL w przypadku błędu.
domyślnego MAC a, zapisanego w szeregowej
pamięci na płytce z kontrolerem RTL8019AS.
uint32_t inet_addr(CONST char void fflush(FILE *stream);
timeout czas w milisekundach, po upływie
*addra); Opróżnia bufor zapisu pliku stream, powodując
którego funkcja kończy działanie jeśli nie otrzy-
Zamiana adresu IP w postaci ciągu znaków na natychmiastowe zapisanie/wysłanie znajdujących
ma odpowiedzi od serwera DHCP.
liczbę 32 bitową. się w nim danych.
Parametry:
int NutNetIfConfig(CONST char
addra adres IP (www.xxx.yyy.zzz) w postaci void NutTcpCloseSocket(TCPSOCKET *sock);
*name, void *mac_dev, u_long
łańcucha znaków. Zamyka gniazdo sieciowe sock i zwalnia pamięć
ip_addr, u_long ip_mask);
zajmowaną przez strukturę TCPSOCKET.
Statyczna konfiguracja parametrów sieci TCP/IP
TCPSOCKET *NutTcpCreateSocket();
adresu IP i maski podsieci.
Tworzy nowe gniazdo sieciowe TCP i zwraca void NutHttpProcessRequest(FILE
Parametry:
wskaznik do struktury reprezentującej je. *stream);
name nazwa interfejsu sieciowego.
W przypadku niepowodzenia, zwraca NULL. Przetwarza połączenie HTTP przypisane do
mac_dev adres MAC interfejsu (lub NULL,
pliku strumienia stream.
jeśli ma być użyty domyślny).
Elektronika Praktyczna 1/2007
94
K U R S
List. 2. Kod prostego serwera TCP przesyłanych informacji,
for (;;)
z a t e m d a n e z o s t a n ą
{
odebrane dokładnie w takiej
char buf[256];
kolejności i postaci, w jakiej
// tworzymy gniazdo TCP
z o s t a ł y w y s ł a n e ( o i l e
s = NutTcpCreateSocket();
istnieje fizyczne połączenie
// oczekujemy na polaczenie na port 23 (telnet)
NutTcpAccept(s, 23); między hostami). Nie ma
potrzeby stosowania sum
// tworzymy plik polaczony z gniazdem s
f = _fdopen((int) s, "r+b");
kontrolnych, itp.
Po utworzeniu gniazda,
// wypisujemy tekst powitalny
fprintf(f,"Kurs EP Ethernut\n");
każemy serwerowi oczeki-
fprintf(f,"Operacje na socketach\n");
wać na połączenie przycho-
fprintf(f," \n");
fprintf(f,"Wpisz \"zgas\", aby zgasic lub \"zapal\" aby zapalic diode.\n");
dzące na określony port
funkcja NutTcpAccept().
// upawniamy sie, ze tekst powitalny zostanie natychmiast wyslany do klienta
fflush(f);
Porty pozawalają na odróż-
// petla odbierajaca i wykonujaca polecenia tekstowe nienie od siebie poszczegól-
for(;;)
nych serwerów działających
{
// odbieramy tekst polecenia
na jednym urządzeniu, np.
int len = fread(buf, 1, 256, f);
serwer FTP pracuje na por-
// czy koniec polaczenia?
cie 21, serwer HTTP 80,
if(len<=0) break;
poczta elektroniczna 25
if(!strncmp(buf,"zapal", 5))
(SMTP wysyłanie) i 110
{
fprintf(f,"Dioda zostala zapalona.\n"); (POP3 odbieranie). Nasz
PORTF|=1;
serwer będzie słuchał na
} else if(!strncmp(buf,"zgas", 4))
{ porcie 23, przeznaczonym
fprintf(f,"Dioda zostala zgaszona.\n");
dla usługi Telnet. Po po-
PORTF&=~1;
};
prawnym odebraniu połą-
fflush(f);
czenia, funkcja NutTcpAc-
}
cept() kończy działanie
// zamykamy plik
i zwraca wartość 0. Może-
fclose(f);
my teraz rozpocząć wymia-
// zamykamy gniazdo
NutTcpCloseSocket(s); nę danych.
}
W s y s t e m i e N u t / O S
d o w y s y ł a n i a i o d b i e -
wera w ciągu 20 sekund, interfejs zapisane do gniazda w jednym rania d a ny c h z g n ia zda TC P
sieciowy zostanie zainicjowany pa- z nich będzie można odczytać s ł u ż ą d e d y k o w a n e f u n k c j e
rametrami statycznymi. z socketa w drugim i na odwrót. NutTcpSend() i NutTcpRece-
Należy tu przypomnieć o bardzo i v e ( ) . Można jednak wykonać
Najprostszy serwer TCP istotnej właściwości protokołu trick, który umożliwi traktowanie
Program, który odbiera połą- TCP zapewnia on integralność socketa jako zwykły plik wówczas
czenia przychodzące TCP jest na-
zywany serwerem, zaś taki, który
inicjuje połączenia wychodzące
klientem. Nazwa serwer nie-
którym Czytelnikom może kojarzyć
się ze skomplikowanym oprogra-
mowaniem, ale w naszym przypad-
ku implementacja prostego serwera
będzie zadaniem bardzo łatwym
i wartym przedstawienia na począt-
ku kursu.
Szkielet prostego serwera TCP
jest pokazany na rys. 1, zaś
uproszczony kod w C (pozbawiony
obsługi błędów) na list. 2. Serwer
zaczyna pracę od utworzenia
nowego gniazda sieciowego (ang.
socket) protokołu TCP (funkcja
NutTcpCreateSocket()). Gniazdo
t a k i e j e s t d w u k i e r u n ko w y m
punktem końcowym pojedynczego
połączenia sieciowego. Jeśli więc
mamy nawiązane połączenie TCP
między dwoma urządzeniami, dane Rys. 1. Szkielet serwera TCP w systemie Nut/OS
Elektronika Praktyczna 1/2007
95
K U R S
Rys. 2. Otwarta sesja telnet z serwerem TCP
będzie możliwe korzystanie ze zna- nych w buforze
nych z języka C funkcji fread(), z a p i s u p l i k u . Rys. 3. Strona testowa przykładowego serwera WWW ba-
fwrite(), fprintf(), fgetc(), Funkcje wykonu- zującego na Nut/OS
itd. Wykorzystamy w tym celu jące operacje za-
funkcję _fdopen(), która tworzy pisu (np. fwrite(), fprintf()) Pokazana tu najprostsza aplika-
plik połączony z gniazdem siecio- gromadzą niewielkie ilości danych cja serwera WWW ma jeszcze jed-
wym. Operacje we/wy na takim w buforach i wysyłają je hurtem , ną wadę może obsługiwać w da-
pliku będą powodowały zapis do/ po napełnieniu bufora. Wywoła- nej chwili tylko jedno połączenie.
odczyt z gniazda sieciowego. Zasto- nie fflush() po fprintf() daje Za miesiąc zapoznam Was z obsłu-
sowanie _fdopen() będzie rów- pewność, że dane zapisane przez gą wątków w systemie Nut/OS, co
nież konieczne przy implementacji funkcję fprintf() zostałną na- umożliwi pokonanie tego ograni-
serwera WWW opisanego na koń- tychmiast wysłane do klienta. czenia.
cu artykułu. Została jeszcze jedna niewyja-
Nasz przykładowy serwer po śniona sprawa jak połączyć się System plików UROM
odebraniu połączenia wysyła komu- z naszym serwerem? Można do tego Pliki strony internetowej, którą
nikat powitalny za pomocą funkcji celu skorzystać z dowolnego klienta będzie obsługiwał nasz serwer mu-
fprintf(). Następnie w nieskoń- usługi Telnet, np. programu Putty szą być gdzieś zapisane. W przy-
czonej pętli, pobiera komendę od (http://www.chiark.greenend.org.uk/~ padku bardzo prostych witryn,
klienta (funkcja fread()), analizu- sgtatham/putty/download.html), który doskonale nadaje się do tego pa-
je ją i zapala lub gasi diodę LED. wysyła do serwera teksty wpisane mięć Flash mikrokontrolera. Twór-
Zwrócenie przez fread() wartości z klawiatury komputera, a odebrane cy Nut/OSa stworzyli w tym celu
mniejszej lub równej 0 oznacza, dane odebrane wyświetla na ekra- prosty system plików UROM, prze-
że (najprawdopodobniej) połączenie nie. Otwartą sesję telnet z naszym znaczony specjalnie do przechowy-
zostało przerwane. Wówczas pętla serwerem przedstawia rys. 2. wania niewielkich plików razem
wykonująca komendy zostaje zakoń- z kodem programu. Aby z niego
czona, a plik gniazdo oraz gniazdo Serwer WWW skorzystać, należy edytować li-
sieciowe są zamykane (fclose() System Nut/OS ma wbudowaną nię CRUROM_DIR w pliku Sour-
i NutTcpCloseSocket()). obsługuję protokołu HTTP, dlatego ces, podając ścieżkę do katalogu,
W kodzie z list. 2 pojawia się stworzenie prostego serwera stron którego zawartość ma znalezć się
także funkcja fflush(). Wymusza internetowych jest bajecznie pro- we Flashu mikrokontrolera. W wy-
ona wysłanie danych zgromadzo- ste. Sprowadza się to do wywoła- niku tego powstanie dodatkowy
nia jednej (nie, to nie jest plik zródłowy n a z w a _ k a t a l o
List. 3. Kod najprostszego serwera WWW błąd w druku) funkcji Nu- gu_crurom.c (automatycznie kom-
for (;;)
tHttpProcessRequest() pilowany i linkowany do projektu)
{
po odebraniu połączenia ze strukturami systemu plików.
char buf[256];
na porcie 80 (HTTP). Kod UROM widziany jest przez sys-
// tworzymy gniazdo TCP
takiego serwera (bez ob- tem Nut/OS jako oddzielne urzą-
s = NutTcpCreateSocket();
sługi błędów) pokazany dzenie, dlatego należy go zareje-
jest na list. 3. strować i zainicjalizować wywołując
// oczekujemy na polaczenie na port 80 (HTTP)
Efekty działania serwe- funkcję:
NutTcpAccept(s, 80);
ra ethernutowego WWW NutRegisterDevice(&devUrom,
// tworzymy plik polaczony z gniazdem s
przedstawiono na rys. 3. 0, 0);
f = _fdopen((int) s, "r+b");
Oczywiście są to mini- Tomasz Włostowski
// przetwarzamy zapytanie HTTP
malne jego możliwości. twlostow@onet.eu
if(f)
{
W następnym odcinku kur-
NutHttpProcessRequest(f);
// zamykamy plik su pokażę, jak obsługiwać
Przedstawione w artykule projekty przy-
fclose(f);
formularze i skrypty CGI,
} kładowe były uruchamiane na zestawie
autoryzację użytkowników
udostępnionym przez firmę Kamami.
oraz generowanie stron
// zamykamy gniazdo
Dodatkowe informacje są dostępne pod
NutTcpCloseSocket(s);
WWW z dynamiczną za-
adresem www.kamami.pl.
}
wartością.
Elektronika Praktyczna 1/2007
96
Wyszukiwarka
Podobne podstrony:
Ethernet i AVR–y, cz 1Ethernet i AVR–y, cz 3Ethernet i AVR–y, cz 5Bootloader AVR cz 2Kurs AVR GCC cz 5Zestaw uruchomieniowy do procesorow rodziny AVR i 51, cz 2Kurs AVR GCC, cz 3Kurs AVR GCC cz 2Kurs AVR GCC cz 3Kurs AVR GCC cz 1Kurs AVR GCC, cz 1AVR owe fusy cz 2Kurs AVR GCC, cz 5Kurs AVR GCC, cz 4Kurs AVR GCC, cz 2Kurs AVR GCC cz 4więcej podobnych podstron