📄 writing low-power applications - 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=(0063)http://docs.tinyos.net/index.php/Writing_Low-Power_Applications -->
<HTML lang=en dir=ltr xml:lang="en"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>Writing Low-Power Applications - TinyOS Documentation Wiki</TITLE>
<META http-equiv=Content-Type content="text/html; charset=UTF-8">
<META content="Writing Low-Power Applications,The TinyOS printf Library"
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="Writing Low-Power Applications - 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="Writing Low-Power Applications - 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 = "Writing_Low-Power_Applications";var wgTitle = "Writing Low-Power Applications";var wgAction = "view";var wgRestrictionEdit = [];var wgRestrictionMove = [];var wgArticleId = "19";var wgIsArticle = true;var wgUserName = null;var wgUserGroups = null;var wgUserLanguage = "en";var wgContentLanguage = "en";var wgBreakFrames = false;var wgCurRevisionId = "830";/*]]>*/</SCRIPT>
<SCRIPT
src="Writing Low-Power Applications - TinyOS Documentation Wiki.files/wikibits.js"
type=text/javascript><!-- wikibits js --></SCRIPT>
<SCRIPT
src="Writing Low-Power Applications - 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="Writing Low-Power Applications - 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-Writing_Low-Power_Applications">
<DIV id=globalWrapper>
<DIV id=column-content>
<DIV id=content><A id=top name=top></A>
<H1 class=firstHeading>Writing Low-Power Applications</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/Writing_Low-Power_Applications#column-one">navigation</A>,
<A
href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications#searchInput">search</A></DIV><!-- start content -->
<P>This lesson demonstrates how to write low power sensing applications in
TinyOS. At any given moment, the power consumption of a wireless sensor node is
a function of its microcontroller power state, whether the radio, flash, and
sensor peripherals are on, and what operations active peripherals are
performing. This tutorial shows you how to best utilize the features provided by
TinyOS to keep the power consumption of applications that use these devices to a
minumum. </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/Writing_Low-Power_Applications#Overview"><SPAN
class=tocnumber>1</SPAN> <SPAN class=toctext>Overview</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications#Peripheral_Energy_Management"><SPAN
class=tocnumber>2</SPAN> <SPAN class=toctext>Peripheral Energy
Management</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications#Radio_Power_Management"><SPAN
class=tocnumber>3</SPAN> <SPAN class=toctext>Radio Power
Management</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications#Microcontroller_Power_Management"><SPAN
class=tocnumber>4</SPAN> <SPAN class=toctext>Microcontroller Power
Management</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications#Low_Power_Sensing_Application"><SPAN
class=tocnumber>5</SPAN> <SPAN class=toctext>Low Power Sensing
Application</SPAN></A>
<LI class=toclevel-1><A
href="http://docs.tinyos.net/index.php/Writing_Low-Power_Applications#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=Overview></A>
<H1><SPAN class=mw-headline>Overview</SPAN></H1>
<P>Energy management is a critical concern in wireless sensor networks. Without
it, the lifetime of a wireless sensor node is limited to just a few short weeks
or even days, depending on the type of application it is running and the size of
batteries it is using. With proper energy management, the same node, running the
same application, can be made to last for months or years on the same set of
batteries. </P>
<P>Ideally, one would want all energy management to be handled transparently by
the operating system, relieving application developers from having to deal with
this burden themselves. While attempts have been made in the past to provide
such capabilities, most operating systems today still just provide the necessary
primitives for performing energy management -- the logic of when and how to do
so is left completely up to the application. </P>
<P>TinyOS provides a novel method of performing energy management directly
within the OS. The method it uses is as efficient as it is elegant. Developers
no longer have to struggle with code that explicitly manages the power state for
any of the peripheral devices that it uses. To get a better idea of the
complexity involved in doing something as simple as periodically taking a set of
sensor readings and logging them to flash in the most energy efficient manner
possible, take a look at the pseudo code found below. </P><PRE>Every Sample Period:
Turn on SPI bus
Turn on flash chip
Turn on voltage reference
Turn on I2C bus
Log prior readings
Start humidity sample
Wait 5ms for log
Turn off flash chip
Turn off SPI bus
Wait 12ms for vref
Turn on ADC
Start total solar sample
Wait 2ms for total solar
Start photo active sample
Wait 2ms for photo active
Turn off ADC
Turn off vref
Wait 34ms for humidity
Start temperature sample
Wait 220ms for temperature
Turn off I2C bus
</PRE>
<P>With the methods provided by TinyOS, hand-tuned application code that looks
like that can be transformed into this: </P><PRE>Every Sample Period:
Log prior readings
Sample photo active
Sample total solar
Sample temperature
Sample humidity
</PRE>
<P>The pseudo code shown above is for concurrently sampling all of the the
onboard sensors found on the latest revision of the tmote sky sensor nodes.
Experiments have shown that using the methods provided by TinyOS, this
application comes within 1.6% of the energy efficiency of the hand-tuned
implementation -- even at sampling rates as fast as 1 sample per second. For
more information on these experiments and the method TinyOS uses to actually
manage energy so efficiently, please refer to the paper found <A
class="external text"
title=http://sing.stanford.edu/klueska/Black_Site/Publications_files/klues07icem.pdf
href="http://sing.stanford.edu/klueska/Black_Site/Publications_files/klues07icem.pdf"
rel=nofollow>here.</A> </P>
<P>The rest of this tutorial is dedicated to teaching you how to write
applications that allow TinyOS to manage energy for you in the most efficient
manner possible. As a rule, TinyOS can manage energy more efficiently when I/O
requests are submitted by an application in parallel. Submitting them serially
may result in energy wasted by unnecessarily turning devices on and off more
frequently than required. </P><A name=Peripheral_Energy_Management></A>
<H1><SPAN class=mw-headline>Peripheral Energy Management</SPAN></H1>
<P>Compare the following two code snippets: </P>
<TABLE>
<TBODY>
<TR>
<TD><B>Parallel</B> </TD>
<TD><B>Serial</B> </TD></TR>
<TR>
<TD vAlign=top><PRE>event void Boot.booted() {
call Timer.startPeriodic(SAMPLE_PERIOD);
}
event void Timer.fired() {
call LogWrite.append(current_entry, sizeof(log_entry_t));
current_entry_num = !current_entry_num;
current_entry = &(entry[current_entry_num]);
current_entry->entry_num = ++log_entry_num;
call Humidity.read();
call Temperature.read();
call Photo.read();
call Radiation.read();
}
event void Humidity.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
current_entry->hum = val;
}
else current_entry->hum = 0xFFFF;
}
event void Temperature.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
current_entry->temp = val;
}
else current_entry->temp = 0xFFFF;
}
event void Photo.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
current_entry->photo = val;
}
else current_entry->photo = 0xFFFF;
}
event void Radiation.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
current_entry->rad = val;
}
else current_entry->rad = 0xFFFF;
}
event void LogWrite.appendDone(void* buf,
storage_len_t len,
bool recordsLost,
error_t error) {
if (error == SUCCESS)
call Leds.led2Toggle();
}
</PRE></TD>
<TD vAlign=top><PRE>event void Boot.booted() {
call Timer.startPeriodic(SAMPLE_PERIOD);
}
event void Timer.fired() {
call Humidity.read();
}
event void Humidity.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
entry->rad = val;
}
else current_entry->rad = 0xFFFF;
call Temperature.read();
}
event void Temperature.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
entry->rad = val;
}
else current_entry->rad = 0xFFFF;
call Photo.read();
}
event void Photo.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
entry->rad = val;
}
else current_entry->rad = 0xFFFF;
call Radiation.read();
}
event void Radiation.readDone(error_t result, uint16_t val) {
if(result == SUCCESS) {
entry->rad = val;
}
else current_entry->rad = 0xFFFF;
call LogWrite.append(entry, sizeof(log_entry_t));
}
event void LogWrite.appendDone(void* buf,
storage_len_t len,
bool recordsLost,
error_t error) {
if (error == SUCCESS)
call Leds.led2Toggle();
}
</PRE></TD></TR></TBODY></TABLE>
<P>In the parallel case, logging to flash and requesting samples from each
sensor is all done within the body of the <CODE>Timer.fired()</CODE> event. In
the serial case, a chain of events is triggered by first calling
<CODE>Humidity.read()</CODE> in <CODE>Timer.fired()</CODE>, sampling each
subsequent sensor in the body of the previous <CODE>readDone()</CODE> event, and
ending with all sensor readings being logged to flash. </P>
<P>By logging to flash and sampling all sensors within the body of a single
event, the OS has the opportunity to schedule each operation as it sees fit.
Performing each operation after the completion of the previous one gives the OS
no such opportunity. The only downside of the parallel approach is that the
application must manually manage a double buffer so that the values written to
flash are not overwritten before they are logged. To save the most energy,
however, the parallel version should always be used. Keep in mind that in both
cases, the developer must also make sure that the sampling interval is longer
than the time it takes to gather all sensor readings. If it is not, data
corruption will inevitably occur. </P><A name=Radio_Power_Management></A>
<H1><SPAN class=mw-headline>Radio Power Management</SPAN></H1>
<P>By default, TinyOS provides low power radio operation through a technique
known as <I>Low-Power Listening</I>. In low-power listening, a node turns on its
radio just long enough to detect a carrier on the channel. If it detects a
carrier, then it keeps the radio on long enough to detect a packet. Because the
LPL check period is much longer than a packet, a transmitter must send its first
packet enough times for a receiver to have a chance to hear it. The transmitter
stops sending once it receives a link-layer acknowledgment or a timeout of twice
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -