Rad - malikolibri/contiki-iris-examples GitHub Wiki

Contiki OS

###Uvod###

Contiki OS je operativni sistem čija je namena prevashodno pravljanje bežičnih senzorskih mreža iako se može koristiti i kao embedded OS opžte namene. On podržava mnoge platforme (uključujući čak Commodore, Atari.. i sl) ali glavni naglasak je na platformama iz niska-potrošnja/niska-cena segmenta koje su svakako najpogodnije za izgradnju sensorskih mreža.

Prva verzija Contiki OS-a izašla je 2002 godine kao delo švedskog inžinjera Adama Dankelsa (Adam Dunkels). Kako je projekat otvorenog koda, u njegovom razvoju danas učestvuju stručnjaci sa poznatih univerziteta širom sveta, preduzeća i etnuzijsati.

Treba napomenuti da je za nagli razvoj u prethodnih par godina doprinela aktuelizacija tzv. IoT (Internet of Things) tehnologija koje u suštini sprežu internet tehnologije sa embedded svetom. "Pametne kuće" su tipičan i popularan primer primene IoT tehnologija gde se sa kućnim uređajima može komunicirati kako iz fotelje koja se nalazi u toj kući tako i sa drugog kraja planete.

####Contiki OS - Glavne osobine####

  • Protothreads - omogućavaju pisanje aplikacija koje su u isto vreme multi-thread i event-driven. S obzirom da se cilja na male embedded sisteme i uzimajući u obzir limitirane hardverske mogućnosti takvih sistema Protothreads ne vode računa o steku. Zato se takav multithreading naziva sackless multithreading.

  • Mrežni slojevi - Contiki OS dolazi sa dva mrežna sloja:

    • RIME - koji se sastoji od mrežnih primitiva(unicast, broadcast, mesh, network flood..) i pogodan je za korišćenje kada je unapre poznata arhitektura mreže

    • uIP - podržava TCP/IP sa standardnim TCP i UDP protokolima i RPL (čita se ripl) sistemom rutiranja koji je namenjen za low-power uređaje.

  • Mala potršnja - Contiki OS je dizajniran s posebnim pažnjom na potrošnju. Idealno bi bilo kada bi baterijeki napajan element mreže mogao da ima višegodišnju autonomiju.

  • Cooja simulator - aplikacija koja omogućava simulaciju senzorskih mreža i lakše pronalaženje eventualnih grešaka pre pokretanja aplikacije na realnom hardveru gde je svakako teže otkriti probleme.

####Podešavanje radnog okruženja####

Linux je najpogodnij kao operativni sistem 'domaćin' u razvoju ContikiOS aplikacija. S obzirom da je Windows daleko rasprostranjenij OS opšte namene, virtualizacija računara se namece kao zgodno rešenje. Virtualna mašina (računar) se pravi u nekom od specijalizovanih softvera kao što su vmware i virtualbox.

Na zvaničnom sajtu ContikiOS-a se može preuzeti vmware bazirana podešena slika virtualne mašine nazvane 'Instant Contiki'.

Neophodni koraci:

  • Preuzeti i instalirati besplatni [vmware player]
  • Preuzeti sliku (image) sa [ContikiOs sajta] i raspakovati fajl.
  • Pokrenuti vmware-player i otvoriti raspakovanu sliku
  • Pre pokretanja same virtualne masine neophodno je u podesavanjima (Virtual Machine > Virtual Machine Settings > Usb Settings) ukljuciti "Show All USB devices"
  • Pokrenuti virtualnu masinu i ulogovati se (password: user).
  • Proveriti da li je programator prepoznat i ukljuciti ga. (Virtual Machine > Removable Devices > Future Devices Crossbow MIB520CA > Connect)

Napomena za linux korisnike: Ukoliko programator nije prepoznat potrebno je pre pokretanja vmware player-a iz terminala pokrenuti: sudo vmware-usbarbitrator

Mađutim u nastavku će biti opisan kompletan nacin pravljenja virtualne mašine zasnovane na virtualbox softveru. Razlog za to su određene manjkavosti Instant Contiki-a kao i sveobuhvatnost ovog uputstva. Potrebno je preuzeti:

  • virtualbox softver sa njihovog zvaničnog sajta

  • Ubuntu linux ili neku od ubuntu baziranih distribucja - u ovom uputstvu će se koristiti xubuntu zbog nešto nižih hardverskih zahteva

