📄 modules and the tinyos execution model - 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=(0071)http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model -->
<HTML lang=en dir=ltr xml:lang="en"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>Modules and the TinyOS Execution Model - TinyOS Documentation Wiki</TITLE>
<META http-equiv=Content-Type content="text/html; charset=UTF-8">
<META
content="Modules and the TinyOS Execution Model,Modules and the TinyOS Execution Model,Getting Started with TinyOS,Mote-mote radio communication"
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="Modules and the TinyOS Execution Model - 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="Modules and the TinyOS Execution Model - 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 = "Modules_and_the_TinyOS_Execution_Model";var wgTitle = "Modules and the TinyOS Execution Model";var wgAction = "view";var wgRestrictionEdit = [];var wgRestrictionMove = [];var wgArticleId = "8";var wgIsArticle = true;var wgUserName = null;var wgUserGroups = null;var wgUserLanguage = "en";var wgContentLanguage = "en";var wgBreakFrames = false;var wgCurRevisionId = "671";/*]]>*/</SCRIPT>
<SCRIPT
src="Modules and the TinyOS Execution Model - TinyOS Documentation Wiki.files/wikibits.js"
type=text/javascript><!-- wikibits js --></SCRIPT>
<SCRIPT
src="Modules and the TinyOS Execution Model - 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="Modules and the TinyOS Execution Model - 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-Modules_and_the_TinyOS_Execution_Model">
<DIV id=globalWrapper>
<DIV id=column-content>
<DIV id=content><A id=top name=top></A>
<H1 class=firstHeading>Modules and the TinyOS Execution Model</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/Modules_and_the_TinyOS_Execution_Model#column-one">navigation</A>,
<A
href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model#searchInput">search</A></DIV><!-- start content -->
<P>This lesson introduces nesC modules, commands, events, and tasks. It explains
the TinyOS execution model. </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/Modules_and_the_TinyOS_Execution_Model#Modules_and_State"><SPAN
class=tocnumber>1</SPAN> <SPAN class=toctext>Modules and
State</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model#Interfaces.2C_Commands.2C_and_Events"><SPAN
class=tocnumber>2</SPAN> <SPAN class=toctext>Interfaces, Commands, and
Events</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model#TinyOS_Execution_Model:_Tasks"><SPAN
class=tocnumber>3</SPAN> <SPAN class=toctext>TinyOS Execution Model:
Tasks</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model#Internal_Functions"><SPAN
class=tocnumber>4</SPAN> <SPAN class=toctext>Internal
Functions</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model#Split-Phase_Operations"><SPAN
class=tocnumber>5</SPAN> <SPAN class=toctext>Split-Phase
Operations</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Modules_and_the_TinyOS_Execution_Model#Related_Documentation"><SPAN
class=tocnumber>6</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=Modules_and_State></A>
<H1><SPAN class=mw-headline>Modules and State</SPAN></H1>
<P>Compiling TinyOS applications produces a single binary image that assumes it
has complete control of the hardware. Therefore, a mote only runs one TinyOS
image at a time. An image consists of the components needed for a single
application. As most more platforms do not have hardware-based memory
protection, there is no seperation between a "user" address space and a "system"
address space; there is only one address space that all components share. This
is why many TinyOS components try to keep their state private and avoid passing
pointers: since there is no hardware protection, the best way to keep memory
uncorrupted is to share it as little as possible. </P>
<P>Recall from lesson 1 that the set of interfaces a component uses and provides
define its signature. Both kinds of components -- configurations and modules --
provide and use interfaces. The difference between the two lies in their
implementation: configurations are implemented in terms of other components,
which they wire, while modules are executable code. After unwrapping all of the
layers of abstraction that configurations introduce, modules always lie within.
Module implementations are for the most part written in C, with some extra
constructions for nesC abstractions. </P>
<P>Modules can declare state variables. Any state a component declares is
private: no other component can name it or directly access it. The only way two
components can directly interact is through interfaces. Let's revisit the Blink
application. Here is the Blink module BlinkC's implementation in its entirety:
</P><PRE>apps/Blink/BlinkC.nc:
module BlinkC {
uses interface Timer<TMilli> as Timer0;
uses interface Timer<TMilli> as Timer1;
uses interface Timer<TMilli> as Timer2;
uses interface Leds;
uses interface Boot;
}
implementation
{
event void Boot.booted()
{
call Timer0.startPeriodic( 250 );
call Timer1.startPeriodic( 500 );
call Timer2.startPeriodic( 1000 );
}
event void Timer0.fired()
{
call Leds.led0Toggle();
}
event void Timer1.fired()
{
call Leds.led1Toggle();
}
event void Timer2.fired()
{
call Leds.led2Toggle();
}
}
</PRE>
<P>BlinkC does not allocate any state. Let's change it so that its logic is a
little different: rather than blink the LEDs from three different timers, we'll
blink them with a single timer and keep some state to know which ones to toggle.
Make a copy of the Blink application, <TT>BlinkSingle</TT>, and go into its
directory. </P><PRE>$ cd tinyos-2.x/apps
$ cp -R Blink BlinkSingle
$ cd BlinkSingle
</PRE>
<P>Open the BlinkC module in an editor. The first step is to comment out the LED
toggles in Timer1 and Timer2: </P><PRE> event void Timer1.fired()
{
// call Leds.led1Toggle();
}
event void Timer2.fired()
{
// call Leds.led2Toggle();
}
</PRE>
<P>The next step is to add some state to BlinkC, a single byte. Just like in C,
variables and functions must be declared before they are used, so put it at the
beginning of the implementation: </P><PRE>implementation
{
uint8_t counter = 0;
event void Boot.booted()
{
call Timer0.startPeriodic( 250 );
call Timer1.startPeriodic( 500 );
call Timer2.startPeriodic( 1000 );
}
</PRE>
<P>Rather than the standard C names of <TT>int</TT>, <TT>long</TT>, or
<TT>char</TT>, TinyOS code uses more explicit types, which declare their size.
In reality, these map to the basic C types, but do so differently for different
platforms. TinyOS code avoids using <TT>int</TT>, for example, because it is
platform-specific. For example, on mica and Telos motes, <TT>int</TT> is 16
bits, while on the IntelMote2, it is 32 bits. Additionally, TinyOS code often
uses unsigned values heavily, as wrap-arounds to negative numbers can often lead
to very unintended consequences. The commonly used types are: </P>
<CENTER>
<TABLE cellPadding=6 border=1>
<TBODY>
<TR>
<TD></TD>
<TD>8 bits </TD>
<TD>16 bits </TD>
<TD>32 bits </TD>
<TD>64 bits </TD></TR>
<TR>
<TD>signed </TD>
<TD><TT>int8_t</TT> </TD>
<TD><TT>int16_t</TT> </TD>
<TD><TT>int32_t</TT> </TD>
<TD><TT>int64_t</TT> </TD></TR>
<TR>
<TD>unsigned </TD>
<TD><TT>uint8_t</TT> </TD>
<TD><TT>uint16_t</TT> </TD>
<TD><TT>uint32_t</TT> </TD>
<TD><TT>uint64_t</TT> </TD></TR></TBODY></TABLE></CENTER>
<P>There is also a <TT>bool</TT> type. You can use the standard C types, but
doing so might raise cross-platform issues. Also, <TT>uint32_t</TT> is often
easier to write than <TT>unsigned long</TT>. Most platforms support floating
point numbers (<TT>float</TT> almost always, <TT>double</TT> sometimes),
although their arithmetic is in software rather than hardware. </P>
<P>Returning to our modified BlinkC, we've allocated a single unsigned byte,
<TT>counter</TT>. When the mote boots, the <TT>counter</TT> will be initialized
to zero. The next step is to make it that when Timer0 fires, it increments
<TT>counter</TT> and displays the result: </P><PRE> event void Timer0.fired()
{
counter++;
if (counter & 0x1) {
call Leds.led0On();
}
else {
call Leds.led0Off();
}
if (counter & 0x2) {
call Leds.led1On();
}
else {
call Leds.led1Off();
}
if (counter & 0x4) {
call Leds.led2On();
}
else {
call Leds.led2Off();
}
}
</PRE>
<P>Another, more succinct way to do it is to use the <TT>set</TT> command: </P><PRE> event void Timer0.fired()
{
counter++;
call Leds.set(counter);
}
</PRE>
<P>Compile your program and install it on a mote. You'll see that it behaves
just as before, except that now the LEDs are being driven by a single, rather
than three, timers. </P>
<P>As only one timer is being used, this means that you don't need Timer1 and
Timer2: they waste CPU resources and memory. Open BlinkC again and remove them
from its signature and implementation. You should have something that looks like
this: </P><PRE>module BlinkC {
uses interface Timer<TMilli> as Timer0;
uses interface Leds;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -