David Culler, Jason Hill, Robert Szewczyk, and Alec Woo U.C. Berkeley 2/9/2001 TinyOS Programming Boot Camp (V) Communication
TOS Boot Camp2 Outline Media Access Control Ad Hoc Routing Mechanism Hands on Exercise
TOS Boot Camp3 Mote Characteristics Hardware: single channel RF radio Nodes contend for the same wireless channel Traffic is likely –Periodic : nature of sensor networks applications –Correlated : detection of common events Collision detection mechanism is not available Carrier Sense Multiple Access (CSMA)
TOS Boot Camp4 CSMA in TOS Framework Channel capacity ~25 packet/s –High amount of traffic due to »High node density »High transmission rate of each node Application layer lacks information about the channel Place CSMA at RADIO_BYTE level in between application layer and RFM radio component
TOS Boot Camp5 CSMA Design Basic mechanism –Listen on the channel before transmit »Only transmit if channel is idle –If the channel is busy, “wait” until channel becomes idle again Correlated periodic traffic may lead to repeated collisions Introduce random delay in MAC layer If channel becomes busy, MAC backpressures to application to drop further transmissions
TOS Boot Camp6 CSMA in TOS Network Stack Application AM PACKET RADIO BYTE RFM Backpressure Channel is busy AM_SEND_MSG fails VAR(state) != 0
TOS Boot Camp7 One CSMA Example In each RADIO_BYTE components Random listening period Transmission Request Listen for Random Period Transmit Busy Idle
TOS Boot Camp8 FOUR_B_RADIO_BYTE.c (RADIO_BYTE_INIT) 16 bit Linear Feedback Shift Register (LFSR) as Pseudo Random Number Generator Initialization char TOS_COMMAND(RADIO_BYTE_INIT)(){ TOS_CALL_COMMAND(RADIO_SUB_INIT)(); VAR(wait_amount) = 12; VAR(shift_reg) = 119 * LOCAL_ADDR_BYTE_2; return 1; } Minimum number of bits to listen (Encoding Dependent) Seed for LFSR
TOS Boot Camp9 FOUR_B_RADIO_BYTE.c (RADIO_BYTE_TX_BYTES) char TOS_COMMAND(RADIO_BYTE_TX_BYTES)(char data){ … if(VAR(state) == 0){ //if currently in idle mode, then switch over to transmit mode //and set state to waiting to transmit first byte. VAR(third) = data; VAR(state) = 10; return 1; } … Goes to CSMA
TOS Boot Camp10 FOUR_B_RADIO_BYTE.c (RADIO_BYTE_RX_BIT_EVENT) else if(VAR(state) == 10){ if(data){ VAR(waiting) = 0; }else{ if (++VAR(waiting) == 11){ bit = (VAR(shift_reg) & 0x2) >> 1; bit ^= ((VAR(shift_reg) & 0x4000) >> 14); bit ^= ((VAR(shift_reg) & 0x8000) >> 15); VAR(shift_reg) >>=1; if (bit & 0x1) VAR(shift_reg) |= 0x8000; VAR(wait_amount) = (VAR(shift_reg) & 0x3f)+12; } if(VAR(waiting) > VAR(wait_amount)){ … Prepare for transmission } 16 bit LFSR Channel is busy. Starts again Listening period [12,75]
TOS Boot Camp11 CSMA Evaluation Channel Utilization ~70% Throughput per node is fair
TOS Boot Camp12 Outline Media Access Control Ad Hoc Routing Mechanism Hands on Exercise
TOS Boot Camp13 Ad Hoc Routing Goal Nodes should self organize into a multi-hop network topology Each node can discover a route to deliver packets to the base station –uni-directional towards the base station Simple, robust, local algorithm Works in an ad hoc, spontaneously changing network Assume bi-directional connectivity in general
TOS Boot Camp14 A Simple Ad Hoc Routing Example (I) AM_ROUTE.c A route is simply knowing a neighboring node (or parent) that can send to the base station Base station broadcasts itself as a route Node gets the route and retransmits the broadcast with itself as the route
TOS Boot Camp15 A Simple Ad Hoc Routing Example (II) Base station refreshes route with periodic broadcast Nodes expire the old route and wait for base station next route refreshment Nodes only broadcast once for each route update it gets –Prevent rebroadcast of children’s broadcasts –has an effect in lowering the number of messages in broadcasting to the entire network –Broadcast becomes unidirectional (from BS outward)
TOS Boot Camp16 Packet Forwarding Node receives a packet destined to it will – forward it to the next hop Base station receives a packet destined to it will –forwards it to the UART
TOS Boot Camp17 Packet Format Defined in system/include/MSG.h #define DATA_LENGTH 30 struct MSG_VALS{ char addr char type char group; char data[DATA_LENGTH]; }; Special Address (addr) –Broadcast 0xff (TOS_BCAST_ADDR) –Send to UART 0x7e (TOS_UART_ADDR) Application Data Unit
TOS Boot Camp18 Routing Data Unit data[0] = number of hops from the base station Each node appends its address to data[] indexed by number of hops (data[(int)data[0]]) 112 BS’s data unit BS (12) Node 33 Node Node 33’s data unit Node 56’s data unit
TOS Boot Camp19 Ad Hoc Routing Code in AM_ROUTE.c
TOS Boot Camp20 AM_ROUTE.c (AM_ROUTE_INIT) (Base Station) char TOS_COMMAND(AM_ROUTE_INIT)(){ … //set beacon rate for route updates to be sent TOS_COMMAND(CONNECT_SUB_CLOCK_INIT)(255, 0x06); //route to base station is over UART. VAR(route) = TOS_UART_ADDR; VAR(set) = 1; VAR(place) = 0; VAR(data_buf).data[0] = 1; VAR(data_buf).data[1] = TOS_LOCAL_ADDRESS; … } Tick every 2 seconds Set route to UART BS is 1 hop away Append my ID
TOS Boot Camp21 AM_ROUTE.c (AM_ROUTE_INIT) (NOT Base Station) char TOS_COMMAND(AM_ROUTE_INIT)(){ … //set rate of sampling TOS_COMMAND(CONNECT_SUB_CLOCK_INIT)(255, 0x03); VAR(set) = 0; VAR(route) = 0; VAR(count) = 0; return 1; } Tick every 0.25 seconds Route is not set initially
TOS Boot Camp22 AM_ROUTE.c (AM_ROUTE_SUB_CLOCK) void TOS_EVENT(AM_ROUTE_SUB_CLOCK)(){ #ifdef BASE_STATION … TOS_CALL_COMMAND(ROUTE_SUB_SEND_MSG)(TOS_BCAST _ADDR,AM_MSG(ROUTE_UPDATE),&VAR(buf)); … #else … if(VAR(set) > 0) VAR(set) --; … #endif } Base station’s periodic broadcast Nodes count down to expire its route
TOS Boot Camp23 AM_ROUTE.c (ROUTE_UPDATE) TOS_MsgPtr TOS_MSG_EVENT(ROUTE_UPDATE)(TOS_MsgPtr msg){ … //if route hasn't already been set this period... if(VAR(set) == 0){ //record route VAR(route) = data[(int)data[0]]; VAR(set) = 8; //create an update packet to be sent out. data[0]++; data[(int)data[0]] = TOS_LOCAL_ADDRESS; … TOS_CALL_COMMAND(ROUTE_SUB_SEND_MSG) (TOS_BCAST_ADDR,AM_MSG(ROUTE_UPDATE),msg); … } Set route to parent’s ID Set to expire the route after 8 ticks I am 1 more hop away from the BS Append my ID to the buffer Broadcast the message
TOS Boot Camp24 AM_ROUTE.c (ROUTE_UPDATE cont.) TOS_MsgPtr TOS_MSG_EVENT(ROUTE_UPDATE)(TOS_MsgPtr msg){ … If (VAR(set) == 0){ … }else{ return msg; } … Only broadcast once for each new route; otherwise, do nothing.
TOS Boot Camp25 Packet Forwarding Code in AM_ROUTE.c
TOS Boot Camp26 AM_ROUTE.c (ROUTE_SUB_DATA_READY) Data source char TOS_EVENT(ROUTE_SUB_DATA_READY)(int data){ … if(VAR(route) != 0 && other App. Specific conditions){ … TOS_CALL_COMMAND(ROUTE_SUB_SEND_MSG) (VAR(route),AM_MSG(DATA_MSG), &VAR(data_buf)); … } Send out a data packet if a node has a route.
TOS Boot Camp27 AM_ROUTE.c (DATA_MSG) TOS_MsgPtrTOS_MSG_EVENT(DATA_MSG) (TOS_MsgPtr msg){ … if(VAR(route) != 0){ Application Specific Modification of the forwarding packet … TOS_CALL_COMMAND(ROUTE_SUB_SEND_MSG) (VAR(route),AM_MSG(DATA_MSG),msg); … } … } Forward message if you have a route. Node has a route
TOS Boot Camp28 AM_ROUTE.c (DATA_MSG) TOS_MsgPtrTOS_MSG_EVENT(DATA_MSG) (TOS_MsgPtr msg){ … if(VAR(route) != 0){ //update the packet. data[5] = data[4]; data[4] = data[3]; data[3] = data[2]; data[2] = data[1]; data[1] = TOS_LOCAL_ADDRESS; … TOS_CALL_COMMAND(ROUTE_SUB_SEND_MSG) (VAR(route),AM_MSG(DATA_MSG),msg); … } … } Modify the forwarding packet to stores the hops taken.
TOS Boot Camp29 Outline Media Access Control Ad Hoc Routing Mechanism Hands on Exercise
TOS Boot Camp30 Hands on Exercise (I) Run the “apps/router.desc” application –Set it to your own LOCAL GROUP in Makefile »Default is 0x13 –Goes to tools directory »Run listen.c
TOS Boot Camp31 Hands on Exercise (II) Modify ROUTE_UPDATE in AM_ROUTE.c GOAL: pick route based on depth of the tree –Pick the route with the smallest number of hops from the base station Can use the same data unit format –data[0] already tells you number of hops from the base station of the sender of the packet –and the corresponding node id = data[(int)data[0]] If a better route (smaller number of hops) is received, use that as the new route. You may need to introduce a new variable (e.g. myLevel) to remember your current depth