Nakon instalacije i pokretanja virtualbox-a, kreira se virtualna mašina na sledeći način:

  • Iz menija se odabira opcija New i u polje name se upisuje proizvoljno ime virtualne mašine. U polju type se selektuje linux i u polju version Ubuntu 64-bit (predpostavka da je preuzeta instalacija xubuntua takodje 64-bit)

  • Količina alocirane memorije za virtualnu mašinu se može ostaviti na preporučenu vrednost (kasnija promena je moguća)

  • Od tri ponuđene opcije treba odabrati opciju koja nudi pravljenje novog virtualnog hard diska.

  • Izabrati VDI format.

  • izabrati dinamičko određivanje veličine diska.

  • Maksimalnu veličinu treba podesiti prema potrebama i mogućnostima ali s obzirom na upotrebu 10GB bi trebalo da bude više nego dovoljno.

Virtualna mašina je kreirana

Instalacija Xubuntu linuxa:

  • U glavnom prozoru virtualbox-a treba selektovati gore kreiranu mašinu i desnim klikom > settings > Storage

  • Selektovati optički uređaj koji je trenutno označen sa empty i sa desne strane slektovati putanju do Xubuntu .iso fajla.

  • Startovati mašinu i sačekati da se xubuntu podigne sa virtualnog optičkog uređaja.

  • Odabrati opciju Install Xubuntu

  • Označiti obe opcije koje se odnose na nadogradnje i dodatne pakete koji nisu otvorenog koda. Continue..

  • potvrditi brisanje virtualnog hard diska

  • selektovanje vremenske zone, jezika

  • popuniti obavezna polja: username i password

  • sačekati da se instalcija završi i restartovati VM

  • iz menija VM prozora Devices > Insert Guest Additions CD Image

  • u virtualnoj mašini će se pojaviti montiran CD sa drajverima koje je potrebno instalirati kako bi Xubuntu koristio virtualbox drajvere. To se obavlja izvršavanjem skripte autorun.sh

Instalacija neophodnih paketa

Lista:

  • avr-binutils - alati za manipulaciju nad binarnim i object fajlovima,
  • avr-gcc - kompajler,
  • avr-gdb - debugger,
  • avr-libc - biblioteke,
  • avrdude - program za upisivanje programa u mikrokontroler.
  • git - alat za distribuciju i upravljanje izvornim kodom
  • wireshark - alat za 'prisluškivanje' mrežnih protokola

Komanda za instalaciju na Ubuntu baziranim distribucijama: sudo apt-get install avrdude binutils-avr gcc-avr avr-libc gdb-avr git-core wireshark libc6-i386 build-essential

####Preuzimanje ContikiOS izvornog koda####

Stabilna verzija ContikiOS-a se može preuzeti sa zvaničnog sajta. Poslednja razvoja nestabilna verzija se može preuzeti sa git-hub repozitorijuma korišćenjeg git alata: git clone https://github.com/contiki-os/contiki.git

Podešavanje dozvola za pristup USB portu

Da bi kontrolu nad USB ure]ajem preneli sa host računara na virtualni potrebno je iz virtualbox prozora izabrati: Devices > USB Devices > Crossbow MIB520CA.

Na Linuxu iz sigunosnih razloga običnim korisnicima obicno nije dozvoljen direktan pristup USB portu.

Da bi proverili ko ima pravo pristupa iz terminala treba pokrenuti: ls -l /dev/ttyUSB0 Dobiće se rezultat sličan:
crw-rw---- 1 root dialout 188, 0 Aug 28 21:17 /dev/ttyUSB0
Iz rezultata se vidi da pravo korišćenja ima vlasnik root i grupa korisnika dialout

Pokretanjem groups u terminalu dobićemo listu grupa u koje je trenutno ulogovani korisnik učlanjen. Primer rezultata:
user adm cdrom sudo dip plugdev lpadmin sambashare
Iz primera se vidi da trenutni korisnik nije član dialout grupe i da neće imati pravo pristupa USB portu.

Da bi dodali korisnika u grupu dialout treba izvršiti sledecu komandu: sudo usermod -a -G dialout $USER, gde username odgovara imenu trenutno ulogovanog korisnika. Da bi se izvršena konfiguracija primenila neophodan je loigout/login ili restart.

####Izmene i izvornom kodu####

