You are on page 1of 15

Elektrotehnički fakultet

Univerziteta u Banjoj Luci

PROJEKTNI ZADATAK
IZ PREDMETA
BEŽIČNE SENZORSKE MREŽE
TEMA
RIOT-OS i OpenMOTE ploča

Student: Darko Simić


Br. Indeksa: 1249/17
Februar 2018. Godine
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Sadržaj

1. UVOD ...................................................................................................................................... 3
1.1. RIOT-OS .......................................................................................................................... 3
1.2. OpenMOTE ...................................................................................................................... 4
2. Generic (GNRC) network stack .............................................................................................. 5
2.1. Integracija u RIOT ........................................................................................................... 5
2.2. RIOT OS sa github-a ........................................................................................................ 5
2.3. Makefile ........................................................................................................................... 6
2.4. Sock API .......................................................................................................................... 7
3. Postupak povezivanja OpenBASE i OpenBattery ................................................................... 8
3.1. Aplikacijski sloj................................................................................................................ 8
3.2. GNRC mrežni slojevi ..................................................................................................... 12
3.3. CC2538 drajveri ............................................................................................................. 15

2
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

1. UVOD

1.1. RIOT-OS

RIOT je mali operativni system za umrežene, male memorije, a fokusiran na bežicne Internet Of
Things(IOT) uredjaje male potrošnje. To je open-source softver izdat pod licencom GNU Lesser
General Public License (LGPL).
RIOT-OS je baziran na microkernel arhitekturi. Podžava programiranje aplikacija pomoću
programskih jezika C i C++.
Napomena:
Mikrokernel je minimalna količina softvera koja može pružiti sledeće mehanizme potrebne za
operativni sistem. To su:
 Menadžment adresnog prostora na niskom nivou
 Menadžment tredova
 Komunikacija izmedju procesa (Inter-process communication (IPC) )

Sl.1: RIOT-OS logo

Sl.2: Poređenje sa drugim operativnim sistemima

3
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Za one koji su više upoznati sa non-embedded programiranjem moguće je početi sa Native


PORT-om za RIOT. To omućava pokretanje RIOT-OS unutar Linux ili Mac OS treda. I to
olaksava razvoj IOT Sistema. Na ovaj način se može dosta posla odraditi bez posjedovanja
konkretnog hardvera.
I link od RIOT – OS Sistema.
https://riot-os.org/#home

1.2. OpenMOTE

OpenMOTE je baziran na SoC (System on Chip) od Texas Instruments. SoC je CC2538. Koji
kombinuje procesor ARM Cortex-M3 i IEEE802.15.4 transiver.

Sl. 3: Neki podaci o OpenMOTE

4
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

2. Generic (GNRC) network stack

RIOT-ov modularni mrežni stek. Ovaj modul uključuje mnoge komponente kao što su Network
interface API sa potpuno implementovanim Ipv6 sa 6LowPAN extenzijom za implementaciju
UDP-a i RPL.

2.1. Integracija u RIOT

Sa aplikacijskog sloja GNRC mrežnom steku se može pristupiti pomoću Sock API, dok je
interfejs sa Network Device Driver API –om definisan pomoću Network Interface API.

Sl.4: Arhitektura GNRC steka

Svaki sloj mrežnog steka se izvršava u svom tredu, a svaki niži sloj ima veći prioritet od svakog
višeg sloja. Zbog tog tred za MAC sloj ima najveći prioritet, a tred za aplikacijski sloj ima najniži
prioritet. Komunikacija je regulisana pomoću Messaging/IPC i GNRC communication interface.
Najčešće će Messaging/IPC prezuzeti komunikaciju između susjednig slojeva za pakete koji
putuju gore ili dole za jedan sloj.

2.2. RIOT OS sa github-a

RIOT-OS se nalazi na github-u. Može se skinuti sa linka:


https://github.com/RIOT-OS/RIOT
Na ovom linku se nalazi RIOT-OS sa primjerima, drajverima, API intefejsima. I sa velikom
podrškom za razne procesore, mikrokontrolere kao i razvojne ploče. Uključujući podršku za
OpenMOTE ploču, ta podrška sadrži definisane tipove podataka koji se koriste za podešavanje,
definisane periferne uredjaje kao što su 4 LED diode, ali nema podršku za senzore koji se nalaze
na OpenBattery. Ima podršku za slične senzore.

5
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Kompajliranje koda, spuštanje na ploču, debagovanje i neke druge opcije su omogućene pomoću
makefile. O kome će biti malo više riječi u narednom dijelu teksta.

2.3. Makefile

Prije nego što nastavim dalje prvo ću malo napisati par stvari o makefile –u koji se koristi pri
razvoju sistema baziranim na RIOT sistemu.
Kad skinete RIOT-OS sa prethodnog linka i raspakujete ako ste skinuli kao .zip. U folderu u
kome ste sačuvali će vam se nalaziti RIOT-OS sa osnovnim funkcionalnostima plus sa svim
trenutno podržanim drajverima i modulima.
Da bi ste prvo kompajlirali vaš kod unutar terminala je potrebno samo ukucati make all
komandu. Za spuštanje koda na ploču se koristi make flash.
Prije svega treba se prvo podesiti makefile.
Unutar vašeg foldera koji ste skinuli RIOT-OS sa github-a. Nalazi se folder /example/ u kome se
nalaze već neki gotovi primjeri ili će biti primjer koji ste pisali. Unutar foldera za primjer ili koji
ste pisali treba da se nalazi makefile.
Na početku tog fajla se odredi naziv vašeg primjera tj aplikacije. Pomoću naredbe
APPLICATION = “naziv”
Nakon tog se podesi koja se ploča koristi pomoću:
BOARD ?= native Ako se RIOT koristi unutar Linux terminala za testiranje ili
podešavanje. Za naš primjer koristi se.
BOARD ?= openmote-cc2538
I sa tim je podešeno koja se ploča koristi. Sad je potrebno podesiti neke stvari oko portova.
Unutar foldera /boards/openmote-cc2538/ se nalazi još makefile fajlova koju služe za neka
podešavanja vezana za OpenMOTE ploču.
Makefile.include fajl koji se nalazi u tome folderu treba otovriti i provjeriti da li je podešen port
na koji se priključuje ploča. PORT_LINUX ?= /dev/ttyUSB0 je podešeno podrazumijevano.
Pomoću naredbe USEMODULE += “ime modula” se uključuju potrebni moduli koji su
implementovani unutar RIOT-OS Sistema.
Prilikom definisanja sa naredbom BOARD ?= openmote-cc2538 podrazumijevano uvrštavate
module
USEMODULE += netif
USEMODULE += cc2538_rf
USEMODULE += netdev_ieee802154

6
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

2.4. Sock API

Sl.5: Sock API


Ovaj modul sadrži različit set funkcija koje omugćavaju slanje i primanje podataka koristeći
različite protokole. Kombinovano, služe kao API koji omogućava aplikacijama i bibliotekama
konektovanje sa mrežom.
Dizajniran je sa sledećim prioritetima:
- Nema potrebe za dinamičkom alokacijom memorije
- Jednostavan za korištenje
- Efikasan
- Portabilan
Trenutno su definisani sock tipovi:
 sock_ip_t (net/sock/ip.h): IP sock tip za osnovni za čisti IP protokol
 sock_tcp_t (net/sock/tcp.h): TCP sock tip za TCP protokol
 sock_udp_t (net/sock/udp.h): UDP sock tip za UDP protokol
NAPOMENA:
Važno je reći da je moguće da nema nikakve povezanosti između različitih sock tipova. Pa
kastovanje npr. sock_ip_t na sock_udp_t moguće da ne bude baš tako jednostavno.
Korištenje Sock API se vrši tako što se prvo uključe potrebni moduli. Ako se koristi GNRC
mrežni stek uključi se udp mudul pomoću, za korištenje udp protokola
USEMODULE += gnrc_sock_udp.
Ovo omogućava da kod u aplikacijskom sloju bude nesvjestan dijela na mrežnom sloju. Tako da
mijenjanje mreznog sloja se može obaviti samo korištenjem USEMODULE sa drugim mrežnim
stekom. Jer se stalno koristi isti kod za povezivanje aplikacijskog i mrežnog nivoa.
Ovde ću pisati o UDP protokolu koji sam ja koristio prilikom povezivanja OpenBASE i
OpenBattery ploča.

7
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

3. Postupak povezivanja OpenBASE i OpenBattery

OpenBASE i OpenBattery su povezani bežično pomoću IEEE802.15.4 standarda. Koje su


