Übung zu
Drahtlose Kommunikation
10. Übung
14.01.2012
Tmote Sky & Tiny OS
• 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
Tmote Sky & Tiny OS
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
–
Tmote Sky & Tiny OS
nesC in a seashell
• 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
Tmote Sky & Tiny OS
Überprüfen der Systemumgebung:
$ 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:~$
Tiny OS - einfaches Programm
C-Beispiel:
test.c
int main () { return 0;
}
gcc –o test test.c
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)
Ein einfaches Programm:
make telosb
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
Tmote Sky & Tiny OS
$ 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
Tmote Sky & Tiny OS
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;
}
Tmote Sky & Tiny OS
File: BlinkToRadio.h
#ifndef BLINKTORADIO_H
#define BLINKTORADIO_H
enum {
TIMER_PERIOD_MILLI = 250 };
#endif
File: Makefile
COMPONENT=BlinkToRadioAppC include $(MAKERULES)
Tmote Sky & Tiny OS
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
Tmote Sky & Tiny OS
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;
}
Tmote Sky & Tiny OS
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);
}
Tmote Sky & Tiny OS
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) { } }
Tmote Sky & Tiny OS
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; } }
}
Tmote Sky & Tiny OS
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; } }
}
Tmote Sky & Tiny OS
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
};
...
Tmote Sky & Tiny OS
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;
...
}
Tmote Sky & Tiny OS
Receiving a Message over the Radio
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.
Tmote Sky & Tiny OS
Receiving a Message over the Radio
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)) {
BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)payload;
call Leds.set(btrpkt->counter);
}
return msg;
}
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);
...
Tmote Sky & Tiny OS
Receiving a Message over the Radio
7. Wire the the interfaces used by the application to the components which provide those interfaces.
File: BlinkToRadioAppC.
implementation { ...
App.Receive -> AMReceiverC;
}
Tmote Sky & Tiny OS
Receiving a Message over the Radio 8. Test your application!
$ motelist
$ make telosb install bsl,/dev/ttyUSB0
$ make telosb reinstall bsl,/dev/tty/USB1