Übung zu Drahtlose Kommunikation 10. Übung 14.01.2012
TinyOS is an operating system designed to target limited-resource sensor network nodes TinyOS 0.4, 0.6 (2000-2001) TinyOS 1.0 (2002): first nesc version TinyOS 1.1 (2003): reliability improvements, many new services TinyOS 2.0 (2006): complete rewrite, improved design, portability, reliability and documentation TinyOS and its application are implemented in nesc, a C dialect: nesc 1.0 (2002): Component-based programming nesc 1.1 (2003): Concurrency support nesc 1.2 (2005): Generic components, external types 2
TinyOS in a nutshell System runs a single application OS services can be tailored to the application s needs These OS services include timers, radio, serial port, A/D conversion, sensing, storage, multihop collection and dissemination, Application and services are built as a set of interacting components (as opposed to threads) using a strictly non-blocking execution model event-driven execution, most service requests are split-phase Implementation based on a set of OS abstractions tasks, atomic with respect to each other; interrupt handlers resource sharing and virtualisation, power management hardware abstraction architecture 3
nesc in a seashell Tmote Sky & Tiny OS C dialect Component based all interaction via interfaces connections ( wiring ) specified at compile-time generic components, interfaces for code reuse, simpler programming External types to simplify interoperable networking Reduced expressivity no dynamic allocation no function pointers Supports TinyOS s concurrency model must declare code that can run in interrupts atomic statements to deal with data accessed by interrupts data race detection to detect (some) concurrency bugs 4
Überprüfen der Systemumgebung: Tmote Sky & Tiny OS $ tos-check-env $ printenv MAKERULES /opt/tinyos-2.x/support/make/makerules $ motelist wcu@wcu-desktop:~$ motelist Reference Device Description ---------- ---------------- --------------------------------------------- M4AMMD4W /dev/ttyusb0 Moteiv tmote sky wcu@wcu-desktop:~$ 5
Tiny OS - einfaches Programm Ein einfaches Programm: C-Beispiel: test.c int main () { gcc o test test.c return 0; 1) Configuration file SimpleAppC.nc configuration SimpleAppC{ implementation{ components SimpleC, MainC; SimpleC.Boot -> MainC.Boot; 2) Component file SimpleC.nc module SimpleC{ uses interface Boot; implementation{ event void Boot.booted() { //The entry point of the program 3) Makefile COMPONENT=SimpleAppC include $(MAKERULES) make telosb 6
Tiny OS einfaches Programm $ motelist wcu@wcu-desktop:~$ motelist Reference Device Description ---------- ---------------- --------------------------------------------- M4AMMD4W /dev/ttyusb0 Moteiv tmote sky wcu@wcu-desktop:~$ $ make telosb reinstall bsl,/dev/ttyusb0 7
$ cd tinyos-2.x/apps $ mkdir BlinkToRadio File: BlinkToRadioC.nc #include <Timer.h> #include "BlinkToRadio.h" module BlinkToRadioC { uses interface Boot; uses interface Leds; uses interface Timer<TMilli> as Timer0; implementation { uint16_t counter = 0; event void Boot.booted() { call Timer0.startPeriodic(TIMER_PERIOD_MILLI); event void Timer0.fired() { counter++; call Leds.set(counter); http://docs.tinyos.net/tinywiki/index.php/mote-mote_radio_communication 8
File: BlinkToRadioAppC.nc #include <Timer.h> #include "BlinkToRadio.h" configuration BlinkToRadioAppC { implementation { components MainC; components LedsC; components BlinkToRadioC as App; components new TimerMilliC() as Timer0; App.Boot -> MainC; App.Leds -> LedsC; App.Timer0 -> Timer0; 9
File: BlinkToRadio.h #ifndef BLINKTORADIO_H #define BLINKTORADIO_H enum { #endif TIMER_PERIOD_MILLI = 250 ; File: Makefile COMPONENT=BlinkToRadioAppC include $(MAKERULES) 10
Defining a Message Structure File: BlinkToRadio.h #ifndef BLINKTORADIO_H #define BLINKTORADIO_H enum { TIMER_PERIOD_MILLI = 250 ; typedef nx_struct BlinkToRadioMsg { nx_uint16_t nodeid; nx_uint16_t counter; BlinkToRadioMsg; #endif 11
Sending a Message 1) Identify the interfaces (and components) that provide access to the radio and allow us to manipulate the message_t type. 2) Update the module block in the BlinkToRadioC.nc by adding uses statements for the interfaces we need: File: BlinkToRadioC.nc module BlinkToRadioC { uses interface Boot; uses interface Leds; uses interface Timer<TMilli> as Timer0; uses interface Packet; uses interface AMPacket; uses interface AMSend; uses interface SplitControl as AMControl; 12
Sending a Message 3) Declare any new variables and add any needed initialization code. File: BlinkToRadioC.nc implementation { bool busy = FALSE; message_t pkt; uint16_t counter = 0; event void Boot.booted() { call Timer0.startPeriodic(TIMER_PERIOD_MILLI); event void Timer0.fired() { counter++; call Leds.set(counter); 13
Sending a Message 3) Declare any new variables and add any needed initialization code. File: BlinkToRadioC.nc implementation { bool busy = FALSE; message_t pkt; uint16_t counter = 0; event void Timer0.fired() { counter++; call Leds.set(counter); event void Boot.booted() { call AMControl.start(); event void AMControl.startDone(error_t err) { if (err == SUCCESS) { call Timer0.startPeriodic(TIMER_PERIOD_MILLI); else { call AMControl.start(); event void AMControl.stopDone(error_t err) { 14
Sending a Message 4. Add any program logic and calls to the used interfaces we need for our application. File: BlinkToRadioC.nc implementation { event void Timer0.fired() { counter++; call Leds.set(counter); if (!busy) { BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)( call Packet.getPayload(&pkt, sizeof (BlinkToRadioMsg)) ); btrpkt->nodeid = TOS_NODE_ID; btrpkt->counter = counter; if (call AMSend.send(AM_BROADCAST_ADDR, &pkt, sizeof(blinktoradiomsg)) == SUCCESS) { busy = TRUE; 15
Sending a Message 5. Implement any (non-initialization) events specified in the interfaces we plan on using. File: BlinkToRadioC.nc implementation { /** * Signaled in response to an accepted send request. msg is * the message buffer sent, and error indicates whether * the send was successful. * * @param msg the packet which was submitted as a send request * @param error SUCCESS if it was sent successfully, FAIL if it was not, * ECANCEL if it was cancelled * @see send * @see cancel */ event void senddone(message_t* msg, error_t error); event void AMSend.sendDone(message_t* msg, error_t error) { if (&pkt == msg) { busy = FALSE; 16
Sending a Message 6. Update the implementation block of the application configuration file by adding a components statement for each component used that provides one of the interfaces chosen earlier. File: BlinkToRadioAppC.nc implementation {... components ActiveMessageC; components new AMSenderC(AM_BLINKTORADIO);... File: BlinkToRadio.h... enum {... AM_BLINKTORADIO = 6, TIMER_PERIOD_MILLI = 250 ; 17
Sending a Message 7. Wire the the interfaces used by the application to the components which provide those interfaces. File: BlinkToRadioAppC.nc implementation {... App.Packet -> AMSenderC; App.AMPacket -> AMSenderC; App.AMSend -> AMSenderC; App.AMControl -> ActiveMessageC;... 18
Receiving a Message over the Radio Tmote Sky & Tiny OS 1. Identify the interfaces (and components) that provide access to the radio and allow us to manipulate the message_t type. We will use the Receive interface to receive packets. 2. Update the module block in the BlinkToRadioC.nc by adding uses statements for the interfaces we need: File: BlinkToRadioC.nc module BlinkToRadioC {... uses interface Receive; 3. Declare any new variables and add any needed initialization code. We will not require any new variables to receive and process messages from the radio. 4. Add any program logic and calls to the used interfaces we need for our application. Message reception is an event-driven process so we do not need to call any commands on the Receive. 19
Receiving a Message over the Radio Tmote Sky & Tiny OS 5. Implemement any (non-initialization) events specified in the interfaces we plan on using. We need to implement the Receive.receive event handler: event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) { if (len == sizeof(blinktoradiomsg)) { return msg; BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)payload; call Leds.set(btrpkt->counter); 6. Update the implementation block of the application configuration file by adding a components statement for each component used that provides one of the interfaces chosen earlier. implementation {...... components new AMReceiverC(AM_BLINKTORADIO); 20
Receiving a Message over the Radio Tmote Sky & Tiny OS 7. Wire the the interfaces used by the application to the components which provide those interfaces. File: BlinkToRadioAppC. implementation {... App.Receive -> AMReceiverC; 21
Receiving a Message over the Radio 8. Test your application! Tmote Sky & Tiny OS $ motelist $ make telosb install bsl,/dev/ttyusb0 $ make telosb reinstall bsl,/dev/tty/usb1 22