U trenutnoj verziji 2.7 Contiki OS-a postoji sitna greška koju je potrebno ispraviti kako bi kompajliranje bilo uspešno.

U fajlu ~/contiki/platform/iris/node-id.c potrebno je porebno dodati #include "contiki-conf.h" i tipove promenljivih izmeniti tako da budu usaglašene sa node-id.h

#####Drajver za senzorsku plčicu MDA100CB##### Na putanji contiki/contiki/platform/iris/dev/sensors/ se nalaze drajveri za sensorsku pločicu MTS300 koja predstavlja napredniju verziju MDA100CB pločice. Na osnovu več postoječeg drajvera i uz konsultovanje dokumentacije mikrokontrolera i sensorske pločice napravljen je drajver za MDA100CB sensorsku pločicu:

mda100cb.h

#ifndef __MDA100CB_H__
#define __MDA100CB_H__

#include "avr/io.h"
#include "contiki-conf.h"
#include "dev/adc.h"

/* MDA100CB, the light sensor power is controlled
 * by setting signal INT1(PORTE pin 5).
 * Both light and thermistor use the same ADC channel.
 */
#define LIGHT_PORT_DDR DDRE
#define LIGHT_PORT PORTE
#define LIGHT_PIN_MASK _BV(5)
#define LIGHT_ADC_CHANNEL 1

/* MDA100CB, the thermistor power is controlled
 * by setting signal PW0(PORTC pin 0).
 * Both light and thermistor use the same ADC channel.
 */
#define TEMP_PORT_DDR DDRC
#define TEMP_PORT PORTC
#define TEMP_PIN_MASK _BV(0)
#define TEMP_ADC_CHANNEL 1

/*
 *  Battery sensor
 *
 */
#define BATTERY_PORT_DDR DDRF
#define BATTERY_PORT PORTF
#define BATTERY_PIN_MASK _BV(1)
#define BATTERY_ADC_CHANNEL 30


uint16_t get_light();
uint16_t get_temp();
uint16_t get_battery();

#endif //__MDA100CB_H__

mda100cb.c

#include "mda100cb.h"


uint16_t
get_light()
{
  uint16_t reading;

  /* Enable light sensor. */
  LIGHT_PORT |= LIGHT_PIN_MASK;
  LIGHT_PORT_DDR |= LIGHT_PIN_MASK;
  /* Disable temperature sensor. */
  TEMP_PORT_DDR &= ~TEMP_PIN_MASK;
  TEMP_PORT &= ~TEMP_PIN_MASK;
  /* Read ADC. */
  reading = get_adc(LIGHT_ADC_CHANNEL);
  /* Disable light sensor. */
  LIGHT_PORT &= ~LIGHT_PIN_MASK;
  LIGHT_PORT_DDR &= ~LIGHT_PIN_MASK;
    return reading;
}
/*---------------------------------------------------------------------------*/
uint16_t
get_temp()
{
  uint16_t reading;

  /* Disable light sensor. */
  LIGHT_PORT &= ~LIGHT_PIN_MASK;
  LIGHT_PORT_DDR &= ~LIGHT_PIN_MASK;
  /* Enable temperature sensor. */
  TEMP_PORT_DDR |= TEMP_PIN_MASK;
  TEMP_PORT |= TEMP_PIN_MASK;
  /* Read ADC. */
  reading = get_adc(TEMP_ADC_CHANNEL);
  /* Disable temperature sensor. */
  TEMP_PORT_DDR &= ~TEMP_PIN_MASK;
  TEMP_PORT &= ~TEMP_PIN_MASK;

  return reading;
}
/*---------------------------------------------------------------------------*/
uint16_t
get_battery()
{
  uint16_t reading;
  
  /* Enable temperature sensor. */
  BATTERY_PORT_DDR |= BATTERY_PIN_MASK;
  BATTERY_PORT |= BATTERY_PIN_MASK;
  /* Read ADC. */
  reading = get_adc(BATTERY_ADC_CHANNEL);
  /* Disable temperature sensor. */
  BATTERY_PORT_DDR &= ~BATTERY_PIN_MASK;
  BATTERY_PORT &= ~BATTERY_PIN_MASK;
  
  return reading;
}

