Ugrađeni operativni sistemi – II deo

U prethodnom članku govorili smo o osnovnim karakteristika ugrađenih operatinih sistema i razlikama u zahtevima koje trebaju ispuniti ugrađeni operativni sistemi u odnosu na operativne sisteme opšte namane. U ovom nastavku bavićemo se raličitim pristupima pri projektovanju ugrađenih operativnih sistema na primerima operativnih sistema eCos i TinyOS, kao i predstaviti praktičan primer upotrebe ovakvog sistema.

eCos Embedded Configurable Operating System (eCos)

je operativni sistem namenjen ugrađenim sistemima. Besplatan je i otvorenog koda, namenjen aplikacijama s jednim procesom i više niti. Dizajniran je zadovolji potrebe rada u realnom vremenu pružajući bolje performanse od sistema opšte namene. Implementiran je u jeziku C/C++.

Konfigurabilnost

Softver eCos ima veliku podršku hardvera na kojima se može pokretati. Usled raznovrsnosti namene i hardvera ugrađenog sistema od operativnog sistema se očekuje da obezbedi veliki broj potrebnih funkcionalnosti. Npr. mnogo sistemi zahtevaće komutaciju zadataka ili upravljanje konkurentnošću, dok oni mnogo jednostavniji nemaju takve zahteve.

Fleksibilnost eCos – a ogleda se u mogućnosti samostalnog konfigurisanja potrebnih komponenti. Tako je ostavljena mogućnost izbora funkcionalnosti koje sistem koristi i funkcionalnosti koje sistem ne koristi. Celokupan paket eCos struktuiran je hijerarhijski što odabir komponenti čini jednostavnim. Odabir se vrši iz alata za konfigurisanje koji se može pokrenuti na Linux ili Windows platformi. Npr. ako korisnik želi da koristi serijski I/O može na višem nivou da odabere serijski I/O, a  na nižem nivou odabere jedan ili više serijskih uređaja koji trebaju biti podržani, zatim brzinu prenosa itd. Sistem će tada sadržati minimum potrebne podrške za navedene zahteve.

Alat za konfiguraciju – konfiguracija višeg nivoa
Alat za konfiguraciju – konfiguracija nižeg nivoa

Komponente sistema eCos

Softver eCos namenjen različitim arhitekturama i platformama. Sastoji se od slojevite strukture komponenata koje omogućavaju jednostavnost promene odabrane arhitekture.

Arhitektura sistema eCos

Sloj apstrakcije hardvera

Na dnu se nalazi sloj apstrakcije hardvera (HAL). Ovaj sloj predstavlja softver koji pruža interfejse višim slojevima i preslikava operacije sa viših nivoa na hardverski nivo. Svaki hardver zahteva specifičnu implementaciju funkcija HAL-a. Pozivi sa viših slojeva su nezavisni od hardvera jer se pozivaju iste funkcije HAL-a. HAL implementaciju čine 3 odvojena modula:

  • Arhitektura
  • Varijanta
  • Platforma

eCos kernel

Pri projektovanju kernela eCos – a zadovoljne se četiri glavna cilja:

  • Malo kašnjenje prekida
  • Malo kašnjenje komutacije zadataka
  • Mali trag u memoriji
  • Determinističko ponašanje

Kernel pruža potrebne funkcionalnosti za razvoj aplikacija u više niti. Nit se može kreirati pri pokretanju ili za vreme rada sistema. Postoji kontrola nad nitima u sistemu,  npr. manipulacija prioritetima. Može se vršiti odabir raspoređivača. Uključeni su mehanizmi sa sinhronizaciju niti i integrisana podrška za prekide i izuzetke.

Za razliku od operativnih sistema opšte namene kernel eCos može izostaviti određene funkcionalnosti, npr. dodela memorije može biti zasebni paket. Jednostavnost kernela dovodi do mogućnosti da određeni jednostavni sistemi uopšte ne koriste kernel. Jednostavne aplikacije mogu se izvršiti direktno na HAL-u.

Funkcije kernela eCos, npr. kreiranje niti, mogu se koristiti na dva načina. Prva način je upotreba API-a kernela. Poziv takve naredbe ima oblik

1. cyg_thread_create

Drugi način je poziv funkcija iz paketa kompatibilnosti, npr. POSIX iz aplikacije

2. pthread_create    

U/I sistem

Paket za konfiguraciju sadrži veliki broj različitih drajvera za različite platforme. Tu su drajveri ja Ethernet, serijsku komunikaciju, flesh memorije, PSI, USB itd. Dodatno korisnici mogu razviti drajvere za sopstvene uređaje.

Drajveri se mogu implemetirati kao deo HAL-a, ili upotrebom API-ja kernela. Kernel koristi tri nivoa prekida:

  • Rutine za opsluživanje prekida (ROP) – pozivaju se kao odziv na hardverski prekid
  • Rutine sa odloženim servisom (ROS) – pozivaju se kao odziv na zahtev ROP. Izvršavaju se kada je bezbedno da se izvrše, bez ometanja raspoređivača.
  • Niti – klijenti drajvera. Mogu da naprave sve pozive API – a, a posebno im je dozvoljeno da čekaju na mutexe i uslovne promenljive.

Standardne C biblioteke

Obezbeđene je kompletna izvršna standardna C biblioteka. Takođe uključena je i kompletna matematička biblioteka.

Raspoređivač sistema eCos

Sistem eCos poseduje dve vrste raspoređivača, to su bitmapni raspoređivač i raspoređivač redova u više nivoa. Korisnik pri konfiguraciji sistema bira željeni raspoređivač.

Bitmapni raspoređivač podržava različite nivoe prioriteta. Svakom nivou može se dodeliti samo po jedna nit. Raspoređivanje je jednostavno, spremna nit višeg prioriteta može da prekine izvršavanje niti nižeg prioriteta. Nit se može zaustaviti usled blokade sinhronizacionim mehanizmom, zato što je prekinuta ili se odriče upravljanja. Postoje raspoređivači sa 8, 16 ili 32 nivoa prioriteta.

Raspoređivač redova u više nivoa takođe koristi 32 nivoa prioriteta. Razlika je u tome sto dozvoljava postojanje više aktivnih niti na istom nivou prioriteta. Slično prethodnom, spremna nit višeg prioriteta može prekinuti nit nižeg prioriteta. Ukoliko se nit blokira raspoređivač proveri da li postoje druge spremne niti istog prioriteta. Ukoliko postoje raspoređuje prvu iz reda čekanja. Dodatna razlika je mogućnost rada sa vremenskim isečcima. Ako postoji više niti sa istim prioritetom jedna će se izvršavati u toku jednog vremenskog isečka, nakon čega se raspoređuje sledeća nit iz reda čekanja. To je politika kružnog dodeljivanja. Ukoliko ne postoji potreba za kružnim dodeljivanjem može se isključiti rad sa vremenskim isečcima.

Sinhronizacija niti sistema eCos

Kernel sistema eCos može da uključi i mehanizme za sinhronizaciju niti. Pored standardnih mehanizama muteksa, semafora i uslovnih promenljivih postoje i dodatni mehanizmi koji su uobičajeni u sistemi za rad u realnom vremenu markere događaja i poštanske sandučiće, a postoji podrška i za obrtna zabravljivanja.

Muteksi su mehanizmi međusobnog isključenja. Samo jedan nit ima pravo pristupa resursu. Muteks ima dva stanja – odbravljeno i zabravljeno. Razlika između muteksa i binarnog semafora je to što samo nit koja je zabravila muteks može da ga odbravi. Dodatno muteksi vode računa o inverziji prioriteta.

Brojčani semafori predstavlja celobrojnu vrednost koja se koristi za signalizaciju između niti. Komande operativnog sistema za upravljanje semaforima su

  • cyg_semaphore_init – inicijalizacija semafora
  • cyg_semaphore_post – povećavanje brojača
  • cyg_semaphore_wait – provera vrednosti semafora

Upotreba semafora omogućava nitima da čekaju dok se neki događaj ne pojavi. Druga primena je upravljanje resursima, gde vrednost semafora odgovara količini raspoloživog resursa.

