<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>Sensors and Sensor Boards</title>
-<meta name="author" content="David Gay, Phil Levis, Wei Hong, Joe Polastre, and Gilman Tolle" />
+<meta name="author" content="David Gay, Philip Levis, Wei Hong, Joe Polastre, and Gilman Tolle" />
<style type="text/css">
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
-:Date: $Date$
-:Revision: $Revision$
-:Copyright: This stylesheet has been placed in the public domain.
+:date: $Date$
+:version: $Revision$
+:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
-
-See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
-customize this style sheet.
*/
+body {
+ font-family: Times;
+ font-size: 16px;
+}
-/* "! important" is used here to override other ``margin-top`` and
- ``margin-bottom`` styles that are later in the stylesheet or
- more specific. See http://www.w3.org/TR/CSS1#the-cascade */
.first {
margin-top: 0 ! important }
-.last, .with-subtitle {
+.last {
margin-bottom: 0 ! important }
.hidden {
blockquote.epigraph {
margin: 2em 5em ; }
-dl.docutils dd {
+dd {
margin-bottom: 0.5em }
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
- font-weight: bold }
-*/
-
div.abstract {
margin: 2em 5em }
font-weight: bold ;
text-align: center }
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
+div.attention, div.caution, div.danger, div.error, div.hint,
+div.important, div.note, div.tip, div.warning, div.admonition {
margin: 2em ;
border: medium outset ;
padding: 1em }
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
- font-weight: bold ;
- font-family: sans-serif }
-
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
-/* Uncomment (and remove this text!) to get reduced vertical space in
- compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
- margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
- margin-top: 0.5em }
-*/
+div.hint p.admonition-title, div.important p.admonition-title,
+div.note p.admonition-title, div.tip p.admonition-title,
+div.admonition p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
margin-left: 2em }
div.footer, div.header {
- clear: both;
font-size: smaller }
div.line-block {
div.sidebar {
margin-left: 1em ;
border: medium outset ;
- padding: 1em ;
+ padding: 0em 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
div.topic {
margin: 2em }
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
- margin-top: 0.4em }
+h1 {
+ font-family: Arial, sans-serif;
+ font-size: 20px;
+}
h1.title {
- text-align: center }
+ text-align: center;
+ font-size: 32px;
+}
+
+h2 {
+ font-size: 16px;
+ font-family: Arial, sans-serif;
+}
h2.subtitle {
text-align: center }
-hr.docutils {
- width: 75% }
-
-img.align-left {
- clear: left }
-
-img.align-right {
- clear: right }
+h3 {
+ font-size: 12px;
+ font-family: Arial, sans-serif;
+}
-img.borderless {
- border: 0 }
+hr {
+ width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
- background-color: #eeeeee }
+ background-color: #eeeeee;
+ border-color: #000000;
+ border-width: thin;
+ font-size: 14px
+}
span.classifier {
font-family: sans-serif ;
span.option {
white-space: nowrap }
+span.option-argument {
+ font-style: italic }
+
span.pre {
white-space: pre }
span.problematic {
color: red }
-span.section-subtitle {
- /* font-size relative to parent (h1..h6 element) */
- font-size: 80% }
+table {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
table.citation {
- border-left: solid thin gray }
+ border-left: solid thin gray ;
+ padding-left: 0.5ex }
table.docinfo {
- margin: 2em 4em }
-
-table.docutils {
- margin-top: 0.5em ;
- margin-bottom: 0.5em }
+ margin: 2em 4em;
+}
table.footnote {
- border-left: solid thin black }
+ border-left: solid thin black ;
+ padding-left: 0.5ex }
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
+td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
-table.docutils th.field-name, table.docinfo th.docinfo-name {
+th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
- white-space: nowrap ;
- padding-left: 0 }
+ white-space: nowrap;
+ }
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
-tt.docutils {
- background-color: #eeeeee }
+tt {}
ul.auto-toc {
list-style-type: none }
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
-<td>Draft</td></tr>
+<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
-<td>David Gay, Phil Levis, Wei Hong, Joe Polastre, and Gilman Tolle</td></tr>
-<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Jun-2006</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu></td>
-</tr>
+<td>David Gay, Philip Levis, Wei Hong, Joe Polastre, and Gilman Tolle</td></tr>
</tbody>
</table>
<div class="note">
reflect the specifc name of the sensor, and MAY provide a component
with a generic name for application authors who only care about the
general class of the sensor.</p>
-<p>This document takes no position on the meaning of the values returned
-by sensor drivers. They MAY be raw uninterpreted values or they MAY
-have some physical meaning. If a driver returns uninterpreted values,
-the driver MAY provide additional interfaces that would allow
-higher-level clients to obtain information needed to properly
-interpret the value.</p>
+<p>This document requires that sensor components specify the range (in
+bits) of values returned by sensor drivers, but takes no position on
+the meaning of these values. They MAY be raw uninterpreted values or
+they MAY have some physical meaning. If a driver returns uninterpreted
+values, the driver MAY provide additional interfaces that would allow
+higher-level clients to obtain information (e.g. calibration
+coefficients) needed to properly interpret the value.</p>
</div>
<div class="section">
<h1><a id="sensor-hil-components" name="sensor-hil-components">2. Sensor HIL Components</a></h1>
interface it corresponds to.</p>
<p>The getSignificantBits() call MUST return the number of significant
bits in the reading. For example, a sensor reading taken from a 12-bit
-ADC MUST return the value "12".</p>
+ADC would typically return the value 12 (it might return less if, e.g.,
+physical constraints limit the maximum A/D result to 10-bits).</p>
<p>Sensor driver components SHOULD be named according to the make and
model of the sensing device being presented. Using specific names
gives the developer the option to bind to a particular sensor, which
<li>A <cite>StdControl</cite> or <cite>SplitControl</cite> interface for manual power
management by the user, following the conventions described in
<a class="citation-reference" href="#tep115" id="id5" name="id5">[TEP115]</a>.</li>
-<li>A Resource[] interface for requesting access to the device and
-possibly performing automated power management.</li>
-<li>Any other interfaces needed to control the device.</li>
+<li>A <cite>Resource</cite> interface for requesting access to the device and
+possibly performing automated power management, following
+the conventions described in <a class="citation-reference" href="#tep108" id="id6" name="id6">[TEP108]</a> and <a class="citation-reference" href="#tep115" id="id7" name="id7">[TEP115]</a>.</li>
+<li>Any other interfaces needed to control the device, e.g., to
+read or write calibration coefficients.</li>
</ul>
<p>For example:</p>
<pre class="literal-block">
</pre>
</div>
<div class="section">
-<h1><a id="directory-organization-guidelines" name="directory-organization-guidelines">4. Directory Organization Guidelines</a></h1>
-<p>Because the same physical sensor can be attached to TinyOS platforms
-in many different ways, the organization of sensor drivers SHOULD
-reflect the distinction between sensor and sensor interconnect.</p>
-<p>Sensor components commonly exist at three levels:
-platform-independent, sensorboard-dependent, and
-platform-dependent. Factoring a sensor driver into these three pieces
-allows for greater code reuse when the same sensor is attached to
-different sensorboards or platforms.</p>
-<p>Platform-independent sensor driver components for a particular sensor,
-like protocol logic, when in the core TinyOS 2.x source tree, SHOULD
-be placed into "tos/chips/<sensor>", where <sensor> reflects the make
-and model of the sensor device being supported. When not a part of the
-core source tree, this directory can be placed anywhere as long as the
-nesC compiler recieves a <cite>-I</cite> directive pointing to the sensor's
-directory. However, not all sensors have a sufficiently large amount
-of platform-independent logic to justify a separate "chips"
-directory. Sensor chips are more likely to be digital sensors than
-analog sensors, for example.</p>
-<p>A sensor board is a collection of sensor components with a fixed name,
-intended for attachment to multiple platforms. Each sensor board MUST
-have its own directory named <sensorboard>. Default TinyOS 2.x sensor
-boards are placed in "tos/sensorboards/<sensorboard>", but sensor
-board directories can be placed anywhere as long as the nesC compiler
-receives a <cite>-I</cite> directive pointing to the sensor board's directory.</p>
-<p>Both sensors and sensor boards MUST have unique names. Case is
-significant, but two sensor boards MUST differ in more than case. This
-is necessary to support platforms where filename case differences are
-not significant.</p>
-<p>Each sensor board directory MUST contain a <cite>.sensor</cite> file. This file
-is a perl script which gets executed as part of the <cite>ncc</cite> nesC
-compiler frontend. It can add or modify any compile-time options
-necessary for a particular sensor board. It MAY modify the following
-perl variables, and MUST NOT modify any others:</p>
+<h1><a id="sensor-component-organization-and-compiler-interaction-guidelines" name="sensor-component-organization-and-compiler-interaction-guidelines">4. Sensor Component Organization and Compiler Interaction Guidelines</a></h1>
+<p>Sensors are associated either with a particular sensor board or with a
+particular platform. Both sensors and sensor boards MUST have unique
+names. Case is significant, but two sensor (or sensor board) names
+MUST differ in more than case. This is necessary to support platforms
+where filename case differences are not significant.</p>
+<p>Each sensor board MUST have its own directory whose name is the sensor
+board's unique name (referred to as <sensorboard> in the rest of this
+section). Default TinyOS 2.x sensor boards are placed in
+<tt class="docutils literal"><span class="pre">tos/sensorboards/<sensorboard></span></tt>, but sensor board directories can be
+placed anywhere as long as the nesC compiler receives a <tt class="docutils literal"><span class="pre">-I</span></tt> directive
+pointing to the sensor board's directory. Each sensor board directory
+MUST contain a <tt class="docutils literal"><span class="pre">.sensor</span></tt> file (described below). If the
+sensor board wishes to define any C types or constants, it SHOULD
+place these in a file named <tt class="docutils literal"><span class="pre"><sensorboard>.h</span></tt> in the sensor board's
+directory.</p>
+<p>A sensor board MAY contain components that override the default TinyOS
+<em>demo sensors</em>. This allows the sensor board to easily be used with
+TinyOS sample applications that use the demo sensors. If a sensor
+board wishes to override the default demo sensor:</p>
+<ul>
+<li><p class="first">It MUST provide a generic component named <tt class="docutils literal"><span class="pre">DemoSensorC</span></tt> with the
+following signature:</p>
+<pre class="literal-block">
+provides interface Read<uint16_t>;
+provides interface DeviceMetadata;
+</pre>
+</li>
+<li><p class="first">It MAY provide a generic component named <tt class="docutils literal"><span class="pre">DemoSensorNowC</span></tt> with the
+following signature:</p>
+<pre class="literal-block">
+provides interface ReadNow<uint16_t>;
+provides interface DeviceMetadata;
+</pre>
+<p>This component SHOULD sample the same sensor as <tt class="docutils literal"><span class="pre">DemoSensorC</span></tt>.</p>
+</li>
+<li><p class="first">It MAY provide a generic component named <tt class="docutils literal"><span class="pre">DemoSensorStreamC</span></tt> with the
+following signature:</p>
+<pre class="literal-block">
+provides interface ReadStream<uint16_t>;
+provides interface DeviceMetadata;
+</pre>
+<p>This component SHOULD sample the same sensor as <tt class="docutils literal"><span class="pre">DemoSensorC</span></tt>.</p>
+</li>
+</ul>
+<p>These components MUST be an alias for one of the sensor board's usual
+sensors, though they change the precision of the sensor if necessary.
+For instance, if <tt class="docutils literal"><span class="pre">DemoSensorC</span></tt> is an alias for a 20-bit sensor that
+provides a <tt class="docutils literal"><span class="pre">Read<uint32_t></span></tt> interface, <tt class="docutils literal"><span class="pre">DemoSensorC</span></tt> would still
+provide <tt class="docutils literal"><span class="pre">Read<uint16_t></span></tt> and would include code to reduce the
+precision of the aliased sensor.</p>
+<div class="section">
+<h2><a id="compiler-interaction" name="compiler-interaction">4.1 Compiler Interaction</a></h2>
+<p>When the <tt class="docutils literal"><span class="pre">ncc</span></tt> nesC compiler frontend is passed a <tt class="docutils literal"><span class="pre">-board=X</span></tt> option,
+it executes the <tt class="docutils literal"><span class="pre">.sensor</span></tt> file found in the sensor board directory
+<tt class="docutils literal"><span class="pre">X</span></tt>. This file is a perl script which can add or modify any
+compile-time options necessary for the sensor board. It MAY modify the
+following perl variables, and MUST NOT modify any others:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">@includes</span></tt>: This array contains the TinyOS search path, i.e., the
+directories which will be passed to nescc (the TinyOS-agnostic nesC
+compiler) as <tt class="docutils literal"><span class="pre">-I</span></tt> arguments. You MUST add to <tt class="docutils literal"><span class="pre">@includes</span></tt> any
+directories needed to compile this sensor board's components. For
+instance, if your sensor boards depends on support code found in
+<tt class="docutils literal"><span class="pre">tos/chips/sht11</span></tt>, you would add <tt class="docutils literal"><span class="pre">"%T/chips/sht11"</span></tt> to <tt class="docutils literal"><span class="pre">@includes</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">@new_args</span></tt>: This is the array of arguments which will be passed to
+nescc. You MUST add any arguments other than <tt class="docutils literal"><span class="pre">-I</span></tt> that are necessary
+to compile your sensor board components to <tt class="docutils literal"><span class="pre">@new_args</span></tt>.</li>
+</ul>
+<p>If a sensor is associated with a platform <cite>P</cite> rather than a sensor
+board, then that platform MUST ensure that, when compiling for
+platform <cite>P</cite>, all directories needed to compile that sensor's
+component are added to the TinyOS search path (see <a class="citation-reference" href="#tep131" id="id8" name="id8">[TEP131]</a> for
+information on how to set up a TinyOS platform).</p>
+</div>
+<div class="section">
+<h2><a id="sensor-components" name="sensor-components">4.2 Sensor Components</a></h2>
+<p>A particular sensor is typically supported by many components,
+including the HIL and HAL components from Sections 2 and 3, A/D
+conversion components (for analog sensors), digital bus components
+(e.g., SPI, for digital sensors), system services (timers, resource
+and power management, ...), glue components (to connect sensors,
+sensor boards and platforms), etc. These components can be divided
+into three classes: sensorboard-dependent, platform-dependent and
+platform-independent. The sensorboard and platform MUST ensure
+(Section 4.1) that all these components can be found at compile-time.</p>
+<p>Because the same physical sensor can be used on many platforms or
+sensor boards, and attached in many different ways, to maximize code
+reuse the organization of sensor drivers SHOULD reflect the
+distinction between sensor and sensor interconnect. The sensor
+components SHOULD be platform-independent, while the sensor
+interconnect components are typically sensorboard or
+platform-dependent. However, some sensors (e.g. analong sensors) will
+not have a sufficiently large amount of platform-independent logic to
+justify creating platform-independent components.</p>
+<p>The following guidelines specify how to organize sensor and sensor
+interconnect components within TinyOS's directory hierarchy. These
+guidelines are only relevant to components that are part of the core
+source tree. The string <tt class="docutils literal"><span class="pre"><sensor></span></tt> SHOULD reflect the make and model
+of the sensor device.</p>
<ul class="simple">
-<li>@new_args: This is the array of arguments which will be passed to
-nescc. For instance, you might add an include directive to @new_args
-with push @new_args, <cite>-Isomedir</cite>. This could be used to include
-subdirectories.</li>
-<li>@commonboards: This can be set to a list of sensor board names which
-will be added to the include path list. These sensor boards MUST be
-in tinyos-2.x/tos/sensorboards.</li>
+<li>Platform-independent sensor components that exist as part of a
+larger chip, like a MCU internal voltage sensor, SHOULD be placed in
+a subdirectory of the chip's directory
+<tt class="docutils literal"><span class="pre">tos/<chip>/sensors/<sensor></span></tt>.</li>
+<li>Other platform-independent sensor components SHOULD be placed
+in <tt class="docutils literal"><span class="pre">tos/chips/<sensor></span></tt>.</li>
+<li>Sensorboard-dependent sensor and sensor interconnect components
+SHOULD be placed either in the <tt class="docutils literal"><span class="pre"><sensorboard></span></tt> directory or in a
+<tt class="docutils literal"><span class="pre"><sensorboard>/chips/<sensor></span></tt> directory.</li>
+<li>Platform-dependent sensor and sensor interconnect components SHOULD
+be placed in <tt class="docutils literal"><span class="pre">tos/<platform>/chips/<sensor></span></tt>.</li>
</ul>
-<p>If the sensor board wishes to define any C types or constants, it
-SHOULD place these in a file named <sensorboard>.h in the sensor
-board's directory.</p>
-<p>A sensor board directory MAY contain a "chips" directory, with
-subdirectories for each of the sensors connected to the sensor board.
-If a "chips" subdirectory is used, sensorboard-dependent driver
-components needed to connect platform-independent logic to a
-particular attachment for that sensor SHOULD be placed in
-"<sensorboard>/chips/<sensor>".</p>
-<p>Components needed to connect the platform-independent sensor driver
-components or sensorboard-dependent components to the hardware
-resources available on a particular platform SHOULD be placed in
-"tos/<platform>/chips/<sensor>". In addition, components for a sensor
-that only exists on a particular platform SHOULD be placed in a such a
-directory.</p>
-<p>Sensors that exist as part of a larger chip, like a MCU internal
-voltage sensor, SHOULD be placed in a subdirectory of the chip's
-directory. "tos/<chip>/sensors/<sensor>".</p>
-<p>The <cite>.platform</cite> and <cite>.sensor</cite> files need to include enough <cite>-I</cite>
-directives to locate all of the necessary components needed to support
-the sensors on a platform and/or sensorboard.</p>
-<p>All of these directory organization guidelines are only intended for
-code that will enter the core source tree. In general, sensor
-components can be placed anywhere as long as the nesC compiler
-receives enough <cite>-I</cite> directives to locate all of the necessary pieces.</p>
+</div>
</div>
<div class="section">
<h1><a id="authors-addresses" name="authors-addresses">5. Authors' Addresses</a></h1>
<tr><td class="label"><a class="fn-backref" href="#id1" name="tep2">[TEP2]</a></td><td>TEP 2: Hardware Abstraction Architecture</td></tr>
</tbody>
</table>
+<table class="docutils citation" frame="void" id="tep108" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id6" name="tep108">[TEP108]</a></td><td>TEP 108: Resource Arbitration</td></tr>
+</tbody>
+</table>
<table class="docutils citation" frame="void" id="tep114" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<table class="docutils citation" frame="void" id="tep115" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a name="tep115">[TEP115]</a></td><td><em>(<a class="fn-backref" href="#id4">1</a>, <a class="fn-backref" href="#id5">2</a>)</em> TEP 115: Power Management of Non-Virtualized Devices</td></tr>
+<tr><td class="label"><a name="tep115">[TEP115]</a></td><td><em>(<a class="fn-backref" href="#id4">1</a>, <a class="fn-backref" href="#id5">2</a>, <a class="fn-backref" href="#id7">3</a>)</em> TEP 115: Power Management of Non-Virtualized Devices</td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep131" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id8" name="tep131">[TEP131]</a></td><td>TEP 131: Creating a New Platform for TinyOS 2.x</td></tr>
</tbody>
</table>
</div>
<pre class="literal-block">
tos/platforms/telosa/chips/s1087/HamamatsuS1087ParC.nc
+// HIL for the HamamatsuS1087 analog photodiode sensor
generic configuration HamamatsuS1087ParC() {
provides interface Read<uint16_t>;
provides interface ReadStream<uint16_t>;
provides interface DeviceMetadata;
}
implementation {
+ // Create a new A/D client and connect it to the Hamamatsu S1087 A/D
+ // parameters
components new AdcReadClientC();
Read = AdcReadClientC;
#include "Msp430Adc12.h"
+// A/D parameters for the Hamamatsu - see the MSP430 A/D converter manual,
+// Hamamatsu specification, Telos hardware schematic and TinyOS MSP430
+// A/D converter component specifications for the explanation of these
+// parameters
module HamamatsuS1087ParP {
provides interface AdcConfigure<const msp430adc12_channel_config_t*>;
provides interface DeviceMetadata;
}
implementation {
-
msp430adc12_channel_config_t config = {
inch: INPUT_CHANNEL_A4,
sref: REFERENCE_VREFplus_AVss,
<pre class="literal-block">
tos/platforms/telosa/UserButtonC.nc
+// HIL for the user button sensor on Telos-family motes
configuration UserButtonC {
- provides interface Get<bool>;
- provides interface Notify<bool>;
+ provides interface Get<bool>; // Get button status
+ provides interface Notify<bool>; // Get button-press notifications
provides interface DeviceMetadata;
}
implementation {
+ // Simply connect the button logic to the button HPL
components UserButtonLogicP;
Get = UserButtonLogicP;
Notify = UserButtonLogicP;
<pre class="literal-block">
tos/platforms/telosa/UserButtonLogicP.nc
+// Transform the low-level (GeneralIO and GpioInterrupt) interface to the
+// button to high-level SID interfaces
module UserButtonLogicP {
provides interface Get<bool>;
provides interface Notify<bool>;
provides interface DeviceMetadata;
uses interface GeneralIO;
- uses interface GpioInterrupt;
+ uses interface GpioInterrupt;
}
implementation {
norace bool m_pinHigh;
command error_t Notify.enable() {
call GeneralIO.makeInput();
+ // If the pin is high, we need to trigger on falling edge interrupt, and
+ // vice-versa
if ( call GeneralIO.get() ) {
m_pinHigh = TRUE;
return call GpioInterrupt.enableFallingEdge();
return call GpioInterrupt.disable();
}
+ // Button changed, signal user (in a task) and update interrupt detection
async event void GpioInterrupt.fired() {
call GpioInterrupt.disable();
task void sendEvent() {
bool pinHigh;
pinHigh = m_pinHigh;
-
+
signal Notify.notify( pinHigh );
-
+
if ( pinHigh ) {
call GpioInterrupt.enableFallingEdge();
} else {
<pre class="literal-block">
tos/platforms/telosa/HplUserButtonC.nc
+// HPL for the user button sensor on Telos-family motes - just provides
+// access to the I/O and interrupt control for the pin to which the
+// button is connected
configuration HplUserButtonC {
provides interface GeneralIO;
provides interface GpioInterrupt;
<pre class="literal-block">
tos/platforms/telosa/chips/sht11/SensirionSht11C.nc
-generic configuration SensirionSht11C() {
+// HIL interface to Sensirion SHT11 temperature and humidity sensor
+generic configuration SensirionSht11C() {
provides interface Read<uint16_t> as Temperature;
provides interface DeviceMetadata as TemperatureDeviceMetadata;
provides interface Read<uint16_t> as Humidity;
provides interface DeviceMetadata as HumidityDeviceMetadata;
}
implementation {
+ // Instantiate the module providing the HIL interfaces
components new SensirionSht11ReaderP();
Temperature = SensirionSht11ReaderP.Temperature;
Humidity = SensirionSht11ReaderP.Humidity;
HumidityDeviceMetadata = SensirionSht11ReaderP.HumidityDeviceMetadata;
+ // And connect it to the HAL component for the Sensirion SHT11
components HalSensirionSht11C;
enum { TEMP_KEY = unique("Sht11.Resource") };
<pre class="literal-block">
tos/chips/sht11/SensirionSht11ReaderP.nc
+// Convert Sensirion SHT11 HAL to HIL interfaces for a single
+// client, performing automatic resource arbitration
generic module SensirionSht11ReaderP() {
provides interface Read<uint16_t> as Temperature;
provides interface DeviceMetadata as TemperatureDeviceMetadata;
provides interface Read<uint16_t> as Humidity;
provides interface DeviceMetadata as HumidityDeviceMetadata;
-
+
+ // Using separate resource interfaces for temperature and humidity allows
+ // temperature and humidity measurements to be requested simultaneously
+ // (if a single Resource interface was used, a request for temperature would
+ // prevent any humidity requests until the temperature measurement was complete)
uses interface Resource as TempResource;
uses interface Resource as HumResource;
uses interface SensirionSht11 as Sht11Temp;
}
implementation {
command error_t Temperature.read() {
- call TempResource.request();
- return SUCCESS;
+ // Start by requesting access to the SHT11
+ return call TempResource.request();
}
event void TempResource.granted() {
error_t result;
+ // If the HAL measurement fails, release the SHT11 and signal failure
if ((result = call Sht11Temp.measureTemperature()) != SUCCESS) {
call TempResource.release();
signal Temperature.readDone( result, 0 );
}
event void Sht11Temp.measureTemperatureDone( error_t result, uint16_t val ) {
+ // Release the SHT11 and signal the result
call TempResource.release();
signal Temperature.readDone( result, val );
}
command uint8_t TemperatureDeviceMetadata.getSignificantBits() { return 14; }
command error_t Humidity.read() {
- call HumResource.request();
- return SUCCESS;
+ // Start by requesting access to the SHT11
+ return call HumResource.request();
}
event void HumResource.granted() {
error_t result;
+ // If the HAL measurement fails, release the SHT11 and signal failure
if ((result = call Sht11Hum.measureHumidity()) != SUCCESS) {
call HumResource.release();
signal Humidity.readDone( result, 0 );
}
event void Sht11Hum.measureHumidityDone( error_t result, uint16_t val ) {
+ // Release the SHT11 and signal the result
call HumResource.release();
signal Humidity.readDone( result, val );
}
command uint8_t HumidityDeviceMetadata.getSignificantBits() { return 12; }
+ // Dummy handlers for unused portions of the HAL interface
event void Sht11Temp.resetDone( error_t result ) { }
event void Sht11Temp.measureHumidityDone( error_t result, uint16_t val ) { }
event void Sht11Temp.readStatusRegDone( error_t result, uint8_t val ) { }
event void Sht11Hum.readStatusRegDone( error_t result, uint8_t val ) { }
event void Sht11Hum.writeStatusRegDone( error_t result ) { }
+ // We need default handlers as a client may wire to only the Temperature
+ // sensor or only the Humidity sensor
default event void Temperature.readDone( error_t result, uint16_t val ) { }
default event void Humidity.readDone( error_t result, uint16_t val ) { }
}
<pre class="literal-block">
tos/platforms/telosa/chips/sht11/HalSensirionSht11C.nc
+// HAL interface to Sensirion SHT11 temperature and humidity sensor
configuration HalSensirionSht11C {
+ // The SHT11 HAL uses resource arbitration to allow the sensor to shared
+ // between multiple clients and for automatic power management (the SHT11
+ // is switched off when no clients are waiting to use it)
provides interface Resource[ uint8_t client ];
provides interface SensirionSht11[ uint8_t client ];
}
implementation {
+ // The HAL implementation logic
components new SensirionSht11LogicP();
SensirionSht11 = SensirionSht11LogicP;
+ // And it's wiring to the SHT11 HPL - the actual resource management is
+ // provided at the HPL layer
components HplSensirionSht11C;
Resource = HplSensirionSht11C.Resource;
SensirionSht11LogicP.DATA -> HplSensirionSht11C.DATA;
SensirionSht11LogicP.CLOCK -> HplSensirionSht11C.SCK;
SensirionSht11LogicP.InterruptDATA -> HplSensirionSht11C.InterruptDATA;
-
+
components new TimerMilliC();
SensirionSht11LogicP.Timer -> TimerMilliC;
<pre class="literal-block">
tos/platforms/telosa/chips/sht11/HplSensirionSht11C.nc
+// Low-level, platform-specific glue-code to access the SHT11 sensor found
+// on telos-family motes - here the HPL just provides resource management
+// and access to the SHT11 data, clock and interrupt pins
configuration HplSensirionSht11C {
provides interface Resource[ uint8_t id ];
provides interface GeneralIO as DATA;
provides interface GpioInterrupt as InterruptDATA;
}
implementation {
+ // Pins used to access the SHT11
components HplMsp430GeneralIOC;
-
+
components new Msp430GpioC() as DATAM;
DATAM -> HplMsp430GeneralIOC.Port15;
DATA = DATAM;
components new Msp430GpioC() as PWRM;
PWRM -> HplMsp430GeneralIOC.Port17;
+ // HPL logic for switching the SHT11 on and off
components HplSensirionSht11P;
HplSensirionSht11P.PWR -> PWRM;
HplSensirionSht11P.DATA -> DATAM;
InterruptDATAC.HplInterrupt -> HplMsp430InterruptC.Port15;
InterruptDATA = InterruptDATAC.Interrupt;
+ // The arbiter and power manager for the SHT11
components new FcfsArbiterC( "Sht11.Resource" ) as Arbiter;
Resource = Arbiter;
-
+
components new SplitControlPowerManagerC();
SplitControlPowerManagerC.SplitControl -> HplSensirionSht11P;
SplitControlPowerManagerC.ArbiterInit -> Arbiter.Init;
SplitControlPowerManagerC.ArbiterInfo -> Arbiter.ArbiterInfo;
- SplitControlPowerManagerC.ResourceController -> Arbiter.ResourceController;
+ SplitControlPowerManagerC.ResourceDefaultOwner -> Arbiter.ResourceDefaultOwner;
}
</pre>
<pre class="literal-block">
tos/platforms/telosa/chips/sht11/HplSensirionSht11P.nc
+// Switch the SHT11 on and off, and handle the 11ms warmup delay
module HplSensirionSht11P {
+ // The SplitControl interface powers the SHT11 on or off (it's automatically
+ // called by the SHT11 power manager, see HplSensirionSht11C)
+ // We use a SplitControl interface as we need to wait 11ms for the sensor to
+ // warm up
provides interface SplitControl;
uses interface Timer<TMilli>;
uses interface GeneralIO as PWR;
task void stopTask();
command error_t SplitControl.start() {
+ // Power SHT11 on and wait for 11ms
call PWR.makeOutput();
call PWR.set();
call Timer.startOneShot( 11 );
return SUCCESS;
}
-
+
event void Timer.fired() {
signal SplitControl.startDone( SUCCESS );
}
command error_t SplitControl.stop() {
+ // Power the SHT11 off
call SCK.makeInput();
call SCK.clr();
call DATA.makeInput();
}
</pre>
</div>
+<div class="section">
+<h2><a id="mda100-sensor-board-directory-organization" name="mda100-sensor-board-directory-organization">4. MDA100 Sensor Board Directory Organization</a></h2>
+<p>Here we show the organization of the sensor board directory for the
+mica-family Xbow MDA100CA and MDA100CB sensor boards, which have
+temperature and light sensors. It is found in
+<tt class="docutils literal"><span class="pre">tos/sensorboards/mda100</span></tt>:</p>
+<pre class="literal-block">
+./tos/sensorboards/mda100:
+.sensor # Compiler configuration
+ArbitratedPhotoDeviceP.nc # Light sensor support component
+ArbitratedTempDeviceP.nc # Temperature sensor support component
+DemoSensorC.nc # Override TinyOS's default sensor
+PhotoC.nc # Light sensor HIL
+PhotoImplP.nc # Light sensor support component
+PhotoTempConfigC.nc # Shared support component
+PhotoTempConfigP.nc # Shared support component
+SharedAnalogDeviceC.nc # Shared support component
+SharedAnalogDeviceP.nc # Shared support component
+TempC.nc # Temperature Sensor HIL
+ca/TempImplP.nc # Temperature sensor support component
+ # (MDA100CA board)
+cb/TempImplP.nc # Temperature sensor support component
+ # (MDA100CB board)
+mda100.h # Header file for mda100
+</pre>
+<p>This sensor board provides only a HIL (PhotoC and TempC components), and overrides the
+TinyOS demo sensor (DemoSensorC). The demo sensor is an alias for PhotoC.</p>
+<p>The two forms of the mda100 differ only by the wiring of the
+temperature sensor. The user has to specify which form of the sensor
+board is in use by providing a <tt class="docutils literal"><span class="pre">-I%T/sensorboards/mda100/ca</span></tt> or
+<tt class="docutils literal"><span class="pre">-I%T/sensorboards/mda100/cb</span></tt> compiler option.</p>
+<p>This sensor board relies on a platform-provided <tt class="docutils literal"><span class="pre">MicaBusC</span></tt> component
+that specifies how the mica-family sensor board bus is connected to
+the microcontroller.</p>
+</div>
</div>
</div>
</body>