#####Makefile##### Make je alat koji se korisiti za automatizaciju procesa gradnje(build) aplikacije. Build sistem se sastoji iz više slojeva Makefile konfiguracionih fajlova. Takvom hierarhijom se postiže određeni nivo apstrakcije. Makefile kojim se konfiguriše buildovanje aplikacija zasnovanih na iris platformi se nalazi na putanji $(CONTIKI)/platform/iris/Makefile. Sadržaj ovog fajla treba izmeniti kako bi usaglasili izmene sa senzorskim plocicama i dodali mogucnost za debugging.

CONTIKI_TARGET_DIRS = . dev dev/sensors
CONTIKI_CORE=contiki-iris
CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o

SENSOR_BOARD_SOURCEFILES = mda100cb.c 
#SENSOR_BOARD_SOURCEFILES = mts300.c 
CONTIKI_TARGET_SOURCEFILES += cfs-coffee.c cfs-coffee-arch.c 
CONTIKI_TARGET_SOURCEFILES += adc.c rs232.c cfs-eeprom.c contiki-iris-main.c \
                              leds-arch.c init-net.c node-id.c \
                              clock.c spi.c rtimer-arch.c ds2401.c \
                              battery-sensor.c slip.c slip_uart0.c

CONTIKI_TARGET_SOURCEFILES += $(SENSOR_BOARD_SOURCEFILES)

CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=.

# IRIS runs on Clock rate 8 MHz
CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 #-DUSART_BAUD_115200

MCU=atmega1281
AVRDUDE_OPTIONS=-V
AVRDUDE_PROGRAMMER=$(PRGBOARD)
AVRDUDE_PORT=$(PORT)
BAUD_RATE=115200
PORT = /dev/ttyUSB0
LPORT=/dev/ttyUSB1
PRGBOARD = mib510


include $(CONTIKIAVR)/Makefile.avr

%.od: %.$(TARGET)
    avr-objdump -zhD $< > $@

login:
	./$(CONTIKI)/tools/sky/serialdump-linux -b$(BAUD_RATE) $(LPORT)

AVRDUDE_OPTIONS += -U hfuse:w:0x91:m -U efuse:w:0xff:m 

PRGBOARD_FILE = $(CONTIKI)/platform/$(TARGET)/buildscripts/Makefile.$(PRGBOARD)
HAVE_PRGBOARD_FILE = $(wildcard $(PRGBOARD_FILE))

ifneq ($(strip $(HAVE_PRGBOARD_FILE)), )
  include $(PRGBOARD_FILE)
endif 

include $(CONTIKIAVR)/radio/Makefile.radio
ifeq ($(UIP_CONF_IPV6),1)
CFLAGS += -DWITH_UIP6=1
endif

Platformski Makefile se sastoji većinom od promenljivih koje se koriste u Makefile za AVR arhitekturu. Osim toga dodat je "login" blok s kojim se pokreće serijska debug konzola i u AVRDUDE_OPTIONS su dodata fuse podešavanja tako da se sadržaj EEPROM-a čuva za vreme programiranja MCU-a.

###Pozdrav svete###

Hello-world aplikacija se nalazi na putanji CONTIKIOS/examples/hello-world/. U examples direktorijumu se mogu naći primeri koji su uz dokumentaciju glavni izvori znanja. Aplikacija su napisane u standardnom C jeziku i svaka aplikacija sadrži minimum jedan .c i Makefile.

#include "contiki.h"

#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();

  printf("Hello, world\n");
  
  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

Iz hello-world.c se može videti primer minmalnog programa sa jednim pokrenutim procesom.

CONTIKI_PROJECT = hello-world
all: $(CONTIKI_PROJECT)

#UIP_CONF_IPV6=1

CONTIKI = ../..
include $(CONTIKI)/Makefile.include

Poslednje dve linije gore navedenog Makefile-a predstavljaju minimum koji mora da sedrži svaki Makefile na nivou aplikacije. U predposlednjoj liniji se promenljivoj CONTIKI dodeljuje relativna petlja izmedju direktorijuma aplikacije i korenog direktorijuma gde je smešten ContikiOs izvorni kod. Poslednjom linijom se vrši inkluzija glavnog Makefile-a koji u zavisnosti od platforme uključuje i ostale slojeve Makefile-a

#####Kompajliranje, pokretanje i konzolni login#####

Za sledece korake predpostavka je da je radna putanja terminala jednak putanji aplikacije. Takodje potrebno je i priključiti MIB520(sa priključenim Iris nodom) programator na USB port računara kao i omogućiti USB port virtualne mašine.

