TinyOS: Sending and Receiving Messages ECE 455/555 Embedded System Design

advertisement
ECE 455/555
Embedded System Design
TinyOS: Sending and Receiving
Messages
Wei Gao
Fall 2015
1
Active Message Model
 Each network packet contains a handler ID
 Multiple access on the radio
 Think TCP/UDP port number!
 Your handler ID specifies which process is going to trigger
and do something with the message.
 Message format
Header
Data
Footer
Metadata
 Data type: message_t, specified in
/opt/tinyos-2.x/tos/types/message.h
ECE 455/555 Embedded System Design
2
Details of Message Format
 \opt\tinyos-2.x\tos\chips\cc2420\CC2420.h
typedef nx_struct cc2420_header_t {
nxle_uint8_t length;
nxle_uint16_t fcf;
nxle_uint8_t dsn;
nxle_uint16_t destpan;
nxle_uint16_t dest;
nxle_uint16_t src;
nxle_uint8_t network;
nxle_uint8_t type;
} cc2420_header_t;
Reserved address:
1. 0x007E – UART for serial port comm
2. 0xFFFF – broadcast address
typedef nx_struct cc2420_footer_t {
} cc2420_footer_t;
typedef nx_struct cc2420_metadata_t {
nx_uint8_t tx_power;
nx_uint8_t rssi;
nx_uint8_t lqi;
nx_bool crc;
nx_bool ack;
nx_uint16_t time;
nx_uint16_t rxInterval;
nx_uint16_t maxRetries;
nx_uint16_t retryDelay;
} cc2420_metadata_t;
ECE 455/555 Embedded System Design
3
Message Accessing Interfaces
 /opt/tinyos-2.x/tos/system
 AMPacket
 Accessors to the fields specified in message_t
 AMSend
 Send out an AM packet to the radio (taking message_t as
input)
 Receive
 Receive an AM packet from the radio (taking message_t as
input)
ECE 455/555 Embedded System Design
4
Example: RadioCountToLeds
 /opt/tinyos-2.x/apps/RadioCountToLeds
 Sending packets periodically based on a 4Hz counter
 Two motes: duplex communication
ECE 455/555 Embedded System Design
5
1. Declare message format
 In RadioCountToLeds.h
 Will be put in the data field of message_t!
typedef nx_struct radio_count_msg {
nx_uint16_t counter;
} radio_count_msg_t;
enum {
AM_RADIO_COUNT_MSG = 6,
};
AM packet type: handler ID/port
ECE 455/555 Embedded System Design
6
2. Configuration
 In RadioCountToLedsAppC.nc
configuration RadioCountToLedsAppC {}
implementation {
components MainC, RadioCountToLedsC as App, LedsC;
components new AMSenderC(AM_RADIO_COUNT_MSG);
components new AMReceiverC(AM_RADIO_COUNT_MSG);
components new TimerMilliC();
components ActiveMessageC;
Specify the ID used.
AMReceiver monitors the
radio
App.Boot -> MainC.Boot;
}
App.Receive -> AMReceiverC;
App.AMSend -> AMSenderC;
App.AMControl -> ActiveMessageC;
App.Leds -> LedsC;
App.MilliTimer -> TimerMilliC;
App.Packet -> AMSenderC;
ECE 455/555 Embedded System Design
Send/Receive interfaces
When to send msg
Message accessor.
Must be wired to AMSender
to access the msg
7
3. Implementation
 In RadioCountToLedsC.nc
module RadioCountToLedsC {
uses {
interface Leds;
interface Boot;
interface Receive;
interface AMSend;
interface Timer<TMilli> as MilliTimer;
interface SplitControl as AMControl;
interface Packet;
}}
implementation {
message_t packet;
bool locked;
uint16_t counter = 0;
• Reset the timer every 250ms
• Why use control: keep trying until the
radio starts successfully
event void Boot.booted() {
call AMControl.start();
}
event void AMControl.startDone(error_t err) {
if (err == SUCCESS) {
call MilliTimer.startPeriodic(250);
}
else {
call AMControl.start();
}
}
event void AMControl.stopDone(error_t err) {
// do nothing
}
ECE 455/555 Embedded System Design
8
Sending messages
event void MilliTimer.fired() {
counter++;
Radio is busy
if (locked) {
Message accessor get
return;
payload from message_t
}
else {
radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet,
NULL);
if (call Packet.maxPayloadLength() < sizeof(radio_count_msg_t)) {
return;
}
Message is broadcasted every 250ms
rcm->counter = counter;
if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t))
== SUCCESS) {
dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n", counter);
locked = TRUE;
}
}
}
ECE 455/555 Embedded System Design
9
Sending messages
event void AMSend.sendDone(message_t* bufPtr, error_t error) {
if (&packet == bufPtr) {
locked = FALSE;
}
}
Release radio when finished
ECE 455/555 Embedded System Design
10
Receiving messages
event message_t* Receive.receive(message_t* bufPtr,
void* payload, uint8_t len) {
dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
if (len != sizeof(radio_count_msg_t)) {return bufPtr;}
else {
radio_count_msg_t* rcm = (radio_count_msg_t*)payload;
if (rcm->counter & 0x1) {
call Leds.led0On();
}
Triggered when packet is
else { call Leds.led0Off(); }
received by the radio
if (rcm->counter & 0x2) {
call Leds.led1On();
}
else { call Leds.led1Off(); }
if (rcm->counter & 0x4) {
call Leds.led2On();
}
else { call Leds.led2Off(); }
return bufPtr;
}
}
ECE 455/555 Embedded System Design
11
Lab 2 Announcement
 Lab 2 is due 10/7 (5:30pm Wednesday)
 Sensor reading and message sending/receiving
 Need to program two motes
• Everyone should check out two more motes from the TA
 Mote1 periodically reads light sensor, displays the readings
on the LEDs, and sends it to the radio
 Mote2 receives the reading and displays it on the LEDs
ECE 455/555 Embedded System Design
12
Download