Uslovna promenljiva se koristi da blokira nit dok je određeni uslov tačan. Koriste se sa muteksima i omogućavaju da više niti deli isti resurs. Pomoću njih mogu se implementirati monitori. Najznačajnije komande su:

  • cyg_cond_wait – Nit čeka uslovnu promenljivu i odbravljuje muteks pridružen uslovnoj promenljivoj.
  • cyg_cond_signal – Budi jednu od niti koja čeka na uslovnu promenljivu. Ta nit postaje vlasnik pridruženog muteksa.
  • cyg_cond_broadcast – Budi sve niti koje čekaju na tu uslovnu promenljivu. Sve probuđene niti postaju vlasnici pridruženog muteksa.

Marker događaja je 32-bitna reč koja je koristi kao sinhronizacioni mehanizam. Svakom bitu možemo pridružiti određeni događaj. Nit može čekati određeni događaj ili kombinaciju događaja. Nit se blokira dok se ne postave svi potrebni markeri (AND) ili samo  jedan od njih (OR). Koristi se komanda cyg_flag_wait koja prihvata marker posebnog događaja, zahtevanu kombinaciju bitova i parametar režima. Parametar režima određuje da li se koristi operacija AND ili OR, kao i da li će se marker obrisati kada čekanje uspe.

Poštanski sandučići su sinhronizacioni mehanizam eCos sistema. Obezbeđuju razmenu informacija između niti. Mogu se koristi blokiranje ili neblokiranje. Maksimalna veličina reda za poruke može se konfigurisati. Postoje tri varijante komande za postavljanje poruke:

  • cyg_mbox_put – ako postoji slobodan slot poruka se postavlja, u suprotnom nit se blokira i čeka da se slot oslobodi
  • cyg_mbox_timed_put – slično kao i prethodna naredba, ali je vreme čekanja ograničeno. Ukoliko vreme istekne funkcija vraća false.
  • cyg_mbox_tryput – neblokirajuća verzija, ukoliko postoji slobodan slot postavlja poruku i vraća true, u suprotnom vraća false.

Analogno prethodnim komandama, postoje i komande za prijem poruke

  • cyg_mbox_get
  • cyg_mbox_timed_get
  • cyg_mbox_tryget

Obrtno zabravljivanje je marker koji nit provera pre nego što izvrši određeni deo koda. Samo jedna nit može da zaume obrtno zabravljivanje dok će svaka druga nit koja proba da zaume isto obrtno zabravljivanje to stalno pokušavati sve dok ne uspe. Resurs koji se provera je lokacija u memoriji. Sve dok vrednost na toj lokaciji ne postane 0 nit će proveravati vrednost. Ovaj mehanizam ne treba koristiti na jednoprocesorskom sistemu jer usled različitih prioriteta niti može doći do međusobne blokade.

TinyOS

je operativni sistem dizajniran za ugrađene sisteme bežičnih mreža senzora. Predstavlja veliko odstupanje od drugih ugrađenih operativnih sistema jer TinyOS nije operativni sistem za rad u realnom vremenu. Razlog za ovakav pristup je upotreba jednostavnih aplikacija koje ne zahtevaju veliko nadmetanja za procesor.

Postoji velika razlika u odnosu na operativne sistem opšte namene, TinyOS ne sadrži kernel, nema kontrolu nad memorijom, nema procesa, a obrada prekida zavisi od periferija.  U osnovi zasnovan je na komponentama, predstavlja raspoređivač i skup drajvera za mikrokontrolere.

Bežične mreže senzora

Osnovna namena TinyOS -a je upotreba u malim mrežama bežičnih senzora. Razvoj senzora male potrošne omogućio je veliku primenu ovakvih mreža.

Bazna stanica povezuje mrežu senzora sa host PS računarom i prosleđuje podatke senzora iz mreže na host PC.  Pojedinačni senzori izmerene vrednosti prosleđuju baznoj stanici. Veza može biti direktna ili preko drugih senzorskih uređaja u mreži. Za određivanje putanje podataka kroz senzorsku mrežu potrebno je rutiranje. Uređaji trebaju biti sposobni da se sami okupe u ad-hoc mreži.

Ciljevi sistema TinyOS

Pri projektovanju sistema postavljeni su sledeći ciljevi:

  • Dozvoljavanje velike konkurentnosti
  • Rad sa ograničenim resursima
  • Prilagođavanje evoluciji hardvera
  • Podrška širokom skupu aplikacija
  • Podrška raznovrsnom skupu platformi
  • Robusnost

Aplikacije će uglavnom koristiti veliki broj umreženih senzora. Prenos tih podataka može izazvati kašnjenje pa je uobičajeno da postoji baferovanje.

Komponente sistema TinyOS

Softver se sastoji od skupa modula koji se nazivaju komponente. Svaka komponenta zadužena je za jedan jednostavan zadatak ili skup zadataka. Razvoj TinyOS – a rezultirao je implementacijom velikog broja standardizovanih komponenti otvorenog koda, npr. umrežavanje s jednim skokom, ad-hoc rutiranje, tajmeri itd. Za specifične konfiguracije moguće je razviti sopstvene komponente.

Komponenta može biti softver ili hardver. Arhitektura sistema je uređena hijerarhijski. Na dnu se nalazi hardver, a na vrhu komponenta aplikativnog softvera.  Svaka komponenta može se povezati najviše sa dve komponente, od kojih se jedna nalazi iznad, a druga ispod nje.

Softverske komponente izvedene su u jeziku nesC koji je proširenje jezika C. Softverska komponenta implemetira jedan ili više zadataka. Zadaci su slični nitima u običnim operativnim sistemima. Kada se neki zadatak pokrene, on se izvršava do kraja. Drugi zadatak iz komponente ga ne može prekinuti, ali može da se prekine događajem. Osim izvršavanja proračuna zadatak može pozivati komponente nižeg nivoa (komande), signale višeg nivoa i da raspoređuje druge zadatke.

Komande su neblokirajući poziv. Komponenta višeg nivoa izdaje komandu komponenti nižeg nivoa da izvrši neku uslugu, npr. očita vrednost senzora. Kada se usluga izvrši signalizira se događaj komponenti koje je pozvala komandu.

Osim pomenutih događaja u TinyOS -u, događaji mogu biti povezani i sa hardverskim događajima. Komponenta najnižeg nivoa može da opsluži prekid ili da prenese poruku o događaju komponenti iznad sebe.

Komponente se organizuju u konfiguracije koje sadrže dve oblasti – specifikaciju i implementaciju. Konvencijom imenovanja velikim C označavamo komponente (TimerC). Ta komponenta obezbeđuje interfejs Timer. Velikim M označavamo module (TimerM).

Raspoređivač sistema TinyOS

Raspoređivač je podrazumevana komponenta TinyOS -a i prisutan je u svakom sistemu. Sistemi koji koriste TinyOS su uglavnom jednoprocesorski tako da se u jednom trenutku može izvršavati samo jedan zadatak. Raspoređivač se organizuje kao jednostavni FIFO red. Kada nema zadataka u redu procesor se stavlja u režim spavanja. Svaki zadatak ima svoj sopstveni rezervisani slot u redu zadataka i svaki zadatak može da se pošalje samo jednom. Ako je potrebno poslati zadatak više puta, može se podesiti da on sam ponovo šalje.

Podrazumevani raspoređivač je moguće promeniti, npr. raspoređivačem zasnovanim na vremenskom roku, ali je to nepotrebno opterećenje za sistem i kršenja modela konkurentnosti.

Interfejs za resurse sistema TinyOS

Koriste se tri apstrakcije za resurse

  • Namenski – kada je potreban ekskluzivni pristup, npr. prekidi i brojači
  • Virtueizovani – virtuelizovana apstrakcija može da se koristi kada se resurs štiti od međusobnog isključenja, npr. generator takta ili tajmer
  • Deljeni – ovo apstrakcijom obezbeđuje se pristup namenskom resursu preko arbitarske komande. Arbitar sprovodi međusobno isključivanje, dozvoljavajući samo samo jednom korisniku istovremeno da ima pristup. Sprovodi politiku kojom klijent može da zabravi resurs, upotrebi resurs i zatim ga oslobodi.

Demo projekat TinyOS

Zadatak:

Kreirati bežičnu mrežu upotrebom TinyOS-a. Bežična mrežu se sastoji od tri čvora (node-a). Potrebno je obezbediti da u tačno određenom intervalu stanice 1 i 3 šalju poruku stanici 2 i zahtevaju izveštaj o isporuci.

Rešenje problema prilagoditi arhitekturi micaz platforme. Dodatno upotrebom TOSSIM simulatora simulirati rad pomenute mreže i dati analizu uspešnosti prosleđivanja poruka u zavisnosti od jačine signala između stanica.

Implementacija modula

Potrebno je kreirati fajlove napisane u nesC jeziku DemoCommunicationC.nc i DemoCommunicationAppC.nc. Prvi fajl sadrži potrebnu implementaciju, dok sledeći povezuje potrebne komponente.

Pre same implementacije upoznajmo se sa definicijom interfejsa koji se koriste u komunikaciji. Interfejs namenjen slanju poruka.

/* interface AMSend */

#include  
#include  
#include  

interface AMSend 
{ 
    command error_t send(am_addr_t addr, message_t* msg, uint8_t len); 
    command error_t cancel(message_t* msg); 
    command uint8_t maxPayloadLength(); 
    command void* getPayload(message_t* msg, uint8_t len); 

    event void sendDone(message_t* msg, error_t error); 

}

Sledeći je interfejs koji se koristi za dobijanje izveštaja o uspešnosti slanja paketa.

/* interface PacketAcknowledgements */

interface PacketAcknowledgements 
{ 
    async command error_t requestAck( message_t* msg ); 
    async command error_t noAck( message_t* msg ); 
    async command bool wasAcked(message_t* msg); 
}

Naredni interfejs koji se koristi sadrži samo događaj koji se označava prijem poruke.

/* interface Receive */

#include  
#include  

interface Receive 
{ 
    event message_t* receive(message_t* msg, void* payload, uint8_t len); 
}

Interfejs namenjen promeni stanja pokrenuto / zaustavljeno komponente koja obezbeđuje interfejs.

/* interface SplitControl */

interface SplitControl 
{
   command error_t start(); 
   command error_t stop(); 

   event void startDone(error_t error); 
   event void stopDone(error_t error); 
}

Da bi se obezbedilo periodično slanje koristi se interfejs Timer.

/* interface Timer */

interface Timer 
{ 
    command void startPeriodic(uint32_t dt); 
    command void startOneShot(uint32_t dt); 
    command void stop(); 
    command bool isRunning(); 
    command bool isOneShot(); 
    command void startPeriodicAt(uint32_t t0, uint32_t dt); 
    command void startOneShotAt(uint32_t t0, uint32_t dt); 
   command uint32_t getNow(); 
   command uint32_t gett0(); 
   command uint32_t getdt(); 

   event void fired(); 
}

Sada se možemo vratiti implementaciji potrebnih funkcionalnosti. Čvorovi  1 i 3 šalju poruke u tačno definisanom vremenskom intervalu, nakon čega čekaju potvrdu o isporuci. Vremenski interval zadajemo pokretanjem Timer-a, a slanje poruke predstavlja reakciju na događaj Timer.fired(). Dodatno potrebno je obraditi događaje za završetak slanja poruke i prijem poruke.

/* interface DemoCommunicationC */

 module DemoCommunicationC 
 { 
     uses 
     {
          interface Boot; 
          interface Timer as Timer; 
          interface Receive; 
          interface AMSend; 
          interface Random; 
          interface SplitControl; 
          interface AMPacket; 
          interface PacketAcknowledgements; 
          interface TossimPacket; 
     } 
 } 
 implementation 
 { 
     message_t packet; 
     uint8_t busy; 

     event void Boot.booted() 
     { 
         dbg("DemoCommunication", "Boot @ %s.\n", sim_time_string()); 
       call SplitControl.start(); 
     } 

     event void SplitControl.startDone(error_t e) 
     {
       // nodovi 1 i 3 emitovaće poruke 
         if (TOS_NODE_ID == 1 || TOS_NODE_ID == 3) 
         { 
             call Timer.startPeriodic(128); 
         } 
     } 
     event void SplitControl.stopDone(error_t e) 
     { } 

     event void Timer.fired() 
     { 
         if (!busy) 
         { 
             // slanje paketa 
             call PacketAcknowledgements.requestAck(&packet); 
             if (call AMSend.send(2, &packet, call AMSend.maxPayloadLength()) == SUCCESS) 
             { 
                 // uspešno slanje 
                 dbg("DemoCommunication", "Slanje uspesno @ %s\n", sim_time_string()); 
                 busy = TRUE; 
             } 
             else 
             { 
                 // neuspesno slanje 
                 dbg("DemoCommunication", "Slanje neuspesno  @ %s\n", sim_time_string()); 
             } 
         } 
         else 
         { 
             dbg("DemoCommunication", "Pokusaj slanja - zauzeto  @ %s\n", sim_time_string()); 
         } 
     } 

     event void AMSend.sendDone(message_t* m, error_t s) 
     { 
         dbg("DemoCommunication", "Slanje zavrseno - potvrda : %s @ %s\n", call PacketAcknowledgements.wasAcked(m)? "ACK":"NOACK", sim_time_string()); 
         busy = FALSE; 
     } 

     event message_t* Receive.receive(message_t* msg, void* p, uint8_t l) 
     { 
         dbg("DemoCommunication", "Poruka primljena od %hu @ %s jacina signala %hhi\n", call AMPacket.source(msg), sim_time_string(), call TossimPacket.strength(msg)); 
         return msg; 
     } 
 }