Kompajliranje hello-world primera: make TARGET="iris" hello-world
Upload hello-world primera(ovaj korak uključuje i kompajliranje): make TARGET="iris" hello-world.u
Čišćenje direktorijuma koje je nekad potrebno izvršiti: make TARGET="iris" clean
Printf je podešen tako da mu je standardni izlaz serijski port. Ovo je naročito zgodan način za pronalaženje eventualnih grešaka.
Da bi videli printf ispise konektovanog iris noda potrebno je pokrenuti komandu: make TARGET="iris" login
Nakon pritiska reset tastera pločice programera na ekranu će se pojaviti ispis sličan ovom:

connecting to /dev/ttyUSB1 (115200) [OK]
Rime started with address 192.117
MAC c0:75:00:00:00:00:00:00
CSMA CX-MAC, channel check rate 8 Hz, radio channel 26
Contiki 2.7 started. Node id 0
Hello, world

###Primeri###

####1-blink#### Pisanjem blink aplikacije biče prikazana osnovna struktura aplikacije zasnovane na ContikiOS:

#include "contiki.h"
#include "dev/leds.h"
#include <stdio.h>

/*---------------------------------------------------------------------------*/
PROCESS(blink_LED, "trepko");
AUTOSTART_PROCESSES(&blink_LED);
/*---------------------------------------------------------------------------*/

PROCESS_THREAD(blink_LED, ev, data) {
    static struct etimer et;
	static unsigned short x;

	PROCESS_BEGIN();
	x = 0;
	while(1) {
		leds_off(LEDS_ALL);
		printf("Led broj: %d \n",x);
		if (x == 0) {leds_on(LEDS_RED);}
		if (x == 1) {leds_on(LEDS_YELLOW);}
		if (x == 2) {leds_on(LEDS_GREEN);}
		x++ ;
		if (x == 3) { x = 0; }
		
		etimer_set(&et, CLOCK_SECOND);
		PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);    
  	}

  	PROCESS_END();
}

Bitno je na početku napomenuti da ContikiOS podržava Protothread-e (multithreading bez steka) i da svaka aplikacija poseduje makar jedan proces. Proces se obično pokreće pri uključenju uređaja, posredno iz drugog procesa ili na događaj (event).

U gore navedenom primeru prikazana je aplikacija koja sadrži jedan proces koji se pokreće (autostartuje) pri uključenju uređaja. Proces je prvo deklarisan uz pomočžć makro komande PROCESS(blink_LED, "trepko"); gde je blink_LED ime procesa, a "trepko" je string koje služi u debug svrhe i obično zluži za opisivanje procesa u za ljude čitljivijoj formi.

Nakon toga sledi makro koji služi za autostartovanje procesa AUTOSTART_PROCESSES(&blink_LED); Kao argument se navode redom adrese procesa koje je potrebno startovati. Procesi se startuju redom kako su navedeni.

Svaki proces se opisuje uz pomoć PROCESS_THREAD koji ima formu funkcije. On počinje sa PROCESS_THREAD(blink_LED, ev, data) gde su argumenti redom: ime procesa koji se definiše, event promenljivak koji nosi podatak o tipu događaja (event-a) i eventualni podaci koji su vezani za događaj koji je pokrenuo proces. Sam procesni deo koda je ograničen sa makro naredbama PROCESS_BEGIN(); i PROCESS_END();.

Deo koda do PROCESS_BEGIN(); se izvršava svaki put, bez obzira da li je porces startovan ili nastavljen. Dok deo koda između PROCESS_BEGIN(); i PROCESS_END(); ima osobinu procesa, tj kod nastavlja sa izvršavanjem tačno na mestu gde je prethodno zaustavljen. Treba napomenuti da se vrednosti promenljivih ne čuvaju na steku u skokovima s procesa na proces. Zbog toga je potrebno obratiti pažnju na promenljive koje je treba da sačuvaju svoje vrednosti i deklarisati ih kao static.

U ovom primeru je deklarisan promenljiva et koja nosi strukturu koja opisuje event timer (etimer) i promenljiva x koja služi kao brojač.