funkcionalsnosti definisane unutar RIOT Sistema. Podrazumijevano je podešeno da se koristi 26
kanal na kome sam ja testirao svoj kod.
Važno je napomenuti da se unutar RIOT-OS koda nalazi i zaglavlje debug.h koje je već
podešeno da na standardni izlaz ispisuje određene poruke o funkcionalnosti tj prijavljivanju neki
grešaka npr. unutar UDP sloja ako je paket ne odgovarajući. Potrebno je samo na vrhu
odgovarajućeg .c fajla koji se koristi nađe dio koda
#define ENABLE_DEBUG (0)
#include "debug.h"

Umjesto 0 da se upiše 1. I jedna od mogućih poruka je sledeća


DEBUG("udp: received packet with zero checksum, dropping it\n");

3.1. Aplikacijski sloj

Prvo sam unutar main() programa napravio tred koji cu koristiti za moju aplikaciju. To se radi
pomoću funkcije thread_create.
Tabela.1: Dio koda za kreiranje aplikacijskog treda
//Create thread
thread_app_pid = thread_create(thread_stack, sizeof(thread_stack),
THREAD_PRIORITY_MAIN + 1,
THREAD_CREATE_STACKTEST | THREAD_CREATE_WOUT_YIELD,
thread_app_handler,
NULL, "thread_app");

//Add thread in Thread table


sched_threads[thread_app_pid + 1] = thread_get(thread_app_pid);

Da bi ovaj gore kod radio potrebno je izvan main-a dodati ekternu variablu sched_threads.
extern volatile thread_t *sched_threads[KERNEL_PID_LAST + 1];
Drugi dio koda služi za ubacivanje treda unutar niza koji koristi scheduler. Potrebno je napisati
handler za aplikacijski tred.

8
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Tabela.2: Tred handler


void *thread_app_handler(void *arg){

//Neke pripreme treda


while(1){

//Izvršavnaje treda
}
return NULL;
}

Za manipulaciju sa tredovima koristi se Thread API. Unutar koga se nalaze razne funkcije za
manipulaciju sa tredovima. Neke se nalaze u primjerima do sad.
Jedna od tih funkcija je xtimer_sleep(seconds) kojoj se za argument proslijedi broj sekunda koje
će tred biti na čekanju. Još jedna funkcija koju sam koristio je thread_yield(void) koja prepušta
rad drugom tredu.
Za rad sa tredovim potrebno je ukljuciti biblioteku.
#include "thread.h"
Napravio sam dvije aplikacije. Na OpenBASE se nalazi aplikacija za UDP server, dok se na
OpenBattery nalazi aplikacija za UDP klijena. Napisane su jednostavne aplikacije. U sledeće
dvije tabele će biti prikazani kodovi koji se nalaze unutar tred hendlera za odredjenu aplikaciju.

9
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Tabela.4: Kod za UDP Server koji se nalazi unutar handlera za tred aplikacije na OpenBASE

void *thread_app_handler(void *arg)


{
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
sock_udp_t sock;
ssize_t res;

msg_init_queue(msg_queue, MSG_QUEUE_SIZE);
local.port = 12345;

if (sock_udp_create(&sock, &local, NULL, 0) < 0) {


printf("Error creating UDP sock");
thread_yield();
}

(void)arg;

while(1){

if ((res = sock_udp_recv(&sock, buf, sizeof(buf), 1 * US_PER_SEC, NULL)) < 0) {


if (res == -ETIMEDOUT) {
printf("Timed out");
}
else {
printf("Error receiving message");
}
}
else {
printf("Received message: \n");
printf("----------------------------------\n");
for (int i = 0; i < res; i++) {
printf("%c", buf[i]);
}
printf("\n----------------------------------\n");
}

xtimer_sleep(1);

}
return NULL;
}