Potrebno je još dodati fajl DemoCommunicationAppC.nc.

/* interface PacketAcknowledgements */

 configuration DemoCommunicationAppC {} 
 implementation 
 {
     enum { 
       AM_TEST  = 133 
     }; 

     components MainC, DemoCommunicationC as App, RandomC, ActiveMessageC, TossimActiveMessageC; 
     components new TimerMilliC(), new AMSenderC(AM_TEST), new AMReceiverC(AM_TEST); 

     App.Boot -> MainC.Boot; 
     App.SplitControl -> ActiveMessageC; 
     App.Timer -> TimerMilliC; 
     App.AMSend -> AMSenderC; 
     App.Receive -> AMReceiverC; 
     App.Random -> RandomC; 
     App.AMPacket -> AMSenderC; 
     App.PacketAcknowledgements -> AMSenderC; 
     App.TossimPacket -> TossimActiveMessageC; 
 }

Za build – odovanje aplikacije koristi se make alat za koji kreiramo Makefile. Pri pokretanju naredbe  make prosleđujemo parametar micaz.

/* Makefile */

COMPONENT=DemoCommunicationAppC 
include $(MAKERULES)

TinyOS simulator TOSSIM

TOSSIM je TinyOS biblioteka otvorenog koda koja je isporučuje u okviru instalacije TinyOS-a. Sadrži implementaciju paketa prilagođenih simulatoru. Trenutno podržava simulaciju platforme micaz. Za pokretanje na simulatoru, pri pokretanju naredbe make treba proslediti argumente micaz sim. U radnom direktorijumu  kopira se TOSSIM biblioteka napisana za programski jezik python.

Možemo startovati python.

/* python */

from TOSSIM import * 
t = Tossim([])

U simulatoru zadajemo topologiju bežične mreže. Simulator vodi računa o uslovima realne komunikacije i pojavi šuma. Svakom čvoru zadaje vrednosti očitavanja šuma na osnovu kojih on proračunava statički model. Vrednosti koje se zadaju dobijene su eksperimentalno od strane Stanford Univerziteta i isporučene u fajlu meyer-heavy.txt.

Potrebno je minimum 100 vrednosti za kreiranje modela, a u našem primeru koristi se skraćena verzija isporučena u fajlu meyer-short.txt. Kreiraćemo tri python skripte koje se razlikuju samo po topologiji mreže, tačnije po jačini signala između čvorova. Te fajlove nazivamo: test-equal.py, test-asym.py, test-unequal.py u kojima je jačina signala između čvorova jednaka, asimetrična i nejednaka respektivno. Prikazaćemo fajl  test-equal.py.

/* Python test-equal.py */

 from TOSSIM import * 
 import sys 
 import time 

 t = Tossim([]) 
 r = t.radio();

 # preusmeravanje kanala na standardni izlaz 
 t.addChannel("DemoCommunication", sys.stdout) 
 t.addChannel("SNRLoss", sys.stdout) 

 #t.addChannel("Acks", sys.stdout) 
 #t.addChannel("Gain", sys.stdout) 
 #t.addChannel("CpmModelC", sys.stdout) 
 #t.addChannel("AM", sys.stdout) 

 start = time.time(); 
 m1 = t.getNode(1) # selektovanje čvora 
 m2 = t.getNode(2) 
 m3 = t.getNode(3) 

 #pokretanje uređaja 
 m1.bootAtTime(345321); 
 m2.bootAtTime(82123411); 
 m3.bootAtTime(345325); 

 # zadavanje topologije i jačine signala
 r.add(1, 2, -60.0);  
 r.add(2, 1, -60.0); 
 r.add(2, 3, -60.0); 
 r.add(3, 2, -60.0); 

 # učitavanje vrednosti za kreiranje statičkog modela šuma 
 noise = open("meyer-short.txt", "r") 
 lines = noise.readlines() 
 for line in lines: 
     str = line.strip() 
     if (str != ""): 
       val = int(str) 
       m1.addNoiseTraceReading(val) 
       m2.addNoiseTraceReading(val) 
       m3.addNoiseTraceReading(val) 

 # kreiranje modela šuma 
 m1.createNoiseModel() 
 m2.createNoiseModel() 
 m3.createNoiseModel() 

 # narednih 200000 koraka simulacije 
 for i in range(0, 200000): 
     t.runNextEvent(); 

Pokrenuta skripta startuje čvorove, zadaje im topologiju mreže, učitava vrednosti šuma u komunikaciji i pokreće narednih 200000 koraka simulacije. Simulacija daje izlaze sa više kanala, a nama je najzanimljiviji DemoCommunication, kanal koji smo koristi za ispis informacija unutar DemoCommunicationC.

Sada možemo napisati bash skriptu kojom izvršavamo simulacije, a zatim prikazujemo statističke podatke o uspešnosti slanja.

/* demo */

 #!/bin/bash 

 make micaz sim 

 for t in test-equal.py test-asym.py test-unequal.py 
     do 
         echo Pokretanje $t... 
         python $t > `basename $t .py`.log 
     done 

 make clean 

 for l in test-equal.log test-asym.log test-unequal.log 
 do 
     echo $l 
     echo -e '\t   ACK \t\t NOACK \t total' 
     for i in 1 3 
        do 
            N1=`grep 'Slanje zavrseno' $l | grep ' ACK' | grep "($i)" | wc -l` 
            N2=`grep 'Slanje zavrseno' $l | grep 'NOACK' | grep "($i)" | wc -l` 
            echo -e "\t $i $N1 \t $N2 \t" `expr $N1 + $N2` 
       done 
 done

Izlaz pokrenute  komande su rezultati simulacija:

/* ./demo */

 test-equal.log 
              ACK           NOACK   total 
            1 4528          3636    8164 
            3 4562          3603    8165 
 test-asym.log 
              ACK           NOACK   total 
            1 1162          6994    8156 
            3 1186          6970    8156 
 test-unequal.log 
              ACK           NOACK   total 
            1 5726          2384    8110 
            3 4490          3620    8110

Na narednom linku možete preuzeti kompletan Demo projekat.

Zaključak

Korišćenje ugrađenih operativnih sistema ima izvesne nedostatke ( u pogledu velikog angažovanja mikrokontrolera), ali i brojne prednosti kao što su ispunjenje zahteva u realnom vremenu, pouzdanost i modularnost. Obezbeđuju kvalitetnu i bezbednu sinhronizaciju.

Prilikom projektovanja ugrađenih sistema, cena hardvera je često jedan od ključnih faktora. Zato je važno da se pri razvijanju RTOS obezbedi podrška za veliki broj različitih hardverskih platformi. Hardverski zahtevi operativnih sistema opšte namene često prevazilaze zadata ograničenja, pa su operativni sistemi specijalne namene optimalniji izbor. Stalni razvoj hardvera (Murov zakon) dovodi do velikog povećanja broja ovakvih sistema.

Poređenje operativnih sistema specijalne namene pokazuje razlike u brzini komutacije niti, brzini otpuštanja semafora, utroška RAM i ROM memorije, vremenu odziva itd. ali je teško utvrditi pobednika. Izbor operativnog sistema  suštinski zavisi od same namene ugrađenog sistema i zahteva koje on propisuje.

Dalja tendencija razvoja ugrađenih operativnih sistema je razvoj sistema za IoT (Internet of Things). Razvoj ovakvih sistema često je zasnovan na sistema bežičnih mreža senzora. Jedan ovakav primer je i besplatni operativni sistem otvorenog koda RIOT namenjen za rad u realnom vremenu.

Literatura