Dalje, nakon PROCESS_BEGIN(); inicializovana je x promenljiva. Posle inicijalizacije telo procesa sadrži beskonačnu while(1) petlju koja služi kao beskonačni iterator sa pauzom od 1s između svake iteracije. Pauza je realizovana sa event tajmerom i makro komandom PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); čije bi značenje bilo: "pauziraj proces dok se ne desi događaj koji potiče od tajmera". Svo vreme dok je proces pauziran procesorsko vreme se koristi za izvršavanje nekog drugok procesa (ukoliko postoji - u ovom primeru ne).

U ovako koncipiranom PROCESS_THREAD-u mogu se zapaziti 3 dela:

  • od početka tela PROCESS_THREAD-a do PROCESS_BEGIN(); - kod se izvršava pri svakom pokretanju ili nastavljanju procesa.
  • PROCESS_BEGIN(); do početka while(1) petlje - kod će se izvršiti samo jednom, pri prvom pokretanju procesa. Ovaj deo je pogodan za iicijalizaciju promenljivih.
  • beskonačna petlja koja omogućava da beskonačan život procesa koji se povremeno pauzira i čime se procesorsko vreme oslobađa za druge procese

Ovaj primer daje sledeći ispis u login konzoli:

Rime started with address 192.117
MAC c0:75:00:00:00:00:00:00
CSMA CX-MAC, channel check rate 8 Hz, radio channel 26
Contiki 2.7 started. Node id 0
Led broj: 0 
Led broj: 1 
Led broj: 2 
Led broj: 0 
Led broj: 1 
Led broj: 2 
.
.

####2-blink#### U ovom primeru je prikazana aplikacija sa dva nezavisna procesa:

#include "contiki.h"
#include "dev/leds.h"

/*---------------------------------------------------------------------------*/
PROCESS(blink_Z, "zeleno");
PROCESS(blink_C, "crveno");
AUTOSTART_PROCESSES(&blink_Z, &blink_C);
/*---------------------------------------------------------------------------*/

PROCESS_THREAD(blink_C, ev, data) {
    static struct etimer et1;
	
	PROCESS_BEGIN();
	
	while(1) {
		leds_toggle(LEDS_RED);	
		etimer_set(&et1, CLOCK_SECOND>>4);
		PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);    
  	}

  	PROCESS_END();
}

PROCESS_THREAD(blink_Z, ev, data) {
	static struct etimer et2;

	PROCESS_BEGIN();
	
	while(1) {
		leds_toggle(LEDS_GREEN);	
		etimer_set(&et2, CLOCK_SECOND>>2);
		PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);    
  	}

  	PROCESS_END();
}

###Contiki procesi i protothread-i#### Svaki proces je interno opisan sledećom strukturom:

 struct process {
   struct process *next;
   const char *name;
   int (* thread)(struct pt *,
                  process_event_t,
     	 process_data_t);
   struct pt pt;
   unsigned char state, needspoll;
 };

Iz gore navedenog isečka se vidi da struktura poseduje polja:

  • pokazivač na sledeći proces u nizu
  • tekstualno ime procesa
  • pokazivač na funkciju PROCESS_THREAD-a procesa
  • protothredar struktura koja nosi status procesa
  • stanje procesa i zahtev za polling

Ova struktura se ne koristi direktno već se koristi kroz makroe kao u prethodno navedenim primerima.

Protothreads su interno realizovani korišćenjem C makroa:

 struct pt { lc_t lc };
 #define PT_WAITING 0
 #define PT_EXITED  1
 #define PT_ENDED   2
 #define PT_INIT(pt)          LC_INIT(pt->lc)
 #define PT_BEGIN(pt)         LC_RESUME(pt->lc)
 #define PT_END(pt)           LC_END(pt->lc);    \
                              return PT_ENDED
 #define PT_WAIT_UNTIL(pt, c) LC_SET(pt->lc);    \
                              if(!(c))           \
                              return PT_WAITING
 #define PT_EXIT(pt)          return PT_EXITED
 typedef unsigned short lc_t;
 #define LC_INIT(c)   c = 0
 #define LC_RESUME(c) switch(c) { case 0:
 #define LC_SET(c)    c = __LINE__; case __LINE__:
 #define LC_END(c)    }

Kao što se vidi iz priloženih isečaka koda, switch se koristi kao mehanizam za proveru stanja. stoga se u korisničkom programu ne preporučuje korišćenje switch-a

####TCP/IP stek i RPL####

####Debugging####

###Senzorska mreža - Temeperatura i osvetljenje###

###Zaključak###

⚠️ **GitHub.com Fallback** ⚠️