10
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Tabela.5: Kod za UDP Klijent koji se nalazi unutar handlera za tred aplikacije na OpenBattery
void *thread_app_handler(void *arg)
{

sock_udp_ep_t remote = { .family = AF_INET6 };


char* data = "Welcome to the RIOT OS!!!";

remote.port = 12345;
ipv6_addr_set_all_nodes_multicast((ipv6_addr_t *)&remote.addr.ipv6,
IPV6_ADDR_MCAST_SCP_LINK_LOCAL);

(void)arg;

printf("UDP client...\n");
while(1){

printf("Beginig.\n");
if (sock_udp_send(NULL, data, strlen(data), &remote) < 0) {
printf("Error sending message");
thread_yield();
}

xtimer_sleep(1);

return NULL;
}

Jedna od grešaka koja se meni javljala je zbog moje nepažnje je ta da kad sam sve napravio
nisam pazio kad sam napravio UDP klijenta prilikom podešavanja porta pomoću remote.port =
12345 kako je podešeno kad sam kreirao UDP server. Nakon ispravljanja tog dijela uspješno je
izvršeno slanje i prijem podatka. Sa tim se može pokazati i ispravnost podešavanja porta za UDP
protokol pomoću funkcija i tipova podataka koji su korišteni.
Poruku koju sam podesio da se šalje svaku sekundu je „Welcome to the RIOT OS!!!“.

11
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

3.2. GNRC mrežni slojevi

Kratko ću opisati mrežne slojeve. Jer njih nije trebalo puno mijenjati. Na početku ću navesti
odmah jednu „gresku“ koju sam našao. Tačnije, tu se ne radi o grešci nego od tome u verziji
koda koju sam ja skinuo nije još bilo u potpunosti podešeno sve.
Grešku koju sam ja našao je bila unutar gnrc_sixlowpan.c fajla. Kad se uključe 6LoWPAN
fragmentiranje izbacivalo je grešku pri kompajliranju. To sam ispravio tako što sam unutar
pomenutog fajla uradio kao što sledeća table pokazuje.
Tabela.3: Prikaz promjene koju sam primijenio
Prije promjene
...
else if (datagram_size <= SIXLOWPAN_FRAG_MAX_LEN) {
DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
(unsigned int)datagram_size, iface->max_frag_size);
msg_t msg;
...
Nakon promjene
...
else if (datagram_size <= SIXLOWPAN_FRAG_MAX_LEN) {
DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
(unsigned int)datagram_size, ((gnrc_netif_6lo_t*)iface)->max_frag_size);
msg_t msg;
...

Unutar tabele se nalazi samo dio koda koji je promijenje, a ostatak koda nisam mijenjao.
Kao što se vidi iz primjera bilo je potrebno samo iface kastovati pomoću gnrc_netif_6lo_t* jer
tip kojeg je iface ne sadrži u sebi max_frag_size. Koji se nalazi unutar sturkture gnrc_netif_6lo_t.
Tabela. 6: Uključeni moduli u projekat

# Include packages that pull up and auto-init the link layer.


# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
#USEMODULE += gnrc_netdev_default
USEMODULE += netdev_ieee802154
USEMODULE += auto_init_gnrc_netif
# Specify the mandatory networking modules for IPv6 and UDP
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_udp
# This application dumps received packets to STDIO using the pktdump module
USEMODULE += gnrc_pktdump

12
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

# Additional networking modules that can be dropped if not needed


USEMODULE += gnrc_icmpv6_echo

# Modules to include:
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
USEMODULE += gnrc_sock_udp
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc

Unutar tabele se nalaze moduli koje sam ja uključio. Neki od modula su već uključeni prilikom
odabiranja ploce pomoću BOARD ?= openmote-cc2538 kao npr. netdev_ieee802154. Ovde sam
ih ubacio samo da imam na jednom mjestu pregled svih modula koje sam uključio.
Module shell se koristi sa terminalom koji vam pruža jednostavni shell u kome možete unositi
komande koje su podržane ili napisati neku specifičnu komandu. To se radi izvan main-a tako
što uključite biblioteke
#include "shell.h"
#include "shell_commands.h"

A nakon tog dio koda koji ubacuje određenu komandu. Ja sam ubacio udp_cmd koja se nalazi
unutar udp.c fajla. I služi da se može u terminalo koristiti funkcije send, start_server,
stop_server. Kod se nalazi u sledećoj tabeli.

Tabela.7: Dio koda za zbacivanje dodatne komande u shell

...
extern int udp_cmd(int argc, char **argv);
...
const shell_command_t shell_commands[] = {
{"udp", "send data over UDP and listen on UDP ports", udp_cmd },
{"set", "Setting channel",thread_for_setting_channel},
{"get", "Getting channel",thread_for_getting_channel},
{"sockudp", "Sock udp",thread_for_sock_udp},
{NULL,NULL,NULL}
};
...
Int main(void){
...

Ovo je samo jedna od mogućnosti koju nisam koristio za realizaciju komunikacije izmedju
OpenBASE i OpenBattery.

13
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

Važno je napomenuti da je GNRC veoma modularan i moguće je koristiti samo neke od


podmodula. To se sve radio kao što sam pokazao pomoću USEMODULE naredbe. Time se može
dosta smanjiti memorija samog projekta.

Ostali mrežni slijevi nisu dirani. Nego sam ih koristio kao što su napisani od strane RIOT tima.

Jedina stvar koja se vidi na slici 4 iz arhitekture GNRC steka je gnrc_conn koji nisam koristio,
nit sam našao bilo šta vezano za to na internetu. Moja pretpostavka da je to bilo nešto ranije pa
da su izbacili podršku za to.
Jer u mom pruimjeru aplikacijski sloj se direktno povezuje preko Sock API na sloj gnrc_udp.
Koji ima definisan svoj tred unutar gnrc_udp.c. I on automatski na osnovu primljenog podatka
koji mu pripremi Sock API odlučuje o njemgovom daljem slanju. Isto tako i kad podatak stigne
od nižeg sloja gnrc_udp će tp direktno poslati na aplikacijski sloj pomoću Sock API.

14
Bežične Senzorske Mreže RIOT-OS i OpenMOTE

3.3. CC2538 drajveri

Drajver za CC2538 se nalazi unutar biblioteka


#include “cc2538_rf.h“
#include “cc2538_rf_internal.h“
#include “cc2538_rf_netdev.h“

Te biblioteke se nalaze unutar foldera /cpu/cc2538/include/ *.h fajlovi. Unutar foldera


/cpu/cc2538/radio/ *.c fajlovi.
cc2538_rf.c je drijver niskog nivoa. Tamo se nalazi funkvije cc2538_init(void) koja inicijalizuje
radio dio mikroprocesora CC2538.
Tabela 9: Dio koda za podešavanje LED dioda na ploči
#ifdef BOARD_OPENMOTE_CC2538
CCTEST_OBSSEL0 = 0; /* PC0 = USB_SEL */
CCTEST_OBSSEL1 = 0; /* PC1 = N/C */
CCTEST_OBSSEL2 = 0; /* PC2 = N/C */
CCTEST_OBSSEL3 = 0; /* PC3 = USER_BUTTON */
CCTEST_OBSSEL4 = OBSSEL_EN | rfc_obs_sig0; /* PC4 = RED_LED */
CCTEST_OBSSEL5 = 0; /* PC5 = ORANGE_LED */
CCTEST_OBSSEL6 = OBSSEL_EN | rfc_obs_sig1; /* PC6 = YELLOW_LED */
CCTEST_OBSSEL7 = OBSSEL_EN | rfc_obs_sig2; /* PC7 = GREEN_LED */
#else
/* Assume BOARD_CC2538DK (or similar). */
CCTEST_OBSSEL0 = OBSSEL_EN | rfc_obs_sig0; /* PC0 = LED_1 (red) */
CCTEST_OBSSEL1 = OBSSEL_EN | rfc_obs_sig1; /* PC1 = LED_2 (yellow) */
CCTEST_OBSSEL2 = OBSSEL_EN | rfc_obs_sig2; /* PC2 = LED_3 (green) */
CCTEST_OBSSEL3 = 0; /* PC3 = LED_4 (red) */
CCTEST_OBSSEL4 = 0; /* PC4 = BTN_L */
CCTEST_OBSSEL5 = 0; /* PC5 = BTN_R */
CCTEST_OBSSEL6 = 0; /* PC6 = BTN_UP */
CCTEST_OBSSEL7 = 0; /* PC7 = BTN_DN */
#endif /* BOARD_OPENMOTE_CC2538 */

U prethodnoj tabeli se vidi dio koda koji pokazuje kako su podešene LED diode ako je izabrana
ploca OPENMOTE_CC2538.
Unutar gnrc_netif.c je definisan najniži tred koji komunicira sa ovim drajverima. Taj tred ima
naziv „cc2538_rf“. Kada podatak stigne drajver će taj podatak primiti sa vanjske mreže pa onda
proslijediti paket gnrc_netif mrežnom sloju najvišeg prioriteta, ili će dobiti od gnrc_netif
mrežnog sloja pa onda poslati na vanjsku mrežu.

15

You might also like