📄 network protocols - tinyos documentation wiki.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0050)http://docs.tinyos.net/index.php/Network_Protocols -->
<HTML lang=en dir=ltr xml:lang="en"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>Network Protocols - TinyOS Documentation Wiki</TITLE>
<META http-equiv=Content-Type content="text/html; charset=UTF-8">
<META content="Network Protocols,TOSSIM,TinyOS Toolchain" name=keywords><LINK
href="/favicon.ico" rel="shortcut icon"><LINK
title="TinyOS Documentation Wiki (English)" href="/opensearch_desc.php"
type=application/opensearchdescription+xml rel=search>
<STYLE type=text/css media="screen, projection">@import url( /skins/common/shared.css?97 );
@import url( /skins/monobook/main.css?97 );
</STYLE>
<LINK media=print
href="Network Protocols - TinyOS Documentation Wiki.files/commonPrint.css"
type=text/css rel=stylesheet><!--[if lt IE 5.5000]><style type="text/css">@import "/skins/monobook/IE50Fixes.css?97";</style><![endif]--><!--[if IE 5.5000]><style type="text/css">@import "/skins/monobook/IE55Fixes.css?97";</style><![endif]--><!--[if IE 6]>
<STYLE type=text/css>@import url( /skins/monobook/IE60Fixes.css?97 );
</STYLE>
<![endif]--><!--[if IE 7]><style type="text/css">@import "/skins/monobook/IE70Fixes.css?97";</style><![endif]--><!--[if lt IE 7]>
<SCRIPT src="Network Protocols - TinyOS Documentation Wiki.files/IEFixes.js"
type=text/javascript></SCRIPT>
<META http-equiv=imagetoolbar content=no><![endif]-->
<SCRIPT type=text/javascript>/*<![CDATA[*/var skin = "monobook";var stylepath = "/skins";var wgArticlePath = "/index.php/$1";var wgScriptPath = "";var wgScript = "/index.php";var wgServer = "http://docs.tinyos.net";var wgCanonicalNamespace = "";var wgCanonicalSpecialPageName = false;var wgNamespaceNumber = 0;var wgPageName = "Network_Protocols";var wgTitle = "Network Protocols";var wgAction = "view";var wgRestrictionEdit = [];var wgRestrictionMove = [];var wgArticleId = "17";var wgIsArticle = true;var wgUserName = null;var wgUserGroups = null;var wgUserLanguage = "en";var wgContentLanguage = "en";var wgBreakFrames = false;var wgCurRevisionId = "812";/*]]>*/</SCRIPT>
<SCRIPT src="Network Protocols - TinyOS Documentation Wiki.files/wikibits.js"
type=text/javascript><!-- wikibits js --></SCRIPT>
<SCRIPT src="Network Protocols - TinyOS Documentation Wiki.files/index.php"
type=text/javascript><!-- site js --></SCRIPT>
<STYLE type=text/css>@import url( /index.php?title=MediaWiki:Common.css&usemsgcache=yes&action=raw&ctype=text/css&smaxage=18000 );
@import url( /index.php?title=MediaWiki:Monobook.css&usemsgcache=yes&action=raw&ctype=text/css&smaxage=18000 );
@import url( /index.php?title=-&action=raw&gen=css&maxage=18000 );
</STYLE>
<!-- Head Scripts -->
<SCRIPT src="Network Protocols - TinyOS Documentation Wiki.files/ajax.js"
type=text/javascript></SCRIPT>
<META content="MSHTML 6.00.2900.3268" name=GENERATOR></HEAD>
<BODY class="mediawiki ns-0 ltr page-Network_Protocols">
<DIV id=globalWrapper>
<DIV id=column-content>
<DIV id=content><A id=top name=top></A>
<H1 class=firstHeading>Network Protocols</H1>
<DIV id=bodyContent>
<H3 id=siteSub>From TinyOS Documentation Wiki</H3>
<DIV id=contentSub></DIV>
<DIV id=jump-to-nav>Jump to: <A
href="http://docs.tinyos.net/index.php/Network_Protocols#column-one">navigation</A>,
<A
href="http://docs.tinyos.net/index.php/Network_Protocols#searchInput">search</A></DIV><!-- start content -->
<P>This lesson introduces the two basic network primitives of Tinyos-2:
Dissemination and Collection.<BR></P>
<TABLE class=toc id=toc summary=Contents>
<TBODY>
<TR>
<TD>
<DIV id=toctitle>
<H2>Contents</H2></DIV>
<UL>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Network_Protocols#Dissemination"><SPAN
class=tocnumber>1</SPAN> <SPAN class=toctext>Dissemination</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Network_Protocols#Collection"><SPAN
class=tocnumber>2</SPAN> <SPAN class=toctext>Collection</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Network_Protocols#To_experiment_further"><SPAN
class=tocnumber>3</SPAN> <SPAN class=toctext>To experiment
further</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Network_Protocols#Related_Documentation"><SPAN
class=tocnumber>4</SPAN> <SPAN class=toctext>Related
Documentation</SPAN></A> </LI></UL></TD></TR></TBODY></TABLE>
<SCRIPT type=text/javascript> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </SCRIPT>
<A name=Dissemination></A>
<H1><SPAN class=mw-headline>Dissemination<BR></SPAN></H1>
<P>The goal of a dissemination protocol is to reliably deliver a piece of data
to every node in the network. It allows administrators to reconfigure, query,
and reprogram a network. Reliability is important because it makes the operation
robust to temporary disconnections or high packet loss. Dissemination is fully
explained in TEP 118.<BR></P>
<P>In TinyOS 2.x, dissemination provides two interfaces: DisseminationValue and
DisseminationUpdate. Let's take a look at these two
interfaces:<BR>tos/lib/net/DisseminationUpdate.nc:<BR></P><PRE>interface DisseminationUpdate<t> {<BR> command void change(t* newVal);<BR>}
</PRE>
<P>tos/lib/net/DisseminationValue.nc:<BR></P><PRE>interface DisseminationValue<t> {<BR> command const t* get();<BR> event void changed();<BR>}
</PRE>
<P>DisseminationUpdate is used by producers. The command
<I><B>DisseminationUpdate.change()</B></I> should be called each time the
producer wants to disseminate a new value, passing this new value as a
parameter.<BR>DisseminationValue is for consumers. The event
<I><B>DisseminationValue.changed()</B></I> is signalled each time the
disseminated value is changed (the producer has called <I><B>change</B></I>),
and the command<I> <B>get</B></I> allows to obtain this new value. <BR></P>
<P>We build now a simple application (EasyDissemination) where one node (the
producer) periodically disseminates the value of a counter to rest of the nodes
in the network (consumers). As a first step, create a new directory in
<TT>apps</TT> named <FONT face=monospace>EasyDissemination</FONT>: </P><PRE>$ cd tinyos-2.x/apps<BR>$ mkdir EasyDissemination<BR>
</PRE>
<P>Inside this directory, create a file <CODE>EasyDisseminationC.nc</CODE>,
which has this code: </P><PRE>#include <Timer.h><BR><BR>module EasyDisseminationC {<BR> uses interface Boot;<BR> uses interface SplitControl as RadioControl;<BR> uses interface StdControl as DisseminationControl;<BR> uses interface DisseminationValue<uint16_t> as Value;<BR> uses interface DisseminationUpdate<uint16_t> as Update;<BR> uses interface Leds;<BR> uses interface Timer<TMilli>;<BR>}<BR><BR>implementation {<BR><BR> uint16_t counter;<BR><BR> task void ShowCounter() {<BR> if (counter & 0x1) <BR> call Leds.led0On();<BR> else <BR> call Leds.led0Off();<BR> if (counter & 0x2) <BR> call Leds.led1On();<BR> else <BR> call Leds.led1Off();<BR> if (counter & 0x4) <BR> call Leds.led2On();<BR> else<BR> call Leds.led2Off();<BR> }<BR><BR> event void Boot.booted() {<BR> call RadioControl.start();<BR> }<BR><BR> event void RadioControl.startDone(error_t err) {<BR> if (err != SUCCESS) <BR> call RadioControl.start();<BR> else {<BR> call DisseminationControl.start();<BR> counter = 0;<BR> if ( TOS_NODE_ID == 1 ) <BR> call Timer.startPeriodic(2000);<BR> }<BR> }<BR><BR> event void RadioControl.stopDone(error_t err) {}<BR><BR> event void Timer.fired() {<BR> counter = counter + 1;<BR> // show counter in leds<BR> post ShowCounter();<BR> // disseminate counter value<BR> call Update.change(&counter);<BR> }<BR><BR> event void Value.changed() {<BR> const uint16_t* newVal = call Value.get();<BR> // show new counter in leds<BR> counter = *newVal;<BR> post ShowCounter();<BR> }<BR>}<BR>
</PRE>
<P>We assume that the base station is the node with ID = 1. First note that the
base station will periodically (every 2 seconds) increment a 3-bit counter,
display the counter using its three leds, and disseminate it through the
network. This is done using the change command provided in the
DisseminationUpdate interface:<BR></P><PRE>call Update.change(&counter);
</PRE>
<P>Second, note that when a node receives a change notification, it updates its
counter value and shows it on the leds:<BR></P><PRE>event void Value.changed() {<BR> const uint16_t* newVal = call Value.get();<BR> // show new counter in leds<BR> counter = *newVal;<BR> post ShowCounter();<BR> }<BR>
</PRE>
<P>The <CODE>EasyDisseminationAppC.nc</CODE> provides the needed wiring: </P><PRE>configuration EasyDisseminationAppC {}<BR>implementation {<BR> components EasyDisseminationC;<BR><BR> components MainC;<BR> EasyDisseminationC.Boot -> MainC;<BR><BR> components ActiveMessageC;<BR> EasyDisseminationC.RadioControl -> ActiveMessageC;<BR><BR> components DisseminationC;<BR> EasyDisseminationC.DisseminationControl -> DisseminationC;<BR><BR> components new DisseminatorC(uint16_t, 0x1234) as Diss16C;<BR> EasyDisseminationC.Value -> Diss16C;<BR> EasyDisseminationC.Update -> Diss16C;<BR><BR> components LedsC;<BR> EasyDisseminationC.Leds -> LedsC;<BR><BR> components new TimerMilliC();<BR> EasyDisseminationC.Timer -> TimerMilliC;<BR>}<BR>
</PRE>
<P>Note that both Dissemination interfaces we use are provided by the module
DisseminatorC. <BR>This module provides the Dissemination
service:<BR>tos/lib/net/Dissemination/DisseminationC.nc: </P><PRE> generic configuration DisseminatorC(typedef t, uint16_t key) {<BR> provides interface DisseminationValue<t>;<BR> provides interface DisseminationUpdate<t>;<BR>}<BR>
</PRE>
<P>Note that we need to specify to the Disseminartor module a type t and a key.
In our case, the value we want to disseminate is just an unsigned two-byte
counter. The key allows to have different instances of DisseminatroC. <BR><BR>To
compile this program we use the following Makefile:<BR></P><PRE>COMPONENT=EasyDisseminationAppC<BR>CFLAGS += -I$(TOSDIR)/lib/net \<BR> -I$(TOSDIR)/lib/net/drip<BR><BR>include $(MAKERULES)<BR>
</PRE>
<P>Now install this program into several nodes (make sure you have one base
station, that is, one node whose ID is 1) and see how the counter displayed in
the base station is "disseminated" to all the nodes belonging to the network.
You will also notice that dissemination works across resets, i.e., if you reset
a node it will rapidly re-'synchronize' and display the correct value after it
reboots. <BR><BR>For more information, read TEP118
[Dissemination].<BR><BR></P><A name=Collection></A>
<H1><SPAN class=mw-headline>Collection<BR></SPAN></H1>
<P>Collection is the complementary operation to disseminating and it consists in
"collecting" the data generated in the network into a base stations. The general
approach used is to build one or more collection <I>trees</I>, each of which is
rooted at a base station. When a node has data which needs to be collected, it
sends the data up the tree, and it forwards collection data that other nodes
send to it. <BR></P>
<P>We build now a simple application (EasyCollection) where nodes periodically
send information to a base station which collects all the data.<BR>As a first
step, create a new directory in <TT>apps</TT> named <FONT
face=monospace>EasyCollection</FONT>: </P><PRE>$ cd tinyos-2.x/apps<BR>$ mkdir EasyCollection<BR>
</PRE>
<P>Inside this directory, create a file <CODE>EasyCollectionC.nc</CODE>, which
has the following code: </P><PRE>#include <Timer.h><BR><BR>module EasyCollectionC {<BR> uses interface Boot;<BR> uses interface SplitControl as RadioControl;<BR> uses interface StdControl as RoutingControl;<BR> uses interface Send;<BR> uses interface Leds;<BR> uses interface Timer<TMilli>;<BR> uses interface RootControl;<BR> uses interface Receive;<BR>}<BR>implementation {<BR> message_t packet;<BR> bool sendBusy = FALSE;<BR><BR> typedef nx_struct EasyCollectionMsg {<BR> nx_uint16_t data;<BR> } EasyCollectionMsg;<BR><BR> event void Boot.booted() {<BR> call RadioControl.start();<BR> }<BR> <BR> event void RadioControl.startDone(error_t err) {<BR> if (err != SUCCESS)<BR> call RadioControl.start();<BR> else {<BR> call RoutingControl.start();<BR> if (TOS_NODE_ID == 1) <BR> call RootControl.setRoot();<BR> else<BR> call Timer.startPeriodic(2000);<BR> }<BR> }<BR><BR> event void RadioControl.stopDone(error_t err) {}<BR><BR> void sendMessage() {<BR> EasyCollectionMsg* msg =<BR> (EasyCollectionMsg*)call Send.getPayload(&packet, sizeof(EasyCollectionMsg));<BR> msg->data = 0xAAAA;<BR> <BR> if (call Send.send(&packet, sizeof(EasyCollectionMsg)) != SUCCESS) <BR> call Leds.led0On();<BR> else <BR> sendBusy = TRUE;<BR> }<BR> event void Timer.fired() {<BR> call Leds.led2Toggle();<BR> if (!sendBusy)<BR> sendMessage();<BR> }<BR> <BR> event void Send.sendDone(message_t* m, error_t err) {<BR> if (err != SUCCESS) <BR> call Leds.led0On();<BR> sendBusy = FALSE;<BR> }<BR> <BR> event message_t* <BR> Receive.receive(message_t* msg, void* payload, uint8_t len) {<BR> call Leds.led1Toggle(); <BR> return msg;<BR> }<BR>}<BR>
</PRE>
<P>Lets take a look at this program. First note that all nodes turn on the radio
into the Boot sequence:<BR></P><PRE> event void Boot.booted() {<BR> call RadioControl.start();<BR> }
</PRE>
<P>Once we are sure that the radio is on, we start the routing sub-system (that
is, to generate the collection <I>tree</I>):<BR></P><PRE>call RoutingControl.start();
</PRE>
<P>Next we need need to specify the root of the collection tree, that is, the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -