]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Full update.
authorscipio <scipio>
Tue, 7 Nov 2006 00:43:43 +0000 (00:43 +0000)
committerscipio <scipio>
Tue, 7 Nov 2006 00:43:43 +0000 (00:43 +0000)
39 files changed:
doc/html/install-tinyos.html
doc/html/overview.html
doc/html/tep1.html
doc/html/tep101.html
doc/html/tep102.html
doc/html/tep103.html
doc/html/tep106.html
doc/html/tep107.html
doc/html/tep108.html
doc/html/tep109.html
doc/html/tep110.html
doc/html/tep111.html
doc/html/tep112.html
doc/html/tep113.html
doc/html/tep114.html
doc/html/tep115.html
doc/html/tep116.html
doc/html/tep117.html
doc/html/tep118.html
doc/html/tep119.html
doc/html/tep120.html
doc/html/tep123.html
doc/html/tep3.html
doc/html/upgrade-tinyos.html
doc/index.html
doc/stylesheets/tinyos.css
doc/txt/overview.txt
doc/txt/tep1.txt
doc/txt/tep101.txt
doc/txt/tep102.txt
doc/txt/tep103.txt
doc/txt/tep109.txt
doc/txt/tep111.txt
doc/txt/tep113.txt
doc/txt/tep115.txt
doc/txt/tep117.txt
doc/txt/tep119.txt
doc/txt/tep120.txt
doc/txt/tep123.txt

index 312a198200707c6736c5d73d17903bc30ef5bc8c..f75cded63e5aa3ddb3427252d33f80a1a1c5195c 100644 (file)
-\r
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">\r
-<html>\r
-<head>\r
-  <title>Installing TinyOS 2.0</title>\r
-  <link href="../stylesheets/tutorial.css" rel="stylesheet" type="text/css">\r
-</head>\r
-<body>\r
-\r
-<div class="title">Installing TinyOS 2.0</div>\r
-<div class="subtitle">Last updated 12 June 2006</div>\r
-\r
-<p>If you already have a 1.x tree, you are better off following the <i>upgrade</i> \r
-instructions at <a href="upgrade-tinyos.html">upgrade-tinyos.html</a>.\r
-\r
-<p>Currently, the TinyOS Core Working Group supports TinyOS on two platforms: Cygwin (Windows)\r
-and Linux. There have been some <A HREF="">successful efforts</A> to getting TinyOS environments working\r
-on Mac OSX, but OSX is not supported by the Core WG.</p>\r
-\r
-<p>Installing a TinyOS enviromnent has four basic steps; Windows requires an extra step,\r
-installing Cygwin, which is a UNIX-like environment. The steps are:</p>\r
-\r
-<ol>\r
-  <li><b>Installing a Java 1.5 (Java 5) JDK.</b> Java is the most common way of interacting\r
-  with mote base stations or gateways that are plugged into a PC or laptop.</li>\r
-  <li><b><font color=red>Windows only.</font> Install Cygwin.</b> This gives you a shell\r
-  and many UNIX tools which the TinyOS environment uses, such as perl and shell\r
-  scripts.</li>\r
-  <li><b>Installing native compilers.</b> As you're compiling code for low-power\r
-  microcontrollers, you need compilers that can generate the proper assembly code.\r
-  If you using mica-family motes, you need the AVR toolchain; if you're using\r
-  telos-family motes, you need the MSP430 toolchain.</li>\r
-  <li><b>Installing the nesC compiler.</b> TinyOS is written in nesC, a dialect\r
-  of C with support for the TinyOS concurrency model and component-based\r
-  programming. The nesC compiler is platform-independent: it passes its output\r
-  to the native compilers, so that it can take advantage of all of the effort\r
-  put into their optimizations.</li>\r
-  <li><b>Installing the TinyOS source tree.</b> If you want to compile and\r
-  install TinyOS programs, you need the code.</li>\r
-  <li><b>Installing the Graphviz visualization tool.</b> The TinyOS\r
-  environment includes <tt>nesdoc</tt>, a tool that automatically\r
-  generates HTML documentation from source code. Part of this process\r
-  involves drawing diagrams that show the relationships between\r
-  different TinyOS components. <A HREF="http://www.graphviz.org">Graphviz</A>\r
-  is an open source tool\r
-  that nesdoc uses to draw the diagrams.</li>\r
-</ol>\r
-\r
-<h1>Step 1: Install Java 1.5 JDK</h1>\r
-\r
-<b>Windows</b><br>\r
-Download and install Sun's 1.5 JDK from <a href="http://java.sun.com">http://java.sun.com</a>.\r
-\r
-<p>\r
-<b>Linux</b><br>\r
-Download and install IBM's 1.5 JDK from <a href="http://www-128.ibm.com/developerworks/java/jdk/">http://www-128.ibm.com/developerworks/java/jdk/</a>.\r
-\r
-<h1>Step 2: Install Cygwin</h1>\r
-\r
-<font color=red> This step is required for Windows installations only. If you are installing\r
-on Linux, skip to step 3.</font>\r
-\r
-<p>We have put online the cygwin packages that we've confirmed to be\r
-compatible with TinyOS. The instructions below use those packages. You\r
-can also upgrade your cygwin environment according to the instructions\r
-at www.cygwin.com and your environment will most likely work. A large\r
-number of TinyOS users, upgrade their cygwin packages at least monthly\r
-from cygnus. However, since we can't test what packages are compatible\r
-as they become available daily, we can't confirm that today's set will\r
-work.\r
-\r
-<p>\r
-<ol>\r
-<li> Download the confirmed-compatible cygwin packages from the tinyos web site <a href="http://www.tinyos.net/dist-1.2.0/tools/windows/cygwin-1.2a.tgz">here</a>.\r
-<p>\r
-<li> In a cygwin shell, unzip the above package into some directory. In these instructions the directory is /cygdrive/c/newcygpkgs.\r
-<pre>\r
-     $ cd /cygdrive/c/newcygpkgs\r
-     $ tar zxvf cygwin-1.2a.tgz \r
-</pre>\r
-This unzips the packages.\r
-<p>\r
-<li> In Windows Explorer, navigate to /cygdrive/c/newcygpkgs and click on the file setup.exe. Setup.exe is the setup program distributed by Cygnus Solutions.\r
-<p>\r
-<li> Follow these steps when the Cygwin Setup windows appears:\r
-<ol>\r
-</ol>\r
-<li> Opt to disable the virus scanner (it will be enabled when you're finished).\r
-<p>\r
-<li> Opt to Install from Local Directory.\r
-<p>\r
-<li> Specify the Root directory to be where your <i>current</i> cygwin installation is. This would be the directory that directories like 'opt' and 'usr' are in. For example, mine is rooted at c:\tinyos\cygwin, so I enter that.  \r
-<p>\r
-<li> Select to Install for All Users\r
-<p>\r
-<li> Select the Unix file type (very important!)\r
-<p>\r
-<li> For the Local Packages Directory, specify where you unzipped the cygwin packages tarfile. For example, I would specify c:\newcygpkgs. (The setup.exe program will probably select the right default directory.)\r
-<p>\r
-<li> The next window will allow you to select packages to install. You should see that most of the packages have an X-ed box next to them; these are the packages that are to be installed. \r
-<p>\r
-<li> Click install. Some notes: \r
-<ul>\r
-<li> You might see a message explaining that you need to reboot because some files are in use. This most likely means that your cygwin DLL is loaded and in-use and, therefore, cannot be replaced. When you reboot, the new DLL will be loaded. \r
-<li> Related to the above warnings, if you see warnings about the cygwin1.dll not being found, don't worry. All will be well once you reboot and the right DLL is loaded. \r
-</ul>\r
-</ol>\r
-</ol>\r
-\r
-<h1>Step 3: Install native compilers </h1>\r
-\r
-Install the appropriate version of the following (Windows or Linux,\r
-avr or msp430 or both) with the rpm command 'rpm -ivh <rpm>'. \r
-On\r
-windows, if you get an error claiming that the rpm was build for an NT\r
-computer and you're on a windows NT computer, bypass the erroneous\r
-error by using 'rpm -ivh --ignoreos <i>rpmname</i>'.\r
-(We have xscale\r
-compiler tools online at \r
-<a href="http://www.tinyos.net/dist-1.2.0/tools/">http://www.tinyos.net/dist-1.2.0/tools/</a>\r
-but they have not yet been extensively tested by a large community.)\r
-\r
-<!----- AVR external tools -------->\r
-</p><p><b><em>Atmel AVR Tools</em></b>\r
-<table border="0">\r
-<tbody><tr>\r
-  <td bgcolor="#dddddd"><b>Tool</b></td>\r
-  <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>\r
-  <td bgcolor="#dddddd"><b>Linux</b></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>avr-binutils<font color="red">&#8224;</font></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avr-binutils-2.15tinyos-3.cygwin.i386.rpm">avr-binutils-2.15tinyos-3.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-binutils-2.15tinyos-3.i386.rpm">avr-binutils-2.15tinyos-3.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td bgcolor="#dddddd">avr-gcc</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avr-gcc-3.4.3-1.cygwin.i386.rpm">avr-gcc-3.4.3-1.cygwin.i386.rpm </a></td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-gcc-3.4.3-1.i386.rpm">avr-gcc-3.4.3-1.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>avr-libc</td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avr-libc-1.2.3-1.cygwin.i386.rpm">avr-libc-1.2.3-1.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-libc-1.2.3-1.i386.rpm">avr-libc-1.2.3-1.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td bgcolor="#dddddd">avarice</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avarice-2.4-1.cygwin.i386.rpm">avarice-2.4-1.cygwin.i386.rpm</a></td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avarice-2.4-1.i386.rpm">avarice-2.4-1.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>insight (avr-gdb)</td>\r
-  <td><a href="http://www.tinyos.net/dist-1.2.0/tools/windows/avr-insight-6.3-1.cygwin.i386.rpm">avr-insight-6.3-1.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-insight-6.3-1.i386.rpm">avr-insight-6.3-1.i386.rpm</a></td>\r
-</tr>\r
-\r
-</tbody></table>\r
-<i><font color="red">&#8224;</font>If you receive an rpm error that indicates that you have a newer version already installed, try <code>rpm -Uvh --force</code></i>\r
-\r
-<!----- MSP external tools -------->\r
-</p><p><b><em>TI MSP430 Tools</em></b>\r
-<table border="0">\r
-<tbody><tr>\r
-  <td bgcolor="#dddddd"><b>Tool</b></td>\r
-  <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>\r
-  <td bgcolor="#dddddd"><b>Linux</b></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>base</td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-base-0.1-20050607.cygwin.i386.rpm">msp430tools-base-0.1-20050607.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-base-0.1-20050607.i386.rpm">msp430tools-base-0.1-20050607.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td bgcolor="#dddddd">python tools</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-python-tools-1.0-1.cygwin.noarch.rpm">msp430tools-python-tools-1.0-1.cygwin.noarch.rpm</a></td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-python-tools-1.0-1.noarch.rpm">msp430tools-python-tools-1.0-1.noarch.rpm</a></td>\r
-</tr>\r
-\r
-\r
-<tr>\r
-  <td>binutils</td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-binutils-2.16-20050607.cygwin.i386.rpm"> msp430tools-binutils-2.16-20050607.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-binutils-2.16-20050607.i386.rpm">msp430tools-binutils-2.16-20050607.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td bgcolor="#dddddd">gcc</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-gcc-3.2.3-20050607.cygwin.i386.rpm">msp430tools-gcc-3.2.3-20050607.cygwin.i386.rpm</a></td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-gcc-3.2.3-20050607.i386.rpm">msp430tools-gcc-3.2.3-20050607.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>libc</td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-libc-20050308cvs-20050608.cygwin.i386.rpm">msp430tools-libc-20050308cvs-20050608.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-libc-20050308cvs-20050608.i386.rpm">msp430tools-libc-20050308cvs-20050608.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td bgcolor="#dddddd">jtag</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/"></a>Not yet available</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-jtag-lib-20031101cvs-20050610.i386.rpm">msp430tools-jtag-lib-20031101cvs-20050610.i386.rpm</a></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>gdb</td>\r
-<!--  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-gdb-6.0-20050609.cygwin.i386.rpm">msp430tools-gdb-6.0-20050609.cygwin.i386.rpm</a></td> -->\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/"></a>Not yet available</td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-gdb-6.0-20050609.i386.rpm">msp430tools-gdb-6.0-20050609.i386.rpm</a></td>\r
-</tr>\r
-\r
-</tbody></table>\r
-\r
-<h1>Step 4: Install TinyOS toolchain</h1>\r
-\r
-The TinyOS-specific tools are the NesC compiler and a set of tools\r
-developed in the tinyos-2.x/tools source code repository. They are\r
-also installed using rpms. If you using the Cygwin version recommended\r
-in these install\r
-instructions, you should install the "Recommended" Windows/Cygwin\r
-nesC RPM (1.2.7b). If you install it and it does not work (e.g., you\r
-get strange errors when you try to execute it), this may be due\r
-to a Cygwin version incompatibility: try the "Other" Windows/Cygwin \r
-RPM (1.2.7a). \r
-\r
-<!----- tinyos-2.x/tinyos rpms  -------->\r
-</p><p><b><em>TinyOS-specific Tools</em></b>\r
-<table border="0">\r
-<tbody><tr>\r
-  <td bgcolor="#dddddd"><b>Tool</b></td>\r
-  <td bgcolor="#dddddd"><b>Recommended Windows/Cygwin</b></td>\r
-  <td bgcolor="#dddddd"><b>Other Windows/Cygwin</b></td>\r
-  <td bgcolor="#dddddd"><b>Linux</b></td>\r
-  <td bgcolor="#dddddd"><b>Command</b></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>NesC</td>\r
-  <td><a href="http://csl.stanford.edu/~pal/tinyos/nesc-1.2.7b-1.cygwin.i386.rpm">nesc-1.2.7b-1.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/windows/nesc-1.2.7a-1.cygwin.i386.rpm">nesc-1.2.7a-1.cygwin.i386.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/linux/nesc-1.2.7a-1.i386.rpm">nesc-1.2.7a-1.i386.rpm </a></td>\r
-  <td><a href=""></a><code>rpm -Uvh</code></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td bgcolor="#dddddd">tinyos-tools</td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.2-1.cygwin.i386.rpm">tinyos-tools-1.2.2-1.cygwin.i386.rpm</a></td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.2-1.cygwin.i386.rpm">tinyos-tools-1.2.2-1.cygwin.i386.rpm</a></td>\r
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-tools-1.2.2-1.i386.rpm">tinyos-tools-1.2.2-1.i386.rpm</a></td>\r
-  <td bgcolor="#dddddd"><a href=""></a><code>rpm -ivh --force</code>&nbsp;(1.x tree)<br><code>rpm -Uvh</code>&nbsp;(no 1.x tree)<br></td>\r
-</tr>\r
-\r
-</tbody></table>\r
-\r
-<h1>Step 5: Install the TinyOS 2.x source tree </h1>\r
-\r
-Now that the tools are installed, you need only install the tinyos 2.x \r
-source tree and then set your environment variables.\r
-Install the appropriate version of the following (Window or Linux)\r
-with the rpm command 'rpm -ivh <rpm>'. \r
-As with the previous rpms, if you get an error claiming that the rpm\r
-was build for an NT computer and you're on a windows NT computer,\r
-bypass the erroneous error by using 'rpm -ivh --ignoreos\r
-<i>rpmname</i>'.\r
-\r
-<ul>\r
-<li> Install tinyos-2.x\r
-<p>\r
-<!----- TinyOS  -------->\r
-\r
-\r
-</p><p><b><em>TinyOS 2.x</em></b>\r
-<table border="0">\r
-<tbody><tr>\r
-  <td bgcolor="#dddddd"><b></b></td>\r
-  <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>\r
-  <td bgcolor="#dddddd"><b>Linux</b></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>TinyOS</td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0beta2-3.cygwin.noarch.rpm">tinyos-2.0.0beta2-3.cygwin.noarch.rpm</a></td>\r
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0beta2-3.noarch.rpm">tinyos-2.0.0beta2-3.noarch.rpm</a></td>\r
-</tr>\r
-\r
-</tbody></table>\r
-</p></li><li> Configure your environment\r
-<p>\r
-Ideally, you'll put these environment variables in a shell script that will run when your shell starts, but you needn't \r
-put such a script under /etc/profile.d. \r
-</p><p>\r
-The example\r
-settings below assume that the tinyos-2.x installation is in /opt/tinyos-2.x.\r
-Change the settings to be correct for where you've put your tinyos-2.x tree. Note\r
-that the windows CLASSPATH must be a windows-style path, not a cygwin path. You can \r
-generate a windows style path from a cygwin-style path using 'cygpath -w'. For example:\r
-</p><pre>export CLASSPATH=`cygpath -w $TOSROOT/support/sdk/java/tinyos.jar`\r
-export CLASSPATH="$CLASSPATH;."\r
-</pre>\r
-\r
-<p><b><em>TinyOS 2.x</em></b>\r
-<table border="0">\r
-<tbody><tr>\r
-  <td bgcolor="#dddddd"><b>Environment Variable</b></td>\r
-  <td bgcolor="#dddddd"><b>Windows</b></td>\r
-  <td bgcolor="#dddddd"><b>Linux</b></td>\r
-</tr>\r
-\r
-<tr>\r
-  <td>TOSROOT</td>\r
-  <td>/opt/tinyos-2.x</td>\r
-  <td>same as in Cygwin</td>\r
-<td>\r
-\r
-</td></tr><tr>\r
-  <td bgcolor="#dddddd">TOSDIR</td>\r
-  <td bgcolor="#dddddd">$TOSROOT/tos</td>\r
-  <td bgcolor="#dddddd">same as in Cygwin</td>\r
-<td>\r
-\r
-</td></tr><tr>\r
-  <td>CLASSPATH</td>\r
-  <td>C:\tinyos\cygwin\opt\tinyos-2.x\support\sdk\java\tinyos.jar;.</td>\r
-  <td>$TOSROOT/support/sdk/java/tinyos.jar:.</td>\r
-<td>\r
-\r
-</td></tr><tr>\r
-  <td bgcolor="#dddddd">MAKERULES</td>\r
-  <td bgcolor="#dddddd">$TOSROOT/support/make/Makerules</td>\r
-  <td bgcolor="#dddddd">same as in Cygwin</td>\r
-<td>\r
-\r
-</td></tr><tr>\r
-  <td>PATH<font color="red">&#8224;</font></td>\r
-  <td>/opt/msp430/bin:$PATH</td>\r
-  <td>same as in Cygwin</td>\r
-<td>\r
-\r
-</td></tr></tbody></table>\r
-\r
-<i><font color="red">&#8224;</font>Only necessary if you're using the MSP430 platform/tools.</i>\r
-\r
-</p><p>\r
-In addition to the above environment variables, do the following on Linux machines:\r
-</p><ol>\r
-<li> Change the ownership on your /opt/tinyos-2.x files: <code>chown -R&nbsp;&lt;your uid&gt;&nbsp;/opt/tinyos-2.x\r
-</code></li><li> Change the permissions on any serial (/dev/ttyS&lt;N&gt;), usb\r
-(/dev/tts/usb&lt;N&gt;, /dev/ttyUSB&lt;N&gt;), or parallel (/dev/parport) devices you\r
-are going to use: <code>chmod 666 /dev/&lt;devicename&gt;<code>\r
-<!-- \r
-<li> Add any users who will be using TinyOS to the uucp, lp, and lock \r
-groups: </li>\r
--->\r
-</code></code></li></ol>\r
-\r
-</li></ul>\r
-\r
-<h1>Step 6: Installing Graphviz</h1>\r
-\r
-<p>Go to <A HREF="http://www.graphviz.org/Download..php">download page</A> of the Graphviz project\r
-and download the appropriate RPM. You only need the basic graphviz RPM (<tt>graphviz-</tt>);\r
-you don't need all of the add-ons, such as -devel, -doc, -perl, etc.\r
-If you're not sure what version of Linux you're running,</p>\r
-\r
-<pre>uname -a</pre>\r
-\r
-<p>might give you some useful information. Install the rpm with <tt>rpm -i </tt> <i>rpm-name</i>.\r
-In the case of Windows, there is a simple install program, so you don't need to deal with RPMs.</p>\r
-\r
-</body>\r
-</html>\r
+
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+  <title>Installing TinyOS 2.0</title>
+  <link href="../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<div class="title">Installing TinyOS 2.0</div>
+<div class="subtitle">Last updated 5 November 2006</div>
+
+<p>If you already have a 1.x tree or an existing 2.x tree, you are better off 
+following the <i>upgrade</i> instructions at 
+<a href="upgrade-tinyos.html">upgrade-tinyos.html</a>.</p>
+
+<p>Currently, the TinyOS Core Working Group supports TinyOS on two platforms: Cygwin (Windows)
+and Linux. There have been some <A HREF="">successful efforts</A> to getting TinyOS environments working
+on Mac OSX, but OSX is not supported by the Core WG.</p>
+
+<p>Installing a TinyOS enviromnent has five basic steps; Windows requires an extra step,
+installing Cygwin, which is a UNIX-like environment. The steps are:</p>
+
+<ol>
+  <li><b>Installing a Java 1.5 (Java 5) JDK.</b> Java is the most common way of interacting
+  with mote base stations or gateways that are plugged into a PC or laptop.</li>
+  <li><b><font color=red>Windows only.</font> Install Cygwin.</b> This gives you a shell
+  and many UNIX tools which the TinyOS environment uses, such as perl and shell
+  scripts.</li>
+  <li><b>Installing native compilers.</b> As you're compiling code for low-power
+  microcontrollers, you need compilers that can generate the proper assembly code.
+  If you using mica-family motes, you need the AVR toolchain; if you're using
+  telos-family motes, you need the MSP430 toolchain.</li>
+  <li><b>Installing the nesC compiler.</b> TinyOS is written in nesC, a dialect
+  of C with support for the TinyOS concurrency model and component-based
+  programming. The nesC compiler is platform-independent: it passes its output
+  to the native compilers, so that it can take advantage of all of the effort
+  put into their optimizations.</li>
+  <li><b>Installing the TinyOS source tree.</b> If you want to compile and
+  install TinyOS programs, you need the code.</li>
+  <li><b>Installing the Graphviz visualization tool.</b> The TinyOS
+  environment includes <tt>nesdoc</tt>, a tool that automatically
+  generates HTML documentation from source code. Part of this process
+  involves drawing diagrams that show the relationships between
+  different TinyOS components. <A HREF="http://www.graphviz.org">Graphviz</A>
+  is an open source tool
+  that nesdoc uses to draw the diagrams.</li>
+</ol>
+
+<h1>Step 1: Install Java 1.5 JDK</h1>
+
+<b>Windows</b><br>
+Download and install Sun's 1.5 JDK from <a href="http://java.sun.com">http://java.sun.com</a>.
+
+<p>
+<b>Linux</b><br>
+Download and install IBM's 1.5 JDK from <a href="http://www-128.ibm.com/developerworks/java/jdk/">http://www-128.ibm.com/developerworks/java/jdk/</a>.
+
+<h1>Step 2: Install Cygwin</h1>
+
+<font color=red> This step is required for Windows installations only. If you are installing
+on Linux, skip to step 3.</font>
+
+<p>We have put online the cygwin packages that we've confirmed to be
+compatible with TinyOS. The instructions below use those packages. You
+can also upgrade your cygwin environment according to the instructions
+at www.cygwin.com and your environment will most likely work. A large
+number of TinyOS users, upgrade their cygwin packages at least monthly
+from cygnus. However, since we can't test what packages are compatible
+as they become available daily, we can't confirm that today's set will
+work.
+
+<p>
+<ol>
+<li> Download the confirmed-compatible cygwin packages from the tinyos web site <a href="http://www.tinyos.net/dist-1.2.0/tools/windows/cygwin-1.2a.tgz">here</a>.
+<p>
+<li> In a cygwin shell, unzip the above package into some directory. In these instructions the directory is /cygdrive/c/newcygpkgs.
+<pre>
+     $ cd /cygdrive/c/newcygpkgs
+     $ tar zxvf cygwin-1.2a.tgz 
+</pre>
+This unzips the packages.
+<p>
+<li> In Windows Explorer, navigate to /cygdrive/c/newcygpkgs and click on the file setup.exe. Setup.exe is the setup program distributed by Cygnus Solutions.
+<p>
+<li> Follow these steps when the Cygwin Setup windows appears:
+<ol>
+</ol>
+<li> Opt to disable the virus scanner (it will be enabled when you're finished).
+<p>
+<li> Opt to Install from Local Directory.
+<p>
+<li> Specify the Root directory to be where your <i>current</i> cygwin installation is. This would be the directory that directories like 'opt' and 'usr' are in. For example, mine is rooted at c:\tinyos\cygwin, so I enter that.  
+<p>
+<li> Select to Install for All Users
+<p>
+<li> Select the Unix file type (very important!)
+<p>
+<li> For the Local Packages Directory, specify where you unzipped the cygwin packages tarfile. For example, I would specify c:\newcygpkgs. (The setup.exe program will probably select the right default directory.)
+<p>
+<li> The next window will allow you to select packages to install. You should see that most of the packages have an X-ed box next to them; these are the packages that are to be installed. 
+<p>
+<li> Click install. Some notes: 
+<ul>
+<li> You might see a message explaining that you need to reboot because some files are in use. This most likely means that your cygwin DLL is loaded and in-use and, therefore, cannot be replaced. When you reboot, the new DLL will be loaded. 
+<li> Related to the above warnings, if you see warnings about the cygwin1.dll not being found, don't worry. All will be well once you reboot and the right DLL is loaded. 
+</ul>
+</ol>
+</ol>
+
+<h1>Step 3: Install native compilers </h1>
+
+Install the appropriate version of the following (Windows or Linux,
+avr or msp430 or both) with the rpm command 'rpm -ivh <rpm>'. 
+On
+windows, if you get an error claiming that the rpm was build for an NT
+computer and you're on a windows NT computer, bypass the erroneous
+error by using 'rpm -ivh --ignoreos <i>rpmname</i>'.
+(We have xscale
+compiler tools online at 
+<a href="http://www.tinyos.net/dist-1.2.0/tools/">http://www.tinyos.net/dist-1.2.0/tools/</a>
+but they have not yet been extensively tested by a large community.)
+
+<!----- AVR external tools -------->
+</p><p><b><em>Atmel AVR Tools</em></b>
+<table border="0">
+<tbody><tr>
+  <td bgcolor="#dddddd"><b>Tool</b></td>
+  <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>
+  <td bgcolor="#dddddd"><b>Linux</b></td>
+</tr>
+
+<tr>
+  <td>avr-binutils<font color="red">&#8224;</font></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avr-binutils-2.15tinyos-3.cygwin.i386.rpm">avr-binutils-2.15tinyos-3.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-binutils-2.15tinyos-3.i386.rpm">avr-binutils-2.15tinyos-3.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td bgcolor="#dddddd">avr-gcc</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avr-gcc-3.4.3-1.cygwin.i386.rpm">avr-gcc-3.4.3-1.cygwin.i386.rpm </a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-gcc-3.4.3-1.i386.rpm">avr-gcc-3.4.3-1.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td>avr-libc</td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avr-libc-1.2.3-1.cygwin.i386.rpm">avr-libc-1.2.3-1.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-libc-1.2.3-1.i386.rpm">avr-libc-1.2.3-1.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td bgcolor="#dddddd">avarice</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/avarice-2.4-1.cygwin.i386.rpm">avarice-2.4-1.cygwin.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avarice-2.4-1.i386.rpm">avarice-2.4-1.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td>insight (avr-gdb)</td>
+  <td><a href="http://www.tinyos.net/dist-1.2.0/tools/windows/avr-insight-6.3-1.cygwin.i386.rpm">avr-insight-6.3-1.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/avr-insight-6.3-1.i386.rpm">avr-insight-6.3-1.i386.rpm</a></td>
+</tr>
+
+</tbody></table>
+<i><font color="red">&#8224;</font>If you receive an rpm error that indicates that you have a newer version already installed, try <code>rpm -Uvh --force</code></i>
+
+<!----- MSP external tools -------->
+</p><p><b><em>TI MSP430 Tools</em></b>
+<table border="0">
+<tbody><tr>
+  <td bgcolor="#dddddd"><b>Tool</b></td>
+  <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>
+  <td bgcolor="#dddddd"><b>Linux</b></td>
+</tr>
+
+<tr>
+  <td>base</td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-base-0.1-20050607.cygwin.i386.rpm">msp430tools-base-0.1-20050607.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-base-0.1-20050607.i386.rpm">msp430tools-base-0.1-20050607.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td bgcolor="#dddddd">python tools</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-python-tools-1.0-1.cygwin.noarch.rpm">msp430tools-python-tools-1.0-1.cygwin.noarch.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-python-tools-1.0-1.noarch.rpm">msp430tools-python-tools-1.0-1.noarch.rpm</a></td>
+</tr>
+
+
+<tr>
+  <td>binutils</td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-binutils-2.16-20050607.cygwin.i386.rpm"> msp430tools-binutils-2.16-20050607.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-binutils-2.16-20050607.i386.rpm">msp430tools-binutils-2.16-20050607.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td bgcolor="#dddddd">gcc</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-gcc-3.2.3-20050607.cygwin.i386.rpm">msp430tools-gcc-3.2.3-20050607.cygwin.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-gcc-3.2.3-20050607.i386.rpm">msp430tools-gcc-3.2.3-20050607.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td>libc</td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-libc-20050308cvs-20050608.cygwin.i386.rpm">msp430tools-libc-20050308cvs-20050608.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-libc-20050308cvs-20050608.i386.rpm">msp430tools-libc-20050308cvs-20050608.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td bgcolor="#dddddd">jtag</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/"></a>Not yet available</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-jtag-lib-20031101cvs-20050610.i386.rpm">msp430tools-jtag-lib-20031101cvs-20050610.i386.rpm</a></td>
+</tr>
+
+<tr>
+  <td>gdb</td>
+<!--  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/msp430tools-gdb-6.0-20050609.cygwin.i386.rpm">msp430tools-gdb-6.0-20050609.cygwin.i386.rpm</a></td> -->
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/windows/"></a>Not yet available</td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tools/linux/msp430tools-gdb-6.0-20050609.i386.rpm">msp430tools-gdb-6.0-20050609.i386.rpm</a></td>
+</tr>
+
+</tbody></table>
+
+<h1>Step 4: Install TinyOS toolchain</h1>
+
+The TinyOS-specific tools are the NesC compiler and a set of tools
+developed in the tinyos-2.x/tools source code repository. They are
+also installed using rpms. If you using the Cygwin version recommended
+in these install
+instructions, you should install the "Recommended" Windows/Cygwin
+nesC RPM. 
+Try installing it and if it does not work (e.g., you
+get strange errors when you try to execute it), this may be due
+to a Cygwin version incompatibility: try the "Other" Windows/Cygwin 
+RPM (1.2.7a). If you are using Cygwin and installing the nesC RPM
+causes an error that the RPM was built for Cygwin,
+add the <code>--ignoreos</code> option.
+
+<!----- tinyos-2.x/tinyos rpms  -------->
+</p><p><b><em>TinyOS-specific Tools</em></b>
+<table border="0">
+<tbody><tr>
+  <td bgcolor="#dddddd"><b>Tool</b></td>
+  <td bgcolor="#dddddd"><b>Recommended Windows/Cygwin</b></td>
+  <td bgcolor="#dddddd"><b>Other Windows/Cygwin</b></td>
+  <td bgcolor="#dddddd"><b>Linux</b></td>
+  <td bgcolor="#dddddd"><b>Command</b></td>
+</tr>
+
+<tr>
+  <td>NesC</td>
+  <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/windows/nesc-1.2.7b-1.cygwin.i386.rpm">nesc-1.2.7b-1.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/windows/nesc-1.2.7a-1.cygwin.i386.rpm">nesc-1.2.7a-1.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/linux/nesc-1.2.7a-1.i386.rpm">nesc-1.2.7a-1.i386.rpm </a></td>
+  <td><a href=""></a><code>rpm -Uvh</code><br>
+                     <code>rpm -Uvh --ignoreos</code> (if Cygwin complains)</td>
+</tr>
+
+<tr>
+  <td bgcolor="#dddddd">tinyos-tools</td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.3-1.cygwin.i386.rpm">tinyos-tools-1.2.3-1.cygwin.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.3-1.cygwin.i386.rpm">tinyos-tools-1.2.3-1.cygwin.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-tools-1.2.3-1.i386.rpm">tinyos-tools-1.2.3-1.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href=""></a><code>rpm -ivh --force</code>&nbsp;(1.x tree)<br><code>rpm -Uvh</code>&nbsp;(no 1.x tree)<br></td>
+</tr>
+
+</tbody></table>
+
+<h1>Step 5: Install the TinyOS 2.x source tree </h1>
+
+Now that the tools are installed, you need only install the tinyos 2.x 
+source tree and then set your environment variables.
+Install the appropriate version of the following (Window or Linux)
+with the rpm command 'rpm -ivh <rpm>'. 
+As with the previous rpms, if you get an error claiming that the rpm
+was build for an NT computer and you're on a windows NT computer,
+bypass the erroneous error by using 'rpm -ivh --ignoreos
+<i>rpmname</i>'.
+
+<ul>
+<li> Install tinyos-2.x
+<p>
+<!----- TinyOS  -------->
+
+
+</p><p><b><em>TinyOS 2.x</em></b>
+<table border="0">
+<tbody><tr>
+  <td bgcolor="#dddddd"><b></b></td>
+  <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>
+  <td bgcolor="#dddddd"><b>Linux</b></td>
+</tr>
+
+<tr>
+  <td>TinyOS</td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0-1.cygwin.noarch.rpm">tinyos-2.0.0-1.cygwin.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0-1.noarch.rpm">tinyos-2.0.0-1.noarch.rpm</a></td>
+</tr>
+
+</tbody></table>
+</p></li><li> Configure your environment
+<p>
+Ideally, you'll put these environment variables in a shell script that will run when your shell starts, but you needn't 
+put such a script under /etc/profile.d. 
+</p><p>
+The example
+settings below assume that the tinyos-2.x installation is in /opt/tinyos-2.x.
+Change the settings to be correct for where you've put your tinyos-2.x tree. Note
+that the windows CLASSPATH must be a windows-style path, not a cygwin path. You can 
+generate a windows style path from a cygwin-style path using 'cygpath -w'. For example:
+</p><pre>export CLASSPATH=`cygpath -w $TOSROOT/support/sdk/java/tinyos.jar`
+export CLASSPATH="$CLASSPATH;."
+</pre>
+
+<p><b><em>TinyOS 2.x</em></b>
+<table border="0">
+<tbody><tr>
+  <td bgcolor="#dddddd"><b>Environment Variable</b></td>
+  <td bgcolor="#dddddd"><b>Windows</b></td>
+  <td bgcolor="#dddddd"><b>Linux</b></td>
+</tr>
+
+<tr>
+  <td>TOSROOT</td>
+  <td>/opt/tinyos-2.x</td>
+  <td>same as in Cygwin</td>
+<td>
+
+</td></tr><tr>
+  <td bgcolor="#dddddd">TOSDIR</td>
+  <td bgcolor="#dddddd">$TOSROOT/tos</td>
+  <td bgcolor="#dddddd">same as in Cygwin</td>
+<td>
+
+</td></tr><tr>
+  <td>CLASSPATH</td>
+  <td>C:\tinyos\cygwin\opt\tinyos-2.x\support\sdk\java\tinyos.jar;.</td>
+  <td>$TOSROOT/support/sdk/java/tinyos.jar:.</td>
+<td>
+
+</td></tr><tr>
+  <td bgcolor="#dddddd">MAKERULES</td>
+  <td bgcolor="#dddddd">$TOSROOT/support/make/Makerules</td>
+  <td bgcolor="#dddddd">same as in Cygwin</td>
+<td>
+
+</td></tr><tr>
+  <td>PATH<font color="red">&#8224;</font></td>
+  <td>/opt/msp430/bin:$PATH</td>
+  <td>same as in Cygwin</td>
+<td>
+
+</td></tr></tbody></table>
+
+<i><font color="red">&#8224;</font>Only necessary if you're using the MSP430 platform/tools.</i>
+
+</p><p>
+In addition to the above environment variables, do the following on Linux machines:
+</p><ol>
+<li> Change the ownership on your /opt/tinyos-2.x files: <code>chown -R&nbsp;&lt;your uid&gt;&nbsp;/opt/tinyos-2.x
+</code></li><li> Change the permissions on any serial (/dev/ttyS&lt;N&gt;), usb
+(/dev/tts/usb&lt;N&gt;, /dev/ttyUSB&lt;N&gt;), or parallel (/dev/parport) devices you
+are going to use: <code>chmod 666 /dev/&lt;devicename&gt;<code>
+<!-- 
+<li> Add any users who will be using TinyOS to the uucp, lp, and lock 
+groups: </li>
+-->
+</code></code></li></ol>
+
+</li></ul>
+
+<h1>Step 6: Installing Graphviz</h1>
+
+<p>Go to <A HREF="http://www.graphviz.org/Download..php">download page</A> of the Graphviz project
+and download the appropriate RPM. You only need the basic graphviz RPM (<tt>graphviz-</tt>);
+you don't need all of the add-ons, such as -devel, -doc, -perl, etc.
+If you're not sure what version of Linux you're running,</p>
+
+<pre>uname -a</pre>
+
+<p>might give you some useful information. Install the rpm with <tt>rpm -i </tt> <i>rpm-name</i>.
+In the case of Windows, there is a simple install program, so you don't need to deal with RPMs.</p>
+
+</body>
+</html>
index a929d36e29a92ccc3ffaf46ed9253c8fc8a86f07..5f54280518372912b0a4444f1f3868e3b92a311a 100644 (file)
@@ -6,7 +6,7 @@
 <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
 <title>TinyOS 2.0 Overview</title>
 <meta name="author" content="Philip Levis" />
-<meta name="date" content="Feb 8 2006" />
+<meta name="date" content="Oct 30 2006" />
 <style type="text/css">
 
 /*
@@ -292,7 +292,7 @@ ul.auto-toc {
 <tr><th class="docinfo-name">Author:</th>
 <td>Philip Levis</td></tr>
 <tr><th class="docinfo-name">Date:</th>
-<td>Feb 8 2006</td></tr>
+<td>Oct 30 2006</td></tr>
 </tbody>
 </table>
 <div class="note">
@@ -361,7 +361,7 @@ use and safely compile on multiple platforms. For example, the HIL
 component of the CC1000 on the mica2 is <tt class="docutils literal"><span class="pre">ActiveMessageC</span></tt>, representing
 a full active message communication layer.</p>
 <p>The HAA is described in TEP 2: Hardware Abstraction Architecture[<a class="reference" href="#tep2">TEP2</a>].</p>
-<p>Currently (as of the 2.0 beta2 release in July 2006), TinyOS 2.0 supports
+<p>Currently (as of the 2.0 release in November 2006), TinyOS 2.0 supports
 the following platforms:</p>
 <blockquote>
 <ul class="simple">
@@ -375,7 +375,7 @@ the following platforms:</p>
 <li>btnode3</li>
 </ul>
 </blockquote>
-<p>The btnode3 platform is not included in the beta2 RPM.</p>
+<p>The btnode3 platform is not included in the RPM.</p>
 </div>
 <div class="section">
 <h1><a id="scheduler" name="scheduler">3. Scheduler</a></h1>
@@ -505,7 +505,10 @@ protocol and component that sends packets is trying to send a packet,
 each one will receive its fair share of transmission opportunities.</p>
 <p>Further information on message_t can be found in TEP 111:
 message_t[<a class="reference" href="#tep111">TEP111</a>], while further information on AM can be
-found in TEP 116: Packet Protocoks[<a class="reference" href="#tep116">TEP116</a>].</p>
+found in TEP 116: Packet Protocols[<a class="reference" href="#tep116">TEP116</a>].</p>
+<p>The current TinyOS release has a low-power stack for the CC1000
+radio (mica2 platform) and an experimental low-power stack for
+the CC2420 radio (micaz, telosb, and intelmote2 platforms).</p>
 </div>
 <div class="section">
 <h1><a id="sensors" name="sensors">8. Sensors</a></h1>
@@ -579,6 +582,16 @@ and interrupt souces are active. The latter, discussed in
 TEP 115: Power Management of Non-Virtualised Devices{<a class="reference" href="#tep115">TEP115</a>], is handled
 through resource abiters. Fully virtualized services have their
 own, individual power management policies.</p>
+<p>TinyOS 2.0 provides low-power stacks for the CC1000 (mica2)
+and CC2420 (micaz, telosb, imote2) radios. Both use a low-power
+listening apporach, where transmitters send long preambles or
+repeatedly send packets and receivers wake up periodically to
+sense the channel to hear if there is a packet being
+transmitted. The low-power stack CC1000 is standard, while
+the CC2420 stack is experimental. That is, the default CC1000
+stack (chips/cc1000) has low-power-listening, while the default
+CC2420 stack (chips/cc2420) does not. To use the low-power CC2420
+stack, you must include chips/cc2420_lpl in your application Makefile.</p>
 </div>
 <div class="section">
 <h1><a id="network-protocols" name="network-protocols">12. Network Protocols</a></h1>
@@ -588,10 +601,13 @@ and collection. Dissemination reliably delivers small (fewer
 than 20 byte) data items to every node in a network, while
 collection builds a routing tree rooted at a sink node. Together,
 these two protocols enable a wide range of data collection
-applications.</p>
+applications. Collection has advanced significantly since the
+most recent beta release; experimental tests in multiple
+network conditions have seen very high (&gt;98%) deliver rates
+as long as the network is not saturated.</p>
 </div>
 <div class="section">
-<h1><a id="conclusion" name="conclusion">12. Conclusion</a></h1>
+<h1><a id="conclusion" name="conclusion">13. Conclusion</a></h1>
 <p>TinyOS 2.0 represents the next step of TinyOS development. Building on
 user experiences over the past few years, it has taken the basic
 TinyOS architecture and pushed it forward in several directions,
@@ -601,7 +617,7 @@ non-volatile storage, basic multihop protocols (collection routing,
 dissemination), and further power management abstractions.</p>
 </div>
 <div class="section">
-<h1><a id="acknowledgments" name="acknowledgments">13. Acknowledgments</a></h1>
+<h1><a id="acknowledgments" name="acknowledgments">14. Acknowledgments</a></h1>
 <p>TinyOS 2.0 is the result of a lot of hard work from a lot of people,
 including (but not limited to) David Gay, Philip Levis, Cory Sharp,
 Vlado Handziski, Jan Hauer, Kevin Klues, Joe Polastre, Jonathan Hui,
@@ -609,10 +625,10 @@ Prabal Dutta,
 Gilman Tolle, Martin Turon, Phil Buonodonna, Ben Greenstein, David Culler,
 Kristin Wright, Ion Yannopoulos, Henri Dubois-Ferriere, Jan Beutel,
 Robert Szewczyk, Rodrigo Fonseca, Kyle Jamieson, Omprakash Gnawali,
-and Kristin Wright.</p>
+David Moss, and Kristin Wright.</p>
 </div>
 <div class="section">
-<h1><a id="author-s-address" name="author-s-address">14. Author's Address</a></h1>
+<h1><a id="author-s-address" name="author-s-address">15. Author's Address</a></h1>
 <div class="line-block">
 <div class="line">Philip Levis</div>
 <div class="line">358 Gates</div>
@@ -626,7 +642,7 @@ and Kristin Wright.</p>
 </div>
 </div>
 <div class="section">
-<h1><a id="citations" name="citations">15. Citations</a></h1>
+<h1><a id="citations" name="citations">16. Citations</a></h1>
 <table class="docutils citation" frame="void" id="tep1" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
index b517558810c74fbcc935b818fe42c92fda9646c1..4222ee201f3c046deb66ce4d564c124fb0ff20d5 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">18-Oct-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.5</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-19</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -434,18 +434,37 @@ become part of it.  Unlike Documentary TEPs, Experimental TEPs may
 describe systems that do not have a reference implementation.</p>
 <p>The fourth field is &quot;Status,&quot; which specifies the status of the TEP.
 A TEP status can either be &quot;Draft,&quot; which means it is a work in
-progress, &quot;Final,&quot; which means it is complete and will not change, or
-&quot;Obsolete,&quot; which means it should no longer be considered. If a TEP is
-&quot;Obsolete&quot; because it has been replaced by another TEP, then the new
-TEP number should follow &quot;Obsolete,&quot; such as &quot;Obsolete by TEP 1231.&quot;</p>
+progress, &quot;Final,&quot; which means it is complete and will not change.
+Once a TEP has the status &quot;Final,&quot; its body MUST NOT change.
+The values of its header fields MUST NOT change. The header of a
+Final TEP MAY have an &quot;Obsoleted By&quot; field added.</p>
+<p>The &quot;Obsoletes&quot; field is a backward pointer to an earlier TEP which
+the current TEP renders obsolete. An Obsoletes field MAY have multiple
+TEPs listed.  For example, if TEP 191 were to replace TEPs 111 and 116, it
+would have the field &quot;Obsoletes: 111, 116&quot;.</p>
+<p>The &quot;Obsoleted By&quot; field is added to a Final TEP when another TEP has
+rendered it obsolete. The field contains the number of the obsoleting
+TEP. For example, if TEP 111 were obsoleted by TEP 191, it would have
+the field &quot;Obsoleted By: 191&quot;.</p>
+<p>&quot;Obsoletes&quot; and &quot;Obsoleted By&quot; fields MUST agree. For a TEP to list another
+TEP in its Obsoletes field, then that TEP MUST list it in the Obsoleted By
+field.</p>
+<p>The obsoletion fields are used to keep track of evolutions and modifications
+of a single abstraction. They are not intended to force a single approach or
+mechanism over alternative possibilities.</p>
 <p>If a TEP is Best Current Practices or Documentary, then it MUST
 include an additional field, &quot;TinyOS-Version:,&quot; which states what
 version(s) of TinyOS the document pertains to. This document pertains
 to all versions of TinyOS, until made obsolete by a future TEP. This
 field MUST appear after the Status field and before the Author field.</p>
-<p>The final required field is Author, which states the names of the
+<p>The final required field is &quot;Author,&quot; which states the names of the
 authors of the document. Full contact information should not be listed
 here (see Section 3.2).</p>
+<p>There is an optional field, &quot;Extends.&quot; The &quot;Extends&quot; field refers to
+another TEP. The purpose of this field is to denote when a TEP represents
+an addition to an existing TEP. Meeting the requirements of a TEP with an
+Extends field requires also meeting the requirements of all TEPs listed
+in the Extends field.</p>
 <p>If a TEP is a Draft, then four additional fields MUST be included:
 Draft-Created, Draft-Modified, Draft-Version, and Draft-Discuss.
 Draft-Created states the date the document was created, Draft-Modified
index 69a56fb450e22365983bdf42217e061d5f8d2a05..85ff3e7ce5b3b4a389d41b69bbc8bbd7b575a982 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Jan-Hinrich Hauer, Philip Levis, Vlado Handziski, David Gay</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">20-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.3</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.9</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-08</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-12</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -320,11 +320,10 @@ of this memo is unlimited. This memo is in full compliance with
 </div>
 <div class="section">
 <h1><a id="abstract" name="abstract">Abstract</a></h1>
-<p>This TEP proposes a hardware abstraction for TinyOS 2.x analog-to-digital
-converters (ADCs). It focuses on aligning the ADC abstraction with the
-three-layer Hardware Abstraction Architecture (HAA) described in <a class="citation-reference" href="#tep2" id="id2" name="id2">[TEP2]</a>, but
-addresses only the HPL and HAL, because the highest level abstraction of an
-ADC is platform-dependent.</p>
+<p>This TEP proposes a hardware abstraction for analog-to-digital converters (ADCs)
+in TinyOS 2.x, which is aligned to the three-layer Hardware Abstraction
+Architecture (HAA) specified in [TEP2]. It describes some design principles and
+documents the set of hardware-independent interfaces to an ADC.</p>
 </div>
 <div class="section">
 <h1><a id="introduction" name="introduction">1. Introduction</a></h1>
@@ -336,14 +335,14 @@ TinyOS, the distinction between a sensor and an ADC were blurred: this led
 components that had nothing to do with an ADC to still resemble one
 programatically, even though the semantics and forms of operation were
 completely different.  To compensate for the difference non-ADC sensors
-introduced additional interfaces, such as ADCError, that were tightly bound to
-sensor acquisition but separate in wiring. The separation between the ADC and
-ADCError interface is bug prone and problematic, as is the equation of a
+introduced additional interfaces, such as <tt class="docutils literal"><span class="pre">ADCError</span></tt>, that were tightly bound
+to sensor acquisition but separate in wiring. The separation between the ADC and
+<tt class="docutils literal"><span class="pre">ADCError</span></tt> interface is bug prone and problematic, as is the equation of a
 sensor and an ADC. TinyOS 2.x separates the structure and interfaces of an ADC
 from those of sensors (which may be on top of an ADC, but this fact is hidden
-from higher level components). This TEP presents how TinyOS 2.x decomposes and
-structures ADC software. TEP 109 (Sensor Boards) shows how a platform can
-present actual named sensors <a class="citation-reference" href="#tep109" id="id3" name="id3">[TEP109]</a>.</p>
+from higher level components). This TEP presents how TinyOS 2.x structures ADC
+software. TEP 109 (Sensor Boards) shows how a platform can present actual named
+sensors <a class="citation-reference" href="#tep109" id="id2" name="id2">[TEP109]</a>.</p>
 <p>As can be seen in Appendix A the ADC hardware used on TinyOS platforms differ
 in many respects, which makes it difficult to find a chip independent
 representation for an ADC. Even if there were such a representation, the
@@ -351,263 +350,340 @@ configuration details of an ADC would still depend on the actual device
 producing the input signal (sensor).  Neither a platform independent
 application nor the ADC hardware stack itself has access to this information,
 as it can only be determined on a platform or sensorboard level. For example,
-determining which ADC port a sensor is attached to and how a conversion result
-is to be interpreted is a platform-specific determination.</p>
+determining which ADC port a sensor is attached to and how conversion results
+need to be interpreted is a platform specific determination. Although the
+actual configuration details may be different the procedure of configuring an
+ADC can be unified on all ADCs with the help of <strong>hardware independent
+interfaces</strong>: in a similar way as the <tt class="docutils literal"><span class="pre">Read</span></tt> interface definition does not
+predefine the type or semantics of the exchanged data (see <a class="citation-reference" href="#tep114" id="id3" name="id3">[TEP114]</a>), a
+configuration interface definition can abstract from the data type and
+semantics of the involved configuration settings.  For example, like a
+component can provide a <tt class="docutils literal"><span class="pre">Read&lt;uint8_t&gt;</span></tt> or <tt class="docutils literal"><span class="pre">Read&lt;uint16_t&gt;</span></tt> interface
+depending on the data it can offer, a component can also use a
+<tt class="docutils literal"><span class="pre">AdcConfigure&lt;atm128_adc_config_t&gt;</span></tt> or
+<tt class="docutils literal"><span class="pre">AdcConfigure&lt;msp430adc12_channel_config_t&gt;</span></tt> interface depending on what ADC
+it represents.  This TEP proposes the (typed) <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface as the
+standard interface for configuring an ADC in TinyOS 2.x.</p>
 <p>In spite of their hardware differences, one aspect represents a common
-denominator of all ADCs: they produce conversion results. In order to
-facilitate sensor software development this capability can be made available
-via chip-independent interfaces for every ADC. However, conversion results
-depend on and have to be interpreted with respect to the platform-specific
-configuration settings (the ADC channel, the applied reference voltage, etc.).
-Therefore the highest level of ADC abstraction consists of
-platform-independent interfaces for ADC data collection and chip-specific
-interfaces for ADC hardware configuration.  The top layer of the ADC stack
-thus remains platform-dependent and consequently the ADC abstraction does not
-include an HIL, but ends with the HAL. Following the principles of the
-HAA <a class="citation-reference" href="#tep2" id="id4" name="id4">[TEP2]</a> the HAL of an ADC should also expose the chip-specific capabilities
-for ADC data collection. For example, the ADC12 on the MSP430 MCU supports a
-complex repeat conversion mode for a set of different input channels, which is
-too specific to be represented by a platform-independent data collection
-interface.  Therefore the HAL of an ADC abstraction is broken into two
-sublayers: The bottom HAL layer, called HAL1, exposes the full capabilities of
-the respective ADC in a chip-specific way. It realizes the standard HAL in the
-HAA <a class="citation-reference" href="#tep2" id="id5" name="id5">[TEP2]</a> and the HPL lies below it.  On top of the HAL1 sits the HAL2 which
-maps the interfaces it uses from HAL1 to a set of platform-independent
-interfaces for data collection and chip-specific configuration interfaces.</p>
+denominator of all ADCs: they produce conversion results. To facilitate sensor
+software development conversion results are returned by the ADC hardware stack
+using the standard TinyOS interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt>
+(see <a class="reference" href="#interfaces">2. Interfaces</a> and <a class="citation-reference" href="#tep114" id="id4" name="id4">[TEP114]</a>). Conversion results are returned as
+uninterpreted values and translating them to engineering units can only be done
+with the configuration knowledge of the respective platform, for example, the
+reference voltage or the resistance of a reference resistor in ratiometric
+measurements.  Translating uninterpreted values to engineering units is
+performed by components located on top of the ADC hardware stack and out of the
+scope of this TEP.</p>
+<p>The top layer of abstraction of an ADC - the Hardware Interface Layer (HIL) -
+thus provides the standard TinyOS interfaces <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and
+<tt class="docutils literal"><span class="pre">ReadStream</span></tt> and uses the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for hardware
+configuration (why it <strong>uses</strong> and does not <strong>provide</strong> <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> is
+explained below).  Since the type and semantics of the parameters passed
+through these interfaces is dependent on the actual ADC implementation, it is
+only a &quot;weak&quot; HIL (see <a class="citation-reference" href="#tep2" id="id5" name="id5">[TEP2]</a>).</p>
+<p>Following the principles of the HAA <a class="citation-reference" href="#tep2" id="id6" name="id6">[TEP2]</a> the Hardware Adaptation Layer (HAL,
+which resides below the HIL) of an ADC should expose all the chip-specific
+capabilities of the chip.  For example, the ADC12 on the MSP430 MCU supports a
+&quot;Repeat-Sequence-of-Channels Mode&quot; and therefore this function should be
+accessible on the HAL of the <strong>MSP430 ADC12</strong> hardware abstraction.  Other ADCs
+might not exhibit such functionality and might therefore - on the level of HAL
+- provide only an interface to perform single conversions. Since all ADCs have
+the same HIL representation it may thus be necessary to perform some degree of
+software emulation in the HIL implementation.  For example, a <tt class="docutils literal"><span class="pre">ReadStream</span></tt>
+command can be emulated by multiple single conversion commands. Below the HAL
+resides the Hardware Presentation Layer (HPL), a stateless component that
+provides access to the hardware registers (see <a class="citation-reference" href="#tep2" id="id7" name="id7">[TEP2]</a>). The general structure
+(without virtualization) of the ADC hardware stack is as follows</p>
+<pre class="literal-block">
+       ^                     |
+       |                     |
+       |                   Read,
+ AdcConfigure              ReadNow (+ Resource),
+       |                   ReadStream
+       |                     |
+       |                     V
+ +----------------------------------+
+ |  Hardware Interface Layer (HIL)  |
+ |  (chip-specific implementation)  |
+ +----------------------------------+
+                  |
+                  |
+   chip-specific interface(s) + Resource
+(e.g. Msp430Adc12SingleChannel + Resource)
+                  |
+                  V
+ +----------------------------------+
+ |  Hardware Adaptation Layer (HAL) |
+ |  (chip-specific implementation)  |
+ +----------------------------------+
+                  |
+                  |
+        chip-specific interface(s)
+            (e.g. HplAdc12)
+                  |
+                  V
+ +----------------------------------+
+ | Hardware Presentation Layer (HPL)|
+ | (chip-specific implementation)   |
+ +----------------------------------+
+</pre>
 <p>The rest of this TEP specifies:</p>
 <ul class="simple">
-<li>the set of platform-independent interfaces for the collection of ADC
-conversion results (<a class="reference" href="#interfaces">2. Interfaces</a>)</li>
-<li>guidelines on how an ADC's HAL should be split into HAL1 and HAL2 and
-how the HAL1 should expose chip-specific interfaces (<a class="reference" href="#hal1-guidelines">3. HAL1 guidelines</a>)</li>
-<li>what components an ADC's HAL2 MUST implement (<a class="reference" href="#hal2-requirements">4. HAL2 requirements</a>)</li>
-<li>guidelines on how the HAL2 may be structured (<a class="reference" href="#hal2-implementation-guidelines">5. HAL2 implementation guidelines</a>)</li>
-<li>a section pointing to the current implementation (<a class="reference" href="#implementation">6. Implementation</a>)</li>
+<li>the set of standard TinyOS interfaces for collecting ADC conversion
+results and for configuring an ADC (<a class="reference" href="#interfaces">2. Interfaces</a>)</li>
+<li>guidelines on how an ADC's HAL should expose chip-specific
+interfaces (<a class="reference" href="#hal-guidelines">3. HAL guidelines</a>)</li>
+<li>what components an ADC's HIL MUST implement (<a class="reference" href="#hil-requirements">4. HIL requirements</a>)</li>
+<li>guidelines on how the HIL should be implemented
+(<a class="reference" href="#hil-guidelines">5. HIL guidelines</a>)</li>
+<li>a section pointing to current implementations (<a class="reference" href="#implementation">6. Implementation</a>)</li>
 </ul>
-<p>This TEP ends with appendices documenting, as an example, the ADC
-implementation for the TI MSP430 MCU.</p>
+<p>This TEP ends with appendices documenting, as an example, the ADC implementation
+for the TI MSP430 MCU.</p>
 </div>
 <div class="section">
 <h1><a id="interfaces" name="interfaces">2. Interfaces</a></h1>
-<p>This TEP proposes to adopt the following three generic, source-independent
-data collection interfaces from <a class="citation-reference" href="#tep114" id="id6" name="id6">[TEP114]</a> for the collection of ADC conversion
-results:</p>
+<p>This TEP proposes the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface for ADC hardware configuration
+and the <tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> and <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interfaces to acquire
+conversion results. A <tt class="docutils literal"><span class="pre">Read[Now|Stream]</span></tt> interface is always provided in
+conjunction with a <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
+<div class="section">
+<h2><a id="interface-for-configuring-the-adc-hardware" name="interface-for-configuring-the-adc-hardware">Interface for configuring the ADC hardware</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is defined as follows:</p>
+<pre class="literal-block">
+interface AdcConfigure&lt; config_type &gt;
+{
+  async command config_type getConfiguration();
+}
+</pre>
+<p>This interface is used by the ADC implementation to retrieve the hardware
+configuration of an ADC client. <tt class="docutils literal"><span class="pre">config_type</span></tt> is a chip-specific data type
+(simple or structured) that contains all information necessary to configure the
+respective ADC hardware. For example, on the ADC12 of the MSP430 the
+<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface will be instantiated with the <tt class="docutils literal"><span class="pre">const</span>
+<span class="pre">msp430adc12_channel_config_t*</span></tt> data type. A client MUST always return the same
+configuration through a <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface and, if configuration data
+is passed as a pointer, the HIL component (see <a class="reference" href="#hil-requirements">4. HIL requirements</a>) MUST NOT
+reference it after the return of the <tt class="docutils literal"><span class="pre">getConfiguration()</span></tt> command. If a
+client wants to use the ADC with different configurations it must provide
+multiple instances of the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface.</p>
+</div>
+<div class="section">
+<h2><a id="interfaces-for-acquiring-conversion-results" name="interfaces-for-acquiring-conversion-results">Interfaces for acquiring conversion results</a></h2>
+<p>This TEP proposes to adopt the following three generic, source-independent data
+collection interfaces from <a class="citation-reference" href="#tep114" id="id8" name="id8">[TEP114]</a> for the collection of ADC conversion
+results on the level of HIL:</p>
 <pre class="literal-block">
 interface Read&lt; size_type &gt;
 interface ReadNow&lt; size_type &gt;
 interface ReadStream&lt; size_type &gt;
 </pre>
-<p>Every data collection interface is associated with certain chip-specific
-configuration data (e.g. input channel, sample-hold-time, etc.).  How this
-association can be realized is explained in Section <a class="reference" href="#hal2-requirements">4.  HAL2 requirements</a>.
-As the resolution of conversion results is chip-specific, the 'size_type'
-parameter reflects an upper bound for the chip-specific resolution of the
-conversion results - the actual resolution may be smaller, depending on the
-ADC and/or data source (e.g.  uint16_t for a 12-bit ADC). The above interfaces
-are specified in <a class="citation-reference" href="#tep114" id="id7" name="id7">[TEP114]</a>, in the following their usage is explained with
-respect to ADCs.</p>
+<p>Every data collection interface is associated with an <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt>
+interface (how this association is realized is explained in Section <a class="reference" href="#hil-requirements">4.  HIL
+requirements</a>).  As the resolution of conversion results is chip-specific, the
+<tt class="docutils literal"><span class="pre">size_type</span></tt> parameter reflects an upper bound for the chip-specific
+resolution of the conversion results - the actual resolution may be smaller
+(e.g.  uint16_t for a 12-bit ADC). The above interfaces are specified in
+<a class="citation-reference" href="#tep114" id="id9" name="id9">[TEP114]</a>, in the following their usage is explained with respect to ADCs.</p>
 <div class="section">
-<h2><a id="read" name="read">Read</a></h2>
-<p>The Read interface can be used to sample an ADC channel and return a single
-conversion result. It provides no guarantees about when exactly the sampling
-occurs (the request may be buffered).</p>
+<h3><a id="read" name="read">Read</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">Read</span></tt> interface can be used to sample an ADC channel and return a single
+conversion result as an uninterpreted value. The meaning of the <tt class="docutils literal"><span class="pre">Read</span></tt>
+interface is explained in <a class="citation-reference" href="#tep114" id="id10" name="id10">[TEP114]</a>.</p>
 </div>
 <div class="section">
-<h2><a id="readnow" name="readnow">ReadNow</a></h2>
-<p>The ReadNow interface provides more precise control over the time of the
-sampling: If a call to ReadNow.read() succeeds, the ADC starts to sample the
-channel immediately (the request is not buffered). Due to its timing
-constraints the ReadNow interface is always provided in conjunction with an
-instance of the Resource interface. Refer to <a class="citation-reference" href="#tep108" id="id8" name="id8">[TEP108]</a> on how the 'Resource'
+<h3><a id="readnow" name="readnow">ReadNow</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is similar to the <tt class="docutils literal"><span class="pre">Read</span></tt> interface. The difference
+is that if a call to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> succeeds, the ADC starts to sample the
+channel immediately (precisely: when <tt class="docutils literal"><span class="pre">SUCCESS</span></tt> is returned the hardware has
+started the sampling process). Due to its timing constraints the <tt class="docutils literal"><span class="pre">ReadNow</span></tt>
+interface is always provided in conjunction with an instance of the
+<tt class="docutils literal"><span class="pre">Resource</span></tt> interface (a client must reserve the ADC before the client may
+call <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt>).  Please refer to <a class="citation-reference" href="#tep108" id="id11" name="id11">[TEP108]</a> on how the <tt class="docutils literal"><span class="pre">Resource</span></tt>
 interface should be used by a client component.</p>
 </div>
 <div class="section">
-<h2><a id="readstream" name="readstream">ReadStream</a></h2>
-<p>The ReadStream interface can be used to sample an ADC channel multiple times
-with a specified sampling period. It provides no guarantees about when exactly
-the first sampling occurs, but all subsequent samplings occur with the
-specified sampling period.</p>
+<h3><a id="readstream" name="readstream">ReadStream</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface can be used to sample an ADC channel multiple times
+with a specified sampling period. The meaning of the <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface
+is explained in <a class="citation-reference" href="#tep114" id="id12" name="id12">[TEP114]</a> .</p>
+</div>
 </div>
 </div>
 <div class="section">
-<h1><a id="hal1-guidelines" name="hal1-guidelines">3. HAL1 guidelines</a></h1>
-<p>As explained in <a class="reference" href="#introduction">1. Introduction</a> the HAL of an ADC abstraction consists of
-two sublayers, HAL1 and HAL2. In the ADC component stack the HAL1 resides
-below HAL2 and above the HPL. It exposes the full capabilities of the ADC in a
-chip-specific way and has the same function as the 'traditional' HAL in the
-HAA <a class="citation-reference" href="#tep2" id="id9" name="id9">[TEP2]</a>. Therefore only chip- and platform-dependent clients MAY wire to
-the HAL1. Although the HAL1 is chip-specific, both, in terms of implementation
+<h1><a id="hal-guidelines" name="hal-guidelines">3. HAL guidelines</a></h1>
+<p>As explained in <a class="reference" href="#introduction">1. Introduction</a> the HAL exposes the full capabilities of the
+ADC hardware. Therefore only chip- and platform-dependent clients can wire to
+the HAL. Although the HAL is chip-specific, both, in terms of implementation
 and representation, its design should follow the guidelines described below to
-facilitate the mapping to platform-independent interfaces on the level of
-HAL2. Appendix B shows the HAL1 specification for the TI MSP430 MCU.</p>
+facilitate the mapping to the HIL representation. Appendix B shows the
+signature of the HAL for the MSP430.</p>
 <div class="section">
 <h2><a id="resource-reservation" name="resource-reservation">Resource reservation</a></h2>
-<p>As the ADC hardware is a shared resource that is multiplexed between several
-clients, it requires access arbitration. Therefore the HAL1 configuration
-component should provide a parameterized 'Resource' interface, instantiate a
-generic arbiter component and connect the 'Resource' interface to the arbiter
-as described in <a class="citation-reference" href="#tep108" id="id10" name="id10">[TEP108]</a>. To ensure fair and uniform arbitration on all
-platforms the standard round robin arbiter is recommended. Refer to <a class="citation-reference" href="#tep108" id="id11" name="id11">[TEP108]</a>
-on how the 'Resource' interface is to be used by a client wiring to HAL1.</p>
+<p>As the ADC hardware is a shared resource that is usually multiplexed between
+several clients some form of access arbitration is necessary.  The HAL should
+therefore provide a parameterized <tt class="docutils literal"><span class="pre">Resource</span></tt> interface, instantiate a
+standard arbiter component and connect the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface to the
+arbiter as described in <a class="citation-reference" href="#tep108" id="id13" name="id13">[TEP108]</a>. To ensure fair and uniform arbitration on
+all platforms the standard round robin arbiter is recommended. Resource
+arbiters and the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface are the topic of <a class="citation-reference" href="#tep108" id="id14" name="id14">[TEP108]</a>.</p>
 </div>
 <div class="section">
 <h2><a id="configuration-and-sampling" name="configuration-and-sampling">Configuration and sampling</a></h2>
-<p>As the ADC hardware is a shared resource the HAL1 should support hardware
-configuration and sampling on a per-client basis (although per-port
-configuration is possible, it is not recommended, because it forces all
-clients to use the same settings for a given port). Therefore an HAL1 should
-provide sampling interfaces parameterized by a client identifier. An HAL1
-client can use its instance of the sampling interface to configure the ADC
-hardware, start the sampling process and get conversion results. It wires to a
-sampling interface using a unique client identifier. All commands and events
-in the sampling interface should be 'async' to reflect the potential timing
-requirements of clients. An HAL1 may provide multiple different parameterized
-sampling interfaces, depending on the hardware capabilities.  This allows to
+<p>As the ADC hardware is a shared resource the HAL should support hardware
+configuration and sampling per client (although per-port configuration is
+possible, it is not recommended, because it forces all clients to use the same
+configuration for a given port).  Therefore the HAL should provide sampling
+interfaces parameterized by a client identifier. A HAL client can use its
+instance of the sampling interface to configure the ADC hardware, start the
+sampling process and acquire conversion results. It wires to a sampling
+interface using a unique client identifier (this may be hidden by a
+virtualization component). All commands and events in the sampling interface
+should be 'async' to reflect the potential timing requirements of clients on
+the level of HAL. A HAL may provide multiple different parameterized sampling
+interfaces, depending on the hardware capabilities.  This allows to
 differentiate/group ADC functionality, for example single vs.  repeated
-sampling, single channel vs. multiple channels or low-frequency vs.
+sampling, single channel vs.  multiple channels or low-frequency vs.
 high-frequency sampling.  Every sampling interface should allow the client to
 individually configure the ADC hardware, for example by including the
 configuration data as parameters in the sampling commands.  However, if
-configuration data is passed as a pointer, the HAL1 component MUST NOT
-reference it after the return of the respective command. Appendix B shows the
-HAL1 interfaces for the TI MSP430 MCU.</p>
+configuration data is passed as a pointer, the HAL component MUST NOT reference
+it after the return of the respective command.  Appendix B shows the HAL
+interfaces for the MSP430.</p>
 </div>
 <div class="section">
-<h2><a id="hal1-virtualization" name="hal1-virtualization">HAL1 virtualization</a></h2>
+<h2><a id="hal-virtualization" name="hal-virtualization">HAL virtualization</a></h2>
 <p>In order to hide wiring complexities and/or export only a subset of all ADC
-functions generic ADC wrapper components may be provided on the level of HAL1
-to be instantiated by chip- and platform-dependent clients.</p>
+functions generic ADC wrapper components may be provided on the level of HAL.
+Such components can also be used to ensure that a sampling interface is always
+provided with a <tt class="docutils literal"><span class="pre">Resource</span></tt> interface and both are instantiated with the same
+client ID if this is required by the HAL implementation.</p>
 </div>
 </div>
 <div class="section">
-<h1><a id="hal2-requirements" name="hal2-requirements">4. HAL2 requirements</a></h1>
-<p>The following components MUST be provided on all platforms that have an ADC:</p>
+<h1><a id="hil-requirements" name="hil-requirements">4. HIL requirements</a></h1>
+<p>The following generic components MUST be provided on all platforms that have an
+ADC:</p>
 <pre class="literal-block">
-AdcReadClient
-AdcReadNowClient
-AdcReadStreamClient
+AdcReadClientC
+AdcReadNowClientC
+AdcReadStreamClientC
 </pre>
-<p>These generic components are instantiated and provide access to the ADC  on a
-per-client basis via a platform-independent interface for data collection and
-a chip-specific ADC configuration interface. This section describes the
-representation of the HAL2. Guidelines on how the HAL2 can be implemented are
-discussed in Section <a class="reference" href="#hal2-implementation-guidelines">5. HAL2 implementation guidelines</a>.  Appendix C shows
-the AdcReadClient for the TI MSP430 MCU.</p>
-<p>The fact that the components use chip-specific ADC configuration interfaces
-(see below) and the fact that the provided interfaces for data-collection must
-be interpreted with respect to the configuration data - for example the
-reference voltage - makes the HAL2 representation chip dependent. Therefore
-the ADC abstraction does not include an HIL.</p>
+<p>These components provide virtualized access to the HIL of an ADC. They are
+instantiated by an ADC client and provide/use the four interfaces described in
+Section <a class="reference" href="#interfaces">2.  Interfaces</a>. An ADC client may instantiate multiple such
+components. The following paragraphs describe their signatures. Note that this
+TEP does not address the issue of how to deal with multiple ADCs on the same
+platform (the question of how to deal with multiple devices of the same class
+is a general one in TinyOS 2.x). Appendix C shows the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> for
+the MSP430.</p>
 <div class="section">
-<h2><a id="adcreadclient" name="adcreadclient">AdcReadClient</a></h2>
+<h2><a id="adcreadclientc" name="adcreadclientc">AdcReadClientC</a></h2>
 <pre class="literal-block">
-generic configuration AdcReadClient() {
+generic configuration AdcReadClientC() {
   provides {
     interface Read&lt; size_type &gt;;
   }
   uses {
-    // chip-dependent configuration interface
+    interface AdcConfigure&lt; config_type &gt;;
   }
 }
 </pre>
-<p>The AdcReadClient provides platform-independent access for data collection via
-the 'Read' interface. The actual ADC channel (port) and further configuration
-details are determined by a chip-dependent configuration interface. It is the
-task of the client to wire this interface to a component that provides its ADC
-configuration.  The HAL2 implementation will use this interface to &quot;pull&quot; the
-client's ADC settings when it translates the 'Read.read()' command to a
-chip-specific sampling command. The resolution of the conversion result is
-chip-specific, the 'size_type' parameter represents an upper bound for the
-resolution of the conversion results.</p>
+<p>The <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">Read</span></tt> interface for acquiring
+single conversion results. The associated ADC channel (port) and further
+configuration details are returned by the <tt class="docutils literal"><span class="pre">AdcConfigure.getConfiguration()</span></tt>
+command. It is the task of the client to wire this interface to a component
+that provides the client's ADC configuration. The HIL implementation will use
+the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface to dynamically &quot;pull&quot; the client's ADC settings
+when it translates the <tt class="docutils literal"><span class="pre">Read.read()</span></tt> command to a chip-specific sampling
+command.  Note that both, <tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only
+placeholders and will be instantiated by the respective HIL implementation (for
+an example, see the AdcReadClientC for the MSP430 in Appendix C).</p>
 </div>
 <div class="section">
-<h2><a id="adcreadnowclient" name="adcreadnowclient">AdcReadNowClient</a></h2>
+<h2><a id="adcreadnowclientc" name="adcreadnowclientc">AdcReadNowClientC</a></h2>
 <pre class="literal-block">
-generic configuration AdcReadNowClient() {
+generic configuration AdcReadNowClientC() {
   provides {
     interface Resource;
     interface ReadNow&lt; size_type &gt;;
   }
   uses {
-     // chip-dependent configuration interface
+    interface AdcConfigure&lt; config_type &gt;;
   }
 }
 </pre>
-<p>The AdcReadNowClient provides platform-independent access for data collection
-via the 'ReadNow' and 'Resource' interface. The actual ADC channel (port) and
-further configuration details are determined by a chip-dependent configuration
-interface. It is the task of the client to wire this interface to a component
-that provides its ADC configuration.  The HAL2 implementation will use this
-interface to &quot;pull&quot; the client's ADC settings when it translates the
-'ReadNow.read()' command to a chip-specific sampling command. A client MUST
-use the 'Resource' interface to request access to the ADC as described in
-<a class="citation-reference" href="#tep108" id="id12" name="id12">[TEP108]</a> (the HAL2 implementation SHOULD return the error code 'ERESERVE' if
-the client has not reserved access). The resolution of the conversion result
-is chip-specific, the 'size_type' parameter represents an upper bound for the
-resolution of the conversion result.</p>
+<p>The <tt class="docutils literal"><span class="pre">AdcReadNowClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface for
+acquiring single conversion results. In contrast to <tt class="docutils literal"><span class="pre">Read.read()</span></tt> when a call
+to <tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> succeeds, the ADC starts to sample the channel
+immediately (a successful <tt class="docutils literal"><span class="pre">Read.read()</span></tt> command may not have this
+implication, see <a class="citation-reference" href="#tep114" id="id15" name="id15">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>). A client MUST reserve the ADC
+through the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface before the client may call
+<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> and it must release the ADC through the <tt class="docutils literal"><span class="pre">Resource</span></tt>
+interface when it no longer needs to access it (for more details on the
+<tt class="docutils literal"><span class="pre">Resource</span></tt> interface please refer to <a class="citation-reference" href="#tep108" id="id16" name="id16">[TEP108]</a>).  The associated ADC channel
+(port) and further configuration details are returned by the
+<tt class="docutils literal"><span class="pre">AdcConfigure.getConfiguration()</span></tt> command. It is the task of the client to
+wire this interface to a component that provides the client's ADC
+configuration.  The HIL implementation will use the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface
+to dynamically &quot;pull&quot; the client's ADC settings when it translates the
+<tt class="docutils literal"><span class="pre">ReadNow.read()</span></tt> command to a chip-specific sampling command. Note that both,
+<tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only placeholders and will be
+instantiated by the respective HIL implementation (for an example how this is
+done for the AdcReadClientC see Appendix C).</p>
 </div>
 <div class="section">
-<h2><a id="adcreadstreamclient" name="adcreadstreamclient">AdcReadStreamClient</a></h2>
+<h2><a id="adcreadstreamclientc" name="adcreadstreamclientc">AdcReadStreamClientC</a></h2>
 <pre class="literal-block">
-generic configuration AdcReadStreamClient() {
+generic configuration AdcReadStreamClientC() {
   provides {
     interface ReadStream&lt; size_type &gt;;
   }
   uses {
-     // chip-dependent configuration interface
+    interface AdcConfigure&lt; config_type&gt;;
   }
 }
 </pre>
-<p>The AdcReadStreamClient provides platform-independent access for data
-collection via the 'ReadStream' interface. The actual ADC channel (port) and
-further configuration details are determined by a chip-dependent configuration
-interface. It is the task of the client to wire this interface to a component
-that provides its ADC configuration.  The HAL2 implementation will use this
-interface to &quot;pull&quot; the client's ADC settings when it translates the
-'ReadStream.read()' command to a chip-specific sampling command. The
-resolution of the conversion results is chip-specific, the 'size_type'
-parameter represents an upper bound for the resolution of the conversion
-results.</p>
+<p>The <tt class="docutils literal"><span class="pre">AdcReadStreamClientC</span></tt> component provides a <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface for
+acquiring multiple conversion results at once. The <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface is
+explained in <a class="citation-reference" href="#tep114" id="id17" name="id17">[TEP114]</a> and <a class="reference" href="#interfaces">2. Interfaces</a>. The <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface is
+used in the same way as described in the section on the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt>.
+Note that both, <tt class="docutils literal"><span class="pre">size_type</span></tt> and <tt class="docutils literal"><span class="pre">config_type</span></tt>, are only placeholders and
+will be instantiated by the respective HIL implementation (for an example how
+this is done for the AdcReadClientC see Appendix C).</p>
 </div>
 </div>
 <div class="section">
-<h1><a id="hal2-implementation-guidelines" name="hal2-implementation-guidelines">5. HAL2 implementation guidelines</a></h1>
-<p>The HAL2 implementation of an ADC stack has two main tasks: It translates a
-platform-independent HAL2 request (from the 'Read', 'ReadNow' or 'ReadStream'
-interface) to a chip-specific HAL1 sampling command and it abstracts from the
-'Resource' interface. The first task cannot be solved in a chip-independent
-way, because it involves chip-specific configuration data. The second task MAY
-be performed by the following library components: ArbitratedReadC, and
-ArbitratedReadStreamC (in tinyos-2.x/tos/system) - refer to the Atmel Atmega
-128 HAL2 implementation (in tinyos-2.x/tos/chips/atm128/adc), for an example.
-Note that since the 'ReadNow' interface is always provided in conjunction with
-a 'Resource' interface the HAL2 implementation does not have to perform the
-ADC resource reservation in this case, but can simply forward an instance of
-the 'Resource' interface from the HAL1 (to AdcReadNowClient).</p>
-<p>To support multiple ADC clients the HAL2 implementation should provide
-parameterized 'Read', 'ReadNow' and 'ReadStream' interfaces as well as a
-parameterized chip-specific configuration interface. It should also use an
-instance of the 'Resource' interface (provided by the HAL1) per provided
-'Read' and 'ReadStream' interface to perform automatic resource reservation.
-The HAL2 representation ('AdcReadClient', 'AdcReadNowClient' and
-'AdcReadStreamClient') should ensure the correct wiring between the HAL1 and
-HAL2.</p>
-<p>From the perspective of the HAL2 the typical sequence of events is as follows:
-After a client has requested data via the 'Read' or 'ReadStream' interface the
-HAL2 will request access to the HAL1 via the 'Resource' interface, e.g. using
-the library components mentioned above.  When it is signalled the 'granted'
-event, the HAL2 will 'pull' the client's ADC settings and translate the
-client's command to a chip-specific HAL1 sampling command. Once it is
-signalled the conversion result(s) it releases the ADC via the 'Resource'
-interface and forwards the conversion result(s) to the client. When a client
-has requested data via the 'ReadNow' interface the HAL2 translates the
-client's command to the chip-specific HAL1 sampling command without using the
-'Resource' interface (it may check ownership of the client via the
-'ArbiterInfo' interface). In order to reduce state in the HAL2 and facilitate
-the mapping between used and provided interfaces the 'AdcReadClient',
-'AdcReadNowClient' and 'AdcReadStreamClient' should use the same interface
-identifier when it connects the HAL2 to HAL1 (see, for example, the MSP430
-ADC12 implementation in Appendix C).</p>
+<h1><a id="hil-guidelines" name="hil-guidelines">5. HIL guidelines</a></h1>
+<p>The HIL implementation of an ADC stack has two main tasks: it translates a
+<tt class="docutils literal"><span class="pre">Read</span></tt>, <tt class="docutils literal"><span class="pre">ReadNow</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> request to a chip-specific HAL sampling
+command and it abstracts from the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface (the latter only for
+the <tt class="docutils literal"><span class="pre">AdcReadClientC</span></tt> and <tt class="docutils literal"><span class="pre">AdcReadStreamClientC</span></tt>). The first task is solved
+with the help of the <tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface which is used by the HIL
+implementation to retrieve a client's ADC configuration.  The second task MAY
+be performed by the following library components: <tt class="docutils literal"><span class="pre">ArbitratedReadC</span></tt>, and
+<tt class="docutils literal"><span class="pre">ArbitratedReadStreamC</span></tt> (in tinyos-2.x/tos/system) - please refer to the
+Atmel Atmega 128 HAL implementation (in tinyos-2.x/tos/chips/atm128/adc) for an
+example.  Note that since the <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface is always provided in
+conjunction with a <tt class="docutils literal"><span class="pre">Resource</span></tt> interface the HIL implementation does not have
+to perform the ADC resource reservation for an <tt class="docutils literal"><span class="pre">AdcReadNowClientC</span></tt>, but may
+simply forward an instance of the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface from the HAL to the
+<tt class="docutils literal"><span class="pre">AdcReadNowClientC</span></tt>.</p>
+<p>The typical sequence of events is as follows: when a client requests data
+through the <tt class="docutils literal"><span class="pre">Read</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface the HIL will request access to
+the HAL using the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface.  After the HIL has been granted
+access, it will &quot;pull&quot; the client's ADC configuration using the
+<tt class="docutils literal"><span class="pre">AdcConfigure</span></tt> interface and translate the client's <tt class="docutils literal"><span class="pre">Read</span></tt> or
+<tt class="docutils literal"><span class="pre">ReadStream</span></tt> command to a chip-specific HAL command. Once the HIL is
+signalled the conversion result(s) from the HAL it releases the ADC through the
+<tt class="docutils literal"><span class="pre">Resource</span></tt> interface and signals the conversion result(s) to the client
+though the <tt class="docutils literal"><span class="pre">Read</span></tt> or <tt class="docutils literal"><span class="pre">ReadStream</span></tt> interface.  When a client requests data
+through the <tt class="docutils literal"><span class="pre">ReadNow</span></tt> interface the HIL translates the client's command to
+the chip-specific HAL command without using the <tt class="docutils literal"><span class="pre">Resource</span></tt> interface (it may
+check ownership of the client through the <tt class="docutils literal"><span class="pre">ArbiterInfo</span></tt> interface - this
+check can also be done in the HAL implementation). Once the HIL is signalled
+the conversion result(s) it forwards it to the respective <tt class="docutils literal"><span class="pre">ReadNow</span></tt> client.</p>
 </div>
 <div class="section">
 <h1><a id="implementation" name="implementation">6. Implementation</a></h1>
@@ -616,13 +692,12 @@ ADC12 implementation in Appendix C).</p>
 <blockquote>
 <ul class="simple">
 <li><tt class="docutils literal"><span class="pre">HplAdc12P.nc</span></tt> is the HPL implementation</li>
-<li><tt class="docutils literal"><span class="pre">Msp430Adc12P.nc</span></tt> is the HAL1 implementation</li>
-<li><tt class="docutils literal"><span class="pre">AdcC.nc</span></tt> is the HAL2 implementation</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Adc12P.nc</span></tt> is the HAL implementation</li>
+<li><tt class="docutils literal"><span class="pre">AdcP.nc</span></tt> is the HIL implementation</li>
 <li><tt class="docutils literal"><span class="pre">AdcReadClientC.nc</span></tt>, <tt class="docutils literal"><span class="pre">AdcReadNowClientC.nc</span></tt> and
-<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide access to the ADC on a per-client
-basis via the interfaces 'Read', 'ReadNow' and 'ReadStream',
-respectively, and the msp430-specific ADC configuration
-interface <tt class="docutils literal"><span class="pre">Msp430Adc12Config.nc</span></tt></li>
+<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide virtualized access to the HIL</li>
+<li>the use of DMA or the reference voltage generator and the
+HAL virtualization components are explained in <tt class="docutils literal"><span class="pre">README.txt</span></tt></li>
 </ul>
 </blockquote>
 <p>The Atmel Atmega 128 ADC implementation can be found in
@@ -630,16 +705,13 @@ interface <tt class="docutils literal"><span class="pre">Msp430Adc12Config.nc</s
 <blockquote>
 <ul class="simple">
 <li><tt class="docutils literal"><span class="pre">HplAtm128AdcC.nc</span></tt> is the HPL implementation</li>
-<li><tt class="docutils literal"><span class="pre">Atm128AdcP.nc</span></tt> is the HAL1 implementation</li>
+<li><tt class="docutils literal"><span class="pre">Atm128AdcP.nc</span></tt> is the HAL implementation</li>
 <li><tt class="docutils literal"><span class="pre">WireAdcP.nc</span></tt> and the library components for arbitrating 'Read',
 'ReadNow' and 'ReadStream', <tt class="docutils literal"><span class="pre">ArbitratedReadC</span></tt> and
 <tt class="docutils literal"><span class="pre">ArbitratedReadStreamC</span></tt> (in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/system</span></tt>), realize
-the HAL2</li>
+the HAL</li>
 <li><tt class="docutils literal"><span class="pre">AdcReadClientC.nc</span></tt>, <tt class="docutils literal"><span class="pre">AdcReadNowClientC.nc</span></tt> and
-<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide access to the ADC on a per-client
-basis via the platform-independent interfaces 'Read', 'ReadNow' and
-'ReadStream', respectively, and the atmega-specific ADC configuration
-interface <tt class="docutils literal"><span class="pre">Atm128AdcConfig.nc</span></tt></li>
+<tt class="docutils literal"><span class="pre">AdcReadStreamClientC.nc</span></tt> provide virtualized access to the HIL</li>
 </ul>
 </blockquote>
 </div>
@@ -774,73 +846,59 @@ sequence conversion</td>
 </table>
 </div>
 <div class="section">
-<h1><a id="appendix-b-an-hal1-representation-msp430-adc12" name="appendix-b-an-hal1-representation-msp430-adc12">Appendix B: an HAL1 representation: MSP430 ADC12</a></h1>
-<p>The following shows the HAL1 representation for the ADC12 of the TI MSP430
-MCU. It reflects the four MSP430 ADC12 conversion modes as it lets a client
-sample an ADC channel once (&quot;Single-channel-single-conversion&quot;) or repeatedly
+<h1><a id="appendix-b-a-hal-representation-msp430-adc12" name="appendix-b-a-hal-representation-msp430-adc12">Appendix B: a HAL representation: MSP430 ADC12</a></h1>
+<p>This section shows the HAL signature for the ADC12 of the TI MSP430 MCU. It
+reflects the four MSP430 ADC12 conversion modes as it lets a client sample an
+ADC channel once (&quot;Single-channel-single-conversion&quot;) or repeatedly
 (&quot;Repeat-single-channel&quot;), multiple times (&quot;Sequence-of-channels&quot;) or multiple
 times repeatedly (&quot;Repeat-sequence-of-channels&quot;). In contrast to the single
 channel conversion modes the sequence conversion modes trigger a single
-interrupt after multiple samples and thus enable high-frequency sampling (a
-sequence conversion mode for multiple different channels is not (yet)
-implemented).:</p>
+interrupt after multiple samples and thus enable high-frequency sampling. The
+<tt class="docutils literal"><span class="pre">DMAExtension</span></tt> interface is used to reset the state machine when the DMA is
+responsible for data transfer (managed in an exterior component):</p>
 <pre class="literal-block">
-configuration Msp430Adc12C
+configuration Msp430Adc12P
 {
-  provides interface Resource[uint8_t id];
-  provides interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+  provides {
+    interface Resource[uint8_t id];
+    interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+    interface AsyncStdControl as DMAExtension[uint8_t id];
+  }
 }
 
 interface Msp430Adc12SingleChannel
 {
-  async command error_t getSingleData(const msp430adc12_channel_config_t *config);
-  async command error_t getSingleDataRepeat(const msp430adc12_channel_config_t *config,
-    uint16_t jiffies);
-  async command error_t getMultipleData( const msp430adc12_channel_config_t *config,
-    uint16_t *buffer, uint16_t numSamples, uint16_t jiffies);
-  async command error_t getMultipleDataRepeat(const msp430adc12_channel_config_t *config,
-    uint16_t *buffer, uint8_t numSamples, uint16_t jiffies);
+  async command error_t configureSingle(const msp430adc12_channel_config_t *config);
+  async command error_t configureSingleRepeat(const msp430adc12_channel_config_t *config, uint16_t jiffies);
+  async command error_t configureMultiple( const msp430adc12_channel_config_t *config, uint16_t buffer[], uint16_t numSamples, uint16_t jiffies);
+  async command error_t configureMultipleRepeat(const msp430adc12_channel_config_t *config, uint16_t buffer[], uint8_t numSamples, uint16_t jiffies);
+  async command error_t getData();
   async event error_t singleDataReady(uint16_t data);
-  async event uint16_t* multipleDataReady(uint16_t *buffer, uint16_t
-    numSamples);
+  async event uint16_t* multipleDataReady(uint16_t buffer[], uint16_t numSamples);
 }
+
+typedef struct {
+  unsigned int inch: 4;            // input channel
+  unsigned int sref: 3;            // reference voltage
+  unsigned int ref2_5v: 1;         // reference voltage level
+  unsigned int adc12ssel: 2;       // clock source sample-hold-time
+  unsigned int adc12div: 3;        // clock divider sample-hold-time
+  unsigned int sht: 4;             // sample-hold-time
+  unsigned int sampcon_ssel: 2;    // clock source sampcon signal
+  unsigned int sampcon_id: 2;      // clock divider sampcon signal
+} msp430adc12_channel_config_t;
 </pre>
-<p>There exist two wrapper components, Msp430Adc12ClientC and
-Msp430Adc12RefVoltAutoClientC, which SHOULD be used to eliminate wiring
-errors.</p>
 </div>
 <div class="section">
-<h1><a id="appendix-c-an-hal2-representation-msp430-adc12" name="appendix-c-an-hal2-representation-msp430-adc12">Appendix C: an HAL2 representation: MSP430 ADC12</a></h1>
-<p>The AdcReadClientC component for the MSP430 ADC12 is implemented as follows:</p>
+<h1><a id="appendix-c-a-hil-representation-msp430-adc12" name="appendix-c-a-hil-representation-msp430-adc12">Appendix C: a HIL representation: MSP430 ADC12</a></h1>
+<p>The signature of the AdcReadClientC component for the MSP430 ADC12 is as
+follows:</p>
 <pre class="literal-block">
 generic configuration AdcReadClientC() {
   provides interface Read&lt;uint16_t&gt;;
-  uses interface Msp430Adc12Config;
-} implementation {
-  components AdcC;
-#ifdef REF_VOLT_AUTO_CONFIGURE
-  components new Msp430Adc12RefVoltAutoClientC() as Msp430AdcClient;
-#else
-  components new Msp430Adc12ClientC() as Msp430AdcClient;
-#endif
-
-  enum {
-    CLIENT = unique(ADCC_SERVICE),
-  };
-
-  Read = AdcC.Read[CLIENT];
-  Msp430Adc12Config = AdcC.Config[CLIENT];
-  AdcC.SingleChannel[CLIENT] -&gt; Msp430AdcClient.Msp430Adc12SingleChannel;
-  AdcC.Resource[CLIENT] -&gt; Msp430AdcClient.Resource;
-#ifdef REF_VOLT_AUTO_CONFIGURE
-  Msp430Adc12Config = Msp430AdcClient.Msp430Adc12Config;
-#endif
+  uses interface AdcConfigure&lt;const msp430adc12_channel_config_t*&gt;;
 }
 </pre>
-<p>Note that the same CLIENT identifier is used for all involved interfaces to
-facilitate the mapping between the HAL2 and HAL1 interfaces. The conditional
-compile directive REF_VOLT_AUTO_CONFIGURE can be used to automatically enable
-the internal reference voltage generator during the sampling process.</p>
 <table class="docutils citation" frame="void" id="tep1" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
@@ -850,25 +908,25 @@ the internal reference voltage generator during the sampling process.</p>
 <table class="docutils citation" frame="void" id="tep2" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="tep2">[TEP2]</a></td><td><em>(<a class="fn-backref" href="#id2">1</a>, <a class="fn-backref" href="#id4">2</a>, <a class="fn-backref" href="#id5">3</a>, <a class="fn-backref" href="#id9">4</a>)</em> TEP 2: Hardware Abstraction Architecture.</td></tr>
+<tr><td class="label"><a name="tep2">[TEP2]</a></td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id6">2</a>, <a class="fn-backref" href="#id7">3</a>)</em> 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 name="tep108">[TEP108]</a></td><td><em>(<a class="fn-backref" href="#id8">1</a>, <a class="fn-backref" href="#id10">2</a>, <a class="fn-backref" href="#id11">3</a>, <a class="fn-backref" href="#id12">4</a>)</em> TEP 108: Resource Arbitration.</td></tr>
+<tr><td class="label"><a name="tep108">[TEP108]</a></td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id13">2</a>, <a class="fn-backref" href="#id14">3</a>, <a class="fn-backref" href="#id16">4</a>)</em> TEP 108: Resource Arbitration.</td></tr>
 </tbody>
 </table>
 <table class="docutils citation" frame="void" id="tep109" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id3" name="tep109">[TEP109]</a></td><td>TEP 109: Sensor Boards.</td></tr>
+<tr><td class="label"><a class="fn-backref" href="#id2" name="tep109">[TEP109]</a></td><td>TEP 109: Sensor Boards.</td></tr>
 </tbody>
 </table>
 <table class="docutils citation" frame="void" id="tep114" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="tep114">[TEP114]</a></td><td><em>(<a class="fn-backref" href="#id6">1</a>, <a class="fn-backref" href="#id7">2</a>)</em> TEP 114: SIDs: Source and Sink Independent Drivers.</td></tr>
+<tr><td class="label"><a name="tep114">[TEP114]</a></td><td><em>(<a class="fn-backref" href="#id3">1</a>, <a class="fn-backref" href="#id4">2</a>, <a class="fn-backref" href="#id8">3</a>, <a class="fn-backref" href="#id9">4</a>, <a class="fn-backref" href="#id10">5</a>, <a class="fn-backref" href="#id12">6</a>, <a class="fn-backref" href="#id15">7</a>, <a class="fn-backref" href="#id17">8</a>)</em> TEP 114: SIDs: Source and Sink Independent Drivers.</td></tr>
 </tbody>
 </table>
 </div>
index c716ce01c3f0814df101daac9156efbb92a3aa05..ce4a3bde3a34f81c524afc03d1deb0e56c2b1df2 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Cory Sharp, Martin Turon, David Gay</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">22-Sep-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.3</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.9</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-06</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-18</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -367,11 +367,11 @@ timer interfaces (2.1).</p>
 <p>Three fundamental properties of timers are <em>precision</em>, <em>width</em> and
 <em>accuracy</em>.</p>
 <p>Examples of precision are millisecond, a cycle of a 32kHz clock, and
-microseconds.  All precisions are in &quot;binary&quot; units with respect to
-one second.  That is, one second contains 1024 binary milliseconds,
-32768 32kHz ticks, or 1048576 microseconds.  This TEP emphasizes
-millisecond and 32kHz tick precisions while reasonably accommodating
-other precisions.</p>
+microseconds.  All precisions presented in this TEP are in &quot;binary&quot;
+units with respect to one second.  That is, one second contains 1024
+binary milliseconds, 32768 32kHz ticks, or 1048576 microseconds.
+This TEP emphasizes millisecond and 32kHz tick precisions while
+reasonably accommodating other precisions.</p>
 <p>Examples of widths are 8-bit, 16-bit, 32-bit, and 64-bit.  The width
 for timer interfaces and components SHOULD be 32-bits.  That is, for
 lack of a good reason, timer interfaces should expose a 32-bit
@@ -397,9 +397,9 @@ reflected in the interface type.</p>
 <p>Precision is expressed as an empty type -- TMilli, T32khz, and
 TMicro -- written in the standard Timer.h header like this:</p>
 <pre class="literal-block">
-typedef struct { } TMilli;
-typedef struct { } T32khz;
-typedef struct { } TMicro;
+typedef struct { } TMilli; // 1024 ticks per second
+typedef struct { } T32khz; // 32768 ticks per second
+typedef struct { } TMicro; // 1048576 ticks per second
 </pre>
 <p>Note that the precision names are expressed as either frequency or
 period, whichever is convenient.</p>
@@ -442,10 +442,14 @@ interface Counter&lt;precision_tag,size_type&gt;
 <dt>get()</dt>
 <dd>return the current time.</dd>
 <dt>isOverflowPending()</dt>
-<dd>return TRUE if an overflow interrupt will occur after the outermost
-atomic block is exits.  FALSE otherwise.</dd>
+<dd>return TRUE if the overflow flag is set for this counter, i.e., if and
+only if an overflow interrupt will occur after the outermost atomic
+block exits.  Return FALSE otherwise.  This command only returns the
+state of the overflow flag and causes no side effect.  It is expected
+that the underlying hardware platform sets the overflow flag when
+appropriate.</dd>
 <dt>clearOverflow()</dt>
-<dd>cancel the pending overflow interrupt.</dd>
+<dd>cancel the pending overflow interrupt clearing the overflow flag.</dd>
 <dt>overflow()</dt>
 <dd>signals that an overflow in the current time.  That is, the current
 time has wrapped around from its maximum value to zero.</dd>
@@ -454,7 +458,7 @@ time has wrapped around from its maximum value to zero.</dd>
 <div class="section">
 <h2><a id="alarm" name="alarm">Alarm</a></h2>
 <p>Alarm components are extensions of Counters that signal an event
-when their Compare register detects the alarm time has been hit.
+when their compare register detects the alarm time has been hit.
 All commands and events of the Alarm interface are asynchronous (or
 in &quot;interrupt context&quot;).  The Alarm interface provides a set of
 &quot;basic&quot; commands for common usage and provides a set of &quot;extended&quot;
@@ -486,24 +490,35 @@ stop.</dd>
 <dt>isRunning()</dt>
 <dd>return TRUE if the alarm has been started and has not been cancelled
 or has not yet fired.  FALSE is returned otherwise.</dd>
-<dt>startAt(t0,dt)</dt>
-<dd>cancel any previously running alarm and set to fire at time t1 =
-t0+dt.  This form allows a delay to be anchored to some time t0
-taken before the invocation of start.  This is also the form used
-internally in the timer subsystem to allow the use of the full width
-of an alarm while being able to detect if the alarm time for a short
-alarm prematurely elapsed.</dd>
+</dl>
+<p>startAt(t0,dt)</p>
+<blockquote>
+cancel any previously running alarm and set to fire at time t1 =
+t0+dt.  This form allows a delay to be anchored to some time t0 taken
+before the invocation of startAt.  The timer subsystem uses this form
+internally, to be able to use of the full width of an alarm while also
+detecting when a short alarm elapses prematurely.</blockquote>
+<dl class="docutils">
 <dt>getNow()</dt>
 <dd>return the current time in the precision and width of the alarm.</dd>
 <dt>getAlarm()</dt>
 <dd>return the time the currently running alarm will fire or the time
-that the previously running alarm was set to fire.</dd>
+that the previously running alarm was set to fire.  getAlarm can
+be used with startAt to set an alarm from the previous alarm time,
+as in startAt(getAlarm(),dt).  This pattern is used within the
+fired() event to construct periodic alarms.</dd>
 </dl>
 </div>
 <div class="section">
 <h2><a id="busywait" name="busywait">BusyWait</a></h2>
-<p>The BusyWait interface replaces the TOSH_uwait macro from TinyOS
-1.x.</p>
+<p>The BusyWait interface allows for very short synchronous delays.
+BusyWait should be used sparingly and when an Alarm would not be
+reasonably efficient or accurate.  The BusyWait interface replaces
+the TOSH_uwait macro from TinyOS 1.x.</p>
+<p>BusyWait blocks for no less than the specified amount of time.  No
+explicit upper bound is imposed on the enacted delay, though it is
+expected the underlying implementation spins in a busy loop until
+the specified amount of time has elapsed.</p>
 <pre class="literal-block">
 interface BusyWait&lt;precision_tag,size_type&gt;
 {
@@ -512,7 +527,7 @@ interface BusyWait&lt;precision_tag,size_type&gt;
 </pre>
 <dl class="docutils">
 <dt>wait(dt)</dt>
-<dd>block for no less than the specified amount of time.</dd>
+<dd>block until at least dt time units have elapsed</dd>
 </dl>
 </div>
 <div class="section">
@@ -595,66 +610,71 @@ of the previous event for periodic timers.</dd>
 </div>
 <div class="section">
 <h1><a id="hal-guidelines" name="hal-guidelines">3. HAL guidelines</a></h1>
-<p>Platforms typically select a clocking option for each of their
-hardware counters, based on their hardware design (e.g., the mica
-family of motes all run their hardware timer 0 at 32kHz, and the micaz
-mote runs its timer 1 at cpu frequency/256). Platforms SHOULD expose
-the timing functionality of these timers using the Alarm and Counter
-interfaces, in the fashion described below. Platforms MAY expose the
-same hardware timer with different frequencies - use of conflicting
-frequences in the same program SHOULD produce compile-time
-errors.</p>
-<p>A hardware timer with precision <em>P</em> and width <em>W</em> SHOULD be exposed as a
-several components:</p>
+<p>Platforms SHOULD expose their relevant timing capabilities using
+standard Alarm and Counter interfaces.  The design pattern presented
+here defines a component naming convention to allow platform
+independent access to particular Alarms and Counters if they exist
+and to cause compile errors if they do not.</p>
+<p>A platform specific hardware timer with precision ${P} and width
+${W} SHOULD be exposed as these two conventional Counter and Alarm
+components:</p>
 <pre class="literal-block">
-configuration CounterPWC {
-  provides interface Counter&lt;TP, uintW_t&gt;;
-} ...
-generic configuration AlarmPWC {
-  provides interface Alarm&lt;TP,uintW_t&gt;;
-} ...
+configuration Counter${P}${W}C
+{
+  provides interface Counter&lt; T${P}, uint${W}_t &gt;;
+}
+
+generic configuration Alarm${P}${W}C()
+{
+  provides interface Alarm&lt; T${P}, uint${W}_t &gt;;
+}
 </pre>
-<p>and, except if <em>W</em> is 32:</p>
+<p>Instantiating an Alarm${P}${W}C component provides a new and
+independent Alarm.  If the platform presents a limited number of
+Alarm resources, then allocating more Alarms in an application than
+are available for the platform SHOULD produce a compile-time error.
+See Appendix B for an example of how to make allocatable Alarms that
+are each implemented on independent hardware timers.</p>
+<p>For example, if a platform has an 8-bit 32kHz counter and three
+8-bit 32kHz alarms, then the Counter and Alarm interfaces for
+${P}=32khz and ${W}=16 are:</p>
 <pre class="literal-block">
-configuration CounterP32C {
-  provides interface Counter&lt;TP, uint32_t&gt;;
-} ...
-generic configuration AlarmP32C {
-  provides interface Alarm&lt;TP,uint32_t&gt;;
-} ...
+configuration Counter32khz8C
+{
+  provides interface Counter&lt; T32khz, uint8_t &gt;;
+}
+
+generic configuration Alarm32khz8C()
+{
+  provides interface Alarm&lt; T32khz, uint8_t &gt;;
+}
 </pre>
-<p>Instantiating the Alarm... components provides a new Alarm independent
-of all prior instantiations. Instantiating such a component &quot;consumes&quot;
-a compare register from the corresponding hardware timer; when no more
-compare registers are available, instantiation SHOULD produce a
-compile-time error (see Appendix B for an example of how to achieve
-this).</p>
-<p>For example, the micaz platform includes an AlarmMilli8C and
-AlarmMilli32C components for timer 0 (one instantiation allowed), and
-Alarm32kHz16C and Alarm32kHz32C for timer 1 (three instantiations
-allowed).</p>
+<p>This pattern MAY be used to defined components for the platform that
+are mutually incompatible in single application.  Incompatible
+components SHOULD produce compile-time errors when compiled
+together.</p>
 </div>
 <div class="section">
 <h1><a id="hil-requirements" name="hil-requirements">4. HIL requirements</a></h1>
 <dl class="docutils">
 <dt>The following component MUST be provided on all platforms::</dt>
-<dd>TimerMilliC
+<dd>HilTimerMilliC
 BusyWaitMicroC</dd>
 </dl>
 <div class="section">
-<h2><a id="timermillic" name="timermillic">TimerMilliC</a></h2>
+<h2><a id="hiltimermillic" name="hiltimermillic">HilTimerMilliC</a></h2>
 <pre class="literal-block">
-#define TIMERMILLIC_SERVICE ...
-configuration TimerMilliC
+configuration HilTimerMilliC
 {
   provides interface Init;
-  provides interface Timer&lt;TMilli&gt;[uint8_t num];
-  provides interface LocalTime&lt;TMilli&gt;;
+  provides interface Timer&lt;TMilli&gt; as TimerMilli[ uint8_t num ];
 }
 </pre>
-<p>A timer is allocated using unique(TIMERMILLIC_SERVICE) to obtain a new
-unique timer number. This timer number is used to index the TimerMilli
-parameterised interface.</p>
+<p>A new timer is allocated using unique(UQ_TIMER_MILLI) to obtain a
+new unique timer number.  This timer number is used to index the
+TimerMilli parameterised interface.  UQ_TIMER_MILLI is defined in
+Timer.h.  HilTimerMilliC is used by the generic component
+TimerMilliC found in <tt class="docutils literal"><span class="pre">tos/system/</span></tt>.</p>
 </div>
 <div class="section">
 <h2><a id="busywaitmicroc" name="busywaitmicroc">BusyWaitMicroC</a></h2>
@@ -665,7 +685,7 @@ configuration BusyWaitMicroC
 }
 </pre>
 <p>BusyWaitMicroC allows applications to busy-wait for a number of
-microseconds. It's use should be restricted to situations where the
+microseconds. Its use should be restricted to situations where the
 delay is small and setting a timer or alarm would be impractical,
 inefficient or insufficiently precise.</p>
 </div>
@@ -747,6 +767,10 @@ created:</p>
 <pre class="literal-block">
 new TransformAlarmC( TMilli, uint32_t, T32khz, uint16_t, 5 )
 </pre>
+<p>It is the exclusive responsibility of the developer using
+TransformAlarmC to ensure that all five of its arguments are self
+consistent.  No compile errors are generated if the parameters
+passed to TransformAlarmC are inconsistent.</p>
 </div>
 <div class="section">
 <h2><a id="transformcounterc" name="transformcounterc">TransformCounterC</a></h2>
@@ -795,13 +819,85 @@ generic component VirtualizeTimerC( typedef precision_tag, int max_timers )
 </div>
 </div>
 <div class="section">
-<h1><a id="author-s-address" name="author-s-address">6. Author's Address</a></h1>
+<h1><a id="implementation" name="implementation">6. Implementation</a></h1>
+<p>The definition of the HIL interfaces are found in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/lib/timer</span></tt>:</p>
+<blockquote>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">Alarm.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">BusyWait.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">Counter.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">LocalTime.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">Timer.h</span></tt> defines precision tags and strings for unique()</li>
+<li><tt class="docutils literal"><span class="pre">Timer.nc</span></tt></li>
+</ul>
+</blockquote>
+<p>The implementation of the utility components are also found in
+<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/lib/timer</span></tt>:</p>
+<blockquote>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">AlarmToTimerC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">BusyWaitCounterC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">CounterToLocalTimeC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">TransformAlarmC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">TransformAlarmCounterC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">TransformCounterC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">VirtualizeAlarmC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">VirtualizeTimerC.nc</span></tt></li>
+</ul>
+</blockquote>
+<p>The implementation of Timers for the MSP430 is in
+<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/msp430/timer</span></tt>:</p>
+<blockquote>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">Alarm32khz16C.nc</span></tt> is generic and provides a new <tt class="docutils literal"><span class="pre">Alarm&lt;T32khz,uint16_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">Alarm32khz32C.nc</span></tt> is generic and provides a new <tt class="docutils literal"><span class="pre">Alarm&lt;T32khz,uint32_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">AlarmMilli16C.nc</span></tt> is generic and provides a new <tt class="docutils literal"><span class="pre">Alarm&lt;TMilli,uint16_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">AlarmMilli32C.nc</span></tt> is generic and provides a new <tt class="docutils literal"><span class="pre">Alarm&lt;TMilli,uint32_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">BusyWait32khzC.nc</span></tt> provides <tt class="docutils literal"><span class="pre">BusyWait&lt;T32khz,uint16_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">BusyWaitMicroC.nc</span></tt> provides <tt class="docutils literal"><span class="pre">BusyWait&lt;TMicro,uint16_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">Counter32khz16C.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Counter&lt;T32khz,uint16_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">Counter32khz32C.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Counter&lt;T32khz,uint32_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">CounterMilli16C.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Counter&lt;TMilli,uint16_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">CounterMilli32C.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Counter&lt;TMilli,uint32_t&gt;</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">GpioCaptureC.nc</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">HilTimerMilliC.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Timer&lt;TMilli&gt;</span> <span class="pre">as</span> <span class="pre">TimerMilli[uint8_t</span> <span class="pre">num]</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">Msp430AlarmC.nc</span></tt> is generic and converts an MSP430 timer to a 16-bit Alarm</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Capture.nc</span></tt> HPL interface definition for MSP430 timer captures</li>
+<li><tt class="docutils literal"><span class="pre">Msp430ClockC.nc</span></tt> exposes MSP430 hardware clock initialization</li>
+<li><tt class="docutils literal"><span class="pre">Msp430ClockInit.nc</span></tt> HPL interface definition for hardware clock initialization</li>
+<li><tt class="docutils literal"><span class="pre">Msp430ClockP.nc</span></tt> implements MSP430 hardware clock initialization and
+calibration and startup</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Compare.nc</span></tt> HPL interface definition for MSP430 timer compares</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Counter32khzC.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Counter&lt;T32khz,uint16_t&gt;</span></tt> based on
+MSP430 TimerB</li>
+<li><tt class="docutils literal"><span class="pre">Msp430CounterC.nc</span></tt> is generic and converts an Msp430Timer to a Counter</li>
+<li><tt class="docutils literal"><span class="pre">Msp430CounterMicroC.nc</span></tt> provides <tt class="docutils literal"><span class="pre">Counter&lt;TMicro,uint16_t&gt;</span></tt> based on
+MSP430 TimerA</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Timer.h</span></tt> defines additional MSP430 timer bitmasks and structs</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Timer.nc</span></tt> HPL interface definition</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Timer32khzC.nc</span></tt> is generic and allocates a new 32khz hardware timer</li>
+<li><tt class="docutils literal"><span class="pre">Msp430Timer32khzMapC.nc</span></tt> exposes the MSP430 hardware timers as a
+parameterized interface allocatable using Msp430Timer32khzC</li>
+<li><tt class="docutils literal"><span class="pre">Msp430TimerC.nc</span></tt> exposes the MSP430 hardware timers</li>
+<li><tt class="docutils literal"><span class="pre">Msp430TimerCapComP.nc</span></tt> is generic and implements the HPL for MSP430
+capture/compare special function registers</li>
+<li><tt class="docutils literal"><span class="pre">Msp430TimerCommonP.nc</span></tt> maps the MSP430 timer interrupts to Msp430TimerEvents</li>
+<li><tt class="docutils literal"><span class="pre">Msp430TimerControl.nc</span></tt> HPL interface definition</li>
+<li><tt class="docutils literal"><span class="pre">Msp430TimerEvent.nc</span></tt> HPL interface definition</li>
+<li><tt class="docutils literal"><span class="pre">Msp430TimerP.nc</span></tt> is generic and implements the HPL for MSP430 timer
+special function registers</li>
+</ul>
+</blockquote>
+</div>
+<div class="section">
+<h1><a id="author-s-address" name="author-s-address">7. Author's Address</a></h1>
 <div class="line-block">
 <div class="line">Cory Sharp</div>
 <div class="line">Moteiv Corporation</div>
 <div class="line">55 Hawthorne St, Suite 550</div>
 <div class="line">San Francisco, CA 94105</div>
 <div class="line"><br /></div>
+<div class="line">phone - +1 415 692 0963</div>
 <div class="line">email - <a class="reference" href="mailto:cory&#64;moteiv.com">cory&#64;moteiv.com</a></div>
 <div class="line"><br /></div>
 <div class="line"><br /></div>
index d43a308bfd7ab68d2bee121a49e19fc9c94c5016..b1c9de14c2e3c32da229ed0ace78976af50acff5 100644 (file)
@@ -296,19 +296,11 @@ ul.auto-toc {
 <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, Jonathan Hui</td></tr>
-<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">27-Sep-2004</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
-</tr>
 </tbody>
 </table>
 <div class="note">
@@ -326,7 +318,7 @@ HAL layers of various flash chips.</p>
 </div>
 <div class="section">
 <h1><a id="introduction" name="introduction">1. Introduction</a></h1>
-<p>Flash chips are a form of EEPROM (electrically-eraseable, programmable
+<p>Flash chips are a form of EEPROM (electrically-erasable, programmable
 read-only memory), distinguished by a fast erase capability. However,
 erases can only be done in large units (from 256B to 128kB depending on the
 flash chip). Erases are the only way to switch bits from 0 to 1, and
@@ -337,30 +329,96 @@ or that it be in relatively large units (e.g., 256B).</p>
 flash chips by their underlying technology (NOR vs NAND). We also
 include a column for Atmel's AT45DB flash chip family, as it has
 significantly different tradeoffs than other flash chips:</p>
-<pre class="literal-block">
-                 NOR                AT45DB         NAND
-
-Erase        :  Slow (seconds)      Fast (ms)      Fast (ms)
-Erase unit   :  Large (64KB-128KB)  Small (256B)   Medium (8K-32KB)
-Writes       :  Slow (100s kB/s)    Slow (60kB/s)  Fast (MBs/s)
-Write unit   :  1 bit               256B           100's of bytes
-Bit-errors   :  Low                 Low            High (requires ECC,
-                                                   bad-block mapping)
-Read         :  Fast*               Slow+I/O bus   Fast (but limited by
-                                                   I/O bus)
-Erase cycles :  10^4 - 10^5         10^4 **        10^5 - 10^7
-Intended use :  Code storage        Data storage   Data storage
-Energy/byte  :  1uJ                 1uJ            .01uJ
-
-*  Intel Mote2 NOR flash is memory mapped (reads are very fast and can
-   directly execute code)
-** Or infinite? Data sheet just says that every page within a sector
-   must be written every 10^4 writes within that sector
-</pre>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="19%" />
+<col width="27%" />
+<col width="25%" />
+<col width="28%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">X</th>
+<th class="head">NOR
+(ex: ST M25P40,
+Intel PXA27x)</th>
+<th class="head">AT45DB</th>
+<th class="head"><dl class="first last docutils">
+<dt>NAND</dt>
+<dd>(ex: Samsung
+K9K1G08R0B)</dd>
+</dl>
+</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>Erase</td>
+<td>Slow (seconds)</td>
+<td>Fast (ms)</td>
+<td>Fast (ms)</td>
+</tr>
+<tr><td>Erase unit</td>
+<td>Large (64KB-128KB)</td>
+<td>Small (256B)</td>
+<td>Medium (8KB-32KB)</td>
+</tr>
+<tr><td>Writes</td>
+<td>Slow (100s kB/s)</td>
+<td>Slow (60kB/s)</td>
+<td>Fast (MBs/s)</td>
+</tr>
+<tr><td>Write unit</td>
+<td>1 bit</td>
+<td>256B</td>
+<td>100's of bytes</td>
+</tr>
+<tr><td>Bit-errors</td>
+<td>Low</td>
+<td>Low</td>
+<td>High (requires ECC,
+bad-block mapping)</td>
+</tr>
+<tr><td>Read</td>
+<td>Bus limited <a class="footnote-reference" href="#id3" id="id1" name="id1">[*]</a></td>
+<td>Slow+Bus limited</td>
+<td>Bus limited</td>
+</tr>
+<tr><td>Erase cycles</td>
+<td>10^4 - 10^5</td>
+<td>10^4 <a class="footnote-reference" href="#id4" id="id2" name="id2">[†]</a></td>
+<td>10^5 - 10^7</td>
+</tr>
+<tr><td>Intended use</td>
+<td>Code storage</td>
+<td>Data storage</td>
+<td>Data storage</td>
+</tr>
+<tr><td>Energy/byte</td>
+<td>1uJ</td>
+<td>1uJ</td>
+<td>.01uJ</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<table class="docutils footnote" frame="void" id="id3" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id1" name="id3">[*]</a></td><td>M25P40 reads are limited by the use of a 25MHz SPI bus. The PXA27x flash
+is memory mapped (reads are very fast and can directly execute code).</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id4" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id2" name="id4">[†]</a></td><td>Or infinite? Data sheet just says that every page within a sector
+must be written every 10^4 writes within that sector</td></tr>
+</tbody>
+</table>
 <p>The energy/byte is the per-byte cost of erasing plus programming. It is
 derived from the timing and power consumption of erase and write operations
 (for NOR flash, values are for the STMicroelectronics M25P family, for NAND
-flash, values are from a Samsung datasheet). Energy/byte for reads appears
+flash, values are from the Samsung datasheet). Energy/byte for reads appears
 to depend mostly on how long the read takes (the power consumptions are
 comparable), i.e., on the efficiency of the bus + processor.</p>
 <p>Early TinyOS platforms all used a flash chip from the AT45DB
@@ -372,7 +430,7 @@ access to per-page read, write and erase operations.</li>
 <li>Using a high-level memory-like interface (<tt class="docutils literal"><span class="pre">ByteEEPROMC</span></tt>) with
 read, write and logging operations.</li>
 <li>Using a simple file system (<tt class="docutils literal"><span class="pre">Matchbox</span></tt>) with sequential-only
-files [<a class="reference" href="#id1">1</a>].</li>
+files [<a class="reference" href="#id5">1</a>].</li>
 </ul>
 <p>Some more recent platforms use different flash chips: the ST M25P family (Telos
 rev. B, eyes) and the Intel Strataflash (Intel Mote2). None of the
@@ -385,6 +443,9 @@ This is not readily implementable on a flash chip with large erase units.</li>
 reimplemented for these other chips, in part because it does not
 support some applications (e.g., network reprogramming) very well.</li>
 </ul>
+</div>
+<div class="section">
+<h1><a id="storage-in-tinyos-2-x" name="storage-in-tinyos-2-x">2. Storage in TinyOS 2.x</a></h1>
 <p>One approach to hiding the differences between different flash chips is to
 provide a disk-like, block interface (with, e.g., 512B blocks). This is the
 approach taken by compact flash cards. However, in the context of TinyOS,
@@ -397,22 +458,36 @@ erase unit, and to deal with the limited number of erase cycles/block
 requires remapping blocks. We believe that maintaining this remapping
 table is too expensive on many mote-class devices.</li>
 </ul>
-<p>Another approach to supporting multiple flash chips is to build a
-file system (like Matchbox) which can be implemented for multiple
-flash chips. However, TinyOS is currently targeted at running a
-single application, and many applications know their storage needs
-in advance: for instance, a little space for configuration data, and
-everything else for a log of all sampled data. In such cases, the
-flexibility offered by a filing system (e.g., arbitrary numbers of
-files) is overkill, and may come at the expense of implementation
-and runtime complexity.</p>
-<p>Instead, TinyOS 2.x, divides flash chips into separate volumes (with
-sizes fixed at compile-time). Each volume provides a single storage
-abstraction (the abstraction defines the format). So far there are three
-such abstractions: large objects written in a single session,
-small objects with arbitrary reads and writes, and logs. This approach
-has two advantages:</p>
+<p>A second approach is to provide a generic low-level interface providing
+operations (read, write, erase) corresponding to the basic flash
+operations, along with information describing the flash chip's layout
+(minimum write and erase unit, timing information, etc). However,
+we believe that the large differences between NAND and NOR flash (see the
+table above), in particular the differences in reliability, write and
+erase units, make the design of a useful generic low-level interface
+tricky at best.</p>
+<p>We thus believe it is best, for now at least, to define high-level
+storage abstractions that are useful for sensor network applications,
+and leave their implementation up to each flash chip - such abstractions
+will be necessary anyway. We leave open the possibility that a future
+TEP may define portable lower-level flash interfaces (either for all
+flash chips, or, e.g., for NOR-family flashes). Such low-level
+interfaces would allow implementations of the storage abstractions
+defined in this TEP to be used for multiple flash chips.</p>
+<p>This TEP describes three high-level storage abstractions: large objects
+written in a single session, small objects with arbitrary reads and
+writes, and logs. TinyOS 2.x, divides flash chips into separate volumes
+(with sizes fixed at compile-time). Each volume provides a single
+storage abstraction (the abstraction defines the format).</p>
+<p>We prefer the use of single abstractions over fixed-size volumes over
+the use of a more general filing system (like Matchbox) for several
+reasons:</p>
 <ul class="simple">
+<li>TinyOS is currently targeted at running a single application, and many
+applications know their storage needs in advance: for instance, a
+little space for configuration data, and everything else for a log of
+all sampled data. In such cases, the flexibility offered by a filing
+system (e.g., arbitrary numbers of files) is overkill,</li>
 <li>Each abstraction is relatively easy to implement on a new flash chip, and
 has relatively little overhead.</li>
 <li>The problem of dealing with the limited number of erase cycles/block
@@ -422,28 +497,28 @@ through their log. Thus the abstractions can mostly ignore the need for
 &quot;wear levelling&quot; (ensuring that each block of the flash is erased
 the same number of time, to maximise flash chip lifetime).</li>
 </ul>
-<p>New abstractions (including a filing system) can easily be added to this
-framework, or can be built on top of these abstractions.</p>
+<p>New abstractions (including a filing system) can easily be added to
+this framework.</p>
 <p>The rest of this TEP covers some principles for the organisation of
-flash chips (Section 2), then describes the flash volumes and
-storage abstractions in detail (Section 3).</p>
+flash chips (Section 3), then describes the flash volumes and
+storage abstractions in detail (Section 4).</p>
 </div>
 <div class="section">
-<h1><a id="hpl-hal-hil-architecture" name="hpl-hal-hil-architecture">2. HPL/HAL/HIL Architecture</a></h1>
-<p>The flash chip architecture dollows the three-layer Hardware
+<h1><a id="hpl-hal-hil-architecture" name="hpl-hal-hil-architecture">3. HPL/HAL/HIL Architecture</a></h1>
+<p>The flash chip architecture follows the three-layer Hardware
 Abstraction Architecture (HAA), with each chip providing a presentation
-layer (HPL, Section 2.1), adaptation layer (HAL, Section 2.2) and
-platform-independent interface layer (the storage abstractions described in
-Section 3) [<a class="reference" href="#id2">2</a>]. The implementation of these layers SHOULD be found in the
+layer (HPL, Section 3.1), adaptation layer (HAL, Section 3.2) and
+platform-independent interface layer (HIL, Section 3.3) [<a class="reference" href="#id6">2</a>].
+The implementation of these layers SHOULD be found in the
 <tt class="docutils literal"><span class="pre">tos/chips/CHIPNAME</span></tt> directory. If a flash chip is part of a larger
 family with a similar interface, the HAA SHOULD support all family members
 by relying, e.g., on platform-provided configuration information.</p>
 <p>Appendix A shows example HPL and HAL specifications for the AT45DB
 and ST M25P chip families.</p>
 <div class="section">
-<h2><a id="hardware-presentation-layer-hpl" name="hardware-presentation-layer-hpl">2.1 Hardware Presentation Layer (HPL)</a></h2>
-<p>The flash HPL has a chip-dependent, system-independent interface. The
-implementation of this HPL is system-dependent. The flash HPL SHOULD be
+<h2><a id="hardware-presentation-layer-hpl" name="hardware-presentation-layer-hpl">3.1 Hardware Presentation Layer (HPL)</a></h2>
+<p>The flash HPL has a chip-dependent, platform-independent interface. The
+implementation of this HPL is platform-dependent. The flash HPL SHOULD be
 stateless.</p>
 <p>To remain platform independent, a flash chip's HPL SHOULD connect to
 platform-specific components
@@ -454,8 +529,8 @@ flash chips, this directory MAY also contain a file describing the
 particular flash chip found on the platform.</p>
 </div>
 <div class="section">
-<h2><a id="hardware-adaptation-layer-hal" name="hardware-adaptation-layer-hal">2.2 Hardware Adaptation Layer (HAL)</a></h2>
-<p>The flash HAL has a chip-dependent, system-independent interface and
+<h2><a id="hardware-adaptation-layer-hal" name="hardware-adaptation-layer-hal">3.2 Hardware Adaptation Layer (HAL)</a></h2>
+<p>The flash HAL has a chip-dependent, platform-independent interface and
 implementation. Flash families with a common HPL SHOULD have a common
 HAL. Flash HAL's SHOULD expose a <tt class="docutils literal"><span class="pre">Resource</span></tt> interface and automatically
 power-manage the underlying flash chip. Finally, the flash HAL MUST
@@ -463,14 +538,28 @@ provide a way to access the volume information specified by the
 programmer (see Section 3). This allows users to build new flash
 abstractions that interact cleanly with the rest of the flash system.</p>
 </div>
+<div class="section">
+<h2><a id="hardware-interface-layer-hil" name="hardware-interface-layer-hil">3.3 Hardware Interface Layer (HIL)</a></h2>
+<p>Each flash chip MUST support at least one of the storage abstractions
+described in Section 4. These abstractions SHOULD be presented in
+components named <tt class="docutils literal"><span class="pre">ChipAbstractionC</span></tt>, e.g., <tt class="docutils literal"><span class="pre">At45dbLogStorageC</span></tt>.
+Additionally, a flash chip implementation MAY support platforms
+with multiple instances of the same storage chip. The way in which
+this is achieved is not specified further in this TEP.</p>
+<p>Each platform MUST have <tt class="docutils literal"><span class="pre">AbstractionC</span></tt> components (e.g.,
+<tt class="docutils literal"><span class="pre">LogStorageC</span></tt>) implementing the storage abstractions of Section 4
+supported by its flash chip(s). On platforms with multiple storage chips
+SHOULD redirect uses of <tt class="docutils literal"><span class="pre">AbstractionC</span></tt> to the appropriate storage
+chip, based on the requested volume.</p>
+</div>
 </div>
 <div class="section">
-<h1><a id="non-volatile-storage-abstracitons-in-tinyos-2-x" name="non-volatile-storage-abstracitons-in-tinyos-2-x">3. Non-Volatile Storage Abstracitons in TinyOS 2.x</a></h1>
-<p>The HIL implementations are system-independent, but chip (family)
+<h1><a id="non-volatile-storage-abstractions" name="non-volatile-storage-abstractions">4. Non-Volatile Storage Abstractions</a></h1>
+<p>The HIL implementations are platform-independent, but chip (family)
 dependent. They implement the three storage abstractions and
 volume structure discussed in the introduction.</p>
 <div class="section">
-<h2><a id="volumes" name="volumes">3.1. Volumes</a></h2>
+<h2><a id="volumes" name="volumes">4.1. Volumes</a></h2>
 <p>The division of the flash chip into fixed-size volumes is specified by
 an XML file that is placed in the application's directory (where one
 types 'make'). The XML file specifies the allocation as follows:</p>
@@ -490,11 +579,12 @@ code. There is no constraint on how this is done or what code is produced,
 except that the specification to physical allocation MUST be one-to-one
 (i.e. a given specification should always have the same resulting physical
 allocation on a given chip) and the result MUST be placed in the build
-directory. When not specified, the tool may give any suitable physical
-location to a volume. If there is any reason that the physical allocation
+directory. When not specified, the tool picks a suitable physical
+location for a volume. If there is any reason that the physical allocation
 cannot be satisfied, an error should be given at compile time. The tool
 SHOULD be named <tt class="docutils literal"><span class="pre">tos-storage-CHIPNAME</span></tt> and be distributed with the other
-tools supporting a platform.</p>
+tools supporting a platform. The XML file SHOULD be named
+<tt class="docutils literal"><span class="pre">volumes-CHIPNAME.xml</span></tt>.</p>
 <p>The compile-time tool MUST prepend 'VOLUME_' to each volume name in
 the XML file and '#define' each resulting name to map to a unique
 integer.</p>
@@ -508,23 +598,20 @@ compile-time error since the symbol will be undefined.</p>
 <p>A volume MUST NOT be used with more than one storage abstraction instance.</p>
 </div>
 <div class="section">
-<h2><a id="large-objects" name="large-objects">3.2 Large objects</a></h2>
-<p>The motivating example for large objects is the transmission or long-term
-storage of large pieces of data. For instance, programs in a network-reprogramming
-system, or large data-packets in a reliable data-transmission system. Such
-objects have two interesting characteristics: each byte in the object is
-written at most once, and a full object is written in a single &quot;session&quot;
-(i.e., without the mote rebooting).</p>
+<h2><a id="large-objects" name="large-objects">4.2 Large objects</a></h2>
+<p>The motivating example for large objects is the transmission or
+long-term storage of large pieces of data. For instance, programs in a
+network-reprogramming system, or large data-packets in a reliable
+data-transmission system. Such objects have an interesting
+characteristic: each byte in the object is written at most once.</p>
 <p>This leads to the definition of the <tt class="docutils literal"><span class="pre">BlockStorageC</span></tt> abstraction for storing
-large objects:</p>
+large objects or other &quot;write-once&quot; objects:</p>
 <ul class="simple">
 <li>A large object ranges from a few kilobytes upwards.</li>
-<li>A large object must be erased before use.</li>
-<li>A large object must be committed to ensure it survives a reboot or crash;
-after a commit no more writes may be performed.</li>
-<li>Random reads are allowed.</li>
-<li>Random writes are allowed are allowed between erase and commit; data
-cannot be overwritten.</li>
+<li>A large object is erased before the first write.</li>
+<li>A sync ensures that a large object survives a reboot or crash</li>
+<li>Reads are unrestricted</li>
+<li>Each byte can only be written once between two erases</li>
 </ul>
 <p>Large objects are accessed by instantiating a BlockStorageC component
 which takes a volume id argument:</p>
@@ -536,17 +623,17 @@ generic configuration BlockStorageC(volume_id_t volid) {
   }
 } ...
 </pre>
-<p>The <tt class="docutils literal"><span class="pre">BlockRead</span></tt> and <tt class="docutils literal"><span class="pre">BlockWrite</span></tt> interfaces contain the following
-operations (all split-phase, except <tt class="docutils literal"><span class="pre">BlockRead.getSize</span></tt>):</p>
+<p>The <tt class="docutils literal"><span class="pre">BlockRead</span></tt> and <tt class="docutils literal"><span class="pre">BlockWrite</span></tt> interfaces (briefly presented in
+Appendix B) contain the following operations (all split-phase, except
+<tt class="docutils literal"><span class="pre">BlockRead.getSize</span></tt>):</p>
 <ul class="simple">
 <li><tt class="docutils literal"><span class="pre">BlockWrite.erase</span></tt>: erase the volume. After a reboot or a commit, a
-volume must be erased before it can be written to.</li>
-<li><tt class="docutils literal"><span class="pre">BlockWrite.write</span></tt>: write some bytes starting at a given offset. Each
-byte can only be written once between an erase and the subsequent commit.</li>
-<li><tt class="docutils literal"><span class="pre">BlockWrite.commit</span></tt>: commit all writes to a given volume. No writes can
-be performed after a commit until a subsequent erase.</li>
-<li><tt class="docutils literal"><span class="pre">BlockRead.verify</span></tt>: verify that the volume contains the results of a
-successful commit.</li>
+volume MUST be erased before it can be written to.</li>
+<li><tt class="docutils literal"><span class="pre">BlockWrite.write</span></tt>: write some bytes starting at a given
+offset. Each byte MUST NOT be written more than once between two erases.</li>
+<li><tt class="docutils literal"><span class="pre">BlockWrite.sync</span></tt>: ensure all previous writes are present on a given
+volume. Sync MUST be called to ensure written data survives a reboot
+or crash.</li>
 <li><tt class="docutils literal"><span class="pre">BlockRead.read</span></tt>: read some bytes starting at a given offset.</li>
 <li><tt class="docutils literal"><span class="pre">BlockRead.computeCrc</span></tt>: compute the CRC of some bytes starting at a
 given offset.</li>
@@ -555,22 +642,25 @@ volume.</li>
 </ul>
 <p>For full details on arguments and other considerations, see the comments in
 the interface definitions.</p>
+<p>Note that these interfaces contain no direct support for verifying the
+integrity of the BlockStorage data, but such support can easily be built
+by using the <tt class="docutils literal"><span class="pre">computeCrc</span></tt> command and storing the result in a
+well-defined location, and checking this CRC when desired.</p>
 </div>
 <div class="section">
-<h2><a id="logging" name="logging">3.3 Logging</a></h2>
-<p>Event and reuslt logging is a common requirement in sensor
+<h2><a id="logging" name="logging">4.3 Logging</a></h2>
+<p>Event and result logging is a common requirement in sensor
 networks. Such logging should be reliable (a mote crash should not
 lose data). It should also be easy to extract data from the log,
 either partially or fully. Some logs are <em>linear</em> (stop logging when
 the volume is full), others are <em>circular</em> (the oldest data is
 overwritten when the volume is full).</p>
-<p>The <tt class="docutils literal"><span class="pre">LogStorageC</span></tt> abstraction supports these requirements.  The log is record
-based: each call to <tt class="docutils literal"><span class="pre">LogWrite.append</span></tt> (see below) creates a new
-record. On failure (crash or reboot), the log is guaranteed to only lose
-whole records from the end of the log. Additionally, once a circular log
-wraps around, calls to <tt class="docutils literal"><span class="pre">LogWrite.append</span></tt> only lose whole records from the
-beginning of the log. These guarantees mean that applications do not to
-have worry about incomplete or inconsistent log entries.</p>
+<p>The <tt class="docutils literal"><span class="pre">LogStorageC</span></tt> abstraction supports these requirements.  The log is
+record based: each call to <tt class="docutils literal"><span class="pre">LogWrite.append</span></tt> (see below) creates a new
+record. On failure (crash or reboot), the log MUST only lose whole
+records from the end of the log. Additionally, once a circular log wraps
+around, calls to <tt class="docutils literal"><span class="pre">LogWrite.append</span></tt> MUST only lose whole records from
+the beginning of the log.</p>
 <p>Logs are accessed by instantiating a LogStorageC component which takes a
 volume id and a boolean argument:</p>
 <pre class="literal-block">
@@ -583,29 +673,39 @@ generic configuration LogStorageC(volume_id_t volid, bool circular) {
 </pre>
 <p>If the <tt class="docutils literal"><span class="pre">circular</span></tt> argument is TRUE, the log is circular; otherwise
 it is linear.</p>
-<p>The <tt class="docutils literal"><span class="pre">LogRead</span></tt> and <tt class="docutils literal"><span class="pre">LogWrite</span></tt> interfaces contain the following
-operations (all split-phase except <tt class="docutils literal"><span class="pre">LogWrite.currentOffset</span></tt>,
-<tt class="docutils literal"><span class="pre">LogRead.currentOffset</span></tt> and <tt class="docutils literal"><span class="pre">LogRead.getSize</span></tt>):</p>
+<p>The <tt class="docutils literal"><span class="pre">LogRead</span></tt> and <tt class="docutils literal"><span class="pre">LogWrite</span></tt> interfaces (briefly presented in
+Appendix B) contain the following operations (all split-phase except
+<tt class="docutils literal"><span class="pre">LogWrite.currentOffset</span></tt>, <tt class="docutils literal"><span class="pre">LogRead.currentOffset</span></tt> and
+<tt class="docutils literal"><span class="pre">LogRead.getSize</span></tt>):</p>
 <ul>
-<li><p class="first"><tt class="docutils literal"><span class="pre">LogWrite.erase</span></tt>: erase the log.</p>
+<li><p class="first"><tt class="docutils literal"><span class="pre">LogWrite.erase</span></tt>: erase the log. A log MUST be erased (possibly in
+some previous session) before any other operation can be used.</p>
 </li>
 <li><p class="first"><tt class="docutils literal"><span class="pre">LogWrite.append</span></tt>: append some bytes to the log. In a circular log,
 this may overwrite the current read position. In this case, the
-read position is implicitly advanced to the log's current beginning
-(i.e., as if <tt class="docutils literal"><span class="pre">LogRead.seek</span></tt> had been called with <tt class="docutils literal"><span class="pre">SEEK_BEGINNING</span></tt>).</p>
+read position MUST be advanced to the log's current beginning
+(i.e., as if <tt class="docutils literal"><span class="pre">LogRead.seek</span></tt> had been called with <tt class="docutils literal"><span class="pre">SEEK_BEGINNING</span></tt>).
+Additionally, the <tt class="docutils literal"><span class="pre">LogWrite.appendDone</span></tt> event reports whenever, in a
+circular log, an append MAY have erased old records.</p>
 <p>Each append creates a separate record. Log implementations may have a
 maximum record size; all implementations MUST support records of up
 to 255 bytes.</p>
 </li>
 <li><p class="first"><tt class="docutils literal"><span class="pre">LogWrite.sync</span></tt>: guarantee that data written so far will not be lost to
 a crash or reboot (it can still be overwritten when a circular log wraps
-around). Using <tt class="docutils literal"><span class="pre">sync</span></tt> may waste some space in the log.</p>
+around). Using <tt class="docutils literal"><span class="pre">sync</span></tt> MAY waste some space in the log.</p>
 </li>
 <li><p class="first"><tt class="docutils literal"><span class="pre">LogWrite.currentOffset</span></tt>: return cookie representing current
 append position (for use with <tt class="docutils literal"><span class="pre">LogRead.seek</span></tt>).</p>
 </li>
 <li><p class="first"><tt class="docutils literal"><span class="pre">LogRead.read</span></tt>: read some bytes from the current read position in
 the log and advance the read position.</p>
+<p><tt class="docutils literal"><span class="pre">LogStorageC</span></tt> implementations MUST include error detection codes
+to increase the likelihood of detection of corrupted or invalid log
+data. Data returned by a successful read MUST have passed this
+error detection check. The behaviour on failure of this check is
+unspecified (e.g., the at45db believes as if the end of the log has
+been reached; other implementations may behave differently).</p>
 </li>
 <li><p class="first"><tt class="docutils literal"><span class="pre">LogRead.currentOffset</span></tt>: return cookie representing current
 read position (for use with <tt class="docutils literal"><span class="pre">LogRead.seek</span></tt>).</p>
@@ -617,18 +717,28 @@ the specified position has been overwritten, behave as if
 <tt class="docutils literal"><span class="pre">SEEK_BEGINNING</span></tt> was requested.</p>
 <p><tt class="docutils literal"><span class="pre">SEEK_BEGINNING</span></tt> positions the read position at the beginning of
 the oldest record still present in the log.</p>
+<p>After reboot, the current read position is <tt class="docutils literal"><span class="pre">SEEK_BEGINNING</span></tt>.</p>
 </li>
-<li><p class="first"><tt class="docutils literal"><span class="pre">LogRead.getSize</span></tt>: return an approximation of the log's capacity.
-Uses of <tt class="docutils literal"><span class="pre">sync</span></tt> and other overhead may reduce this number.</p>
+<li><p class="first"><tt class="docutils literal"><span class="pre">LogRead.getSize</span></tt>: return an approximation of the log's capacity
+in bytes. Uses of <tt class="docutils literal"><span class="pre">sync</span></tt> and other overhead may reduce this number.</p>
 </li>
 </ul>
 <p>For full details on arguments, etc, see the comments in the interface
 definitions.</p>
+<p>Note that while each call to <tt class="docutils literal"><span class="pre">append</span></tt> logically creates a separate
+record, the <tt class="docutils literal"><span class="pre">LogStorageC</span></tt> API does not report record
+boundaries. Additionally, crashes, reboots, and appends after
+wrap-around in a circular log can cause the loss of multiple consecutive
+records. Taken together, these restrictions mean that a <tt class="docutils literal"><span class="pre">LogStorageC</span></tt>
+implementation MAY internally aggregate several consecutive appends into
+a single record. However, the guarantee that only whole records are lost
+is sufficient to ensure that applications do not to have worry about
+incomplete or inconsistent log entries.</p>
 </div>
 <div class="section">
-<h2><a id="small-objects" name="small-objects">3.4 Small objects:</a></h2>
-<p>Sensor network applications may need to store configuration data, e.g.,
-mote id, radio frequency, sample rates, etc. Such data is not large, but
+<h2><a id="small-objects" name="small-objects">4.4 Small objects:</a></h2>
+<p>Sensor network applications need to store configuration data, e.g.,
+mote identity, radio frequency, sample rates, etc. Such data is not large, but
 losing it may lead to a mote misbehaving or losing contact with the
 network.</p>
 <p>The <tt class="docutils literal"><span class="pre">ConfigStorageC</span></tt> abstraction stores a single small object in a volume. It:</p>
@@ -653,9 +763,9 @@ generic configuration ConfigStorageC(volume_id_t volid) {
 </pre>
 <p>A small object MUST be mounted (via the <tt class="docutils literal"><span class="pre">Mount</span></tt> interface) before
 the first use.</p>
-<p>The <tt class="docutils literal"><span class="pre">Mount</span></tt> and <tt class="docutils literal"><span class="pre">ConfigStorage</span></tt> interfaces contain the following
-operations (all split-phase except <tt class="docutils literal"><span class="pre">ConfigStorage.getSize</span></tt> and
-<tt class="docutils literal"><span class="pre">ConfigStorage.valid</span></tt>):</p>
+<p>The <tt class="docutils literal"><span class="pre">Mount</span></tt> and <tt class="docutils literal"><span class="pre">ConfigStorage</span></tt> interfaces (briefly presented in
+Appendix B) contain the following operations (all split-phase except
+<tt class="docutils literal"><span class="pre">ConfigStorage.getSize</span></tt> and <tt class="docutils literal"><span class="pre">ConfigStorage.valid</span></tt>):</p>
 <ul class="simple">
 <li><tt class="docutils literal"><span class="pre">Mount.mount</span></tt>: mount the volume.</li>
 <li><tt class="docutils literal"><span class="pre">ConfigStorage.valid</span></tt>: return TRUE if the volume contains a
@@ -674,12 +784,12 @@ definitions.</p>
 </div>
 </div>
 <div class="section">
-<h1><a id="implementations" name="implementations">4. Implementations</a></h1>
+<h1><a id="implementations" name="implementations">5. Implementations</a></h1>
 <p>An AT45DB implementation can be found in tinyos-2.x/tos/chips/at45db.</p>
 <p>An ST M25P implementation can be found in tinyos-2.x/tos/chips/stm25p.</p>
 </div>
 <div class="section">
-<h1><a id="authors-addresses" name="authors-addresses">5. Authors' Addresses</a></h1>
+<h1><a id="authors-addresses" name="authors-addresses">6. Authors' Addresses</a></h1>
 <div class="line-block">
 <div class="line">David Gay</div>
 <div class="line">2150 Shattuck Ave, Suite 1300</div>
@@ -700,18 +810,18 @@ definitions.</p>
 </div>
 </div>
 <div class="section">
-<h1><a id="citations" name="citations">6. Citations</a></h1>
-<table class="docutils footnote" frame="void" id="id1" rules="none">
+<h1><a id="citations" name="citations">7. Citations</a></h1>
+<table class="docutils footnote" frame="void" id="id5" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="id1">[1]</a></td><td>David Gay. &quot;Design of Matchbox, the simple filing system for
+<tr><td class="label"><a name="id5">[1]</a></td><td>David Gay. &quot;Design of Matchbox, the simple filing system for
 motes. (version 1.0).&quot;</td></tr>
 </tbody>
 </table>
-<table class="docutils footnote" frame="void" id="id2" rules="none">
+<table class="docutils footnote" frame="void" id="id6" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="id2">[2]</a></td><td>TEP 2: Hardware Abstraction Architecture.</td></tr>
+<tr><td class="label"><a name="id6">[2]</a></td><td>TEP 2: Hardware Abstraction Architecture.</td></tr>
 </tbody>
 </table>
 </div>
@@ -802,6 +912,99 @@ volume-relative addresses. Clients of the ST M25P HAL must implement the
 obtain the volume id of each of its clients.</p>
 </div>
 </div>
+<div class="section">
+<h1><a id="appendix-b-storage-interfaces" name="appendix-b-storage-interfaces">Appendix B. Storage interfaces</a></h1>
+<p>These interfaces are presented briefly here for reference; please refer
+to the TinyOS documentation for a full description of the commands,
+events and their parameters.</p>
+<div class="section">
+<h2><a id="b-1-blockstorage-interfaces" name="b-1-blockstorage-interfaces">B.1 BlockStorage interfaces</a></h2>
+<p>The BlockStorage interfaces are:</p>
+<pre class="literal-block">
+interface BlockRead {
+  command error_t read(storage_addr_t addr, void* buf, storage_len_t len);
+  event void readDone(storage_addr_t addr, void* buf, storage_len_t len,
+                      error_t error);
+
+  command error_t computeCrc(storage_addr_t addr, storage_len_t len,
+                             uint16_t crc);
+  event void computeCrcDone(storage_addr_t addr, storage_len_t len,
+                            uint16_t crc, error_t error);
+
+  command storage_len_t getSize();
+}
+
+interface BlockWrite {
+  command error_t write(storage_addr_t addr, void* buf, storage_len_t len);
+  event void writeDone(storage_addr_t addr, void* buf, storage_len_t len,
+                       error_t error);
+
+  command error_t erase();
+  event void eraseDone(error_t error);
+
+  command error_t sync();
+  event void syncDone(error_t error);
+}
+</pre>
+</div>
+<div class="section">
+<h2><a id="b-2-configstorage-interfaces" name="b-2-configstorage-interfaces">B.2 ConfigStorage interfaces</a></h2>
+<p>The ConfigStorage interfaces are:</p>
+<pre class="literal-block">
+interface Mount {
+  command error_t mount();
+  event void mountDone(error_t error);
+}
+
+interface ConfigStorage {
+  command error_t read(storage_addr_t addr, void* buf, storage_len_t len);
+  event void readDone(storage_addr_t addr, void* buf, storage_len_t len,
+                      error_t error);
+
+  command error_t write(storage_addr_t addr, void* buf, storage_len_t len);
+  event void writeDone(storage_addr_t addr, void* buf, storage_len_t len,
+                       error_t error);
+
+  command error_t commit();
+  event void commitDone(error_t error);
+
+  command storage_len_t getSize();
+  command bool valid();
+}
+</pre>
+</div>
+<div class="section">
+<h2><a id="b-3-logstorage-interfaces" name="b-3-logstorage-interfaces">B.3 LogStorage interfaces</a></h2>
+<p>The LogStorage interfaces are:</p>
+<pre class="literal-block">
+interface LogRead {
+  command error_t read(void* buf, storage_len_t len);
+  event void readDone(void* buf, storage_len_t len, error_t error);
+
+  command storage_cookie_t currentOffset();
+
+  command error_t seek(storage_cookie_t offset);
+  event void seekDone(error_t error);
+
+  command storage_len_t getSize();
+}
+
+interface LogWrite {
+  command error_t append(void* buf, storage_len_t len);
+  event void appendDone(void* buf, storage_len_t len, bool recordsLost,
+                        error_t error);
+
+  command storage_cookie_t currentOffset();
+
+  command error_t erase();
+  event void eraseDone(error_t error);
+
+  command error_t sync();
+  event void syncDone(error_t error);
+}
+</pre>
+</div>
+</div>
 </div>
 </body>
 </html>
index 4becd9dfbd93d01e189ad8991737291fc27e3543..d65a035a650aaa60dcb412829da57249881fbd23 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis and Cory Sharp</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.3</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.10</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-08</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-08-17</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index 4814463fe9b57853936f124179c6a3bf21c0b36e..5c9f4e3673cb3adff10e9d1a45d4dcecc63d8ad5 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.11</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-06-13</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index f1d33c115e50e9047fb8deca9bf590b3c4fe4b0a..cfde1dd6e491a33a65b9d3cae7432a1b68d1d7a6 100644 (file)
@@ -307,7 +307,7 @@ ul.auto-toc {
 <br />Vlado Handziski</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">28-Mar-2005</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.3</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.11</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-08</td>
 </tr>
index ac263e9b3015ea2fb9ca8e668fb566dac5878109..dec7d902550c9a7271a903d8ca210fb31f652848 100644 (file)
@@ -367,9 +367,11 @@ sensor itself. The naming of the sensor driver components should
 reflect the specifc name of the sensor, and optionally provide a
 component with a generic name for application authors who only care
 about the general class of the sensor.</p>
-<p>This document assumes that sensors return uninterpreted values of
-arbitrary size or datatype. Conversion of sensor values to something
-with actual physical meaning is beyond the scope of this document.</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 interpret the value properly.</p>
 </div>
 <div class="section">
 <h1><a id="sensor-hil-components" name="sensor-hil-components">2. Sensor HIL Components</a></h1>
@@ -496,31 +498,7 @@ implementation {
 </pre>
 </div>
 <div class="section">
-<h1><a id="sensor-hpl-components" name="sensor-hpl-components">4. Sensor HPL Components</a></h1>
-<p>A sensor HPL is necessarily platform-dependent or
-sensorboard-dependent. These components should provide access to the
-physical resources needed by the sensor, in a platform-independent
-manner that can be used by the shared logic of the sensor HAL
-components. In the case of bus-based sensors, this HPL may be nothing
-more than wiring to the appropriate bus interface for use by the HAL
-component.</p>
-<p>For example:</p>
-<pre class="literal-block">
-configuration HplSensirionSht11C {
-  provides interface Init;
-  provides interface Resource[ uint8_t id ];
-  provides interface GeneralIO as DATA;
-  provides interface GeneralIO as SCK;
-  provides interface GpioInterrupt as InterruptDATA;
-}
-implementation {
-  // connect to platform or sensorboard-dependent resources
-  // power-manage the sensor through platform-specific means
-}
-</pre>
-</div>
-<div class="section">
-<h1><a id="directory-organization-guidelines" name="directory-organization-guidelines">5. Directory Organization Guidelines</a></h1>
+<h1><a id="directory-organization-guidelines" name="directory-organization-guidelines">4. Directory Organization Guidelines</a></h1>
 <p>Because the same physical sensor may be attached to TinyOS platforms
 in many different ways, the organization of sensor drivers should
 reflect the distinction between sensor and sensor interconnect.</p>
@@ -590,7 +568,7 @@ components may 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 class="section">
-<h1><a id="authors-addresses" name="authors-addresses">6. Authors' Addresses</a></h1>
+<h1><a id="authors-addresses" name="authors-addresses">5. Authors' Addresses</a></h1>
 <div class="line-block">
 <div class="line">David Gay</div>
 <div class="line">2150 Shattuck Ave, Suite 1300</div>
@@ -634,7 +612,7 @@ receives enough <cite>-I</cite> directives to locate all of the necessary pieces
 </div>
 </div>
 <div class="section">
-<h1><a id="citations" name="citations">7. Citations</a></h1>
+<h1><a id="citations" name="citations">6. Citations</a></h1>
 <table class="docutils citation" frame="void" id="tep2" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
@@ -654,6 +632,413 @@ receives enough <cite>-I</cite> directives to locate all of the necessary pieces
 </tbody>
 </table>
 </div>
+<div class="section">
+<h1><a id="appendix-a-sensor-driver-examples" name="appendix-a-sensor-driver-examples">Appendix A: Sensor Driver Examples</a></h1>
+<div class="section">
+<h2><a id="analog-adc-connected-sensor" name="analog-adc-connected-sensor">1. Analog ADC-Connected Sensor</a></h2>
+<p>The Analog sensor requires two components</p>
+<ul class="simple">
+<li>a component to present the sensor itself (HamamatsuS1087ParC)</li>
+<li>a component to select the appropriate hardware resources, such as
+ADC port 4, reference voltage 1.5V, and a slow sample and hold time
+(HamamatsuS1087ParP).</li>
+</ul>
+<p>The AdcReadClientC component and underlying machinery handles all of
+the arbitration and access to the ADC.</p>
+<pre class="literal-block">
+tos/platforms/telosa/chips/s1087/HamamatsuS1087ParC.nc
+
+generic configuration HamamatsuS1087ParC() {
+  provides interface Read&lt;uint16_t&gt;;
+  provides interface ReadStream&lt;uint16_t&gt;;
+}
+implementation {
+  components new AdcReadClientC();
+  Read = AdcReadClientC;
+
+  components new AdcReadStreamClientC();
+  ReadStream = AdcReadStreamClientC;
+
+  components HamamatsuS1087ParP;
+  AdcReadClientC.Msp430Adc12Config -&gt; HamamatsuS1087ParP;
+  AdcReadStreamClientC.Msp430Adc12Config -&gt; HamamatsuS1087ParP;
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/s1087/HamamatsuS1087ParP.nc
+
+module HamamatsuS1087ParP {
+  provides interface Msp430Adc12Config;
+}
+implementation {
+
+  async command msp430adc12_channel_config_t
+    Msp430Adc12Config.getChannelSettings() {
+
+    msp430adc12_channel_config_t config = {
+      inch: INPUT_CHANNEL_A4,
+      sref: REFERENCE_VREFplus_AVss,
+      ref2_5v: REFVOLT_LEVEL_1_5,
+      adc12ssel: SHT_SOURCE_ACLK,
+      adc12div: SHT_CLOCK_DIV_1,
+      sht: SAMPLE_HOLD_4_CYCLES,
+      sampcon_ssel: SAMPCON_SOURCE_SMCLK,
+      sampcon_id: SAMPCON_CLOCK_DIV_1
+    };
+
+    return config;
+  }
+}
+</pre>
+</div>
+<div class="section">
+<h2><a id="binary-pin-connected-sensor" name="binary-pin-connected-sensor">2. Binary Pin-Connected Sensor</a></h2>
+<p>The Binary sensor gets a bit more complex, because it has three
+components:</p>
+<ul class="simple">
+<li>one to present the sensor (UserButtonC)</li>
+<li>one to execute the driver logic (UserButtonLogicP)</li>
+<li>one to select the appropriate hardware resources, such as MSP430
+Port 27 (HplUserButtonC).</li>
+</ul>
+<p>Note that the presentation of this sensor is not arbitrated because
+none of the operations are split-phase.</p>
+<pre class="literal-block">
+tos/platforms/telosa/UserButtonC.nc
+
+configuration UserButtonC {
+  provides interface Get&lt;bool&gt;;
+  provides interface Notify&lt;bool&gt;;
+}
+implementation {
+
+  components UserButtonLogicP;
+
+  components HplUserButtonC;
+  UserButtonLogicP.GpioInterrupt -&gt; HplUserButtonC.GpioInterrupt;
+  UserButtonLogicP.GeneralIO -&gt; HplUserButtonC.GeneralIO;
+
+  Get = UserButtonLogicP;
+  Notify = UserButtonLogicP;
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/UserButtonLogicP.nc
+
+module UserButtonLogicP {
+  provides interface Get&lt;bool&gt;;
+  provides interface Notify&lt;bool&gt;;
+
+  uses interface GeneralIO;
+  uses interface GpioInterrupt;
+}
+implementation {
+  norace bool m_pinHigh;
+
+  task void sendEvent();
+
+  command bool Get.get() { return call GeneralIO.get(); }
+
+  command error_t Notify.enable() {
+    call GeneralIO.makeInput();
+
+    if ( call GeneralIO.get() ) {
+      m_pinHigh = TRUE;
+      return call GpioInterrupt.enableFallingEdge();
+    } else {
+      m_pinHigh = FALSE;
+      return call GpioInterrupt.enableRisingEdge();
+    }
+  }
+
+  command error_t Notify.disable() {
+    return call GpioInterrupt.disable();
+  }
+
+  async event void GpioInterrupt.fired() {
+    call GpioInterrupt.disable();
+
+    m_pinHigh = !m_pinHigh;
+
+    post sendEvent();
+  }
+
+  task void sendEvent() {
+    bool pinHigh;
+    pinHigh = m_pinHigh;
+
+    signal Notify.notify( pinHigh );
+
+    if ( pinHigh ) {
+      call GpioInterrupt.enableFallingEdge();
+    } else {
+      call GpioInterrupt.enableRisingEdge();
+    }
+  }
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/HplUserButtonC.nc
+
+configuration HplUserButtonC {
+  provides interface GeneralIO;
+  provides interface GpioInterrupt;
+}
+implementation {
+
+  components HplMsp430GeneralIOC as GeneralIOC;
+
+  components new Msp430GpioC() as UserButtonC;
+  UserButtonC -&gt; GeneralIOC.Port27;
+  GeneralIO = UserButtonC;
+
+  components HplMsp430InterruptC as InterruptC;
+
+  components new Msp430InterruptC() as InterruptUserButtonC;
+  InterruptUserButtonC.HplInterrupt -&gt; InterruptC.Port27;
+  GpioInterrupt = InterruptUserButtonC.Interrupt;
+}
+</pre>
+</div>
+<div class="section">
+<h2><a id="digital-bus-connected-sensor" name="digital-bus-connected-sensor">3. Digital Bus-Connected Sensor</a></h2>
+<p>The Digital sensor is the most complex out of the set, and includes
+six components:</p>
+<ul class="simple">
+<li>one to present the sensor (SensirionSht11C)</li>
+<li>one to request arbitrated access and to transform the sensor HAL
+into the sensor HIL (SensirionSht11P)</li>
+<li>one to present the sensor HAL (HalSensirionSht11C)</li>
+<li>one to perform the driver logic needed to support the HAL, which
+twiddles pins according to a sensor-specific protocol
+(SensirionSht11LogicP).</li>
+<li>one to select the appropriate hardware resources, such as the clock,
+data, and power pins, and to provide an arbiter for the sensor
+(HplSensirionSht11C).</li>
+<li>one to perform the power control logic needed to support the power
+manager associated with the arbiter (HplSensirionSht11P).</li>
+</ul>
+<p>This bus-connected sensor is overly complex because it does not rely
+on a shared framework of bus manipulation components. A sensor built
+on top of the I2C or SPI bus would likely require fewer components.</p>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/SensirionSht11C.nc
+
+generic configuration SensirionSht11C() {
+  provides interface Read&lt;uint16_t&gt; as Temperature;
+  provides interface Read&lt;uint16_t&gt; as Humidity;
+}
+implementation {
+  components new SensirionSht11ReaderP();
+
+  Temperature = SensirionSht11ReaderP.Temperature;
+  Humidity = SensirionSht11ReaderP.Humidity;
+
+  components HalSensirionSht11C;
+
+  enum { TEMP_KEY = unique(&quot;Sht11.Resource&quot;) };
+  enum { HUM_KEY = unique(&quot;Sht11.Resource&quot;) };
+
+  SensirionSht11ReaderP.TempResource -&gt; HalSensirionSht11C.Resource[ TEMP_KEY ];
+  SensirionSht11ReaderP.Sht11Temp -&gt; HalSensirionSht11C.SensirionSht11[ TEMP_KEY ];
+  SensirionSht11ReaderP.HumResource -&gt; HalSensirionSht11C.Resource[ HUM_KEY ];
+  SensirionSht11ReaderP.Sht11Hum -&gt; HalSensirionSht11C.SensirionSht11[ HUM_KEY ];
+}
+</pre>
+<pre class="literal-block">
+tos/chips/sht11/SensirionSht11ReaderP.nc
+
+generic module SensirionSht11ReaderP() {
+  provides interface Read&lt;uint16_t&gt; as Temperature;
+  provides interface Read&lt;uint16_t&gt; as Humidity;
+
+  uses interface Resource as TempResource;
+  uses interface Resource as HumResource;
+  uses interface SensirionSht11 as Sht11Temp;
+  uses interface SensirionSht11 as Sht11Hum;
+}
+implementation {
+  command error_t Temperature.read() {
+    call TempResource.request();
+    return SUCCESS;
+  }
+
+  event void TempResource.granted() {
+    error_t result;
+    if ((result = call Sht11Temp.measureTemperature()) != SUCCESS) {
+      call TempResource.release();
+      signal Temperature.readDone( result, 0 );
+    }
+  }
+
+  event void Sht11Temp.measureTemperatureDone( error_t result, uint16_t val ) {
+    call TempResource.release();
+    signal Temperature.readDone( result, val );
+  }
+
+  command error_t Humidity.read() {
+    call HumResource.request();
+    return SUCCESS;
+  }
+
+  event void HumResource.granted() {
+    error_t result;
+    if ((result = call Sht11Hum.measureHumidity()) != SUCCESS) {
+      call HumResource.release();
+      signal Humidity.readDone( result, 0 );
+    }
+  }
+
+  event void Sht11Hum.measureHumidityDone( error_t result, uint16_t val ) {
+    call HumResource.release();
+    signal Humidity.readDone( result, val );
+  }
+
+  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 Sht11Temp.writeStatusRegDone( error_t result ) { }
+
+  event void Sht11Hum.resetDone( error_t result ) { }
+  event void Sht11Hum.measureTemperatureDone( error_t result, uint16_t val ) { }
+  event void Sht11Hum.readStatusRegDone( error_t result, uint8_t val ) { }
+  event void Sht11Hum.writeStatusRegDone( error_t result ) { }
+
+  default event void Temperature.readDone( error_t result, uint16_t val ) { }
+  default event void Humidity.readDone( error_t result, uint16_t val ) { }
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/HalSensirionSht11C.nc
+
+configuration HalSensirionSht11C {
+  provides interface Resource[ uint8_t client ];
+  provides interface SensirionSht11[ uint8_t client ];
+}
+implementation {
+  components new SensirionSht11LogicP();
+  SensirionSht11 = SensirionSht11LogicP;
+
+  components HplSensirionSht11C;
+  Resource = HplSensirionSht11C.Resource;
+  SensirionSht11LogicP.DATA -&gt; HplSensirionSht11C.DATA;
+  SensirionSht11LogicP.CLOCK -&gt; HplSensirionSht11C.SCK;
+  SensirionSht11LogicP.InterruptDATA -&gt; HplSensirionSht11C.InterruptDATA;
+
+  components new TimerMilliC();
+  SensirionSht11LogicP.Timer -&gt; TimerMilliC;
+
+  components LedsC;
+  SensirionSht11LogicP.Leds -&gt; LedsC;
+}
+</pre>
+<pre class="literal-block">
+tos/chips/sht11/SensirionSht11LogicP.nc
+
+generic module SensirionSht11LogicP() {
+  provides interface SensirionSht11[ uint8_t client ];
+
+  uses interface GeneralIO as DATA;
+  uses interface GeneralIO as CLOCK;
+  uses interface GpioInterrupt as InterruptDATA;
+
+  uses interface Timer&lt;TMilli&gt;;
+
+  uses interface Leds;
+}
+implementation {
+
+  ... bus protocol details omitted for brevity ...
+
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/HplSensirionSht11C.nc
+
+configuration HplSensirionSht11C {
+  provides interface Resource[ uint8_t id ];
+  provides interface GeneralIO as DATA;
+  provides interface GeneralIO as SCK;
+  provides interface GpioInterrupt as InterruptDATA;
+}
+implementation {
+  components HplMsp430GeneralIOC;
+
+  components new Msp430GpioC() as DATAM;
+  DATAM -&gt; HplMsp430GeneralIOC.Port15;
+  DATA = DATAM;
+
+  components new Msp430GpioC() as SCKM;
+  SCKM -&gt; HplMsp430GeneralIOC.Port16;
+  SCK = SCKM;
+
+  components new Msp430GpioC() as PWRM;
+  PWRM -&gt; HplMsp430GeneralIOC.Port17;
+
+  components HplSensirionSht11P;
+  HplSensirionSht11P.PWR -&gt; PWRM;
+  HplSensirionSht11P.DATA -&gt; DATAM;
+  HplSensirionSht11P.SCK -&gt; SCKM;
+
+  components new TimerMilliC();
+  HplSensirionSht11P.Timer -&gt; TimerMilliC;
+
+  components HplMsp430InterruptC;
+  components new Msp430InterruptC() as InterruptDATAC;
+  InterruptDATAC.HplInterrupt -&gt; HplMsp430InterruptC.Port15;
+  InterruptDATA = InterruptDATAC.Interrupt;
+
+  components new FcfsArbiterC( &quot;Sht11.Resource&quot; ) as Arbiter;
+  Resource = Arbiter;
+
+  components new SplitControlPowerManagerC();
+  SplitControlPowerManagerC.SplitControl -&gt; HplSensirionSht11P;
+  SplitControlPowerManagerC.ArbiterInit -&gt; Arbiter.Init;
+  SplitControlPowerManagerC.ArbiterInfo -&gt; Arbiter.ArbiterInfo;
+  SplitControlPowerManagerC.ResourceController -&gt; Arbiter.ResourceController;
+}
+</pre>
+<pre class="literal-block">
+tos/platforms/telosa/chips/sht11/HplSensirionSht11P.nc
+
+module HplSensirionSht11P {
+  provides interface SplitControl;
+  uses interface Timer&lt;TMilli&gt;;
+  uses interface GeneralIO as PWR;
+  uses interface GeneralIO as DATA;
+  uses interface GeneralIO as SCK;
+}
+implementation {
+  task void stopTask();
+
+  command error_t SplitControl.start() {
+    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() {
+    call SCK.makeInput();
+    call SCK.clr();
+    call DATA.makeInput();
+    call DATA.clr();
+    call PWR.clr();
+    post stopTask();
+    return SUCCESS;
+  }
+
+  task void stopTask() {
+    signal SplitControl.stopDone( SUCCESS );
+  }
+}
+</pre>
+</div>
+</div>
 </div>
 </body>
 </html>
index 2f46f3e77bec7304e3e51acf5544745acf85a9c0..e1f4648c2cb4a7bf3f509f89ac1e40a20efb5bad 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">20-Jun-2005</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.2</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-02-08</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index db1226c139e761a5aa909adef7d1dbff76b2c82a..74ac4a0c7455d071366cfd2ff5c0fc66b1e3f10d 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">11-Jul-2005</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.15</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-04</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -416,6 +416,10 @@ Depending on the underlying link layer, the header fields
 preceding it might have different lengths, and packet-level radios
 often require packets to be contiguous memory regions. Overall, these
 complexities make specifying the format of <tt class="docutils literal"><span class="pre">TOS_Msg</span></tt> very difficult.</p>
+<p>TinyOS has traditionally used statically sized packet buffers,
+rather than more dynamic approaches, such as scatter-gather I/O
+in UNIX sockets (see the man page for <tt class="docutils literal"><span class="pre">recv(2)</span></tt> for details).
+TinyOS 2.x continues this approach.</p>
 </div>
 <div class="section">
 <h1><a id="id1" name="id1">2. message_t</a></h1>
@@ -433,7 +437,11 @@ typedef nx_struct message_t {
 passing a message buffer between two different link layers. If the
 data payload were at different offsets for different link layers, then
 passing a packet between two link layers would require a <tt class="docutils literal"><span class="pre">memmove(3)</span></tt>
-operation (essentially, a copy).</p>
+operation (essentially, a copy). Unlike in TinyOS 1.x, where TOS_Msg
+as explicitly an active messaging packet, message_t is a more general
+data-link buffer. In practice, most data-link layers in TinyOS 2.x
+provide active messaging, but it is possible for a non-AM stack to
+share message_t with AM stacks.</p>
 <p>The header, footer, and metadata formats are all opaque. Source code
 cannot access fields directly. Instead, data-link layers provide access
 to fields through nesC interfaces.  Section 3 discusses this in
@@ -542,9 +550,10 @@ for other components.</p>
 <h2><a id="headers" name="headers">3.1 Headers</a></h2>
 <p>The message_t header field is an array of bytes whose size is
 the size of a platform's union of data-link headers.
-Because packets are stored contiguously, the layout of a packet
-in memory is not the same as the layout of its nesC structure.</p>
-<p>A packet header does not necessarily start at the beginning of
+Because radio stacks often prefer packets to be stored contiguously,
+the layout of a packet in memory does not necessarily reflect the
+layout of its nesC structure.</p>
+<p>A packet header MAY start somewhere besides the beginning of
 the message_t. For example, consider the Telos platform:</p>
 <pre class="literal-block">
 typedef union message_header {
@@ -654,22 +663,52 @@ typedef nx_struct cc2420_metadata_t {
 } cc2420_metadata_t;
 </pre>
 </div>
+<div class="section">
+<h2><a id="variable-sized-structures" name="variable-sized-structures">3.5 Variable Sized Structures</a></h2>
+<p>The message_t structure is optimized for packets with fixed-size
+headers and footers. Variable-sized footers are generally easy
+to implement. Variable-sized headers are a bit more difficult.
+There are three general approaches that can be used.</p>
+<p>If the underlying link hardware is byte-based, the header can
+just be stored at the beginning of the message_t, giving it
+a known offset. There may be padding between the header and
+the data region, but assuming a byte-based send path this merely
+requires adjusting the index.</p>
+<p>If the underlying link hardware is packet-based, then the
+protocol stack can either include metadata (e.g., in the
+metadata structure) stating where the header begins or it
+can place the header at a fixed position and use <tt class="docutils literal"><span class="pre">memmove(3)</span></tt>
+on reception and transmit. In this latter case, on
+reception the packet is continguously read into the message_t
+beginning at the offset of the header structure. Once the
+packet is completely received, the header can be decoded,
+its length calculated, and the data region of the packet
+can be moved to the <tt class="docutils literal"><span class="pre">data</span></tt> field. On transmission,
+the opposite occurs: the data region (and footer if need
+be) are moved to be contiguous with the header. Note that
+on completion of transmission, they need to be moved back.
+Alternatively, the radio stack can institute a single
+copy at the botttom layer.</p>
+</div>
 </div>
 <div class="section">
-<h1><a id="implementation" name="implementation">5. Implementation</a></h1>
+<h1><a id="implementation" name="implementation">4. Implementation</a></h1>
 <p>The definition of message_t can be found in
-<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/types/message.h</span></tt>. The definition of the CC2420
-message format can be found in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/cc2420/CC2420.h</span></tt>.
-The defintion of the CC1000 message format can be found in
-<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/cc1000/CC1000Msg.h</span></tt>. The definition
+<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/types/message.h</span></tt>.</p>
+<p>The definition of the CC2420
+message format can be found in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/cc2420/CC2420.h</span></tt>.</p>
+<p>The defintion of the CC1000 message format can be found in
+<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/cc1000/CC1000Msg.h</span></tt>.</p>
+<p>The definition
 of the standard serial stack packet format can be found in
-<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/lib/serial/Serial.h''.</span> <span class="pre">The</span> <span class="pre">definition</span> <span class="pre">of</span>
-<span class="pre">the</span> <span class="pre">telosb</span> <span class="pre">packet</span> <span class="pre">format</span> <span class="pre">can</span> <span class="pre">be</span> <span class="pre">found</span> <span class="pre">in</span>
-<span class="pre">``tinyos-2.x/tos/platform/telosa/platform_message.h</span></tt> and the micaz format can be found in
+<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/lib/serial/Serial.h</span></tt></p>
+<p>The definition of
+the telos family packet format can be found in
+<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/platform/telosa/platform_message.h</span></tt> and the micaz format can be found in
 <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/platforms/micaz/platform_message.h</span></tt>.</p>
 </div>
 <div class="section">
-<h1><a id="author-s-address" name="author-s-address">6. Author's Address</a></h1>
+<h1><a id="author-s-address" name="author-s-address">5. Author's Address</a></h1>
 <div class="line-block">
 <div class="line">Philip Levis</div>
 <div class="line">358 Gates Hall</div>
index 82f534fdcc462d66f1fe2522efd66829118ce2c9..2dcba25ef56fcd2c22903d7e9a1359fd589339dd 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Robert Szewczyk, Philip Levis, Martin Turon, Lama Nachman, Philip Buonadonna, Vlado Handziski</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">19-Sep-2005</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.2</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2005-10-31</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index 6bb77b955b68d2860bb23a398dfd0d083bdfcebd..3bb4595da65ddde5a27ca375a82367ae35709e76 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Ben Greenstein and Philip Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">11-Jul-2005</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.5</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-11-06</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -691,19 +691,19 @@ no snooping capabilities.</p>
 <table class="docutils citation" frame="void" id="tep2" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="tep2">[TEP2]</a></td><td>TEP 2: Hardware Abstraction Architecture. <a class="reference" href="http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep2.txt?view=markup">http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep2.txt?view=markup</a></td></tr>
+<tr><td class="label"><a name="tep2">[TEP2]</a></td><td>TEP 2: Hardware Abstraction Architecture. tinyos-2.x/doc/txt/tep2.txt</td></tr>
 </tbody>
 </table>
 <table class="docutils citation" frame="void" id="tep111" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="tep111">[TEP111]</a></td><td>TEP 111: message_t. <a class="reference" href="http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep111.txt?view=markup">http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep111.txt?view=markup</a></td></tr>
+<tr><td class="label"><a name="tep111">[TEP111]</a></td><td>TEP 111: message_t. tinyos-2.x/doc/txt/tep111.txt</td></tr>
 </tbody>
 </table>
 <table class="docutils citation" frame="void" id="tep116" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a name="tep116">[TEP116]</a></td><td>TEP 116: Packet Protocols. <a class="reference" href="http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep116.txt?view=markup">http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep116.txt?view=markup</a></td></tr>
+<tr><td class="label"><a name="tep116">[TEP116]</a></td><td>TEP 116: Packet Protocols. tinyos-2.x/doc/txt/tep116.txt</td></tr>
 </tbody>
 </table>
 <table class="docutils citation" frame="void" id="hdlc" rules="none">
index 2a63b51640f4aafade0a1c0ac5b3d50dc076a6cf..5476f57cec4bb343ae08dc2f2bc07a9327bfaa85 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Gilman Tolle, Philip Levis, and David Gay</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">30-Oct-2005</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.3</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.4</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-08</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-08-30</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index 633dd17ae6792d077755891374c2a0f200f8bef6..09830d6bea39682f6ad99528f1b04459e98c0171 100644 (file)
@@ -5,7 +5,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
 <title>Power Management of Non-Virtualised Devices</title>
-<meta name="author" content="Vlado Handziski, Kevin Klues, Jan-Hinrich Hauer, Phil Levis" />
+<meta name="author" content="Kevin Klues, Vlado Handziski, Jan-Hinrich Hauer, Phil Levis" />
 <style type="text/css">
 
 /*
@@ -300,12 +300,12 @@ ul.auto-toc {
 <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>Vlado Handziski, Kevin Klues, Jan-Hinrich Hauer, Phil Levis</td></tr>
+<td>Kevin Klues, Vlado Handziski, Jan-Hinrich Hauer, Phil Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">11-Jan-2006</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.4</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-19</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List
 &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
index 50b9aa6383ea42c7bacbeb292cc32270cbf69605..e7f71113a58c07ce1ef8e936bef7f7027e49d9b7 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.11</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-06-27</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index 7d1b01d94e0a1eb443d9ffa0169a91deb786363f..077bb58acbbd913edf7387d9583c518928db15bc 100644 (file)
@@ -4,8 +4,8 @@
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
-<title>Pins and Buses</title>
-<meta name="author" content="Phil Buonadonna" />
+<title>Low-Level I/O</title>
+<meta name="author" content="Phil Buonadonna, Jonathan Hui" />
 <style type="text/css">
 
 /*
@@ -283,8 +283,8 @@ ul.auto-toc {
 </style>
 </head>
 <body>
-<div class="document" id="pins-and-buses">
-<h1 class="title">Pins and Buses</h1>
+<div class="document" id="low-level-i-o">
+<h1 class="title">Low-Level I/O</h1>
 <table class="docinfo" frame="void" rules="none">
 <col class="docinfo-name" />
 <col class="docinfo-content" />
@@ -300,12 +300,12 @@ ul.auto-toc {
 <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>Phil Buonadonna</td></tr>
+<td>Phil Buonadonna, Jonathan Hui</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">23-Jan-2006</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.9</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-30</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -321,35 +321,34 @@ TEP 1.</p>
 <div class="section">
 <h1><a id="abstract" name="abstract">Abstract</a></h1>
 <p>The memo documents the TinyOS 2.x interfaces used for controlling
-digital IO functionality and digital interfaces other than serial
-communication covered in [tep113].</p>
+digital IO functionality and digital interfaces.</p>
 </div>
 <div class="section">
 <h1><a id="introduction" name="introduction">1. Introduction</a></h1>
 <p>The canonical TinyOS device is likely to have a variety of digital
 interfaces. These interfaces may be divided into two broad
-categories. The first are general purpose digital I/O lines (pins)
-for individual digital signals at physical pins on a chip or
-platform. The second are digital I/O interfaces that have predefined
-communication protocol formats. The two buses covered in this
-document are the Serial Peripheral Interface (SPI) and the
-Inter-Integrated Circuit (I2c) or Two-Wire interface. While there are
-likely other bus formats, we presume SPI and I2C to have the largest
-coverage. While the UART interface is also in this category, it is
-covered separately in [tep113].</p>
-<p>This memo documents the interfaces used for pins and the two buses.</p>
+categories. The first are general purpose digital I/O lines (pins) for
+individual digital signals at physical pins on a chip or platform. The
+second are digital I/O interfaces that have predefined communication
+protocol formats. The three buses covered in this document are the
+Serial Peripheral Interface (SPI), the Inter-Integrated Circuit (I2C)
+or Two-Wire interface, and the Universal Asynchronous
+Receiver/Transmitter (UART) interface. While there are likely other
+bus formats, we presume SPI, I2C, and UART to have the largest
+coverage.</p>
+<p>This memo documents the interfaces used for pins and the three buses.</p>
 </div>
 <div class="section">
 <h1><a id="pins" name="pins">2. Pins</a></h1>
-<p>General Purpose I/O (GPIO) pins are single, versatile digital I/O signals
-individually controllable on a particular chip or platform. Each GPIO
-can be placed into either an input mode or an output mode. On
-some platforms a third 'tri-state' mode may exist, but this
-functionality is platform specific and will not be covered in this
-document.</p>
-<p>On many platforms, a physical pin may function as either a digital GPIO
-or another special function I/O such. Examples include ADC I/O or a bus
-I/O. Interfaces to configure the specific function of a pin are
+<p>General Purpose I/O (GPIO) pins are single, versatile digital I/O
+signals individually controllable on a particular chip or
+platform. Each GPIO can be placed into either an input mode or an
+output mode. On some platforms a third 'tri-state' mode may exist, but
+this functionality is platform specific and will not be covered in
+this document.</p>
+<p>On many platforms, a physical pin may function as either a digital
+GPIO or another special function I/O such. Examples include ADC I/O or
+a bus I/O. Interfaces to configure the specific function of a pin are
 platform specific.</p>
 <p>The objective of the interfaces described here is not to attempt to
 cover all possibilities of GPIO functionality and features, but to
@@ -398,7 +397,9 @@ interface GeneralIO
   async command void toggle();
   async command bool get();
   async command void makeInput();
+  async command bool isInput();
   async command void makeOutput();
+  async command bool isOutput();
 }
 </pre>
 </div>
@@ -414,7 +415,9 @@ through a platform specific HAL interface.</p>
 interface GpioInterrupt {
 
   async command error_t enableRisingEdge();
+  async command bool isRisingEdgeEnabled();
   async command error_t enableFallingEdge();
+  async command bool isFallingEdgeEnabled();
   async command error_t disable();
   async event void fired();
 
@@ -428,12 +431,15 @@ with a GPIO event. Platforms MAY provide this interface.</p>
 <p>Some platforms may have hardware support for such a feature. Other
 platforms may emulate this capability using the SoftCaptureC
 component. The interface makes not declaration of the precision or
-accuracy of the timestamp with respect to the associated GPIO event.</p>
+accuracy of the timestamp with respect to the associated GPIO
+event.</p>
 <pre class="literal-block">
 interface GpioCapture {
 
   async command error_t captureRisingEdge();
+  async command bool isRisingEdgeEnabled();
   async command error_t captureFallingEdge();
+  async command bool isFallingEdgeEnabled();
   async event void captured(uint16_t time);
   async command void disable();
 
@@ -463,18 +469,18 @@ interfaces and implementations.</p>
 asynchronous packet level interface. The byte level interface is
 intended for short transactions (3-4 bytes) on the SPI bus.</p>
 <pre class="literal-block">
-interface SPIByte {
-  async command error_t write( uint8_t tx, uint8_t* rx );
+interface SpiByte {
+  async command uint8_t write( uint8_t tx );
 }
 </pre>
 <p>The packet level interface is for larger bus transactions. The
-pointer/length interface permits use of hardware assist such as DMA.</p>
+pointer/length interface permits use of hardware assist such as
+DMA.</p>
 <pre class="literal-block">
-interface SPIPacket {
-
+interface SpiPacket {
   async command error_t send( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len );
   async event void sendDone( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len,
-                            error_t error );
+                             error_t error );
 }
 </pre>
 </div>
@@ -483,33 +489,112 @@ interface SPIPacket {
 <p>The Inter-Integrated Circuit (I2C) interface is another type of
 digital bus that is often used for chip-to-chip communication. It is
 also known as a two-wire interface.</p>
-<p>The I2CPacket interface provides for asynchronous Master mode communication on an
-I2C with application framed packets.  It supports only single
-transfers with a start-stop condition around each transfer.</p>
+<p>The I2CPacket interface provides for asynchronous Master mode
+communication on an I2C with application framed packets. Individual
+I2C START-STOP events are controllable which allows the using
+component to do multiple calls within a single I2C transaction and
+permits multiple START sequences</p>
 <p>Platforms providing I2C capability MUST provide this interface.</p>
 <pre class="literal-block">
-interface I2CPacket {
-  async command result_t readPacket(uint16_t _addr, uint8_t _length, uint8_t* _data);
-  async command result_t writePacket(uint16_t _addr, uint8_t _length, uint8_t* _data);
-  async event void readPacketDone(uint16_t addr, uint8_t length, uint8_t* data, result_t success);
-  async event void writePacketDone(uint16_t addr, uint8_t length, uint8_t* data, result_t success);
+interface I2CPacket&lt;addr_size&gt; {
+  async command error_t read(i2c_flags_t flags, uint16_t addr, uint8_t length, u int8_t* data);
+  async event void readDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data);
+  async command error_t write(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data);
+  async event void writeDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data)
+}
+</pre>
+<p>The interface is typed according to the addressing space the
+underlying implementation supports.  Valid type values are below.</p>
+<pre class="literal-block">
+TI2CExtdAddr - Interfaces uses the extended (10-bit) addressing mode.
+TI2CBasicAddr - Interfaces uses the basic (7-bit) addressing mode.
+</pre>
+<p>The i2c_flags_t values are defined below. The flags define the
+behavior of the operation for the call being made. These values may be
+ORed together.</p>
+<pre class="literal-block">
+I2C_START    - Transmit an I2C STOP at the beginning of the operation.
+I2C_STOP     - Transmit an I2C STOP at the end of the operation. Cannot be used
+               with the I2C_ACK_END flag.
+I2C_ACK_END  - ACK the last byte sent from the buffer. This flags is only valid
+               a write operation. Cannot be used with the I2C_STOP flag.
+</pre>
+</div>
+<div class="section">
+<h2><a id="uart" name="uart">3.3 UART</a></h2>
+<p>The Universal Asynchronous Receiver/Transmitter (UART) interface is a
+type of serial interconnect. The interface is &quot;asynchronous&quot; since it
+recovers timing from the data stream itself, rather than a separate
+control stream. The interface is split into an asynchronous multi-byte
+level interface and a synchronous single-byte level interface.</p>
+<p>The multi-byte level interface, UartStream, provides a split-phase
+interface for sending and receiving one or more bytes at a time. When
+receiving bytes, a byte-level interrupt can be enabled or an interrupt
+can be generated after receiving one or more bytes. The latter is
+intended to support use cases where the number of bytes to receive is
+already known. If the byte-level receive interrupt is enabled, the
+receive command MUST return FAIL. If a multi-byte receive interrupt is
+enabled, the enableReceiveInterrupt command MUST return FAIL.</p>
+<pre class="literal-block">
+interface UartStream {
+  async command error_t send( uint8_t* buf, uint16_t len );
+  async event void sendDone( uint8_t* buf, uint16_t len, error_t error );
+
+  async command error_t enableReceiveInterrupt();
+  async command error_t disableReceiveInterrupt();
+  async event void receivedByte( uint8_t byte );
+
+  async command error_t receive( uint8_t* buf, uint8_t len );
+  async event void receiveDone( uint8_t* buf, uint16_t len, error_t error );
+}
+</pre>
+<p>The single-byte level interface, UartByte, provides a synchronous
+interface for sending and receiving a single byte. This interface is
+intended to support use cases with short transactions. Because UART is
+asynchronous, the receive command takes a timeout which represents
+units in byte-times, after which the command returns with an
+error. Note that use of this interface is discouraged if the UART baud
+rate is low.</p>
+<pre class="literal-block">
+interface UartByte {
+  async command error_t send( uint8_t byte );
+  async command error_t receive( uint8_t* byte, uint8_t timeout );
 }
 </pre>
 </div>
 </div>
 <div class="section">
-<h1><a id="author-s-address" name="author-s-address">4. Author's Address</a></h1>
+<h1><a id="implementation" name="implementation">4. Implementation</a></h1>
+<p>Example implementations of the pin interfaces can be found in tos/chips/msp430/pins,
+tos/chips/atm128/pins, and tos/chips/pxa27x/gpio.</p>
+<p>Example implementations of the SPI interfaces can be found in tos/chips/msp430/usart,
+tos/chips/atm128/spi, and tos/chips/pxa27x/ssp.</p>
+<p>Example implementations of the I2C interfaces can be found in tos/chips/msp430/usart,
+tos/chips/atm128/i2c, and tos/chips/pxa27x/i2c.</p>
+<p>Example implementations of the UART interfaces can be found in tos/chips/msp430/usart,
+tos/chips/atm128/uart/ and tos/chips/pxa27x/uart.</p>
+</div>
+<div class="section">
+<h1><a id="author-s-address" name="author-s-address">5. Author's Address</a></h1>
 <div class="line-block">
 <div class="line">Phil Buonadonna</div>
-<div class="line">Arched Rock Corporation</div>
+<div class="line">Arch Rock Corporation</div>
 <div class="line">657 Mission St. Ste 600</div>
 <div class="line">San Francisco, CA 94105-4120</div>
 <div class="line"><br /></div>
 <div class="line">phone - +1 415 692-0828 x2833</div>
+<div class="line"><br /></div>
+<div class="line"><br /></div>
+<div class="line">Jonathan Hui</div>
+<div class="line">Arched Rock Corporation</div>
+<div class="line">657 Mission St. Ste 600</div>
+<div class="line">San Francisco, CA 94105-4120</div>
+<div class="line"><br /></div>
+<div class="line">phone - +1 415 692-0828 x2835</div>
 </div>
 </div>
 <div class="section">
-<h1><a id="citations" name="citations">5. Citations</a></h1>
+<h1><a id="citations" name="citations">6. Citations</a></h1>
 <table class="docutils citation" frame="void" id="tep113" rules="none">
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
index 47d1b974aab9e8cf3b1bb4568de64e29eda8a01f..dfede355926d98906026ca8f2387a7c923a99160 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Philip Levis and Gilman Tolle</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.3</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-06-20</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -401,7 +401,7 @@ generic configuration DisseminatorC(typedef t, uint16_t key) {
   provides interface DisseminationUpdate &lt;t&gt;;
 }
 </pre>
-<p>The t argument MUST be able to fit in a single message_t[<a href="#id4" name="id5"><span class="problematic" id="id5">tep111_</span></a>]  after
+<p>The t argument MUST be able to fit in a single message_t[<a class="reference" href="#id2">1</a>]  after
 considering the headers that the dissemination protocol introduces.
 A dissemination implementation SHOULD have a compile error if a larger
 type than this is used.</p>
@@ -516,12 +516,6 @@ trickle.</p>
 </tbody>
 </table>
 </div>
-<div class="system-messages section">
-<h1>Docutils System Messages</h1>
-<div class="system-message" id="id4">
-<p class="system-message-title">System Message: <a name="id4">ERROR/3</a> (<tt class="docutils">txt/tep118.txt</tt>, line 116); <em><a href="#id5">backlink</a></em></p>
-Unknown target name: &quot;tep111&quot;.</div>
-</div>
 </div>
 </body>
 </html>
index 3719f95ec2cf6198818bc906cc7e31a55b646e3f..32516a775e15b1933b0a5c6c365bf0a15c6f62b4 100644 (file)
@@ -497,36 +497,54 @@ such as queueing and timing.</p>
 <p>LinkEstimatorP estimates the quality of link to or from each
 neighbor. Link estimation can be done in a variety of ways, and we do
 not impose one here. It is decoupled from the establishment of
-routes. There is a narrow interface (LinkEstimator) between the link
-estimator and the routing engine. The one requirement is that the
-quality returned is standardized. A larger return value from
-LinkEstimator.getQuality(), LinkEstimator.getforwardQuality(),
-LinkEstimator.getreserveQuality() MUST imply that the link to the
-neighbor is estimated to be of a higher quality than the one that
-results in a smaller return value. The range of value SHOULD be
-[0,255] and the variation in link quality in that range SHOULD be
-linear. Radio provided values such as LQI or RSI, beacon based link
-estimation to compute ETX, or their combination are some possible
-approaches to estimating link qualities. LinkEstimatorP MAY have its
-own control messages to compute bi-directional link qualities:</p>
+routes. There is a narrow interface (LinkEstimator and
+NeighborTableEviction) between the link estimator and the routing
+engine. The one requirement is that the quality returned is
+standardized. A smaller return value from LinkEstimator.getQuality(),
+LinkEstimator.getforwardQuality(), LinkEstimator.getreserveQuality()
+MUST imply that the link to the neighbor is estimated to be of a
+higher quality than the one that results in a smaller return
+value. The range of value SHOULD be [0,255] and the variation in link
+quality in that range SHOULD be linear. Radio provided values such as
+LQI or RSI, beacon based link estimation to compute ETX, or their
+combination are some possible approaches to estimating link
+qualities. LinkEstimatorP MAY have its own control messages to compute
+bi-directional link qualities. LinkEstimatorP provides calls (txAck(),
+txNoAck(), and clearDLQ()) to update the link estimates based on
+successful or unsuccessful data transmission to the neighbors. The
+user of LinkEstimatorP can call insertNeighbor() to manually insert a
+node in the neighbor table, pinNeighbor() to prevent a neighbor from
+being evicted, and unpinNeighbor() to restore eviction policy:</p>
 <pre class="literal-block">
-typedef uint16_t neighbor_t
+typedef uint16_t neighbor_table_entry_t
 
 LinkEstimatorP {
   provides {
+    interface StdControl;
+    interface AMSend as Send;
+    interface Receive;
     interface LinkEstimator;
-    interface NeighborTable;
+    interface Init;
+    interface Packet;
+    interface LinkSrcPacket;
   }
 }
 
 interface LinkEstimator {
-  command uint8_t getLinkQuality(neighbot_t neighbor);
-  command uint8_t getReverseQuality(neighbot_t neighbor);
-  command uint8_t getForwardQuality(neighbot_t neighbor);
+  command uint8_t getLinkQuality(uint16_t neighbor);
+  command uint8_t getReverseQuality(uint16_t neighbor);
+  command uint8_t getForwardQuality(uint16_t neighbor);
+  command error_t insertNeighbor(am_addr_t neighbor);
+  command error_t pinNeighbor(am_addr_t neighbor);
+  command error_t unpinNeighbor(am_addr_t neighbor);
+  command error_t txAck(am_addr_t neighbor);
+  command error_t txNoAck(am_addr_t neighbor);
+  command error_t clearDLQ(am_addr_t neighbor);
+  event void evicted(am_addr_t neighbor);
 }
 
-interface NeighborTable {
-  event void evicted(neighbot_t neighbor)
+interface NeighborTableEviction {
+  event void evicted(uint16_t neighbor)
 }
 </pre>
 </div>
index 02affb5a5f1c8bc8d77086f9c40b4241f6b84308..e50e9f1473abfd0caec085cdfdfd36dc9755c5c2 100644 (file)
@@ -314,9 +314,9 @@ ul.auto-toc {
 <br />Adam Wolisz</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">17-April-2006</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.5</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-25</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Alliance &lt;tinyos-alliance at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -758,29 +758,32 @@ standardized interfaces that allows such technology to interoperate.</p>
 </div>
 <div class="section">
 <h1><a id="funding" name="funding">9. Funding</a></h1>
-<p>As with the IETF, individuals are responsible for their own costs,
-which primarily involve meetings, travel, and generation of work
-products.  Membership participation will involve attendance at
-Alliance meetings.  Registration fees will be charged to cover costs
-associated with adminstration of the meetings.</p>
-<p>Companies and institutions are encouraged to contribute financial and
-in-kind support.  It will be essential that companies provide initial
-funding to create the legal structure and to establish basic IT
-capabilities to host the web site and working groups.</p>
 <p>Initially, we expect that there are no full time employees in the
 Alliance and that funding needs are limited to such items as lawyer's
 fees, web site costs, and insurance. If the Alliance eventually
 requires full time support personnel, the funding structure will have
 to be re-visited.</p>
+<p>As with the IETF, individuals are responsible for their own costs,
+which primarily involve meetings, travel, and generation of work
+products.  The Alliance is predominantly a volunteer organization.
+Membership participation will involve attendance at
+Alliance meetings.  Registration fees will be charged to cover costs
+associated with adminstration of the meetings.</p>
 <p>To maintain the focus on technical excellence and meritocracy, we want
 to avoid the heavy-handed quid-pro-quo seen in many industrial
 consortiums where funding determines influence.  The best use of funds
 and the best form of influence is direct contribution to the work
-products of the Alliance.  We will permit targeted contributions
-toward specific working groups or technical capabilities.</p>
-<p>We seek to keep overall structure lean, mostly volunteer.
-Focus on desired impact and recognition, rather than control.</p>
-<p>Institutional members
+products of the Alliance.
+To keep the structure of the Alliance and its operations minimalist
+and lean, membership focuses on desired impact and recognition, rather
+than control. We want the best way to influence the direction of the Alliance
+to be to contribute technical work and demonstrate leadership, rather than
+try to control what individuals can or cannot contribute.</p>
+<p>Companies and institutions are encouraged to contribute financial and
+in-kind support.  It will be essential that companies provide initial
+funding to create the legal structure and to establish basic IT
+capabilities to host the web site and working groups.
+Institutional members
 will pay an annual membership fee. In some cases, a
 contributing corporate member may provide in-kind services
 such as lawyers' time used to
@@ -790,52 +793,80 @@ solicited and encouraged. In this case the donator need not
 become a contributing corporate member, e.g., in those cases
 where such a membership may be prohibited or unwanted.
 The costs of meetings, such as the TinyOS
-technology exchange, will be covered through registration fees.</p>
-<p>Individuals are responsible
-for their own costs such as
-for travel, meeting costs, or costs for contributing
-software or documentation to the Alliance. The Alliance
-is primarily a volunteer organization.</p>
+technology exchange, will be covered through registration fees and
+not by institutional membership fees.</p>
 </div>
 <div class="section">
 <h1><a id="work-products" name="work-products">10. Work Products</a></h1>
-<p>Code base
-Stable, robust core release
-Rapidly evolving, innovative extensions
-Reference Implementations
-Tools
-Data
-Documentation
-Standard proposals
-Marketing and Promotion
-Testing and Compliance
-Assessments
-Applications and uses of technology
-Educational Materials</p>
+<p>The broad mission of the Alliance calls for a broad range of
+work products.</p>
+<p>Foremost among these are a set of TEPs documenting
+systems and protocols as well as TEPs that provide guidance
+and knowledge to the community. Technical documentation will have
+robust and open reference implementations for the community to
+use, refine, improve, and discuss. These reference implementations
+will not preclude alternative, compatibile implementations which may
+have additional features or optimizations. The Alliance Working Groups
+will periodically produce periodic releases of these reference
+implementations for the community to use and improve.</p>
+<p>The Alliance will support community contributions
+of innovative extensions and systems by providing a CVS repository
+to store them.
+In order to keep these contributions organized for users, the
+Steering Committee may nominate one or more people to caretake
+the repository by setting minimal guidelines for the use of
+the directory structure and migrating code as it joins the core
+or falls into disuse.</p>
+<p>To make these technological resources more accessible and useful
+to a broad embedded networks community, the Alliance will be
+dedicated to providing a set of educational materials. This
+includes introductory tutorials, documentation of core systems,
+simple and complex example applications, and user guides.</p>
+<p>In addition to educational sample applications, whose purpose
+is to teach new developers about the internals and workings of
+the technology, the Alliance will develop and make available
+several end-user applications and tools. The goal is to improve
+the accessibility of the technology to end-users while
+demonstrating its effectiveness. Historical examples of such applications
+include Surge and TinyDB. An important part of this effort is
+good documentation for users who are not expert programmers, as well
+as tools and graphical environments.</p>
 </div>
 <div class="section">
 <h1><a id="conclusions" name="conclusions">11. Conclusions</a></h1>
-<p>The time has come to create an organizational structure to allow the effort to grow
-Beyond the Berkeley + Others
-It is a balancing act
-Stability vs Innovation
-Broad Participation vs Strong Requirements
-Uniform Licensing vs Institutional Differences
-Goal is to help to community to work together
-Not a forum for maneuvering and intrigue
-Focus on consensus building and technical soundness
-Minimal mechanism to resolve rare differences
-Focus on working groups and individual contributions
-with architectural and organization oversight
-Be pragmatic on participation
-Don\92t have to make deep commitments to participate
-Can\92t expect broad guarantees in return</p>
+<p>By focusing on consensus building and technical excellence, the
+Alliance seeks to avoid being a forum for political and economic
+positioning. It will achieve this by focusing on working groups
+and the contributions of individuals, while not taking strong
+positions on the benefits or drawbacks of different approaches.
+The variety of application domains sensornets are used in and
+the huge differences in requirements mean that having a suite
+of solutions, rather than a single one, is often not only
+desirable but essential.</p>
+<p>Over the past five years, low-power embedded sensor networks have
+grown from research prototypes to working systems that are being
+actively deployed. Furthermore, there is a vibrant research community
+that actively works to deploy these systems and collaborate with
+industry, making advances quickly accessible and usable. A great
+catalyst to this growth has been the presence of a large community
+around a shared, free code base.</p>
+<p>The time has come to create an organizational structure to
+allow the effort to grow further. As sensornets become more widespread,
+contributions and advancements will be from an increasingly broad
+demographic of users, and bringing them all together will speed
+progress and improve the potential benefit these systems can bring
+to society. This focus on bringing disparate groups together lies
+at the heart of the Alliance. Rather than depend on strong requirements,
+it depends on broad collaboration and participation, placing a minimalist
+set of expectations that will encourage the exchange of ideas and
+technology.</p>
 </div>
 <div class="section">
 <h1><a id="author-s-address" name="author-s-address">12. Author's Address</a></h1>
 <div class="line-block">
 <div class="line">Philippe Bonnet &lt;<a class="reference" href="mailto:bonnet.p&#64;gmail.com">bonnet.p&#64;gmail.com</a>&gt;</div>
 <div class="line">David Culler    &lt;<a class="reference" href="mailto:culler&#64;cs.berkeley.edu">culler&#64;cs.berkeley.edu</a>&gt;</div>
+<div class="line">David Culler &lt;dculler at archrock.com&gt;,</div>
 <div class="line">Deborah Estrin        &lt;<a class="reference" href="mailto:destrin&#64;cs.ucla.edu">destrin&#64;cs.ucla.edu</a>&gt;</div>
 <div class="line">Ramesh Govindan &lt;<a class="reference" href="mailto:ramesh&#64;usc.edu">ramesh&#64;usc.edu</a>&gt;</div>
 <div class="line">Mike Horton   &lt;<a class="reference" href="mailto:mhorton&#64;xbow.com">mhorton&#64;xbow.com</a>&gt;</div>
@@ -847,9 +878,6 @@ Can\92t expect broad guarantees in return</p>
 <div class="line">Matt Welsh    &lt;<a class="reference" href="mailto:mdw&#64;cs.harvard.edu">mdw&#64;cs.harvard.edu</a>&gt;</div>
 <div class="line">Adam Wolisz   &lt;<a class="reference" href="mailto:awo&#64;ieee.org">awo&#64;ieee.org</a>&gt;</div>
 </div>
-<div class="line-block">
-<div class="line">David Culler &lt;dculler at archrock.com&gt;,</div>
-</div>
 </div>
 </div>
 </body>
index 4ff751b42f9d5e5fe53de77fb91cc55a7ba9052d..997d719ff941ddaca9f491342b54de2aade083af 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Rodrigo Fonseca, Omprakash Gnawali, Kyle Jamieson, Sukun Kim, Philip Levis, and Alec Woo</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">3-Aug-2006</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.3</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-09-08</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-10-25</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
@@ -418,14 +418,14 @@ to do so.</p>
 <p>Field definitions are as follows:</p>
 <blockquote>
 <ul class="simple">
-<li>C: Congestion notification. If a node is receiving packets faster than it can forward them, it MAY set the C field to notify other nodes. If a node hears a packet from node N with the C bit set, it MUST NOT transmit CTP data frames to N until it hears a packet from N with the C bit cleared.</li>
-<li>P: Routing pull. The P bit allows nodes to request routing information from other nodes. If a node hears a packet with the P bit set, it SHOULD transmit a routing frame in the near future if it has a valid route.</li>
+<li>C: Congestion notification. If a node is receiving packets faster than it can forward them, it MAY set the C field to notify other nodes. If a node hears a packet from node <em>N</em> with the C bit set, it MUST NOT transmit CTP data frames to <em>N</em> until it hears a packet from N with the C bit cleared.</li>
+<li>P: Routing pull. The P bit allows nodes to request routing information from other nodes. If a node with a valid route hears a packet with the P bit set, it SHOULD transmit a routing frame in the near future.</li>
 <li>THL: Time Has Lived. When a node generates a CTP data frame, it MUST set THL to 0. When a node receives a CTP data frame, it MUST increment the THL. If a node receives a THL of 255, it increments it to 0.</li>
 <li>ETX: The ETX routing metric of the single-hop sender. When a node transmits a CTP data frame, it MUST put the ETX value of its route through the single-hop destination in the ETX field.  If a node receives a packet with a lower gradient than its own, then it MUST schedule a routing frame in the near future.</li>
 <li>origin: The originating address of the packet. A node forwarding a data frame MUST NOT modify the origin field.</li>
 <li>seqno: Origin sequence number. The originating node sets this field, and a node forwarding a data frame MUST NOT modify it.</li>
 <li>collect_id: Higher-level protocol identifier. The origin sets this field, and a node forwarding a data frame MUST NOT modify it.</li>
-<li>data: the data payload, of zero or more bytes.</li>
+<li>data: the data payload, of zero or more bytes. A node forwarding a data frame MUST NOT modify the data payload.</li>
 </ul>
 </blockquote>
 <p>Together, the origin, seqno and collect_id fields denote a unique
@@ -434,9 +434,9 @@ THL denote a unique <strong>*packet instance*</strong> within the network. The
 distinction is important for duplicate suppression in the presence
 of routing loops. If a node suppresses origin packets, then if
 asked to forward the same packet twice due to a routing loop, it will
-drop the packet. However, if it suppresses packet instances, then
-unless the THL has wrapped around to the identical value it had
-on previous times around.</p>
+drop the packet. However, if it suppresses packet instances, then it
+will route succesfully in the presence of transient loops unless the
+THL happens to wrap around to a forwarded packet instance.</p>
 <p>A node MUST send CTP data frames as unicast messages with link-layer
 acknowledgments enabled.</p>
 </div>
@@ -473,6 +473,79 @@ below its own. When a parent hears a child advertise an ETX below its
 own, it MUST schedule a routing frame for transmission in the near
 future.</p>
 </div>
+<div class="section">
+<h1><a id="implementation" name="implementation">6. Implementation</a></h1>
+<p>An implementation of CTP can be found in the tos/lib/net/ctp directory
+of TinyOS 2.0. This section describes the structure of that implementation
+and is not in any way part of the specification of CTP.</p>
+<p>This implementation has three major subcomponents:</p>
+<p>1) A <strong>link estimator</strong>, which is responsible for estimating the
+single-hop ETX of communication with single-hop neighbors.</p>
+<p>2) A <strong>routing engine</strong>, which uses link estimates as well as
+network-level information to decide which neighbor is the next
+routing hop.</p>
+<p>3) A <strong>forwarding engine</strong>, which maintains a queue of packets
+to send. It decides when and if to send them. The name is a little
+misleading: the forwarding engine is responsible for forwarded traffic
+as well as traffic generated on the node.</p>
+<div class="section">
+<h2><a id="link-estimation" name="link-estimation">6.1 Link Estimation</a></h2>
+<p>The link estimator estimates the ETX to single-hop neighbors.
+The implementation uses two mechanisms to estimate the quality of a link:
+periodic broadcast packets and data packets. The estimator itself
+only generates broadcast packets. For data traffic, it depends on
+other components telling it about acknowledged and unacknowledged
+transmissions.</p>
+<p>The periodic broadcast packets have sequence numbers, which the
+estimator uses to estimate the sender-to-receiver packet reception
+rate (PRR). The data payload of periodic broadcast packets contain
+these estimates. Therefore, when node A receives a link estimation
+broadcast message from node B, it can use the packet header to
+estimate the B-to-A PRR and the packet payload to update B's
+estimate of the A-to-B PRR.</p>
+<p>Multiplying these two values gives a <em>bidirectional</em> PRR, or
+an estimate of the probability that if A transmits a packet to B,
+B will successfully hear and acknowledge the packet and A will
+hear the acknowledgment. The inverse of the bidirecitonal PRR
+is the ETX.</p>
+<p>CTP link estimation adapts its beaconing rate to be slow when
+its routing table is stable and faster when changes occur.
+It adjusts the beaconing interval using an algorithm similar
+to the trickle dissemination protocol[<a href="#id1" name="id2"><span class="problematic" id="id2">2_</span></a>]. CTP sends beacons
+more often when one of three conditions occurs:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>The routing table is empty (this also sets the P bit)</li>
+<li>The node's routing ETX increases by &gt;= 1 trasmission</li>
+<li>The node hears a packet with the P bit set</li>
+</ol>
+</blockquote>
+<p>CTP also estimates link quality using data transmissions. This
+is a direct measure of ETX. Whenever the data path transmits a
+packet, it tells the link estimator the destimation and whether
+it was successfully acknowledged. The estimator produces an ETX
+estimate every 5 such transmissions, where 0 successes has an
+ETX of 6.</p>
+<p>The estimator combines the beacon and data estimates by incorporating
+them into an exponentially weighted moving average. Beacon-based
+estimates seed the neighbor table. The expectation is that the low
+beacon rate in a stable network means that for a selected route,
+data estimates will outweigh beacon estimates. Additionally, as
+the rate at which CTP collects data estimates is proportional to
+the transmission rate, then it can quickly detect a broken link and
+switch to another candidate neighbor.</p>
+</div>
+<div class="section">
+<h2><a id="routing-engine" name="routing-engine">6.2 Routing Engine</a></h2>
+<p>The</p>
+</div>
+</div>
+<div class="system-messages section">
+<h1>Docutils System Messages</h1>
+<div class="system-message" id="id1">
+<p class="system-message-title">System Message: <a name="id1">ERROR/3</a> (<tt class="docutils">txt/tep123.txt</tt>, line 232); <em><a href="#id2">backlink</a></em></p>
+Unknown target name: &quot;2&quot;.</div>
+</div>
 </div>
 </body>
 </html>
index 7153aad81a42a99a3424e2db5c56101ad49ab925..a5f6123a24906ee94d0feceeac578b3662022bba 100644 (file)
@@ -303,9 +303,9 @@ ul.auto-toc {
 <td>Ion Yannopoulos, David Gay</td></tr>
 <tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">31-Dec-2004</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.2</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.3</td>
 </tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-07-12</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-01-16</td>
 </tr>
 <tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List &lt;tinyos-devel at mail.millennium.berkeley.edu&gt;</td>
 </tr>
index 0ef16dffef96a687845b5d92adfd017af6473654..50fbfaa9f867562880e92eb4f8c02002ec381ddf 100644 (file)
@@ -1,20 +1,15 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html><head><style type="text/css">
-<!--
+<html>
+  <head>
 
-BODY { font-size: 10pt; font-family: Arial, Helvetica, sans-serif; }
-TD { font-size: 10pt; font-family: Arial, Helvetica, sans-serif; }
+  <title>Installing TinyOS 2.0</title>\r
+  <link href="../stylesheets/tutorial.css" rel="stylesheet" type="text/css">\r
+</head>
+  <body>
 
-P { font-size: 10pt; font-family: Arial, Helvetica, sans-serif; }
-P.headline { font-size = 14pt; font-weight=bold; }
-
--->
-</style></head><body>
+    <div class="title">Upgrading from TinyOS 1.x to TinyOS 2.x</div>
+    <div class="subtitle">Last updated 5 November 2006</div>
 <p>
-<table border="0" cellpadding="0" cellspacing="0" width="100%">
-<tbody><tr><td bgcolor="#eeeeee"><font face="verdana, arial, helvetica, sans-serif" size="3"><b>Upgrading from TinyOS 1.x to TinyOS 2.x</b></font></td>
-</tr></tbody></table>
-</p><p>
 This document describes how to upgrade your TinyOS 1.x environment to
 a TinyOS 2.x environment. This requires that you not only install the 
 TinyOS 2.x rpm, but also that you upgrade your tools from the toolset
@@ -37,9 +32,7 @@ There are 3 steps to upgrading from 1.x to 2.x:
   </li><li> <a href="#tinyos2">Install the Tinyos 2.x source tree. </a>
 </li></ol>
 
-<hr>
-
-<a name="external-tools"><h3> 1. Upgrade your external tools. </h3></a>
+<a name="external-tools"><h1> Step 1: Upgrade your external tools. </h1></a>
 The 1.2 toolset uses the same Java JDK and ATT Graphviz versions, so 
 those do not need to be upgraded. What does need to be upgraded are
 your compiler tools. Install the appropriate version of the following 
@@ -149,8 +142,8 @@ distribution trees, but are linked below for convenience.
 
 </tbody></table>
 
-</p><hr>
-<a name="tinyos-tools"><h3> 2. Upgrade your TInyOS-specific tools. </h3></a>
+</p>
+<a name="tinyos-tools"><h1> Step 2: Upgrade your TinyOS-specific tools. </h1></a>
 
 The TinyOS-specific tools are the NesC compiler and a set of tools
 developed in the tinyos-2.x/tools source code repository. They are
@@ -161,14 +154,15 @@ Also, if you plan on maintaining a tinyos-1.x tree
 simultaneously with a tinyos-2.x tree, the tinyos-tools installed for the
 1.x versions must remain installed so use <code>rpm -ivh</code>. If you are 
 only installing a 2.x tree, you can use <code>rpm -Uvh</code>.
-If you using the Cygwin version recommendedin these install
+If you using the Cygwin version recommended
+in these install
 instructions, you should install the "Recommended" Windows/Cygwin
-nesC RPM (1.2.7b). If you install it and it does not work (e.g., you
+nesC RPM. 
+Try installing it and if it does not work (e.g., you
 get strange errors when you try to execute it), this may be due
-to a Cygwin version incompatibility: try the "Other" Windows/Cygwin
+to a Cygwin version incompatibility: try the "Other" Windows/Cygwin 
 RPM (1.2.7a). 
 
-
 <p>
 
 <!----- tinyos-2.x/tinyos rpms  -------->
@@ -184,24 +178,24 @@ RPM (1.2.7a).
 
 <tr>
   <td>NesC</td>
-  <td><a href="http://csl.stanford.edu/~pal/tinyos/nesc-1.2.7b-1.cygwin.i386.rpm">nesc-1.2.7b-1.cygwin.i386.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/windows/nesc-1.2.7b-1.cygwin.i386.rpm">nesc-1.2.7b-1.cygwin.i386.rpm</a></td>
   <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/windows/nesc-1.2.7a-1.cygwin.i386.rpm">nesc-1.2.7a-1.cygwin.i386.rpm</a></td>
   <td><a href="http://www.tinyos.net/dist-1.2.0/tinyos/linux/nesc-1.2.7a-1.i386.rpm">nesc-1.2.7a-1.i386.rpm </a></td>
-  <td><a href=""></a><code>rpm -Uvh</code></td>
+  <td><a href=""></a><code>rpm -Uvh</code><br><code>rpm -Uvh --ignoreos</code> (if Cygwin complains)</td>
 </tr>
 
 <tr>
   <td bgcolor="#dddddd">tinyos-tools</td>
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.2-1.cygwin.i386.rpm">tinyos-tools-1.2.2-1.cygwin.i386.rpm</a></td>
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.2-1.cygwin.i386.rpm">tinyos-tools-1.2.2-1.cygwin.i386.rpm</a></td>
-  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-tools-1.2.2-1.i386.rpm">tinyos-tools-1.2.2-1.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.3-1.cygwin.i386.rpm">tinyos-tools-1.2.2-1.cygwin.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-tools-1.2.3-1.cygwin.i386.rpm">tinyos-tools-1.2.2-1.cygwin.i386.rpm</a></td>
+  <td bgcolor="#dddddd"><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-tools-1.2.3-1.i386.rpm">tinyos-tools-1.2.2-1.i386.rpm</a></td>
   <td bgcolor="#dddddd"><a href=""></a><code>rpm -ivh --force</code>&nbsp;(1.x tree)<br><code>rpm -Uvh</code>&nbsp;(no 1.x tree)<br></td>
 </tr>
 
 </tbody></table>
 
-</p><hr>
-<a name="tinyos2"><h3> 3. Install the TinyOS 2.x source tree. </h3></a>
+</p>
+<a name="tinyos2"><h1> Step 3: Install the TinyOS 2.x source tree. </h1></a>
 
 Now that the tools are installed, you need only install the tinyos 2.x 
 source tree and then set your environment variables.
@@ -210,11 +204,21 @@ source tree and then set your environment variables.
 <li> Install tinyos-2.x
 <p>
 <!----- TinyOS  -------->
-To preserve your old tinyos-1.x tree, we strongly recommend that you use
+
+<p>If you have an existing 1.x tree, we strongly recommend that you use
 the install (<code>-i</code>) rpm argument when installing the tinyos-2.x rpm rather 
 than the upgrade (<code>-U</code>) argument. The difference is that the <code>-U</code> will 
 first remove the tinyos-1.x tree while <code>-i</code> will not remove previously installed
-files. Said another way, we recommend using <code>rpm -ivh</code>.
+files. Said another way, we recommend using <code>rpm -ivh</code>.</p>
+
+<p>If you have an existing 2.x tree which you want to keep unchanged, then
+you will need to move it to make space for the new one. For example, if you
+have an existing tree in <tt>/opt/tinyos-2.x/</tt>, then you can move it
+to <tt>/opt/tinyos-2.x-old</tt>. Once you have moved it, we recommend
+performing a forced installation of the 2.0 tree.</p>
+
+<p>If you have an existing 2.x tree which you do not care about, then we
+recommend removing it before installing the new one with a forced install.</p>
 
 </p><p><b><em>TinyOS 2.x</em></b>
 <table border="0">
@@ -222,12 +226,17 @@ files. Said another way, we recommend using <code>rpm -ivh</code>.
   <td bgcolor="#dddddd"><b></b></td>
   <td bgcolor="#dddddd"><b>Windows/Cygwin</b></td>
   <td bgcolor="#dddddd"><b>Linux</b></td>
+  <td bgcolor="#dddddd"><b>Command</b></td>
 </tr>
 
 <tr>
   <td>TinyOS</td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0beta2-3.cygwin.noarch.rpm">tinyos-2.0.0beta2-3.cygwin.noarch.rpm</a></td>
-  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0beta2-3.noarch.rpm">tinyos-2.0.0beta2-3.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/windows/tinyos-2.0.0-1.cygwin.noarch.rpm">tinyos-2.0.0-1.cygwin.noarch.rpm</a></td>
+  <td><a href="http://www.tinyos.net/dist-2.0.0/tinyos/linux/tinyos-2.0.0-1.noarch.rpm">tinyos-2.0.0-1.noarch.rpm</a></td>
+  <td><tt>rpm -Uvh</tt> (to upgrade)<br>
+      <tt>rpm -ivh</tt> (to install)<br>
+      <tt>rpm -ivh --force</tt> (to force install)<br>
+  </td>      
 </tr>
 
 </tbody></table>
@@ -308,8 +317,7 @@ groups: </li>
 </code></code></li></ol>
 
 </li></ul>
-<hr>
-<a name="tinyos1"><h3>Switching back to a TinyOS 1.x tree</h3></a>
+<a name="tinyos1"><h1>Switching back to a TinyOS 1.x tree</h1></a>
 Since the tools are backwardly compatible, you need only change
 your environment variables to point to the 1.x settings. Assuming 
 that your old tree was in /opt/tinyos-1.x, you would use the following 
@@ -347,4 +355,8 @@ values:
 <td>
 
 </td></tr></tbody></table>
-</p></body></html>
+</p>
+
+<p>Switching between the two should require switching only these environment
+variables.</p>
+</body></html>
index dca149c758292698444665cbdd03ead7b9a9cfce..e482e6cbae217d3a9b3289c23347f4428dec5c78 100644 (file)
@@ -11,7 +11,7 @@
        <TR>
          <TD CLASS="title">
            TinyOS 2.0 Documentation<br>
-           <DIV CLASS="subtitle">Last Modified: Oct 31 2005</DIV>
+           <DIV CLASS="subtitle">Last Modified: October 27 2006</DIV>
          </TD>
        </TR>
        <TR>
              <li><A HREF="html/overview.html">TinyOS 2.0 overview</A></li>
              <li><A HREF="html/install-tinyos.html">TinyOS 2.0 install instructions </A></li>
              <li><A HREF="html/upgrade-tinyos.html">TinyOS 2.0 upgrade instructions (includes instructions for how to upgrade your tools for 2.0)</A></li>
+              <li><A HREF="html/porting.html">A brief set of notes on porting code from TinyOS 1.x to 2.0.</A></li>
            </ul>
          </TD>
        </TR>
 
 
        <TR>
-         <TD CLASS="subtitle">Tutorials</TD>
+         <TD CLASS="subtitle"><A HREF="html/tutorial/index.html">Tutorials</A></TD>
        </TR>
        <TR>
-         <TD><p>TinyOS 2.0 has a few tutorials to get a new user started with programming
+         <TD><p>TinyOS 2.0 has a few <A HREF="html/tutorial/index.html">tutorials</A> to get a new user started with programming
               the system. These tutorials introduce nesC programming and some major
               TinyOS abstractions, such as timers and communication.</p>
 
-              <p><A HREF="html/tutorial/index.html"><DIV class=sublink>TinyOS 2.0 Tutorials</div></a></p></TD>
+              <p>Additionally, for more advanced programming, there is a
+                 <A HREF="pdf/tinyos-programming.pdf">TinyOS Programming Manual</A>.
+                 The book describes nesC's features in greater detail,
+                 including generic components, concurrency, and common
+                 component design patterns.</p>
        </TR>
 
 
        <TR>
-         <TD CLASS="subtitle">TEPs and Source Code Documentation</TD>
+         <TD CLASS="subtitle">TEPs</TD>
        </TR>
        <TR>
          <TD>
@@ -64,7 +69,7 @@
            different kinds of TEPs and their roles. TEPs 1-100 are
            BCP (Best Current Practice) TEPs, while TEPS 101+ are
            Informational, Documentary, or Experimental. Currently,
-           all TEPs are still Drafts: comments and feedback to the
+           many TEPs are Drafts: comments and feedback to the
            authors or the associated working group is welcome.
 
            <BR><BR>
              <li>TEP 107: Boot Sequence                    [<A HREF="html/tep107.html">HTML</A>] [<A HREF="txt/tep107.txt">TXT</A>]</li>
              <li>TEP 108: Resource Arbitration             [<A HREF="html/tep108.html">HTML</A>] [<A HREF="txt/tep108.txt">TXT</A>]</li>
              <li>TEP 109: Sensorboards                     [<A HREF="html/tep109.html">HTML</A>] [<A HREF="txt/tep109.txt">TXT</A>]</li>
-             <li>TEP 110: Service Distributions            [<A HREF="html/tep110.html">HTML</A>] [<A HREF="txt/tep110.txt">TXT</A>]</li>
              <li>TEP 111: message_t                        [<A HREF="html/tep111.html">HTML</A>] [<A HREF="txt/tep111.txt">TXT</A>]</li>
              <li>TEP 112: Microcontroller Power Management [<A HREF="html/tep112.html">HTML</A>] [<A HREF="txt/tep112.txt">TXT</A>]</li>
              <li>TEP 113: Serial Communication             [<A HREF="html/tep113.html">HTML</A>] [<A HREF="txt/tep113.txt">TXT</A>]</li>
              <li>TEP 114: SIDs: Source and Sink Independent Drivers [<A HREF="html/tep114.html">HTML</A>] [<A HREF="txt/tep114.txt">TXT</A>]</li>
              <li>TEP 115: Power Management of Non-Virtualized Devices [<A HREF="html/tep115.html">HTML</A>] [<A HREF="txt/tep115.txt">TXT</A>]</li>
              <li>TEP 116: Packet Protocols                 [<A HREF="html/tep116.html">HTML</A>] [<A HREF="txt/tep116.txt">TXT</A>]</li>
+             <li>TEP 117: Low-Level I/O                  [<A HREF="html/tep117.html">HTML</A>] [<A HREF="txt/tep117.txt">TXT</A>]</li>
+             <li>TEP 118: Dissemination                 [<A HREF="html/tep118.html">HTML</A>] [<A HREF="txt/tep118.txt">TXT</A>]</li>
+             <li>TEP 119: Collection                  [<A HREF="html/tep119.html">HTML</A>] [<A HREF="txt/tep119.txt">TXT</A>]</li>
            </ul>
 
+           <BR><BR>
+          </TD>
+        </TR>
+       <TR>
+         <TD CLASS="subtitle"><A HREF="html/nesdoc/">TinyOS Source Code Documentation</A></TD>
+       </TR>
+        <TR>
+          <TD>
           <p>In addition to TEPs, which document the organization and design
-             behind important parts of TinyOS, there is also source code
-             documentation. TinyOS (nesC) code has nesdoc annotations,
-             which can be found here (note that this link is external):<br><br>
-
-             <A HREF="http://www.tinyos.net/dist-2.0.0/tinyos-2.x/doc/html/nesdoc/">
-             <div class=sublink>TinyOS 2.0 nesdoc documentation</div></a>
-             
-          </p>
+             behind important parts of TinyOS, there is also <A HREF="html/nesdoc/">source code
+             documentation</A>.<br><br>
+          </TD>
+        </TR>
+       <TR>
+         <TD CLASS="subtitle"><A HREF="html/tos-javasdk-javadoc/index.html">TinyOS Java toolchain Code Documentation</A></TD>
+       </TR>
+        <TR>
+          <TD>
 
-          <p>There is similar javadoc documentation for the Java toolchain, 
-             which can be found here:<br><br>
-             <A HREF="http://www.tinyos.net/dist-2.0.0/tinyos-2.x/doc/html/tos-javasdk-javadoc/">
-             <div class=sublink>TinyOS 2.0 javadoc documentation</div></a>
 
+          <p>There is similar 
+         <A HREF="html/tos-javasdk-javadoc/index.html">javadoc documentation</A> for the Java toolchain, 
+             which describes the Java classes and their functionality. This documentation
+             is incomplete. 
           </p>
               
 </p>
index 0937e6b8f554986d04e4cc007ecdd515e8a13b00..bb305d20c1a994aadbe2bf223ce65f86ea63d4a9 100644 (file)
@@ -14,12 +14,12 @@ table {
         font-size: 14px;
 }
 a:link { 
-       color: #d3595e;
+       color: #c3494e;
        text-decoration: none;
        font-weight: bold; 
 } 
 a:visited { 
-       color: #404040; 
+       color: #c3494e;
        text-decoration: none;
        font-weight: bold; 
 }
@@ -73,7 +73,7 @@ ul.links {
 
 .menu {
        width: 100%;
-       background-color: #c00000;
+       background-color: #d0d0d0;
        padding: .2em 1em .2em 1em;
        border: 0;
        margin: 0;
@@ -101,7 +101,7 @@ ul.links {
        width: 100%;
        margin: 0 0 0 0;
        border: 0 0 0 0;
-        background-color: #a0a0a0;
+        background-color: #d0d0d0;
         color: #000000;
 }
 
@@ -111,17 +111,17 @@ ul.links {
        border: 0 0 0 0;
        padding: .2em .2em .2em .2em;
        text-align: left; 
-       background-color: #e0e0c0;
+       background-color: #d0d0d0;
 }
 
 .title {
-        background-color: grey;
+        background-color: #d0d0d0;
         font-family: Helvetica, sans-serif;
         font-size: x-large;
        font-weight: bold; 
 }
 .subtitle {
-        background-color: grey;
+        background-color: #d0d0d0;
         font-family: Helvetica, sans-serif;
        font-weight: normal;
         font-size: medium;
index 73e5dcc74f08f89391c8c58b67f8658eb247733b..c8616f4e771d95b6ef14cff49e14f5ea33107ba3 100644 (file)
@@ -3,7 +3,7 @@ TinyOS 2.0 Overview
 ============================
 
 :Author: Philip Levis
-:Date: Feb 8 2006
+:Date: Oct 30 2006
 
 .. Note::
  
@@ -81,7 +81,7 @@ a full active message communication layer.
 
 The HAA is described in TEP 2: Hardware Abstraction Architecture[TEP2_].
 
-Currently (as of the 2.0 beta2 release in July 2006), TinyOS 2.0 supports
+Currently (as of the 2.0 release in November 2006), TinyOS 2.0 supports
 the following platforms:
 
  * eyesIFXv2
@@ -94,7 +94,7 @@ the following platforms:
  * btnode3
 
 
-The btnode3 platform is not included in the beta2 RPM.
+The btnode3 platform is not included in the RPM.
 
 3. Scheduler
 ====================================================================
@@ -241,7 +241,12 @@ each one will receive its fair share of transmission opportunities.
 
 Further information on message_t can be found in TEP 111:
 message_t[TEP111_], while further information on AM can be
-found in TEP 116: Packet Protocoks[TEP116_].
+found in TEP 116: Packet Protocols[TEP116_].
+
+The current TinyOS release has a low-power stack for the CC1000
+radio (mica2 platform) and an experimental low-power stack for
+the CC2420 radio (micaz, telosb, and intelmote2 platforms). 
+
 
 8. Sensors
 ====================================================================
@@ -326,6 +331,17 @@ TEP 115: Power Management of Non-Virtualised Devices{TEP115_], is handled
 through resource abiters. Fully virtualized services have their
 own, individual power management policies.
 
+TinyOS 2.0 provides low-power stacks for the CC1000 (mica2)
+and CC2420 (micaz, telosb, imote2) radios. Both use a low-power
+listening apporach, where transmitters send long preambles or
+repeatedly send packets and receivers wake up periodically to 
+sense the channel to hear if there is a packet being 
+transmitted. The low-power stack CC1000 is standard, while
+the CC2420 stack is experimental. That is, the default CC1000
+stack (chips/cc1000) has low-power-listening, while the default 
+CC2420 stack (chips/cc2420) does not. To use the low-power CC2420
+stack, you must include chips/cc2420_lpl in your application Makefile.
+
 12. Network Protocols
 ====================================================================
 
@@ -335,9 +351,12 @@ and collection. Dissemination reliably delivers small (fewer
 than 20 byte) data items to every node in a network, while
 collection builds a routing tree rooted at a sink node. Together,
 these two protocols enable a wide range of data collection
-applications. 
+applications. Collection has advanced significantly since the
+most recent beta release; experimental tests in multiple 
+network conditions have seen very high (>98%) deliver rates
+as long as the network is not saturated.
 
-12. Conclusion
+13. Conclusion
 ====================================================================
 
 TinyOS 2.0 represents the next step of TinyOS development. Building on
@@ -348,7 +367,7 @@ still under active development: future prereleases will include
 non-volatile storage, basic multihop protocols (collection routing,
 dissemination), and further power management abstractions.
 
-13. Acknowledgments
+14. Acknowledgments
 ====================================================================
 
 TinyOS 2.0 is the result of a lot of hard work from a lot of people,
@@ -358,10 +377,10 @@ Prabal Dutta,
 Gilman Tolle, Martin Turon, Phil Buonodonna, Ben Greenstein, David Culler, 
 Kristin Wright, Ion Yannopoulos, Henri Dubois-Ferriere, Jan Beutel, 
 Robert Szewczyk, Rodrigo Fonseca, Kyle Jamieson, Omprakash Gnawali,
-and Kristin Wright.
+David Moss, and Kristin Wright.
 
 
-14. Author's Address
+15. Author's Address
 ====================================================================
 
 | Philip Levis
@@ -374,7 +393,7 @@ and Kristin Wright.
 |
 | email - pal@cs.stanford.edu
 
-15. Citations
+16. Citations
 ====================================================================
 
 .. [TEP1] TEP 1: TEP Structure and Keywords. http://tinyos.cvs.sourceforge.net/*checkout*/tinyos/tinyos-2.x/doc/html/tep1.html?pathrev=tinyos-2_0_devel-BRANCH
index ea35a2b0bdb815d9c16f5aaefe17ce20e253a782..a2fee1bc4f9d89d8952557207a26405bf668a282 100644 (file)
@@ -160,10 +160,28 @@ describe systems that do not have a reference implementation.
 
 The fourth field is "Status," which specifies the status of the TEP.
 A TEP status can either be "Draft," which means it is a work in
-progress, "Final," which means it is complete and will not change, or
-"Obsolete," which means it should no longer be considered. If a TEP is
-"Obsolete" because it has been replaced by another TEP, then the new
-TEP number should follow "Obsolete," such as "Obsolete by TEP 1231."
+progress, "Final," which means it is complete and will not change. 
+Once a TEP has the status "Final," its body MUST NOT change. 
+The values of its header fields MUST NOT change. The header of a
+Final TEP MAY have an "Obsoleted By" field added.
+
+The "Obsoletes" field is a backward pointer to an earlier TEP which
+the current TEP renders obsolete. An Obsoletes field MAY have multiple
+TEPs listed.  For example, if TEP 191 were to replace TEPs 111 and 116, it
+would have the field "Obsoletes: 111, 116".
+
+The "Obsoleted By" field is added to a Final TEP when another TEP has
+rendered it obsolete. The field contains the number of the obsoleting
+TEP. For example, if TEP 111 were obsoleted by TEP 191, it would have
+the field "Obsoleted By: 191".
+
+"Obsoletes" and "Obsoleted By" fields MUST agree. For a TEP to list another
+TEP in its Obsoletes field, then that TEP MUST list it in the Obsoleted By
+field.
+
+The obsoletion fields are used to keep track of evolutions and modifications
+of a single abstraction. They are not intended to force a single approach or
+mechanism over alternative possibilities.
 
 If a TEP is Best Current Practices or Documentary, then it MUST
 include an additional field, "TinyOS-Version:," which states what
@@ -171,10 +189,16 @@ version(s) of TinyOS the document pertains to. This document pertains
 to all versions of TinyOS, until made obsolete by a future TEP. This
 field MUST appear after the Status field and before the Author field.
 
-The final required field is Author, which states the names of the
+The final required field is "Author," which states the names of the
 authors of the document. Full contact information should not be listed
 here (see Section 3.2).
 
+There is an optional field, "Extends." The "Extends" field refers to
+another TEP. The purpose of this field is to denote when a TEP represents
+an addition to an existing TEP. Meeting the requirements of a TEP with an
+Extends field requires also meeting the requirements of all TEPs listed 
+in the Extends field.
+
 If a TEP is a Draft, then four additional fields MUST be included:
 Draft-Created, Draft-Modified, Draft-Version, and Draft-Discuss.
 Draft-Created states the date the document was created, Draft-Modified
index 2c0d1c7a312fa31267009757eeac7b3b2e03696c..8ef7838957d9ae9dad51ec80b125e7589b70be98 100644 (file)
@@ -25,11 +25,10 @@ Analog-to-Digital Converters (ADCs)
 Abstract
 ====================================================================
 
-This TEP proposes a hardware abstraction for TinyOS 2.x analog-to-digital
-converters (ADCs). It focuses on aligning the ADC abstraction with the
-three-layer Hardware Abstraction Architecture (HAA) described in [TEP2]_, but
-addresses only the HPL and HAL, because the highest level abstraction of an
-ADC is platform-dependent.
+This TEP proposes a hardware abstraction for analog-to-digital converters (ADCs)
+in TinyOS 2.x, which is aligned to the three-layer Hardware Abstraction
+Architecture (HAA) specified in [TEP2]. It describes some design principles and
+documents the set of hardware-independent interfaces to an ADC.
 
 1. Introduction
 ====================================================================
@@ -42,14 +41,14 @@ TinyOS, the distinction between a sensor and an ADC were blurred: this led
 components that had nothing to do with an ADC to still resemble one
 programatically, even though the semantics and forms of operation were
 completely different.  To compensate for the difference non-ADC sensors
-introduced additional interfaces, such as ADCError, that were tightly bound to
-sensor acquisition but separate in wiring. The separation between the ADC and
-ADCError interface is bug prone and problematic, as is the equation of a
+introduced additional interfaces, such as ``ADCError``, that were tightly bound
+to sensor acquisition but separate in wiring. The separation between the ADC and
+``ADCError`` interface is bug prone and problematic, as is the equation of a
 sensor and an ADC. TinyOS 2.x separates the structure and interfaces of an ADC
 from those of sensors (which may be on top of an ADC, but this fact is hidden
-from higher level components). This TEP presents how TinyOS 2.x decomposes and
-structures ADC software. TEP 109 (Sensor Boards) shows how a platform can
-present actual named sensors [TEP109]_.
+from higher level components). This TEP presents how TinyOS 2.x structures ADC
+software. TEP 109 (Sensor Boards) shows how a platform can present actual named
+sensors [TEP109]_. 
 
 As can be seen in Appendix A the ADC hardware used on TinyOS platforms differ
 in many respects, which makes it difficult to find a chip independent
@@ -58,286 +57,366 @@ configuration details of an ADC would still depend on the actual device
 producing the input signal (sensor).  Neither a platform independent
 application nor the ADC hardware stack itself has access to this information,
 as it can only be determined on a platform or sensorboard level. For example,
-determining which ADC port a sensor is attached to and how a conversion result
-is to be interpreted is a platform-specific determination. 
+determining which ADC port a sensor is attached to and how conversion results
+need to be interpreted is a platform specific determination. Although the
+actual configuration details may be different the procedure of configuring an
+ADC can be unified on all ADCs with the help of **hardware independent
+interfaces**: in a similar way as the ``Read`` interface definition does not
+predefine the type or semantics of the exchanged data (see [TEP114]_), a
+configuration interface definition can abstract from the data type and
+semantics of the involved configuration settings.  For example, like a
+component can provide a ``Read<uint8_t>`` or ``Read<uint16_t>`` interface
+depending on the data it can offer, a component can also use a
+``AdcConfigure<atm128_adc_config_t>`` or
+``AdcConfigure<msp430adc12_channel_config_t>`` interface depending on what ADC
+it represents.  This TEP proposes the (typed) ``AdcConfigure`` interface as the
+standard interface for configuring an ADC in TinyOS 2.x.
 
 In spite of their hardware differences, one aspect represents a common
-denominator of all ADCs: they produce conversion results. In order to
-facilitate sensor software development this capability can be made available
-via chip-independent interfaces for every ADC. However, conversion results
-depend on and have to be interpreted with respect to the platform-specific
-configuration settings (the ADC channel, the applied reference voltage, etc.).
-Therefore the highest level of ADC abstraction consists of
-platform-independent interfaces for ADC data collection and chip-specific
-interfaces for ADC hardware configuration.  The top layer of the ADC stack
-thus remains platform-dependent and consequently the ADC abstraction does not
-include an HIL, but ends with the HAL. Following the principles of the
-HAA [TEP2]_ the HAL of an ADC should also expose the chip-specific capabilities
-for ADC data collection. For example, the ADC12 on the MSP430 MCU supports a
-complex repeat conversion mode for a set of different input channels, which is
-too specific to be represented by a platform-independent data collection
-interface.  Therefore the HAL of an ADC abstraction is broken into two
-sublayers: The bottom HAL layer, called HAL1, exposes the full capabilities of
-the respective ADC in a chip-specific way. It realizes the standard HAL in the
-HAA [TEP2]_ and the HPL lies below it.  On top of the HAL1 sits the HAL2 which
-maps the interfaces it uses from HAL1 to a set of platform-independent
-interfaces for data collection and chip-specific configuration interfaces.
+denominator of all ADCs: they produce conversion results. To facilitate sensor
+software development conversion results are returned by the ADC hardware stack
+using the standard TinyOS interfaces ``Read``, ``ReadNow`` and ``ReadStream``
+(see `2. Interfaces`_ and [TEP114]_). Conversion results are returned as
+uninterpreted values and translating them to engineering units can only be done
+with the configuration knowledge of the respective platform, for example, the
+reference voltage or the resistance of a reference resistor in ratiometric
+measurements.  Translating uninterpreted values to engineering units is
+performed by components located on top of the ADC hardware stack and out of the
+scope of this TEP.
+
+The top layer of abstraction of an ADC - the Hardware Interface Layer (HIL) -
+thus provides the standard TinyOS interfaces ``Read``, ``ReadNow`` and
+``ReadStream`` and uses the ``AdcConfigure`` interface for hardware
+configuration (why it **uses** and does not **provide** ``AdcConfigure`` is
+explained below).  Since the type and semantics of the parameters passed
+through these interfaces is dependent on the actual ADC implementation, it is
+only a "weak" HIL (see [TEP2]_).
+
+Following the principles of the HAA [TEP2]_ the Hardware Adaptation Layer (HAL,
+which resides below the HIL) of an ADC should expose all the chip-specific
+capabilities of the chip.  For example, the ADC12 on the MSP430 MCU supports a
+"Repeat-Sequence-of-Channels Mode" and therefore this function should be
+accessible on the HAL of the **MSP430 ADC12** hardware abstraction.  Other ADCs
+might not exhibit such functionality and might therefore - on the level of HAL
+- provide only an interface to perform single conversions. Since all ADCs have
+the same HIL representation it may thus be necessary to perform some degree of
+software emulation in the HIL implementation.  For example, a ``ReadStream``
+command can be emulated by multiple single conversion commands. Below the HAL
+resides the Hardware Presentation Layer (HPL), a stateless component that
+provides access to the hardware registers (see [TEP2]_). The general structure
+(without virtualization) of the ADC hardware stack is as follows ::
+
+
+        ^                     |
+        |                     |
+        |                   Read,
+  AdcConfigure              ReadNow (+ Resource),
+        |                   ReadStream
+        |                     |
+        |                     V
+  +----------------------------------+
+  |  Hardware Interface Layer (HIL)  |
+  |  (chip-specific implementation)  |
+  +----------------------------------+
+                   |
+                   |
+    chip-specific interface(s) + Resource
+ (e.g. Msp430Adc12SingleChannel + Resource)
+                   |
+                   V
+  +----------------------------------+
+  |  Hardware Adaptation Layer (HAL) |
+  |  (chip-specific implementation)  |
+  +----------------------------------+
+                   |
+                   |
+         chip-specific interface(s)
+             (e.g. HplAdc12)
+                   |
+                   V
+  +----------------------------------+
+  | Hardware Presentation Layer (HPL)|
+  | (chip-specific implementation)   |
+  +----------------------------------+
 
-The rest of this TEP specifies:
 
-* the set of platform-independent interfaces for the collection of ADC
-  conversion results (`2. Interfaces`_)
-* guidelines on how an ADC's HAL should be split into HAL1 and HAL2 and
-  how the HAL1 should expose chip-specific interfaces (`3. HAL1 guidelines`_)
-* what components an ADC's HAL2 MUST implement (`4. HAL2 requirements`_)
-* guidelines on how the HAL2 may be structured (`5. HAL2 implementation guidelines`_)
-* a section pointing to the current implementation (`6. Implementation`_)
+The rest of this TEP specifies:
 
+* the set of standard TinyOS interfaces for collecting ADC conversion
+  results and for configuring an ADC (`2. Interfaces`_)
+* guidelines on how an ADC's HAL should expose chip-specific 
+  interfaces (`3. HAL guidelines`_)
+* what components an ADC's HIL MUST implement (`4. HIL requirements`_)
+* guidelines on how the HIL should be implemented 
+  (`5. HIL guidelines`_)
+* a section pointing to current implementations (`6. Implementation`_)
 
-This TEP ends with appendices documenting, as an example, the ADC
-implementation for the TI MSP430 MCU.
+This TEP ends with appendices documenting, as an example, the ADC implementation
+for the TI MSP430 MCU.
 
 
 2. Interfaces
 ====================================================================
 
-This TEP proposes to adopt the following three generic, source-independent
-data collection interfaces from [TEP114]_ for the collection of ADC conversion
-results::
+This TEP proposes the ``AdcConfigure`` interface for ADC hardware configuration
+and the ``Read``, ``ReadNow`` and ``ReadStream`` interfaces to acquire
+conversion results. A ``Read[Now|Stream]`` interface is always provided in
+conjunction with a ``AdcConfigure`` interface.
+
+Interface for configuring the ADC hardware
+--------------------------------------------------------------------
+
+The ``AdcConfigure`` interface is defined as follows::
+
+  interface AdcConfigure< config_type > 
+  {
+    async command config_type getConfiguration(); 
+  }
+
+This interface is used by the ADC implementation to retrieve the hardware
+configuration of an ADC client. ``config_type`` is a chip-specific data type
+(simple or structured) that contains all information necessary to configure the
+respective ADC hardware. For example, on the ADC12 of the MSP430 the
+``AdcConfigure`` interface will be instantiated with the ``const
+msp430adc12_channel_config_t*`` data type. A client MUST always return the same
+configuration through a ``AdcConfigure`` interface and, if configuration data
+is passed as a pointer, the HIL component (see `4. HIL requirements`_) MUST NOT
+reference it after the return of the ``getConfiguration()`` command. If a
+client wants to use the ADC with different configurations it must provide
+multiple instances of the ``AdcConfigure`` interface.
+
+
+Interfaces for acquiring conversion results
+--------------------------------------------------------------------
+   
+This TEP proposes to adopt the following three generic, source-independent data
+collection interfaces from [TEP114]_ for the collection of ADC conversion
+results on the level of HIL::
 
   interface Read< size_type >
   interface ReadNow< size_type >
   interface ReadStream< size_type >
 
-Every data collection interface is associated with certain chip-specific
-configuration data (e.g. input channel, sample-hold-time, etc.).  How this
-association can be realized is explained in Section `4.  HAL2 requirements`_.
-As the resolution of conversion results is chip-specific, the 'size_type'
-parameter reflects an upper bound for the chip-specific resolution of the
-conversion results - the actual resolution may be smaller, depending on the
-ADC and/or data source (e.g.  uint16_t for a 12-bit ADC). The above interfaces
-are specified in [TEP114]_, in the following their usage is explained with
-respect to ADCs.
+Every data collection interface is associated with an ``AdcConfigure``
+interface (how this association is realized is explained in Section `4.  HIL
+requirements`_).  As the resolution of conversion results is chip-specific, the
+``size_type`` parameter reflects an upper bound for the chip-specific
+resolution of the conversion results - the actual resolution may be smaller
+(e.g.  uint16_t for a 12-bit ADC). The above interfaces are specified in
+[TEP114]_, in the following their usage is explained with respect to ADCs.
 
 Read
---------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The Read interface can be used to sample an ADC channel and return a single
-conversion result. It provides no guarantees about when exactly the sampling
-occurs (the request may be buffered). 
+The ``Read`` interface can be used to sample an ADC channel and return a single
+conversion result as an uninterpreted value. The meaning of the ``Read``
+interface is explained in [TEP114]_.
 
 ReadNow
---------------------------------------------------------------------
-
-The ReadNow interface provides more precise control over the time of the
-sampling: If a call to ReadNow.read() succeeds, the ADC starts to sample the
-channel immediately (the request is not buffered). Due to its timing
-constraints the ReadNow interface is always provided in conjunction with an
-instance of the Resource interface. Refer to [TEP108]_ on how the 'Resource'
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``ReadNow`` interface is similar to the ``Read`` interface. The difference
+is that if a call to ``ReadNow.read()`` succeeds, the ADC starts to sample the
+channel immediately (precisely: when ``SUCCESS`` is returned the hardware has
+started the sampling process). Due to its timing constraints the ``ReadNow``
+interface is always provided in conjunction with an instance of the
+``Resource`` interface (a client must reserve the ADC before the client may
+call ``ReadNow.read()``).  Please refer to [TEP108]_ on how the ``Resource``
 interface should be used by a client component.
 
-
 ReadStream
---------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The ReadStream interface can be used to sample an ADC channel multiple times
-with a specified sampling period. It provides no guarantees about when exactly
-the first sampling occurs, but all subsequent samplings occur with the
-specified sampling period.
+The ``ReadStream`` interface can be used to sample an ADC channel multiple times
+with a specified sampling period. The meaning of the ``ReadStream`` interface
+is explained in [TEP114]_ .
 
 
-3. HAL1 guidelines
+3. HAL guidelines
 ====================================================================
 
-As explained in `1. Introduction`_ the HAL of an ADC abstraction consists of
-two sublayers, HAL1 and HAL2. In the ADC component stack the HAL1 resides
-below HAL2 and above the HPL. It exposes the full capabilities of the ADC in a
-chip-specific way and has the same function as the 'traditional' HAL in the
-HAA [TEP2]_. Therefore only chip- and platform-dependent clients MAY wire to
-the HAL1. Although the HAL1 is chip-specific, both, in terms of implementation
+As explained in `1. Introduction`_ the HAL exposes the full capabilities of the
+ADC hardware. Therefore only chip- and platform-dependent clients can wire to
+the HAL. Although the HAL is chip-specific, both, in terms of implementation
 and representation, its design should follow the guidelines described below to
-facilitate the mapping to platform-independent interfaces on the level of
-HAL2. Appendix B shows the HAL1 specification for the TI MSP430 MCU.
+facilitate the mapping to the HIL representation. Appendix B shows the
+signature of the HAL for the MSP430.
 
 Resource reservation
 --------------------------------------------------------------------
 
-As the ADC hardware is a shared resource that is multiplexed between several
-clients, it requires access arbitration. Therefore the HAL1 configuration
-component should provide a parameterized 'Resource' interface, instantiate a
-generic arbiter component and connect the 'Resource' interface to the arbiter
-as described in [TEP108]_. To ensure fair and uniform arbitration on all
-platforms the standard round robin arbiter is recommended. Refer to [TEP108]_
-on how the 'Resource' interface is to be used by a client wiring to HAL1.
+As the ADC hardware is a shared resource that is usually multiplexed between
+several clients some form of access arbitration is necessary.  The HAL should
+therefore provide a parameterized ``Resource`` interface, instantiate a
+standard arbiter component and connect the ``Resource`` interface to the
+arbiter as described in [TEP108]_. To ensure fair and uniform arbitration on
+all platforms the standard round robin arbiter is recommended. Resource
+arbiters and the ``Resource`` interface are the topic of [TEP108]_.
 
 Configuration and sampling
 --------------------------------------------------------------------
 
-As the ADC hardware is a shared resource the HAL1 should support hardware
-configuration and sampling on a per-client basis (although per-port
-configuration is possible, it is not recommended, because it forces all
-clients to use the same settings for a given port). Therefore an HAL1 should
-provide sampling interfaces parameterized by a client identifier. An HAL1
-client can use its instance of the sampling interface to configure the ADC
-hardware, start the sampling process and get conversion results. It wires to a
-sampling interface using a unique client identifier. All commands and events
-in the sampling interface should be 'async' to reflect the potential timing
-requirements of clients. An HAL1 may provide multiple different parameterized
-sampling interfaces, depending on the hardware capabilities.  This allows to
+As the ADC hardware is a shared resource the HAL should support hardware
+configuration and sampling per client (although per-port configuration is
+possible, it is not recommended, because it forces all clients to use the same
+configuration for a given port).  Therefore the HAL should provide sampling
+interfaces parameterized by a client identifier. A HAL client can use its
+instance of the sampling interface to configure the ADC hardware, start the
+sampling process and acquire conversion results. It wires to a sampling
+interface using a unique client identifier (this may be hidden by a
+virtualization component). All commands and events in the sampling interface
+should be 'async' to reflect the potential timing requirements of clients on
+the level of HAL. A HAL may provide multiple different parameterized sampling
+interfaces, depending on the hardware capabilities.  This allows to
 differentiate/group ADC functionality, for example single vs.  repeated
-sampling, single channel vs. multiple channels or low-frequency vs.
+sampling, single channel vs.  multiple channels or low-frequency vs.
 high-frequency sampling.  Every sampling interface should allow the client to
 individually configure the ADC hardware, for example by including the
 configuration data as parameters in the sampling commands.  However, if
-configuration data is passed as a pointer, the HAL1 component MUST NOT
-reference it after the return of the respective command. Appendix B shows the
-HAL1 interfaces for the TI MSP430 MCU.
+configuration data is passed as a pointer, the HAL component MUST NOT reference
+it after the return of the respective command.  Appendix B shows the HAL
+interfaces for the MSP430.
 
-HAL1 virtualization
+HAL virtualization
 --------------------------------------------------------------------
 
 In order to hide wiring complexities and/or export only a subset of all ADC
-functions generic ADC wrapper components may be provided on the level of HAL1
-to be instantiated by chip- and platform-dependent clients.
+functions generic ADC wrapper components may be provided on the level of HAL.
+Such components can also be used to ensure that a sampling interface is always
+provided with a ``Resource`` interface and both are instantiated with the same
+client ID if this is required by the HAL implementation.
 
 
-4. HAL2 requirements
+4. HIL requirements
 ====================================================================
 
-The following components MUST be provided on all platforms that have an ADC::
+The following generic components MUST be provided on all platforms that have an
+ADC::
 
-  AdcReadClient 
-  AdcReadNowClient 
-  AdcReadStreamClient 
+  AdcReadClientC 
+  AdcReadNowClientC 
+  AdcReadStreamClientC 
 
-These generic components are instantiated and provide access to the ADC  on a
-per-client basis via a platform-independent interface for data collection and
-a chip-specific ADC configuration interface. This section describes the
-representation of the HAL2. Guidelines on how the HAL2 can be implemented are
-discussed in Section `5. HAL2 implementation guidelines`_.  Appendix C shows
-the AdcReadClient for the TI MSP430 MCU.  
+These components provide virtualized access to the HIL of an ADC. They are
+instantiated by an ADC client and provide/use the four interfaces described in
+Section `2.  Interfaces`_. An ADC client may instantiate multiple such
+components. The following paragraphs describe their signatures. Note that this
+TEP does not address the issue of how to deal with multiple ADCs on the same
+platform (the question of how to deal with multiple devices of the same class
+is a general one in TinyOS 2.x). Appendix C shows the ``AdcReadClientC`` for
+the MSP430.
 
-The fact that the components use chip-specific ADC configuration interfaces
-(see below) and the fact that the provided interfaces for data-collection must
-be interpreted with respect to the configuration data - for example the
-reference voltage - makes the HAL2 representation chip dependent. Therefore
-the ADC abstraction does not include an HIL.
 
-AdcReadClient
+AdcReadClientC
 --------------------------------------------------------------------
 ::
 
-  generic configuration AdcReadClient() {
+  generic configuration AdcReadClientC() {
     provides {
       interface Read< size_type >;
     }
     uses {
-      // chip-dependent configuration interface
+      interface AdcConfigure< config_type >;
     }
   }
 
-The AdcReadClient provides platform-independent access for data collection via
-the 'Read' interface. The actual ADC channel (port) and further configuration
-details are determined by a chip-dependent configuration interface. It is the
-task of the client to wire this interface to a component that provides its ADC
-configuration.  The HAL2 implementation will use this interface to "pull" the
-client's ADC settings when it translates the 'Read.read()' command to a
-chip-specific sampling command. The resolution of the conversion result is
-chip-specific, the 'size_type' parameter represents an upper bound for the
-resolution of the conversion results.
-
-AdcReadNowClient
+The ``AdcReadClientC`` component provides a ``Read`` interface for acquiring
+single conversion results. The associated ADC channel (port) and further
+configuration details are returned by the ``AdcConfigure.getConfiguration()``
+command. It is the task of the client to wire this interface to a component
+that provides the client's ADC configuration. The HIL implementation will use
+the ``AdcConfigure`` interface to dynamically "pull" the client's ADC settings
+when it translates the ``Read.read()`` command to a chip-specific sampling
+command.  Note that both, ``size_type`` and ``config_type``, are only
+placeholders and will be instantiated by the respective HIL implementation (for
+an example, see the AdcReadClientC for the MSP430 in Appendix C).
+
+AdcReadNowClientC
 --------------------------------------------------------------------
 ::
 
-  generic configuration AdcReadNowClient() {
+  generic configuration AdcReadNowClientC() {
     provides {
       interface Resource;
       interface ReadNow< size_type >;
     }
     uses {
-       // chip-dependent configuration interface
+      interface AdcConfigure< config_type >;
     }
   }
 
-The AdcReadNowClient provides platform-independent access for data collection
-via the 'ReadNow' and 'Resource' interface. The actual ADC channel (port) and
-further configuration details are determined by a chip-dependent configuration
-interface. It is the task of the client to wire this interface to a component
-that provides its ADC configuration.  The HAL2 implementation will use this
-interface to "pull" the client's ADC settings when it translates the
-'ReadNow.read()' command to a chip-specific sampling command. A client MUST
-use the 'Resource' interface to request access to the ADC as described in
-[TEP108]_ (the HAL2 implementation SHOULD return the error code 'ERESERVE' if
-the client has not reserved access). The resolution of the conversion result
-is chip-specific, the 'size_type' parameter represents an upper bound for the
-resolution of the conversion result.
-
-AdcReadStreamClient
+The ``AdcReadNowClientC`` component provides a ``ReadNow`` interface for
+acquiring single conversion results. In contrast to ``Read.read()`` when a call
+to ``ReadNow.read()`` succeeds, the ADC starts to sample the channel
+immediately (a successful ``Read.read()`` command may not have this
+implication, see [TEP114]_ and `2. Interfaces`_). A client MUST reserve the ADC
+through the ``Resource`` interface before the client may call
+``ReadNow.read()`` and it must release the ADC through the ``Resource``
+interface when it no longer needs to access it (for more details on the
+``Resource`` interface please refer to [TEP108]_).  The associated ADC channel
+(port) and further configuration details are returned by the
+``AdcConfigure.getConfiguration()`` command. It is the task of the client to
+wire this interface to a component that provides the client's ADC
+configuration.  The HIL implementation will use the ``AdcConfigure`` interface
+to dynamically "pull" the client's ADC settings when it translates the
+``ReadNow.read()`` command to a chip-specific sampling command. Note that both,
+``size_type`` and ``config_type``, are only placeholders and will be
+instantiated by the respective HIL implementation (for an example how this is
+done for the AdcReadClientC see Appendix C).
+
+AdcReadStreamClientC
 --------------------------------------------------------------------
 ::
 
-  generic configuration AdcReadStreamClient() {
+  generic configuration AdcReadStreamClientC() {
     provides {
       interface ReadStream< size_type >;
     }
     uses {
-       // chip-dependent configuration interface
+      interface AdcConfigure< config_type>;
     }
   }
 
-The AdcReadStreamClient provides platform-independent access for data
-collection via the 'ReadStream' interface. The actual ADC channel (port) and
-further configuration details are determined by a chip-dependent configuration
-interface. It is the task of the client to wire this interface to a component
-that provides its ADC configuration.  The HAL2 implementation will use this
-interface to "pull" the client's ADC settings when it translates the
-'ReadStream.read()' command to a chip-specific sampling command. The
-resolution of the conversion results is chip-specific, the 'size_type'
-parameter represents an upper bound for the resolution of the conversion
-results.
-
-5. HAL2 implementation guidelines
+The ``AdcReadStreamClientC`` component provides a ``ReadStream`` interface for
+acquiring multiple conversion results at once. The ``ReadStream`` interface is
+explained in [TEP114]_ and `2. Interfaces`_. The ``AdcConfigure`` interface is
+used in the same way as described in the section on the ``AdcReadClientC``.
+Note that both, ``size_type`` and ``config_type``, are only placeholders and
+will be instantiated by the respective HIL implementation (for an example how
+this is done for the AdcReadClientC see Appendix C).
+
+5. HIL guidelines
 ====================================================================
 
-The HAL2 implementation of an ADC stack has two main tasks: It translates a
-platform-independent HAL2 request (from the 'Read', 'ReadNow' or 'ReadStream'
-interface) to a chip-specific HAL1 sampling command and it abstracts from the
-'Resource' interface. The first task cannot be solved in a chip-independent
-way, because it involves chip-specific configuration data. The second task MAY
-be performed by the following library components: ArbitratedReadC, and
-ArbitratedReadStreamC (in tinyos-2.x/tos/system) - refer to the Atmel Atmega
-128 HAL2 implementation (in tinyos-2.x/tos/chips/atm128/adc), for an example.
-Note that since the 'ReadNow' interface is always provided in conjunction with
-a 'Resource' interface the HAL2 implementation does not have to perform the
-ADC resource reservation in this case, but can simply forward an instance of
-the 'Resource' interface from the HAL1 (to AdcReadNowClient).
-
-To support multiple ADC clients the HAL2 implementation should provide
-parameterized 'Read', 'ReadNow' and 'ReadStream' interfaces as well as a
-parameterized chip-specific configuration interface. It should also use an
-instance of the 'Resource' interface (provided by the HAL1) per provided
-'Read' and 'ReadStream' interface to perform automatic resource reservation.
-The HAL2 representation ('AdcReadClient', 'AdcReadNowClient' and
-'AdcReadStreamClient') should ensure the correct wiring between the HAL1 and
-HAL2.
-
-From the perspective of the HAL2 the typical sequence of events is as follows:
-After a client has requested data via the 'Read' or 'ReadStream' interface the
-HAL2 will request access to the HAL1 via the 'Resource' interface, e.g. using
-the library components mentioned above.  When it is signalled the 'granted'
-event, the HAL2 will 'pull' the client's ADC settings and translate the
-client's command to a chip-specific HAL1 sampling command. Once it is
-signalled the conversion result(s) it releases the ADC via the 'Resource'
-interface and forwards the conversion result(s) to the client. When a client
-has requested data via the 'ReadNow' interface the HAL2 translates the
-client's command to the chip-specific HAL1 sampling command without using the
-'Resource' interface (it may check ownership of the client via the
-'ArbiterInfo' interface). In order to reduce state in the HAL2 and facilitate
-the mapping between used and provided interfaces the 'AdcReadClient',
-'AdcReadNowClient' and 'AdcReadStreamClient' should use the same interface
-identifier when it connects the HAL2 to HAL1 (see, for example, the MSP430
-ADC12 implementation in Appendix C).
+The HIL implementation of an ADC stack has two main tasks: it translates a
+``Read``, ``ReadNow`` or ``ReadStream`` request to a chip-specific HAL sampling
+command and it abstracts from the ``Resource`` interface (the latter only for
+the ``AdcReadClientC`` and ``AdcReadStreamClientC``). The first task is solved
+with the help of the ``AdcConfigure`` interface which is used by the HIL
+implementation to retrieve a client's ADC configuration.  The second task MAY
+be performed by the following library components: ``ArbitratedReadC``, and
+``ArbitratedReadStreamC`` (in tinyos-2.x/tos/system) - please refer to the
+Atmel Atmega 128 HAL implementation (in tinyos-2.x/tos/chips/atm128/adc) for an
+example.  Note that since the ``ReadNow`` interface is always provided in
+conjunction with a ``Resource`` interface the HIL implementation does not have
+to perform the ADC resource reservation for an ``AdcReadNowClientC``, but may
+simply forward an instance of the ``Resource`` interface from the HAL to the
+``AdcReadNowClientC``.
+
+The typical sequence of events is as follows: when a client requests data
+through the ``Read`` or ``ReadStream`` interface the HIL will request access to
+the HAL using the ``Resource`` interface.  After the HIL has been granted
+access, it will "pull" the client's ADC configuration using the
+``AdcConfigure`` interface and translate the client's ``Read`` or
+``ReadStream`` command to a chip-specific HAL command. Once the HIL is
+signalled the conversion result(s) from the HAL it releases the ADC through the
+``Resource`` interface and signals the conversion result(s) to the client
+though the ``Read`` or ``ReadStream`` interface.  When a client requests data
+through the ``ReadNow`` interface the HIL translates the client's command to
+the chip-specific HAL command without using the ``Resource`` interface (it may
+check ownership of the client through the ``ArbiterInfo`` interface - this
+check can also be done in the HAL implementation). Once the HIL is signalled
+the conversion result(s) it forwards it to the respective ``ReadNow`` client.
 
 6. Implementation
 ====================================================================
@@ -346,28 +425,24 @@ The implementation of the ADC12 stack on the MSP430 can be found in
 ``tinyos-2.x/tos/chips/msp430/adc12``:
 
   * ``HplAdc12P.nc`` is the HPL implementation
-  * ``Msp430Adc12P.nc`` is the HAL1 implementation
-  * ``AdcC.nc`` is the HAL2 implementation
+  * ``Msp430Adc12P.nc`` is the HAL implementation
+  * ``AdcP.nc`` is the HIL implementation
   * ``AdcReadClientC.nc``, ``AdcReadNowClientC.nc`` and
-    ``AdcReadStreamClientC.nc`` provide access to the ADC on a per-client
-    basis via the interfaces 'Read', 'ReadNow' and 'ReadStream', 
-    respectively, and the msp430-specific ADC configuration 
-    interface ``Msp430Adc12Config.nc``
+    ``AdcReadStreamClientC.nc`` provide virtualized access to the HIL
+  * the use of DMA or the reference voltage generator and the
+    HAL virtualization components are explained in ``README.txt``
 
 The Atmel Atmega 128 ADC implementation can be found in
 ``tinyos-2.x/tos/chips/atm128/adc``:
 
   * ``HplAtm128AdcC.nc`` is the HPL implementation
-  * ``Atm128AdcP.nc`` is the HAL1 implementation
+  * ``Atm128AdcP.nc`` is the HAL implementation
   * ``WireAdcP.nc`` and the library components for arbitrating 'Read', 
     'ReadNow' and 'ReadStream', ``ArbitratedReadC`` and
     ``ArbitratedReadStreamC`` (in ``tinyos-2.x/tos/system``), realize
-    the HAL2
+    the HAL
   * ``AdcReadClientC.nc``, ``AdcReadNowClientC.nc`` and
-    ``AdcReadStreamClientC.nc`` provide access to the ADC on a per-client
-    basis via the platform-independent interfaces 'Read', 'ReadNow' and
-    'ReadStream', respectively, and the atmega-specific ADC configuration 
-    interface ``Atm128AdcConfig.nc``
+    ``AdcReadStreamClientC.nc`` provide virtualized access to the HIL
 
 
 Appendix A: Hardware differences between platforms
@@ -436,78 +511,62 @@ commonly used in TinyOS platforms:
 +----------------------+----------------------+---------------------+
 
 
-Appendix B: an HAL1 representation: MSP430 ADC12
+Appendix B: a HAL representation: MSP430 ADC12
 ====================================================================
 
-The following shows the HAL1 representation for the ADC12 of the TI MSP430
-MCU. It reflects the four MSP430 ADC12 conversion modes as it lets a client
-sample an ADC channel once ("Single-channel-single-conversion") or repeatedly
+This section shows the HAL signature for the ADC12 of the TI MSP430 MCU. It
+reflects the four MSP430 ADC12 conversion modes as it lets a client sample an
+ADC channel once ("Single-channel-single-conversion") or repeatedly
 ("Repeat-single-channel"), multiple times ("Sequence-of-channels") or multiple
 times repeatedly ("Repeat-sequence-of-channels"). In contrast to the single
 channel conversion modes the sequence conversion modes trigger a single
-interrupt after multiple samples and thus enable high-frequency sampling (a
-sequence conversion mode for multiple different channels is not (yet)
-implemented).::
+interrupt after multiple samples and thus enable high-frequency sampling. The
+``DMAExtension`` interface is used to reset the state machine when the DMA is
+responsible for data transfer (managed in an exterior component)::
 
-  configuration Msp430Adc12C 
+  configuration Msp430Adc12P 
   { 
-    provides interface Resource[uint8_t id]; 
-    provides interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id]; 
-  }  
+    provides {
+      interface Resource[uint8_t id]; 
+      interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id]; 
+      interface AsyncStdControl as DMAExtension[uint8_t id];
+    }
+  }
 
   interface Msp430Adc12SingleChannel 
   {   
-    async command error_t getSingleData(const msp430adc12_channel_config_t *config);
-    async command error_t getSingleDataRepeat(const msp430adc12_channel_config_t *config, 
-      uint16_t jiffies);
-    async command error_t getMultipleData( const msp430adc12_channel_config_t *config,
-      uint16_t *buffer, uint16_t numSamples, uint16_t jiffies);
-    async command error_t getMultipleDataRepeat(const msp430adc12_channel_config_t *config, 
-      uint16_t *buffer, uint8_t numSamples, uint16_t jiffies);
+    async command error_t configureSingle(const msp430adc12_channel_config_t *config);
+    async command error_t configureSingleRepeat(const msp430adc12_channel_config_t *config, uint16_t jiffies);
+    async command error_t configureMultiple( const msp430adc12_channel_config_t *config, uint16_t buffer[], uint16_t numSamples, uint16_t jiffies);
+    async command error_t configureMultipleRepeat(const msp430adc12_channel_config_t *config, uint16_t buffer[], uint8_t numSamples, uint16_t jiffies);
+    async command error_t getData();
     async event error_t singleDataReady(uint16_t data);
-    async event uint16_t* multipleDataReady(uint16_t *buffer, uint16_t
-      numSamples); 
+    async event uint16_t* multipleDataReady(uint16_t buffer[], uint16_t numSamples); 
   }
 
-There exist two wrapper components, Msp430Adc12ClientC and
-Msp430Adc12RefVoltAutoClientC, which SHOULD be used to eliminate wiring
-errors.
+  typedef struct { 
+    unsigned int inch: 4;            // input channel 
+    unsigned int sref: 3;            // reference voltage 
+    unsigned int ref2_5v: 1;         // reference voltage level 
+    unsigned int adc12ssel: 2;       // clock source sample-hold-time 
+    unsigned int adc12div: 3;        // clock divider sample-hold-time 
+    unsigned int sht: 4;             // sample-hold-time
+    unsigned int sampcon_ssel: 2;    // clock source sampcon signal 
+    unsigned int sampcon_id: 2;      // clock divider sampcon signal
+  } msp430adc12_channel_config_t;
 
-Appendix C: an HAL2 representation: MSP430 ADC12
+
+Appendix C: a HIL representation: MSP430 ADC12
 ====================================================================
 
-The AdcReadClientC component for the MSP430 ADC12 is implemented as follows:
-::
+The signature of the AdcReadClientC component for the MSP430 ADC12 is as
+follows::
 
   generic configuration AdcReadClientC() {
     provides interface Read<uint16_t>;
-    uses interface Msp430Adc12Config;
-  } implementation {
-    components AdcC;
-  #ifdef REF_VOLT_AUTO_CONFIGURE     
-    components new Msp430Adc12RefVoltAutoClientC() as Msp430AdcClient;
-  #else
-    components new Msp430Adc12ClientC() as Msp430AdcClient;
-  #endif
-
-    enum {
-      CLIENT = unique(ADCC_SERVICE),
-    };
-
-    Read = AdcC.Read[CLIENT];
-    Msp430Adc12Config = AdcC.Config[CLIENT];
-    AdcC.SingleChannel[CLIENT] -> Msp430AdcClient.Msp430Adc12SingleChannel;
-    AdcC.Resource[CLIENT] -> Msp430AdcClient.Resource;
-  #ifdef REF_VOLT_AUTO_CONFIGURE
-    Msp430Adc12Config = Msp430AdcClient.Msp430Adc12Config;
-  #endif 
+    uses interface AdcConfigure<const msp430adc12_channel_config_t*>;
   }
 
-Note that the same CLIENT identifier is used for all involved interfaces to
-facilitate the mapping between the HAL2 and HAL1 interfaces. The conditional
-compile directive REF_VOLT_AUTO_CONFIGURE can be used to automatically enable
-the internal reference voltage generator during the sampling process.
-
 .. [TEP1] TEP 1: TEP Structure and Keywords. 
 .. [TEP2] TEP 2: Hardware Abstraction Architecture. 
 .. [TEP108] TEP 108: Resource Arbitration. 
index 8c1c1dcc2d49958dac8728de233e556c1a04e876..1a2c6e418d407d1b8d5183bcb340f728c976387d 100644 (file)
@@ -78,11 +78,11 @@ Three fundamental properties of timers are *precision*, *width* and
 *accuracy*.
 
 Examples of precision are millisecond, a cycle of a 32kHz clock, and
-microseconds.  All precisions are in "binary" units with respect to
-one second.  That is, one second contains 1024 binary milliseconds,
-32768 32kHz ticks, or 1048576 microseconds.  This TEP emphasizes
-millisecond and 32kHz tick precisions while reasonably accommodating
-other precisions.
+microseconds.  All precisions presented in this TEP are in "binary"
+units with respect to one second.  That is, one second contains 1024
+binary milliseconds, 32768 32kHz ticks, or 1048576 microseconds.
+This TEP emphasizes millisecond and 32kHz tick precisions while
+reasonably accommodating other precisions.
 
 Examples of widths are 8-bit, 16-bit, 32-bit, and 64-bit.  The width
 for timer interfaces and components SHOULD be 32-bits.  That is, for
@@ -112,9 +112,9 @@ reflected in the interface type.
 Precision is expressed as an empty type -- TMilli, T32khz, and
 TMicro -- written in the standard Timer.h header like this::
 
-  typedef struct { } TMilli;
-  typedef struct { } T32khz;
-  typedef struct { } TMicro;
+  typedef struct { } TMilli; // 1024 ticks per second
+  typedef struct { } T32khz; // 32768 ticks per second
+  typedef struct { } TMicro; // 1048576 ticks per second
 
 Note that the precision names are expressed as either frequency or
 period, whichever is convenient.
@@ -159,11 +159,15 @@ get()
   return the current time.
 
 isOverflowPending() 
-  return TRUE if an overflow interrupt will occur after the outermost
-  atomic block is exits.  FALSE otherwise.
+  return TRUE if the overflow flag is set for this counter, i.e., if and
+  only if an overflow interrupt will occur after the outermost atomic
+  block exits.  Return FALSE otherwise.  This command only returns the
+  state of the overflow flag and causes no side effect.  It is expected
+  that the underlying hardware platform sets the overflow flag when
+  appropriate.
 
 clearOverflow() 
-  cancel the pending overflow interrupt.
+  cancel the pending overflow interrupt clearing the overflow flag.
 
 overflow() 
   signals that an overflow in the current time.  That is, the current
@@ -174,7 +178,7 @@ Alarm
 --------------------------------------------------------------------
 
 Alarm components are extensions of Counters that signal an event
-when their Compare register detects the alarm time has been hit.
+when their compare register detects the alarm time has been hit.
 All commands and events of the Alarm interface are asynchronous (or
 in "interrupt context").  The Alarm interface provides a set of
 "basic" commands for common usage and provides a set of "extended"
@@ -210,26 +214,37 @@ isRunning()
   or has not yet fired.  FALSE is returned otherwise.
 
 startAt(t0,dt) 
+
   cancel any previously running alarm and set to fire at time t1 =
-  t0+dt.  This form allows a delay to be anchored to some time t0
-  taken before the invocation of start.  This is also the form used
-  internally in the timer subsystem to allow the use of the full width
-  of an alarm while being able to detect if the alarm time for a short
-  alarm prematurely elapsed.
+  t0+dt.  This form allows a delay to be anchored to some time t0 taken
+  before the invocation of startAt.  The timer subsystem uses this form
+  internally, to be able to use of the full width of an alarm while also
+  detecting when a short alarm elapses prematurely.
 
 getNow() 
   return the current time in the precision and width of the alarm.
 
 getAlarm() 
   return the time the currently running alarm will fire or the time
-  that the previously running alarm was set to fire.
+  that the previously running alarm was set to fire.  getAlarm can
+  be used with startAt to set an alarm from the previous alarm time,
+  as in startAt(getAlarm(),dt).  This pattern is used within the
+  fired() event to construct periodic alarms.
 
 
 BusyWait
 --------------------------------------------------------------------
 
-The BusyWait interface replaces the TOSH_uwait macro from TinyOS
-1.x.  ::
+The BusyWait interface allows for very short synchronous delays.
+BusyWait should be used sparingly and when an Alarm would not be
+reasonably efficient or accurate.  The BusyWait interface replaces
+the TOSH_uwait macro from TinyOS 1.x. 
+
+BusyWait blocks for no less than the specified amount of time.  No
+explicit upper bound is imposed on the enacted delay, though it is
+expected the underlying implementation spins in a busy loop until
+the specified amount of time has elapsed.
+::
 
   interface BusyWait<precision_tag,size_type>
   {
@@ -237,7 +252,7 @@ The BusyWait interface replaces the TOSH_uwait macro from TinyOS
   }
 
 wait(dt)
-  block for no less than the specified amount of time.
+  block until at least dt time units have elapsed
 
 LocalTime
 --------------------------------------------------------------------
@@ -330,71 +345,76 @@ getdt()
 3. HAL guidelines
 ====================================================================
 
-Platforms typically select a clocking option for each of their
-hardware counters, based on their hardware design (e.g., the mica
-family of motes all run their hardware timer 0 at 32kHz, and the micaz
-mote runs its timer 1 at cpu frequency/256). Platforms SHOULD expose
-the timing functionality of these timers using the Alarm and Counter
-interfaces, in the fashion described below. Platforms MAY expose the
-same hardware timer with different frequencies - use of conflicting
-frequences in the same program SHOULD produce compile-time
-errors.
-
-
-A hardware timer with precision *P* and width *W* SHOULD be exposed as
-several components::
-
-  configuration CounterPWC {
-    provides interface Counter<TP, uintW_t>;
-  } ... 
-  generic configuration AlarmPWC {
-    provides interface Alarm<TP,uintW_t>;
-  } ...
+Platforms SHOULD expose their relevant timing capabilities using
+standard Alarm and Counter interfaces.  The design pattern presented
+here defines a component naming convention to allow platform
+independent access to particular Alarms and Counters if they exist
+and to cause compile errors if they do not.
 
-and, except if *W* is 32::
+A platform specific hardware timer with precision ${P} and width
+${W} SHOULD be exposed as these two conventional Counter and Alarm
+components::
 
-  configuration CounterP32C {
-    provides interface Counter<TP, uint32_t>;
-  } ... 
-  generic configuration AlarmP32C {
-    provides interface Alarm<TP,uint32_t>;
-  } ...
+  configuration Counter${P}${W}C
+  {
+    provides interface Counter< T${P}, uint${W}_t >;
+  }
 
-Instantiating the Alarm... components provides a new Alarm independent
-of all prior instantiations. Instantiating such a component "consumes"
-a compare register from the corresponding hardware timer; when no more
-compare registers are available, instantiation SHOULD produce a
-compile-time error (see Appendix B for an example of how to achieve
-this).
+  generic configuration Alarm${P}${W}C()
+  {
+    provides interface Alarm< T${P}, uint${W}_t >;
+  }
+
+Instantiating an Alarm${P}${W}C component provides a new and
+independent Alarm.  If the platform presents a limited number of
+Alarm resources, then allocating more Alarms in an application than
+are available for the platform SHOULD produce a compile-time error.
+See Appendix B for an example of how to make allocatable Alarms that
+are each implemented on independent hardware timers.
+
+For example, if a platform has an 8-bit 32kHz counter and three
+8-bit 32kHz alarms, then the Counter and Alarm interfaces for
+${P}=32khz and ${W}=16 are::
+
+  configuration Counter32khz8C
+  {
+    provides interface Counter< T32khz, uint8_t >;
+  }
+
+  generic configuration Alarm32khz8C()
+  {
+    provides interface Alarm< T32khz, uint8_t >;
+  }
+
+This pattern MAY be used to defined components for the platform that
+are mutually incompatible in single application.  Incompatible
+components SHOULD produce compile-time errors when compiled
+together.
 
-For example, the micaz platform includes an AlarmMilli8C and
-AlarmMilli32C components for timer 0 (one instantiation allowed), and
-Alarm32kHz16C and Alarm32kHz32C for timer 1 (three instantiations
-allowed).
 
 4. HIL requirements
 ====================================================================
 
 The following component MUST be provided on all platforms::
-  TimerMilliC
+  HilTimerMilliC
   BusyWaitMicroC
 
-TimerMilliC
+HilTimerMilliC
 --------------------------------------------------------------------
 
 ::
 
-  #define TIMERMILLIC_SERVICE ...
-  configuration TimerMilliC
+  configuration HilTimerMilliC
   {
     provides interface Init;
-    provides interface Timer<TMilli>[uint8_t num];
-    provides interface LocalTime<TMilli>;
+    provides interface Timer<TMilli> as TimerMilli[ uint8_t num ];
   }
 
-A timer is allocated using unique(TIMERMILLIC_SERVICE) to obtain a new
-unique timer number. This timer number is used to index the TimerMilli
-parameterised interface.
+A new timer is allocated using unique(UQ_TIMER_MILLI) to obtain a
+new unique timer number.  This timer number is used to index the
+TimerMilli parameterised interface.  UQ_TIMER_MILLI is defined in
+Timer.h.  HilTimerMilliC is used by the generic component
+TimerMilliC found in ``tos/system/``.
 
 BusyWaitMicroC
 --------------------------------------------------------------------
@@ -495,6 +515,11 @@ created::
 
   new TransformAlarmC( TMilli, uint32_t, T32khz, uint16_t, 5 )
 
+It is the exclusive responsibility of the developer using
+TransformAlarmC to ensure that all five of its arguments are self
+consistent.  No compile errors are generated if the parameters
+passed to TransformAlarmC are inconsistent.
+
 
 TransformCounterC
 --------------------------------------------------------------------
@@ -543,13 +568,79 @@ timers.  ::
     uses interface Timer<precision_tag> as TimerFrom;
   }
 
-6. Author's Address
+6. Implementation
+====================================================================
+
+The definition of the HIL interfaces are found in ``tinyos-2.x/tos/lib/timer``:
+
+  * ``Alarm.nc``
+  * ``BusyWait.nc``
+  * ``Counter.nc``
+  * ``LocalTime.nc``
+  * ``Timer.h`` defines precision tags and strings for unique()
+  * ``Timer.nc``
+
+The implementation of the utility components are also found in
+``tinyos-2.x/tos/lib/timer``:
+
+  * ``AlarmToTimerC.nc``
+  * ``BusyWaitCounterC.nc``
+  * ``CounterToLocalTimeC.nc``
+  * ``TransformAlarmC.nc``
+  * ``TransformAlarmCounterC.nc``
+  * ``TransformCounterC.nc``
+  * ``VirtualizeAlarmC.nc``
+  * ``VirtualizeTimerC.nc``
+
+The implementation of Timers for the MSP430 is in
+``tinyos-2.x/tos/chips/msp430/timer``:
+
+  * ``Alarm32khz16C.nc`` is generic and provides a new ``Alarm<T32khz,uint16_t>``
+  * ``Alarm32khz32C.nc`` is generic and provides a new ``Alarm<T32khz,uint32_t>``
+  * ``AlarmMilli16C.nc`` is generic and provides a new ``Alarm<TMilli,uint16_t>``
+  * ``AlarmMilli32C.nc`` is generic and provides a new ``Alarm<TMilli,uint32_t>``
+  * ``BusyWait32khzC.nc`` provides ``BusyWait<T32khz,uint16_t>``
+  * ``BusyWaitMicroC.nc`` provides ``BusyWait<TMicro,uint16_t>``
+  * ``Counter32khz16C.nc`` provides ``Counter<T32khz,uint16_t>``
+  * ``Counter32khz32C.nc`` provides ``Counter<T32khz,uint32_t>``
+  * ``CounterMilli16C.nc`` provides ``Counter<TMilli,uint16_t>``
+  * ``CounterMilli32C.nc`` provides ``Counter<TMilli,uint32_t>``
+  * ``GpioCaptureC.nc``
+  * ``HilTimerMilliC.nc`` provides ``Timer<TMilli> as TimerMilli[uint8_t num]``
+  * ``Msp430AlarmC.nc`` is generic and converts an MSP430 timer to a 16-bit Alarm
+  * ``Msp430Capture.nc`` HPL interface definition for MSP430 timer captures
+  * ``Msp430ClockC.nc`` exposes MSP430 hardware clock initialization
+  * ``Msp430ClockInit.nc`` HPL interface definition for hardware clock initialization
+  * ``Msp430ClockP.nc`` implements MSP430 hardware clock initialization and
+    calibration and startup
+  * ``Msp430Compare.nc`` HPL interface definition for MSP430 timer compares
+  * ``Msp430Counter32khzC.nc`` provides ``Counter<T32khz,uint16_t>`` based on
+    MSP430 TimerB
+  * ``Msp430CounterC.nc`` is generic and converts an Msp430Timer to a Counter
+  * ``Msp430CounterMicroC.nc`` provides ``Counter<TMicro,uint16_t>`` based on
+    MSP430 TimerA
+  * ``Msp430Timer.h`` defines additional MSP430 timer bitmasks and structs
+  * ``Msp430Timer.nc`` HPL interface definition
+  * ``Msp430Timer32khzC.nc`` is generic and allocates a new 32khz hardware timer
+  * ``Msp430Timer32khzMapC.nc`` exposes the MSP430 hardware timers as a
+    parameterized interface allocatable using Msp430Timer32khzC
+  * ``Msp430TimerC.nc`` exposes the MSP430 hardware timers
+  * ``Msp430TimerCapComP.nc`` is generic and implements the HPL for MSP430
+    capture/compare special function registers
+  * ``Msp430TimerCommonP.nc`` maps the MSP430 timer interrupts to Msp430TimerEvents
+  * ``Msp430TimerControl.nc`` HPL interface definition
+  * ``Msp430TimerEvent.nc`` HPL interface definition
+  * ``Msp430TimerP.nc`` is generic and implements the HPL for MSP430 timer
+    special function registers
+
+7. Author's Address
 ====================================================================
 | Cory Sharp
 | Moteiv Corporation
 | 55 Hawthorne St, Suite 550
 | San Francisco, CA 94105
 |
+| phone - +1 415 692 0963
 | email - cory@moteiv.com
 |
 |
index d5aaee13c813178ee02f832e7d31ea8757ea07b0..d90ad7fe565fb8587807ea355c4616c8b483f247 100644 (file)
@@ -3,18 +3,12 @@ Permanent Data Storage (Flash)
 ==============================================
 
 :TEP: 103
-:Group: Core Working Group 
+:Group: Core Working Group
 :Type: Documentary
-:Status: Draft
+:Status: Final
 :TinyOS-Version: 2.x
 :Author: David Gay, Jonathan Hui
 
-:Draft-Created: 27-Sep-2004
-:Draft-Version: $Revision$
-:Draft-Modified: $Date$
-:Draft-Discuss: TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu>
-
-
 .. Note::
 
    This memo documents a part of TinyOS for the TinyOS Community, and
@@ -32,39 +26,41 @@ HAL layers of various flash chips.
 1. Introduction
 ====================================================================
 
-Flash chips are a form of EEPROM (electrically-eraseable, programmable
+Flash chips are a form of EEPROM (electrically-erasable, programmable
 read-only memory), distinguished by a fast erase capability. However,
 erases can only be done in large units (from 256B to 128kB depending on the
 flash chip). Erases are the only way to switch bits from 0 to 1, and
 programming operations can only switch 1's to 0's. Additionally, some
 chips require that programming only happen once between each erase,
-or that it be in relatively large units (e.g., 256B). 
+or that it be in relatively large units (e.g., 256B).
 
 In the table below, we summarise these differences by categorising
 flash chips by their underlying technology (NOR vs NAND). We also
 include a column for Atmel's AT45DB flash chip family, as it has
-significantly different tradeoffs than other flash chips: ::
-
-
-                  NOR                AT45DB             NAND
-                  (ex: ST M25P40,                       (ex: Samsung
-                  Intel PXA27x)                         K9K1G08R0B)
-
-  Erase               :  Slow (seconds)      Fast (ms)          Fast (ms)
-  Erase unit   :  Large (64KB-128KB)  Small (256B)       Medium (8KB-32KB)
-  Writes       :  Slow (100s kB/s)    Slow (60kB/s)      Fast (MBs/s)
-  Write unit   :  1 bit               256B               100's of bytes
-  Bit-errors   :  Low                 Low                High (requires ECC, 
-                                                         bad-block mapping)
-  Read        :  Bus limited*        Slow+Bus limited   Bus limited
-  Erase cycles :  10^4 - 10^5         10^4 **            10^5 - 10^7
-  Intended use :  Code storage        Data storage       Data storage
-  Energy/byte  :  1uJ                 1uJ                .01uJ
-
-  *  M25P40 reads are limited by the use of a 25MHz SPI bus. The PXA27x flash is
-     memory mapped (reads are very fast and can directly execute code).
-  ** Or infinite? Data sheet just says that every page within a sector
-     must be written every 10^4 writes within that sector
+significantly different tradeoffs than other flash chips:
+
+
+  =============  ==================  =================  ===================
+               X        NOR                 AT45DB             NAND
+                (ex: ST M25P40,                         (ex: Samsung
+                Intel PXA27x)                           K9K1G08R0B)
+  =============  ==================  =================  ===================
+  Erase                 Slow (seconds)      Fast (ms)          Fast (ms)
+  Erase unit     Large (64KB-128KB)  Small (256B)       Medium (8KB-32KB)
+  Writes         Slow (100s kB/s)    Slow (60kB/s)      Fast (MBs/s)
+  Write unit     1 bit               256B               100's of bytes
+  Bit-errors     Low                 Low                High (requires ECC,
+                                                        bad-block mapping)
+  Read          Bus limited [*]_    Slow+Bus limited   Bus limited
+  Erase cycles   10^4 - 10^5         10^4 [*]_          10^5 - 10^7
+  Intended use   Code storage        Data storage       Data storage
+  Energy/byte    1uJ                 1uJ                .01uJ
+  =============  ==================  =================  ===================
+
+.. [*] M25P40 reads are limited by the use of a 25MHz SPI bus. The PXA27x flash
+       is memory mapped (reads are very fast and can directly execute code).
+.. [*] Or infinite? Data sheet just says that every page within a sector
+       must be written every 10^4 writes within that sector
 
 The energy/byte is the per-byte cost of erasing plus programming. It is
 derived from the timing and power consumption of erase and write operations
@@ -92,7 +88,7 @@ three components listed above are supported on these chips:
 - ``ByteEEPROMC`` allows arbitrary rewrites of sections of the flash.
   This is not readily implementable on a flash chip with large erase units.
 - The ``Matchbox`` implementation was AT45DB-specific. It was not
-  reimplemented for these other chips, in part because it does not 
+  reimplemented for these other chips, in part because it does not
   support some applications (e.g., network reprogramming) very well.
 
 2. Storage in TinyOS 2.x
@@ -107,7 +103,7 @@ this approach has several drawbacks:
   in a free, open-source operating system.
 - To support arbitrary block writes where blocks are smaller than the
   erase unit, and to deal with the limited number of erase cycles/block
-  requires remapping blocks. We believe that maintaining this remapping 
+  requires remapping blocks. We believe that maintaining this remapping
   table is too expensive on many mote-class devices.
 
 A second approach is to provide a generic low-level interface providing
@@ -117,7 +113,7 @@ operations, along with information describing the flash chip's layout
 we believe that the large differences between NAND and NOR flash (see the
 table above), in particular the differences in reliability, write and
 erase units, make the design of a useful generic low-level interface
-tricky at best. 
+tricky at best.
 
 We thus believe it is best, for now at least, to define high-level
 storage abstractions that are useful for sensor network applications,
@@ -137,7 +133,7 @@ storage abstraction (the abstraction defines the format).
 We prefer the use of single abstractions over fixed-size volumes over
 the use of a more general filing system (like Matchbox) for several
 reasons:
-     
+
 - TinyOS is currently targeted at running a single application, and many
   applications know their storage needs in advance: for instance, a
   little space for configuration data, and everything else for a log of
@@ -152,7 +148,7 @@ reasons:
   "wear levelling" (ensuring that each block of the flash is erased
   the same number of time, to maximise flash chip lifetime).
 
-New abstractions (including a filing system...) can easily be added to
+New abstractions (including a filing system) can easily be added to
 this framework.
 
 The rest of this TEP covers some principles for the organisation of
@@ -166,7 +162,7 @@ storage abstractions in detail (Section 4).
 The flash chip architecture follows the three-layer Hardware
 Abstraction Architecture (HAA), with each chip providing a presentation
 layer (HPL, Section 3.1), adaptation layer (HAL, Section 3.2) and
-platform-independent interface layer (HIL, Section 3.3) [2_]. 
+platform-independent interface layer (HIL, Section 3.3) [2_].
 The implementation of these layers SHOULD be found in the
 ``tos/chips/CHIPNAME`` directory. If a flash chip is part of a larger
 family with a similar interface, the HAA SHOULD support all family members
@@ -181,13 +177,13 @@ and ST M25P chip families.
 
 The flash HPL has a chip-dependent, platform-independent interface. The
 implementation of this HPL is platform-dependent. The flash HPL SHOULD be
-stateless. 
+stateless.
 
 To remain platform independent, a flash chip's HPL SHOULD connect to
 platform-specific components
 providing access to the flash chip; these components
 SHOULD be placed in the ``tos/platforms/PLATFORM/chips/CHIPNAME``
-directory. If the flash chip implementation supports a family of 
+directory. If the flash chip implementation supports a family of
 flash chips, this directory MAY also contain a file describing the
 particular flash chip found on the platform.
 
@@ -205,16 +201,18 @@ abstractions that interact cleanly with the rest of the flash system.
 3.3 Hardware Interface Layer (HIL)
 --------------------------------------------------------------------
 
-Each flash chip MUST provide implementations of the storage abstractions
-described in Section 4. These abstractions MUST be presented in
+Each flash chip MUST support at least one of the storage abstractions
+described in Section 4. These abstractions SHOULD be presented in
 components named ``ChipAbstractionC``, e.g., ``At45dbLogStorageC``.
+Additionally, a flash chip implementation MAY support platforms
+with multiple instances of the same storage chip. The way in which
+this is achieved is not specified further in this TEP.
 
-Each platform MUST have ``AbstractionC`` components (e.g., ``LogStorageC``)
-implementing the storage abstractions of Section 4. Platforms with a single
-storage chip SHOULD simply make ``AbstractionC`` be a simple configuration
-wrapping the appropriate ``ChipAbstractionC`` component. Platforms with
-multiple storage chips SHOULD redirect uses of ``AbstractionC`` to the 
-appropriate storage chip, based on the requested volume.
+Each platform MUST have ``AbstractionC`` components (e.g.,
+``LogStorageC``) implementing the storage abstractions of Section 4
+supported by its flash chip(s). On platforms with multiple storage chips
+SHOULD redirect uses of ``AbstractionC`` to the appropriate storage
+chip, based on the requested volume.
 
 4. Non-Volatile Storage Abstractions
 ===================================================================
@@ -249,11 +247,12 @@ directory. When not specified, the tool picks a suitable physical
 location for a volume. If there is any reason that the physical allocation
 cannot be satisfied, an error should be given at compile time. The tool
 SHOULD be named ``tos-storage-CHIPNAME`` and be distributed with the other
-tools supporting a platform.
+tools supporting a platform. The XML file SHOULD be named
+``volumes-CHIPNAME.xml``.
 
 The compile-time tool MUST prepend 'VOLUME\_' to each volume name in
 the XML file and '#define' each resulting name to map to a unique
-integer. 
+integer.
 
 The storage abstractions are accessed by instantiating generic
 components that take the volume macro as argument: ::
@@ -269,22 +268,20 @@ A volume MUST NOT be used with more than one storage abstraction instance.
 4.2 Large objects
 ------------------------------------------------------------------
 
-The motivating example for large objects is the transmission or long-term
-storage of large pieces of data. For instance, programs in a network-reprogramming
-system, or large data-packets in a reliable data-transmission system. Such
-objects have two interesting characteristics: each byte in the object is
-written at most once, and a full object is written in a single "session"
-(i.e., without the mote rebooting).
+The motivating example for large objects is the transmission or
+long-term storage of large pieces of data. For instance, programs in a
+network-reprogramming system, or large data-packets in a reliable
+data-transmission system. Such objects have an interesting
+characteristic: each byte in the object is written at most once.
 
 This leads to the definition of the ``BlockStorageC`` abstraction for storing
-large objects:
+large objects or other "write-once" objects:
 
 - A large object ranges from a few kilobytes upwards.
 - A large object is erased before the first write.
-- A commit ensures that a large object survives a reboot or crash
+- A sync ensures that a large object survives a reboot or crash
 - Reads are unrestricted
-- Writes can only be performed between an erase and a commit
-- Each byte can only be written once between an erase and a commit
+- Each byte can only be written once between two erases
 
 Large objects are accessed by instantiating a BlockStorageC component
 which takes a volume id argument: ::
@@ -296,23 +293,20 @@ which takes a volume id argument: ::
     }
   } ...
 
-The ``BlockRead`` and ``BlockWrite`` interfaces contain the following
-operations (all split-phase, except ``BlockRead.getSize``):
+The ``BlockRead`` and ``BlockWrite`` interfaces (briefly presented in
+Appendix B) contain the following operations (all split-phase, except
+``BlockRead.getSize``):
 
 - ``BlockWrite.erase``: erase the volume. After a reboot or a commit, a
   volume MUST be erased before it can be written to.
 
 - ``BlockWrite.write``: write some bytes starting at a given
-  offset. Each byte MUST NOT be written more than once between an erase
-  and the subsequent commit. Writes MUST NOT be performed between a
-  commit and the subsequent erase.
+  offset. Each byte MUST NOT be written more than once between two erases.
 
-- ``BlockWrite.commit``: commit all writes to a given volume. Writes
-  MUST NOT be performed after a commit until a subsequent erase. Commit
-  MUST be called to ensure written data survives a reboot or crash.
 
-- ``BlockRead.verify``: verify that the volume contains the results of a
-  successful commit.
+- ``BlockWrite.sync``: ensure all previous writes are present on a given
+  volume. Sync MUST be called to ensure written data survives a reboot
+  or crash.
 
 - ``BlockRead.read``: read some bytes starting at a given offset.
 
@@ -325,6 +319,11 @@ operations (all split-phase, except ``BlockRead.getSize``):
 For full details on arguments and other considerations, see the comments in
 the interface definitions.
 
+Note that these interfaces contain no direct support for verifying the
+integrity of the BlockStorage data, but such support can easily be built
+by using the ``computeCrc`` command and storing the result in a
+well-defined location, and checking this CRC when desired.
+
 
 4.3 Logging
 ------------------------------------------------------------------
@@ -341,7 +340,7 @@ record based: each call to ``LogWrite.append`` (see below) creates a new
 record. On failure (crash or reboot), the log MUST only lose whole
 records from the end of the log. Additionally, once a circular log wraps
 around, calls to ``LogWrite.append`` MUST only lose whole records from
-the beginning of the log. 
+the beginning of the log.
 
 Logs are accessed by instantiating a LogStorageC component which takes a
 volume id and a boolean argument: ::
@@ -356,19 +355,20 @@ volume id and a boolean argument: ::
 If the ``circular`` argument is TRUE, the log is circular; otherwise
 it is linear.
 
-The ``LogRead`` and ``LogWrite`` interfaces contain the following
-operations (all split-phase except ``LogWrite.currentOffset``,
-``LogRead.currentOffset`` and ``LogRead.getSize``):
+The ``LogRead`` and ``LogWrite`` interfaces (briefly presented in
+Appendix B) contain the following operations (all split-phase except
+``LogWrite.currentOffset``, ``LogRead.currentOffset`` and
+``LogRead.getSize``):
 
 - ``LogWrite.erase``: erase the log. A log MUST be erased (possibly in
   some previous session) before any other operation can be used.
 
 - ``LogWrite.append``: append some bytes to the log. In a circular log,
-  this may overwrite the current read position. In this case, the 
+  this may overwrite the current read position. In this case, the
   read position MUST be advanced to the log's current beginning
   (i.e., as if ``LogRead.seek`` had been called with ``SEEK_BEGINNING``).
   Additionally, the ``LogWrite.appendDone`` event reports whenever, in a
-  circular log, an append erases old records.
+  circular log, an append MAY have erased old records.
 
   Each append creates a separate record. Log implementations may have a
   maximum record size; all implementations MUST support records of up
@@ -397,7 +397,7 @@ operations (all split-phase except ``LogWrite.currentOffset``,
 - ``LogRead.seek``: set the read position to a value returned by
   a prior call to ``LogWrite.currentOffset`` or ``LogRead.currentOffset``,
   or to the special ``SEEK_BEGINNING`` value. In a circular log, if
-  the specified position has been overwritten, behave as if 
+  the specified position has been overwritten, behave as if
   ``SEEK_BEGINNING`` was requested.
 
   ``SEEK_BEGINNING`` positions the read position at the beginning of
@@ -450,12 +450,12 @@ which takes a volume id argument: ::
     }
   } ...
 
-A small object MUST be mounted (via the ``Mount`` interface) before 
+A small object MUST be mounted (via the ``Mount`` interface) before
 the first use.
 
-The ``Mount`` and ``ConfigStorage`` interfaces contain the following
-operations (all split-phase except ``ConfigStorage.getSize`` and
-``ConfigStorage.valid``):
+The ``Mount`` and ``ConfigStorage`` interfaces (briefly presented in
+Appendix B) contain the following operations (all split-phase except
+``ConfigStorage.getSize`` and ``ConfigStorage.valid``):
 
 - ``Mount.mount``: mount the volume.
 
@@ -519,7 +519,7 @@ Appendix A. HAA for some existing flash chips
 
 A.1 AT45DB
 ------------------------------------------------------------------
+
 The Atmel AT45DB family HPL is: ::
 
   configuration HplAt45dbC {
@@ -529,7 +529,7 @@ The Atmel AT45DB family HPL is: ::
 The ``HplAt45db`` interface has flash->buffer, buffer->flash, compare
 buffer to flash, erase page, read, compute CRC, and write operations.  Most
 of these operations are asynchronous, i.e., their completion is signaled
-before the flash chip has completed the operation. The HPL also includes 
+before the flash chip has completed the operation. The HPL also includes
 operations to wait for asynchronous operations to complete.
 
 A generic, system-independent implementation of the HPL
@@ -560,7 +560,7 @@ providing volume information: ::
 Note that the AT45DB HAL resource management is independent of the
 underlying HPL's power management. The motivation for this is that
 individual flash operations may take a long time, so it may be desirable to
-release the flash's bus during long-running operations. 
+release the flash's bus during long-running operations.
 
 The ``At45db`` interface abstracts from the low-level HPL operations by:
 
@@ -577,7 +577,7 @@ map volume-relative pages to absolute pages.
 
 A.2 ST M25P
 ------------------------------------------------------------------
+
 The ST M25P family HPL is: ::
 
   configuration Stm25pSpiC {
@@ -610,3 +610,97 @@ erase. Additionally, it has operations to report volume size and remap
 volume-relative addresses. Clients of the ST M25P HAL must implement the
 ``getVolumeId`` event of the ``Stm25pVolume`` interface so that the HAL can
 obtain the volume id of each of its clients.
+
+Appendix B. Storage interfaces
+====================================================================
+
+These interfaces are presented briefly here for reference; please refer
+to the TinyOS documentation for a full description of the commands,
+events and their parameters.
+
+B.1 BlockStorage interfaces
+------------------------------------------------------------------
+
+The BlockStorage interfaces are: ::
+
+  interface BlockRead {
+    command error_t read(storage_addr_t addr, void* buf, storage_len_t len);
+    event void readDone(storage_addr_t addr, void* buf, storage_len_t len,
+                       error_t error);
+
+    command error_t computeCrc(storage_addr_t addr, storage_len_t len,
+                              uint16_t crc);
+    event void computeCrcDone(storage_addr_t addr, storage_len_t len,
+                             uint16_t crc, error_t error);
+
+    command storage_len_t getSize();
+  }
+
+  interface BlockWrite {
+    command error_t write(storage_addr_t addr, void* buf, storage_len_t len);
+    event void writeDone(storage_addr_t addr, void* buf, storage_len_t len,
+                        error_t error);
+
+    command error_t erase();
+    event void eraseDone(error_t error);
+
+    command error_t sync();
+    event void syncDone(error_t error);
+  }
+
+B.2 ConfigStorage interfaces
+------------------------------------------------------------------
+
+The ConfigStorage interfaces are: ::
+
+  interface Mount {
+    command error_t mount();
+    event void mountDone(error_t error);
+  }
+
+  interface ConfigStorage {
+    command error_t read(storage_addr_t addr, void* buf, storage_len_t len);
+    event void readDone(storage_addr_t addr, void* buf, storage_len_t len,
+                       error_t error);
+
+    command error_t write(storage_addr_t addr, void* buf, storage_len_t len);
+    event void writeDone(storage_addr_t addr, void* buf, storage_len_t len,
+                        error_t error);
+
+    command error_t commit();
+    event void commitDone(error_t error);
+
+    command storage_len_t getSize();
+    command bool valid();
+  }
+
+B.3 LogStorage interfaces
+------------------------------------------------------------------
+
+The LogStorage interfaces are: ::
+
+  interface LogRead {
+    command error_t read(void* buf, storage_len_t len);
+    event void readDone(void* buf, storage_len_t len, error_t error);
+
+    command storage_cookie_t currentOffset();
+
+    command error_t seek(storage_cookie_t offset);
+    event void seekDone(error_t error);
+
+    command storage_len_t getSize();
+  }
+
+  interface LogWrite {
+    command error_t append(void* buf, storage_len_t len);
+    event void appendDone(void* buf, storage_len_t len, bool recordsLost,
+                         error_t error);
+
+    command storage_cookie_t currentOffset();
+
+    command error_t erase();
+    event void eraseDone(error_t error);
+
+    command error_t sync();
+    event void syncDone(error_t error);
+  }
index ba8809fc7b98a56519d6def7792c923c032cb924..12894aaba16d804cfa50e62a7a3304430ca167d4 100644 (file)
@@ -80,9 +80,11 @@ reflect the specifc name of the sensor, and optionally provide a
 component with a generic name for application authors who only care
 about the general class of the sensor.
 
-This document assumes that sensors return uninterpreted values of
-arbitrary size or datatype. Conversion of sensor values to something
-with actual physical meaning is beyond the scope of this document.
+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 interpret the value properly.
 
 2. Sensor HIL Components
 ====================================================================
@@ -217,32 +219,7 @@ For example::
     // connect to the sensor's platform-dependent HPL here
   }
 
-4. Sensor HPL Components
-====================================================================
-
-A sensor HPL is necessarily platform-dependent or
-sensorboard-dependent. These components should provide access to the
-physical resources needed by the sensor, in a platform-independent
-manner that can be used by the shared logic of the sensor HAL
-components. In the case of bus-based sensors, this HPL may be nothing
-more than wiring to the appropriate bus interface for use by the HAL
-component.
-
-For example::
-
-  configuration HplSensirionSht11C {
-    provides interface Init;
-    provides interface Resource[ uint8_t id ];
-    provides interface GeneralIO as DATA;
-    provides interface GeneralIO as SCK;
-    provides interface GpioInterrupt as InterruptDATA;
-  }
-  implementation {
-    // connect to platform or sensorboard-dependent resources
-    // power-manage the sensor through platform-specific means
-  }
-
-5. Directory Organization Guidelines
+4. Directory Organization Guidelines
 ====================================================================
 
 Because the same physical sensor may be attached to TinyOS platforms
@@ -324,7 +301,7 @@ code that will enter the core source tree. In general, sensor
 components may be placed anywhere as long as the nesC compiler
 receives enough `-I` directives to locate all of the necessary pieces.
 
-6. Authors' Addresses
+5. Authors' Addresses
 ====================================================================
 
 | David Gay
@@ -367,10 +344,438 @@ receives enough `-I` directives to locate all of the necessary pieces.
 |
 | email - gtolle@archrock.com
 
-7. Citations
+6. Citations
 ====================================================================
 
 .. [TEP2] TEP 2: Hardware Abstraction Architecture
 .. [TEP114] TEP 114: SIDs: Source and Sink Indepedent Drivers
 .. [TEP115] TEP 115: Power Management of Non-Virtualized Devices
 
+Appendix A: Sensor Driver Examples
+====================================================================
+
+1. Analog ADC-Connected Sensor
+------------------------------
+
+The Analog sensor requires two components
+
+* a component to present the sensor itself (HamamatsuS1087ParC)
+
+* a component to select the appropriate hardware resources, such as
+  ADC port 4, reference voltage 1.5V, and a slow sample and hold time
+  (HamamatsuS1087ParP).
+
+The AdcReadClientC component and underlying machinery handles all of
+the arbitration and access to the ADC.
+
+::
+
+  tos/platforms/telosa/chips/s1087/HamamatsuS1087ParC.nc
+
+  generic configuration HamamatsuS1087ParC() {
+    provides interface Read<uint16_t>;
+    provides interface ReadStream<uint16_t>;
+  }
+  implementation {
+    components new AdcReadClientC();
+    Read = AdcReadClientC;
+
+    components new AdcReadStreamClientC();
+    ReadStream = AdcReadStreamClientC;
+
+    components HamamatsuS1087ParP;
+    AdcReadClientC.Msp430Adc12Config -> HamamatsuS1087ParP;
+    AdcReadStreamClientC.Msp430Adc12Config -> HamamatsuS1087ParP;
+  }
+  
+::
+
+  tos/platforms/telosa/chips/s1087/HamamatsuS1087ParP.nc
+
+  module HamamatsuS1087ParP {
+    provides interface Msp430Adc12Config;
+  }
+  implementation {
+
+    async command msp430adc12_channel_config_t 
+      Msp430Adc12Config.getChannelSettings() {
+      msp430adc12_channel_config_t config = {
+        inch: INPUT_CHANNEL_A4,
+        sref: REFERENCE_VREFplus_AVss,
+        ref2_5v: REFVOLT_LEVEL_1_5,
+        adc12ssel: SHT_SOURCE_ACLK,
+        adc12div: SHT_CLOCK_DIV_1,
+        sht: SAMPLE_HOLD_4_CYCLES,
+        sampcon_ssel: SAMPCON_SOURCE_SMCLK,
+        sampcon_id: SAMPCON_CLOCK_DIV_1
+      };
+      
+      return config;
+    }
+  }
+
+2. Binary Pin-Connected Sensor
+------------------------------
+
+The Binary sensor gets a bit more complex, because it has three
+components: 
+
+* one to present the sensor (UserButtonC)
+
+* one to execute the driver logic (UserButtonLogicP)
+
+* one to select the appropriate hardware resources, such as MSP430
+  Port 27 (HplUserButtonC).
+
+Note that the presentation of this sensor is not arbitrated because
+none of the operations are split-phase. 
+
+::
+
+  tos/platforms/telosa/UserButtonC.nc
+
+  configuration UserButtonC {
+    provides interface Get<bool>;
+    provides interface Notify<bool>;
+  }
+  implementation {
+
+    components UserButtonLogicP;
+
+    components HplUserButtonC;
+    UserButtonLogicP.GpioInterrupt -> HplUserButtonC.GpioInterrupt;
+    UserButtonLogicP.GeneralIO -> HplUserButtonC.GeneralIO;
+
+    Get = UserButtonLogicP;
+    Notify = UserButtonLogicP;
+  }
+
+::
+
+  tos/platforms/telosa/UserButtonLogicP.nc
+  module UserButtonLogicP {
+    provides interface Get<bool>;
+    provides interface Notify<bool>;
+
+    uses interface GeneralIO;
+    uses interface GpioInterrupt; 
+  }
+  implementation {
+    norace bool m_pinHigh;
+
+    task void sendEvent();
+    command bool Get.get() { return call GeneralIO.get(); }
+
+    command error_t Notify.enable() {
+      call GeneralIO.makeInput();
+
+      if ( call GeneralIO.get() ) {
+        m_pinHigh = TRUE;
+        return call GpioInterrupt.enableFallingEdge();
+      } else {
+        m_pinHigh = FALSE;
+        return call GpioInterrupt.enableRisingEdge();
+      }
+    }
+
+    command error_t Notify.disable() {
+      return call GpioInterrupt.disable();
+    }
+
+    async event void GpioInterrupt.fired() {
+      call GpioInterrupt.disable();
+
+      m_pinHigh = !m_pinHigh;
+
+      post sendEvent();
+    }
+
+    task void sendEvent() {
+      bool pinHigh;
+      pinHigh = m_pinHigh;
+    
+      signal Notify.notify( pinHigh );
+    
+      if ( pinHigh ) {
+        call GpioInterrupt.enableFallingEdge();
+      } else {
+        call GpioInterrupt.enableRisingEdge();
+      }
+    }
+  }
+
+::
+
+  tos/platforms/telosa/HplUserButtonC.nc
+
+  configuration HplUserButtonC {
+    provides interface GeneralIO;
+    provides interface GpioInterrupt;
+  }
+  implementation {
+
+    components HplMsp430GeneralIOC as GeneralIOC;
+
+    components new Msp430GpioC() as UserButtonC;
+    UserButtonC -> GeneralIOC.Port27;
+    GeneralIO = UserButtonC;
+
+    components HplMsp430InterruptC as InterruptC;
+
+    components new Msp430InterruptC() as InterruptUserButtonC;
+    InterruptUserButtonC.HplInterrupt -> InterruptC.Port27;
+    GpioInterrupt = InterruptUserButtonC.Interrupt;
+  }
+
+3. Digital Bus-Connected Sensor
+-------------------------------
+
+The Digital sensor is the most complex out of the set, and includes
+six components:
+
+* one to present the sensor (SensirionSht11C)
+
+* one to request arbitrated access and to transform the sensor HAL
+  into the sensor HIL (SensirionSht11P)
+
+* one to present the sensor HAL (HalSensirionSht11C)
+
+* one to perform the driver logic needed to support the HAL, which
+  twiddles pins according to a sensor-specific protocol
+  (SensirionSht11LogicP).
+
+* one to select the appropriate hardware resources, such as the clock,
+  data, and power pins, and to provide an arbiter for the sensor
+  (HplSensirionSht11C).
+
+* one to perform the power control logic needed to support the power
+  manager associated with the arbiter (HplSensirionSht11P).
+
+This bus-connected sensor is overly complex because it does not rely
+on a shared framework of bus manipulation components. A sensor built
+on top of the I2C or SPI bus would likely require fewer components.
+
+::
+
+  tos/platforms/telosa/chips/sht11/SensirionSht11C.nc
+  
+  generic configuration SensirionSht11C() {  
+    provides interface Read<uint16_t> as Temperature;
+    provides interface Read<uint16_t> as Humidity;
+  }
+  implementation {
+    components new SensirionSht11ReaderP();
+  
+    Temperature = SensirionSht11ReaderP.Temperature;
+    Humidity = SensirionSht11ReaderP.Humidity;
+  
+    components HalSensirionSht11C;
+  
+    enum { TEMP_KEY = unique("Sht11.Resource") };
+    enum { HUM_KEY = unique("Sht11.Resource") };
+  
+    SensirionSht11ReaderP.TempResource -> HalSensirionSht11C.Resource[ TEMP_KEY ];
+    SensirionSht11ReaderP.Sht11Temp -> HalSensirionSht11C.SensirionSht11[ TEMP_KEY ];
+    SensirionSht11ReaderP.HumResource -> HalSensirionSht11C.Resource[ HUM_KEY ];
+    SensirionSht11ReaderP.Sht11Hum -> HalSensirionSht11C.SensirionSht11[ HUM_KEY ];
+  }
+  
+::
+  
+  tos/chips/sht11/SensirionSht11ReaderP.nc
+  
+  generic module SensirionSht11ReaderP() {
+    provides interface Read<uint16_t> as Temperature;
+    provides interface Read<uint16_t> as Humidity;
+    
+    uses interface Resource as TempResource;
+    uses interface Resource as HumResource;
+    uses interface SensirionSht11 as Sht11Temp;
+    uses interface SensirionSht11 as Sht11Hum;
+  }
+  implementation {
+    command error_t Temperature.read() {
+      call TempResource.request();
+      return SUCCESS;
+    }
+  
+    event void TempResource.granted() {
+      error_t result;
+      if ((result = call Sht11Temp.measureTemperature()) != SUCCESS) {
+        call TempResource.release();
+        signal Temperature.readDone( result, 0 );
+      }
+    }
+  
+    event void Sht11Temp.measureTemperatureDone( error_t result, uint16_t val ) {
+      call TempResource.release();
+      signal Temperature.readDone( result, val );
+    }
+  
+    command error_t Humidity.read() {
+      call HumResource.request();
+      return SUCCESS;
+    }
+  
+    event void HumResource.granted() {
+      error_t result;
+      if ((result = call Sht11Hum.measureHumidity()) != SUCCESS) {
+        call HumResource.release();
+        signal Humidity.readDone( result, 0 );
+      }
+    }
+  
+    event void Sht11Hum.measureHumidityDone( error_t result, uint16_t val ) {
+      call HumResource.release();
+      signal Humidity.readDone( result, val );
+    }
+  
+    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 Sht11Temp.writeStatusRegDone( error_t result ) { }
+  
+    event void Sht11Hum.resetDone( error_t result ) { }
+    event void Sht11Hum.measureTemperatureDone( error_t result, uint16_t val ) { }
+    event void Sht11Hum.readStatusRegDone( error_t result, uint8_t val ) { }
+    event void Sht11Hum.writeStatusRegDone( error_t result ) { }
+  
+    default event void Temperature.readDone( error_t result, uint16_t val ) { }
+    default event void Humidity.readDone( error_t result, uint16_t val ) { }
+  }
+  
+::
+  
+  tos/platforms/telosa/chips/sht11/HalSensirionSht11C.nc
+  
+  configuration HalSensirionSht11C {
+    provides interface Resource[ uint8_t client ];
+    provides interface SensirionSht11[ uint8_t client ];
+  }
+  implementation {
+    components new SensirionSht11LogicP();
+    SensirionSht11 = SensirionSht11LogicP;
+  
+    components HplSensirionSht11C;
+    Resource = HplSensirionSht11C.Resource;
+    SensirionSht11LogicP.DATA -> HplSensirionSht11C.DATA;
+    SensirionSht11LogicP.CLOCK -> HplSensirionSht11C.SCK;
+    SensirionSht11LogicP.InterruptDATA -> HplSensirionSht11C.InterruptDATA;
+    
+    components new TimerMilliC();
+    SensirionSht11LogicP.Timer -> TimerMilliC;
+  
+    components LedsC;
+    SensirionSht11LogicP.Leds -> LedsC;
+  }
+  
+::
+  
+  tos/chips/sht11/SensirionSht11LogicP.nc
+  
+  generic module SensirionSht11LogicP() {
+    provides interface SensirionSht11[ uint8_t client ];
+  
+    uses interface GeneralIO as DATA;
+    uses interface GeneralIO as CLOCK;
+    uses interface GpioInterrupt as InterruptDATA;
+  
+    uses interface Timer<TMilli>;
+  
+    uses interface Leds;
+  }
+  implementation {
+  
+    ... bus protocol details omitted for brevity ...
+  
+  }
+  
+::
+  
+  tos/platforms/telosa/chips/sht11/HplSensirionSht11C.nc
+  
+  configuration HplSensirionSht11C {
+    provides interface Resource[ uint8_t id ];
+    provides interface GeneralIO as DATA;
+    provides interface GeneralIO as SCK;
+    provides interface GpioInterrupt as InterruptDATA;
+  }
+  implementation {
+    components HplMsp430GeneralIOC;
+    
+    components new Msp430GpioC() as DATAM;
+    DATAM -> HplMsp430GeneralIOC.Port15;
+    DATA = DATAM;
+  
+    components new Msp430GpioC() as SCKM;
+    SCKM -> HplMsp430GeneralIOC.Port16;
+    SCK = SCKM;
+  
+    components new Msp430GpioC() as PWRM;
+    PWRM -> HplMsp430GeneralIOC.Port17;
+  
+    components HplSensirionSht11P;
+    HplSensirionSht11P.PWR -> PWRM;
+    HplSensirionSht11P.DATA -> DATAM;
+    HplSensirionSht11P.SCK -> SCKM;
+  
+    components new TimerMilliC();
+    HplSensirionSht11P.Timer -> TimerMilliC;
+  
+    components HplMsp430InterruptC;
+    components new Msp430InterruptC() as InterruptDATAC;
+    InterruptDATAC.HplInterrupt -> HplMsp430InterruptC.Port15;
+    InterruptDATA = InterruptDATAC.Interrupt;
+  
+    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;
+  }
+  
+::
+  
+  tos/platforms/telosa/chips/sht11/HplSensirionSht11P.nc
+  
+  module HplSensirionSht11P {
+    provides interface SplitControl;
+    uses interface Timer<TMilli>;
+    uses interface GeneralIO as PWR;
+    uses interface GeneralIO as DATA;
+    uses interface GeneralIO as SCK;
+  }
+  implementation {
+    task void stopTask();
+  
+    command error_t SplitControl.start() {
+      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() {
+      call SCK.makeInput();
+      call SCK.clr();
+      call DATA.makeInput();
+      call DATA.clr();
+      call PWR.clr();
+      post stopTask();
+      return SUCCESS;
+    }
+  
+    task void stopTask() {
+      signal SplitControl.stopDone( SUCCESS );
+    }
+  }
index 0dc1ca4487bbab94bf03c5419694c4eeb48db5b7..17fe6f61ae8ddbeeab9d14653467486ae06a8c2f 100644 (file)
@@ -126,6 +126,11 @@ preceding it might have different lengths, and packet-level radios
 often require packets to be contiguous memory regions. Overall, these 
 complexities make specifying the format of ``TOS_Msg`` very difficult.
 
+TinyOS has traditionally used statically sized packet buffers,
+rather than more dynamic approaches, such as scatter-gather I/O
+in UNIX sockets (see the man page for ``recv(2)`` for details). 
+TinyOS 2.x continues this approach.
+
 2. message_t
 ====================================================================
 
@@ -143,7 +148,11 @@ This format keeps data at a fixed offset, which is important when
 passing a message buffer between two different link layers. If the
 data payload were at different offsets for different link layers, then
 passing a packet between two link layers would require a ``memmove(3)``
-operation (essentially, a copy).
+operation (essentially, a copy). Unlike in TinyOS 1.x, where TOS_Msg
+as explicitly an active messaging packet, message_t is a more general
+data-link buffer. In practice, most data-link layers in TinyOS 2.x 
+provide active messaging, but it is possible for a non-AM stack to 
+share message_t with AM stacks.
 
 The header, footer, and metadata formats are all opaque. Source code
 cannot access fields directly. Instead, data-link layers provide access
@@ -259,10 +268,11 @@ for other components.
 
 The message_t header field is an array of bytes whose size is 
 the size of a platform's union of data-link headers.
-Because packets are stored contiguously, the layout of a packet
-in memory is not the same as the layout of its nesC structure.
+Because radio stacks often prefer packets to be stored contiguously, 
+the layout of a packet in memory does not necessarily reflect the 
+layout of its nesC structure.
 
-A packet header does not necessarily start at the beginning of
+A packet header MAY start somewhere besides the beginning of
 the message_t. For example, consider the Telos platform::
 
   typedef union message_header {
@@ -377,21 +387,60 @@ the CC2420 metadata structure::
     nx_uint16_t time;
   } cc2420_metadata_t;
 
-5. Implementation
+3.5 Variable Sized Structures
+----------------------------------------------------------------
+
+The message_t structure is optimized for packets with fixed-size
+headers and footers. Variable-sized footers are generally easy
+to implement. Variable-sized headers are a bit more difficult.
+There are three general approaches that can be used.
+
+If the underlying link hardware is byte-based, the header can
+just be stored at the beginning of the message_t, giving it
+a known offset. There may be padding between the header and
+the data region, but assuming a byte-based send path this merely
+requires adjusting the index.
+
+If the underlying link hardware is packet-based, then the
+protocol stack can either include metadata (e.g., in the 
+metadata structure) stating where the header begins or it
+can place the header at a fixed position and use ``memmove(3)``
+on reception and transmit. In this latter case, on
+reception the packet is continguously read into the message_t
+beginning at the offset of the header structure. Once the
+packet is completely received, the header can be decoded,
+its length calculated, and the data region of the packet 
+can be moved to the ``data`` field. On transmission,
+the opposite occurs: the data region (and footer if need
+be) are moved to be contiguous with the header. Note that
+on completion of transmission, they need to be moved back.
+Alternatively, the radio stack can institute a single
+copy at the botttom layer.
+
+
+
+4. Implementation
 ====================================================================
 
 The definition of message_t can be found in 
-``tinyos-2.x/tos/types/message.h``. The definition of the CC2420
+``tinyos-2.x/tos/types/message.h``. 
+
+The definition of the CC2420
 message format can be found in ``tinyos-2.x/tos/chips/cc2420/CC2420.h``.
+
 The defintion of the CC1000 message format can be found in 
-``tinyos-2.x/tos/chips/cc1000/CC1000Msg.h``. The definition
+``tinyos-2.x/tos/chips/cc1000/CC1000Msg.h``. 
+
+The definition
 of the standard serial stack packet format can be found in
-``tinyos-2.x/tos/lib/serial/Serial.h''. The definition of
-the telosb packet format can be found in 
+``tinyos-2.x/tos/lib/serial/Serial.h`` 
+
+The definition of
+the telos family packet format can be found in 
 ``tinyos-2.x/tos/platform/telosa/platform_message.h`` and the micaz format can be found in
 ``tinyos-2.x/tos/platforms/micaz/platform_message.h``.
 
-6. Author's Address
+5. Author's Address
 ====================================================================
 
 | Philip Levis
index 6eb0e586d744242bc90997fd77290e4581d6448f..629d73708cbd5761552015b379d8160e6cdf62a4 100644 (file)
@@ -449,11 +449,11 @@ no snooping capabilities.
 6. Citations
 ====================================================================
 
-.. [TEP2] TEP 2: Hardware Abstraction Architecture. http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep2.txt?view=markup
+.. [TEP2] TEP 2: Hardware Abstraction Architecture. tinyos-2.x/doc/txt/tep2.txt
 
-.. [TEP111] TEP 111: message_t. http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep111.txt?view=markup
+.. [TEP111] TEP 111: message_t. tinyos-2.x/doc/txt/tep111.txt
 
-.. [TEP116] TEP 116: Packet Protocols. http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/beta/teps/txt/tep116.txt?view=markup
+.. [TEP116] TEP 116: Packet Protocols. tinyos-2.x/doc/txt/tep116.txt
  
 .. [HDLC] International Organization For Standardization, ISO Standard 3309-1979, "Data communication - High-level data link control procedures - Frame structure", 1979.
 
index 8c13ccbba821e3f6726f336124eb0df2a2ee0918..f83c53eee7eb23e05ba324b83e06e7d86a4f558d 100644 (file)
@@ -7,7 +7,7 @@ Power Management of Non-Virtualised Devices
 :Type: Documentary
 :Status: Draft
 :TinyOS-Version: 2.x
-:Author: Vlado Handziski, Kevin Klues, Jan-Hinrich Hauer, Phil Levis
+:Author: Kevin Klues, Vlado Handziski, Jan-Hinrich Hauer, Phil Levis
 
 :Draft-Created: 11-Jan-2006
 :Draft-Version: $Revision$
index 635fde13402ab5b91fa8f0d14db7fe0f9a053156..4aac10db7a5e169104c2a683507c20d3ec3c5a84 100644 (file)
@@ -1,5 +1,5 @@
 ============================
-Pins and Buses
+Low-Level I/O
 ============================
 
 :TEP: 117
@@ -7,7 +7,7 @@ Pins and Buses
 :Type: Documentary
 :Status: Draft
 :TinyOS-Version: 2.x
-:Author: Phil Buonadonna
+:Author: Phil Buonadonna, Jonathan Hui
 
 :Draft-Created: 23-Jan-2006
 :Draft-Version: $Revision$
@@ -25,8 +25,7 @@ Abstract
 ====================================================================
 
 The memo documents the TinyOS 2.x interfaces used for controlling
-digital IO functionality and digital interfaces other than serial
-communication covered in [tep113].
+digital IO functionality and digital interfaces.
 
 
 1. Introduction
@@ -34,32 +33,32 @@ communication covered in [tep113].
 
 The canonical TinyOS device is likely to have a variety of digital
 interfaces. These interfaces may be divided into two broad
-categories. The first are general purpose digital I/O lines (pins)
-for individual digital signals at physical pins on a chip or
-platform. The second are digital I/O interfaces that have predefined
-communication protocol formats. The two buses covered in this
-document are the Serial Peripheral Interface (SPI) and the
-Inter-Integrated Circuit (I2c) or Two-Wire interface. While there are
-likely other bus formats, we presume SPI and I2C to have the largest
-coverage. While the UART interface is also in this category, it is
-covered separately in [tep113].
-
-This memo documents the interfaces used for pins and the two buses.
+categories. The first are general purpose digital I/O lines (pins) for
+individual digital signals at physical pins on a chip or platform. The
+second are digital I/O interfaces that have predefined communication
+protocol formats. The three buses covered in this document are the
+Serial Peripheral Interface (SPI), the Inter-Integrated Circuit (I2C)
+or Two-Wire interface, and the Universal Asynchronous
+Receiver/Transmitter (UART) interface. While there are likely other
+bus formats, we presume SPI, I2C, and UART to have the largest
+coverage.
+
+This memo documents the interfaces used for pins and the three buses.
 
 2. Pins
 ====================================================================
 
-General Purpose I/O (GPIO) pins are single, versatile digital I/O signals
-individually controllable on a particular chip or platform. Each GPIO
-can be placed into either an input mode or an output mode. On
-some platforms a third 'tri-state' mode may exist, but this
-functionality is platform specific and will not be covered in this
-document.  
+General Purpose I/O (GPIO) pins are single, versatile digital I/O
+signals individually controllable on a particular chip or
+platform. Each GPIO can be placed into either an input mode or an
+output mode. On some platforms a third 'tri-state' mode may exist, but
+this functionality is platform specific and will not be covered in
+this document.
 
-On many platforms, a physical pin may function as either a digital GPIO
-or another special function I/O such. Examples include ADC I/O or a bus
-I/O. Interfaces to configure the specific function of a pin are
-platform specific.  
+On many platforms, a physical pin may function as either a digital
+GPIO or another special function I/O such. Examples include ADC I/O or
+a bus I/O. Interfaces to configure the specific function of a pin are
+platform specific.
 
 The objective of the interfaces described here is not to attempt to
 cover all possibilities of GPIO functionality and features, but to
@@ -101,7 +100,9 @@ provided in other components as needed. ::
    async command void toggle();
    async command bool get();
    async command void makeInput();
+   async command bool isInput();
    async command void makeOutput();
+   async command bool isOutput();
  }
 
 
@@ -109,7 +110,7 @@ provided in other components as needed. ::
 2.2 GpioInterrupt
 --------------------------------------------------------------------
 
-The GPIO Interrupt HIL interface provides baseline event control for a 
+The GPIO Interrupt HIL interface provides baseline event control for a
 GPIO pin. It provides a mechanism to detect a rising edge OR a falling
 edge. Note that calls to enableRisingEdge and enableFallingEdge are
 NOT cumulative and only one edge may be detected at a time. There may
@@ -119,7 +120,9 @@ through a platform specific HAL interface. ::
  interface GpioInterrupt {
  
    async command error_t enableRisingEdge();
+   async command bool isRisingEdgeEnabled();
    async command error_t enableFallingEdge();
+   async command bool isFallingEdgeEnabled();
    async command error_t disable();
    async event void fired();
  
@@ -135,12 +138,15 @@ with a GPIO event. Platforms MAY provide this interface.
 Some platforms may have hardware support for such a feature. Other
 platforms may emulate this capability using the SoftCaptureC
 component. The interface makes not declaration of the precision or
-accuracy of the timestamp with respect to the associated GPIO event. ::
+accuracy of the timestamp with respect to the associated GPIO
+event. ::
 
  interface GpioCapture {
  
    async command error_t captureRisingEdge();
+   async command bool isRisingEdgeEnabled();
    async command error_t captureFallingEdge();
+   async command bool isFallingEdgeEnabled();
    async event void captured(uint16_t time);
    async command void disable();
  
@@ -176,18 +182,18 @@ The interface is split into a synchronous byte level and an
 asynchronous packet level interface. The byte level interface is
 intended for short transactions (3-4 bytes) on the SPI bus. ::
 
- interface SPIByte {
-   async command error_t write( uint8_t tx, uint8_t* rx );
+ interface SpiByte {
+   async command uint8_t write( uint8_t tx );
  }
 
 The packet level interface is for larger bus transactions. The
-pointer/length interface permits use of hardware assist such as DMA. ::
+pointer/length interface permits use of hardware assist such as
+DMA. ::
 
- interface SPIPacket {
+ interface SpiPacket {
    async command error_t send( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len );
-   async event void sendDone( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len, 
-                            error_t error );
+   async event void sendDone( uint8_t* txBuf, uint8_t* rxBuf, uint16_t len,
+                              error_t error );
  }
 
 3.2 I2C
@@ -195,34 +201,118 @@ pointer/length interface permits use of hardware assist such as DMA. ::
 
 The Inter-Integrated Circuit (I2C) interface is another type of
 digital bus that is often used for chip-to-chip communication. It is
-also known as a two-wire interface. 
+also known as a two-wire interface.
 
-The I2CPacket interface provides for asynchronous Master mode communication on an
-I2C with application framed packets.  It supports only single
-transfers with a start-stop condition around each transfer.
+The I2CPacket interface provides for asynchronous Master mode
+communication on an I2C with application framed packets. Individual
+I2C START-STOP events are controllable which allows the using
+component to do multiple calls within a single I2C transaction and
+permits multiple START sequences
 
 Platforms providing I2C capability MUST provide this interface. ::
 
- interface I2CPacket {
-   async command result_t readPacket(uint16_t _addr, uint8_t _length, uint8_t* _data);
-   async command result_t writePacket(uint16_t _addr, uint8_t _length, uint8_t* _data);
-   async event void readPacketDone(uint16_t addr, uint8_t length, uint8_t* data, result_t success);
-   async event void writePacketDone(uint16_t addr, uint8_t length, uint8_t* data, result_t success);
+ interface I2CPacket<addr_size> {
+   async command error_t read(i2c_flags_t flags, uint16_t addr, uint8_t length, u int8_t* data);
+   async event void readDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data);
+   async command error_t write(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data);
+   async event void writeDone(error_t error, uint16_t addr, uint8_t length, uint8_t* data)
  }
 
+The interface is typed according to the addressing space the
+underlying implementation supports.  Valid type values are below. ::
+
+  TI2CExtdAddr - Interfaces uses the extended (10-bit) addressing mode. 
+  TI2CBasicAddr - Interfaces uses the basic (7-bit) addressing mode.
+
+The i2c_flags_t values are defined below. The flags define the
+behavior of the operation for the call being made. These values may be
+ORed together. ::
+
+  I2C_START    - Transmit an I2C STOP at the beginning of the operation.
+  I2C_STOP     - Transmit an I2C STOP at the end of the operation. Cannot be used
+                 with the I2C_ACK_END flag.
+  I2C_ACK_END  - ACK the last byte sent from the buffer. This flags is only valid 
+                 a write operation. Cannot be used with the I2C_STOP flag.
 
 
-4. Author's Address
+3.3 UART
+--------------------------------------------------------------------
+
+The Universal Asynchronous Receiver/Transmitter (UART) interface is a
+type of serial interconnect. The interface is "asynchronous" since it
+recovers timing from the data stream itself, rather than a separate
+control stream. The interface is split into an asynchronous multi-byte
+level interface and a synchronous single-byte level interface.
+
+The multi-byte level interface, UartStream, provides a split-phase
+interface for sending and receiving one or more bytes at a time. When
+receiving bytes, a byte-level interrupt can be enabled or an interrupt
+can be generated after receiving one or more bytes. The latter is
+intended to support use cases where the number of bytes to receive is
+already known. If the byte-level receive interrupt is enabled, the
+receive command MUST return FAIL. If a multi-byte receive interrupt is
+enabled, the enableReceiveInterrupt command MUST return FAIL. ::
+
+ interface UartStream {
+   async command error_t send( uint8_t* buf, uint16_t len );
+   async event void sendDone( uint8_t* buf, uint16_t len, error_t error );
+   
+   async command error_t enableReceiveInterrupt();
+   async command error_t disableReceiveInterrupt();
+   async event void receivedByte( uint8_t byte );
+   
+   async command error_t receive( uint8_t* buf, uint8_t len );
+   async event void receiveDone( uint8_t* buf, uint16_t len, error_t error );
+ }
+
+The single-byte level interface, UartByte, provides a synchronous
+interface for sending and receiving a single byte. This interface is
+intended to support use cases with short transactions. Because UART is
+asynchronous, the receive command takes a timeout which represents
+units in byte-times, after which the command returns with an
+error. Note that use of this interface is discouraged if the UART baud
+rate is low. ::
+ interface UartByte {
+   async command error_t send( uint8_t byte );
+   async command error_t receive( uint8_t* byte, uint8_t timeout );
+ }
+
+4. Implementation
+====================================================================
+
+Example implementations of the pin interfaces can be found in tos/chips/msp430/pins,
+tos/chips/atm128/pins, and tos/chips/pxa27x/gpio.
+
+Example implementations of the SPI interfaces can be found in tos/chips/msp430/usart,
+tos/chips/atm128/spi, and tos/chips/pxa27x/ssp.
+
+Example implementations of the I2C interfaces can be found in tos/chips/msp430/usart,
+tos/chips/atm128/i2c, and tos/chips/pxa27x/i2c.
+
+Example implementations of the UART interfaces can be found in tos/chips/msp430/usart,
+tos/chips/atm128/uart/ and tos/chips/pxa27x/uart.
+
+
+5. Author's Address
 ====================================================================
 
 | Phil Buonadonna
-| Arched Rock Corporation
+| Arch Rock Corporation
 | 657 Mission St. Ste 600
 | San Francisco, CA 94105-4120
 |
 | phone - +1 415 692-0828 x2833
+|
+|
+| Jonathan Hui
+| Arched Rock Corporation
+| 657 Mission St. Ste 600
+| San Francisco, CA 94105-4120
+|
+| phone - +1 415 692-0828 x2835
 
-5. Citations
+6. Citations
 ====================================================================
 
 .. [tep113] TEP 113: Serial Communication.
index 94580b31e4869ec2db68a4c321bd6360bf52d60a..2f6edce1c024382821b319b755bd02b46d8bdaf1 100644 (file)
@@ -24,7 +24,11 @@ Abstract
 
 The memo documents the interfaces, components, and semantics used by
 collection protocol in TinyOS 2.x. Collection provides a best-effort,
-multihop delivery of packets to the root of a tree.
+multihop delivery of packets to the root of *a* tree. There may be
+multiple roots in a network, and in this case the semantics implemented
+are of *anycast* delivery to at least one of the roots. A node sending
+a packet does not specify which root the packet is destined to.
 
 1. Introduction
 ====================================================================
@@ -44,7 +48,11 @@ rather than one tree, it has a *forest* of trees. By picking a
 parent node, a collection protocol implicitly joins one of these
 trees. Collection provides a best-effort,
 multihop delivery of packets to one of a network's tree roots:
-it is an *anycast* protocol.
+it is an *anycast* protocol. The semantics is that the protocol
+will make a reasonable effort to deliver the message to at least
+one of the roots in the network. There are however no guarantees of 
+delivery, and there can be duplicates delivered to one or more
+roots. There is also no ordering guarantees.
 
 Given the limited state that nodes can store and a general need
 for distributed tree building algorithms, simple collection protocols
@@ -75,34 +83,21 @@ for a collection service outlined above.
 A node can perform four different roles in collection: producer,
 consumer, snooper, and in-network processor. Depending on their role,
 the nodes use different interfaces to interact with the collection
-component.
-
-The nodes that generate data to be sent to the root are
-*producers*. The producers use the Send interface [1_] to send
-data to the root of the collection tree. The collection tree
-identifier is be specified as a parameter to Send during
-instantiation.
-
-Root nodes that receive data from the network are *consumers*. The
-consumers use the Receive interface [1_] to receive a message
-delivered by collection. The collection tree identifier is be
-specified as a parameter to Receive during instantiation.
+component. 
 
-The nodes that overhear messages in transit are *snoopers*. The snoopers
-use the Receive interface [1_] to receive a snooped message. The
-collection tree identifier is be specified as a parameter to Receive
-during instantiation.
-
-The nodes can process a packet that are in transit. These in-network
-*processors* use the Intercept interface [1_] to receive and
-update a packet. The collection tree identifier is be specified as a
-parameter to Intercept during instantiation.
+A consumer is a root of a tree. The set of all roots and the paths that
+lead to them form the collection routing infrastructure in the network.
+For any connected set of nodes implementing the collection protocol 
+there is only one collection infrastructure, *i.e.*, all roots in this 
+set active at the same time are part of the same infrastructure.
 
 A node is configured to become a root by using the RootControl
 interface. RootControl.setRoot() MUST make the current node a root of
-the tree specified during instantiation. RootControl.unsetRoot() MUST
-make the current root no longer a root in the tree specified during
-instantiation. RootControl.unsetRoot() MAY be called on a node that is
+the the collection infrastructure. RootControl.unsetRoot() MUST
+make the current root no longer a root in the collection infrastructure.
+Both calls are idempotent.
+RootControl.setRoot() MAY be called on a node that is already a root, to
+no effect. RootControl.unsetRoot() MAY be called on a node that is
 not a root::
 
   interface RootControl {
@@ -111,14 +106,38 @@ not a root::
     command bool isRoot();
   }
 
+The collection infrastructure can be multiplexed among independent
+applications, by means of a *collection identifier*. It is important
+to note that the *data* traffic in the protocol is multiplexed,
+while the *control* traffic is not.
+
+The nodes that generate data to be sent to the root are *producers*.
+The producers use the Send interface [1_] to send data to the root
+of the collection tree.  The collection identifier is specified as a
+parameter to Send during instantiation.
+
+Root nodes that receive data from the network are *consumers*. The
+consumers use the Receive interface [1_] to receive a message
+delivered by collection. The collection identifier is specified
+as a parameter to Receive during instantiation.
+
+The nodes that overhear messages in transit are *snoopers*. The
+snoopers use the Receive interface [1_] to receive a snooped
+message. The collection identifier is specified as a parameter
+to Receive during instantiation.
+
+The nodes can process a packet that are in transit. These in-network
+*processors* use the Intercept interface [1_] to receive and update
+a packet. The collection identifier is specified as a parameter
+to Intercept during instantiation.
 
 3 Collection Services
 ====================================================================
 
-A collection service MUST provide one component, TreeCollectionC,
+A collection service MUST provide one component, CollectionC,
 which has the following signature::
 
-  configuration TreeCollectionC {
+  configuration CollectionC {
     provides {
       interface StdControl;
       interface Send[uint8_t client];
@@ -128,7 +147,6 @@ which has the following signature::
       interface RootControl;
       interface Packet;
       interface CollectionPacket;
-      interface TreeRoutingInspect;
     }
     uses {
       interface CollectionId[uint8_t client];
@@ -136,12 +154,12 @@ which has the following signature::
   }
 
 
-TreeCollectionC MAY have additional interfaces, but they MUST have
+CollectionC MAY have additional interfaces, but they MUST have
 default functions on all outgoing invocations (commands for uses,
 events for provides) of those interfaces so that it can operate
 properly if they are not wired.
 
-Components SHOULD NOT wire to TreeCollectionC.Send. The generic
+Components SHOULD NOT wire to CollectionC.Send. The generic
 component CollectionSenderC (described in section 3.1) provides
 a virtualized sending interface.
 
@@ -154,41 +172,25 @@ collection_id_t generally have the same payload format, so that
 snoopers, intercepters, and receivers can parse it properly.
 
 Receive.receive MUST NOT be signaled on non-root
-nodes. TreeCollectionC MAY signal Receive.receive on a root node when
+nodes. CollectionC MAY signal Receive.receive on a root node when
 a data packet successfully arrives at that node. If a root node calls
-Send, TreeCollectionC MUST treat it as it if were a received packet.
+Send, CollectionC MUST treat it as it if were a received packet.
 Note that the buffer swapping semantics of Receive.receive, when
-combined with the pass semantics of Send, require that TreeCollectionC
+combined with the pass semantics of Send, require that CollectionC
 make a copy of the buffer if it signals Receive.receive.
 
-If TreeCollectionC receives a data packet to forward and it is not a
+If CollectionC receives a data packet to forward and it is not a
 root node, it MAY signal Intercept.forward.
 
-If TreeCollectionC receives a data packet that a different node
+If CollectionC receives a data packet that a different node
 is supposed to forward, it MAY signal Snoop.receive.
 
 RootControl allows a node to be made a collection tree root.
-TreeCollectionC SHOULD NOT configure a node as a root by default.
+CollectionC SHOULD NOT configure a node as a root by default.
 
 Packet and CollectionPacket allow components to access collection
 data packet fields [1_].
 
-TreeRoutingInspect provides information on the current position of
-the node in a routing tree::
-
-  interface TreeRoutingInspect {
-    command error_t getParent(am_addr_t* parent);
-    command error_t getHopcount(uint8_t* hopcount);
-    command error_t getMetric(uint16_t* metric);
-  }
-
-In each of these commands, if the return value is not SUCCESS, the
-value stored in the pointer argument is undefined. The getMetric
-command provides a measure of the quality of a node's route to the
-base station. This routing metric MUST be monotonically increasing
-across hops. In a collection tree, if node A is the parent of node B,
-then node B's metric value MUST be greater than node A's.
-
 3.1 CollectionSenderC
 --------------------------------------------------------------------
 
@@ -202,6 +204,8 @@ component CollectionSenderC::
     }
   }
 
+
+
 This abstraction follows a similar virtualization approach to
 AMSenderC [1_], except that it is parameterized by a collection_id_t
 rather than an am_id_t. As with am_id_t, every collection_id_t SHOULD
@@ -212,25 +216,30 @@ based on its collection ID and contents.
 ====================================================================
 
 An implementation of this TEP can be found in
-``tinyos-2.x/tos/lib/net/collection``. The implementation consists of
-three major components, which are wired together to form a
-CollectionC: LinkEstimatorP, TreeRoutingEngineP, and ForwardingEngineP.
-
-This decomposition tries to encourage evolution of components and ease
-of use through modularization. Neighbor management and link estimation
-are are decoupled from the routing protocol. Furthermore, the routing
-protocol and route selection are decoupled from the forwarding policies,
-such as queueing and timing.
+``tinyos-2.x/tos/lib/net/ctp`` and ``tinyos-2.x/tos/lib/net/le``, in
+the CTP protocol. It is beyond the scope of this document to fully
+describe CTP, but we outline its main components. CTP will be
+described in an upcoming TEP [2_].  This implementation is a
+reference implementation, and is not the only possibility.  It
+consists of three major components, which are wired together to form
+a CollectionC: LinkEstimatorP, CtpTreeRoutingEngineP, and
+CtpForwardingEngineP. 
+
+This decomposition tries to encourage evolution of components and
+ease of use through modularization. Neighbor management and link
+estimation are decoupled from the routing protocol. Furthermore, the
+routing protocol and route selection are decoupled from the
+forwarding policies, such as queueing and timing.
 
 4.1 LinkEstimatorP
 --------------------------------------------------------------------
 
 LinkEstimatorP estimates the quality of link to or from each
-neighbor. Link estimation can be done in a variety of ways, and we do
-not impose one here. It is decoupled from the establishment of
-routes. There is a narrow interface (LinkEstimator) between the link
-estimator and the routing engine. The one requirement is that the
-quality returned is standardized. A larger return value from
+neighbor. Link estimation can be done in a variety of ways, and we
+do not impose one here. It is decoupled from the establishment of
+routes. There is a narrow interface -- LinkEstimator -- between the
+link estimator and the routing engine. The one requirement is that
+the quality returned is standardized. A smaller return value from
 LinkEstimator.getQuality(), LinkEstimator.getforwardQuality(),
 LinkEstimator.getreserveQuality() MUST imply that the link to the
 neighbor is estimated to be of a higher quality than the one that
@@ -238,70 +247,114 @@ results in a smaller return value. The range of value SHOULD be
 [0,255] and the variation in link quality in that range SHOULD be
 linear. Radio provided values such as LQI or RSI, beacon based link
 estimation to compute ETX, or their combination are some possible
-approaches to estimating link qualities. LinkEstimatorP MAY have its
-own control messages to compute bi-directional link qualities::
+approaches to estimating link qualities. 
 
-  typedef uint16_t neighbor_t
+LinkEstimatorP MAY have its own control messages to compute
+bi-directional link qualities. LinkEstimatorP provides calls
+(txAck(), txNoAck(), and clearDLQ()) to update the link estimates
+based on successful or unsuccessful data transmission to the
+neighbors. 
+
+The user of LinkEstimatorP can call insertNeighbor() to manually
+insert a node in the neighbor table, pinNeighbor() to prevent a
+neighbor from being evicted, and unpinNeighbor() to restore eviction
+policy::
+
+  typedef uint16_t neighbor_table_entry_t
 
   LinkEstimatorP {
     provides {
+      interface StdControl;
+      interface AMSend as Send;
+      interface Receive;
       interface LinkEstimator;
-      interface NeighborTable;
+      interface Init;
+      interface Packet;
+      interface LinkSrcPacket;
     }
   }
 
   interface LinkEstimator {
-    command uint8_t getLinkQuality(neighbot_t neighbor);
-    command uint8_t getReverseQuality(neighbot_t neighbor);
-    command uint8_t getForwardQuality(neighbot_t neighbor);
+    command uint8_t getLinkQuality(uint16_t neighbor);
+    command uint8_t getReverseQuality(uint16_t neighbor);
+    command uint8_t getForwardQuality(uint16_t neighbor);
+    command error_t insertNeighbor(am_addr_t neighbor);
+    command error_t pinNeighbor(am_addr_t neighbor);
+    command error_t unpinNeighbor(am_addr_t neighbor);
+    command error_t txAck(am_addr_t neighbor);
+    command error_t txNoAck(am_addr_t neighbor);
+    command error_t clearDLQ(am_addr_t neighbor);
+    event void evicted(am_addr_t neighbor);
   }
 
-  interface NeighborTable {
-    event void evicted(neighbot_t neighbor)
-  }
 
 
-4.2 TreeRoutingEngineP
+4.2 CtpRoutingEngineP
 --------------------------------------------------------------------
 
-TreeRoutingEngineP is responsible for computing routes to the roots of a
-tree. It uses NeighborTable and LinkEstimator interfaces to learn
+CtpRoutingEngineP is responsible for computing routes to the roots of a
+tree. In traditional networking terminology, this is part of the
+control plane of the network, and is does not directly forward any
+data packets, which is the responsibility of CtpForwardingEngine. 
+The main interface between the two is UnicastNameFreeRouting.
+
+CtpRoutingEngineP uses the LinkEstimator interface to learn
 about the nodes in the neighbor table maintained by LinkEstimatorP and
 the quality of links to and from the neighbors. The routing protocol
 on which collection is implemented MUST be a tree-based routing
-protocol with a single or multiple roots. TreeRoutingEngineP 
+protocol with a single or multiple roots. CtpRoutingEngineP 
 allows a node to be configured as a root or a non-root node
-dynamically. TreeRoutingEngineP maintains multiple candidate next hops::
-
-  generic module TreeRoutingEngineP(uint8_t routingTableSize) {
-    provides {
-        interface UnicastNameFreeRouting as Routing;
-        interface RootControl;
-        interface TreeRoutingInspect;
-        interface StdControl;
-        interface Init;
-    } 
-    uses {
-        interface AMSend as BeaconSend;
-        interface Receive as BeaconReceive;
-        interface LinkEstimator;
-        interface AMPacket;
-        interface LinkSrcPacket;
-        interface SplitControl as RadioControl;
-        interface Timer<TMilli> as BeaconTimer;
-        interface Random;
-        interface CollectionDebug;
-    }
+dynamically. CtpRoutingEngineP maintains multiple candidate next hops::
+
+  generic module CtpRoutingEngineP(uint8_t routingTableSize, 
+                                   uint16_t minInterval, 
+                                   uint16_t maxInterval) {
+      provides {
+          interface UnicastNameFreeRouting as Routing;
+          interface RootControl;
+          interface CtpInfo;
+          interface StdControl;
+          interface CtpRoutingPacket;
+          interface Init;
+      } 
+      uses {
+          interface AMSend as BeaconSend;
+          interface Receive as BeaconReceive;
+          interface LinkEstimator;
+          interface AMPacket;
+          interface LinkSrcPacket;
+          interface SplitControl as RadioControl;
+          interface Timer<TMilli> as BeaconTimer;
+          interface Timer<TMilli> as RouteTimer;
+          interface Random;
+          interface CollectionDebug;
+          interface CtpCongestion;
+      }
   }
 
-4.3 ForwardingEngineP
+
+::
+
+ interface UnicastNameFreeRouting {
+   command am_addr_t nextHop();
+
+   command bool hasRoute();
+   event void routeFound();
+   event void noRoute();
+ }
+
+
+
+4.3 CtpForwardingEngineP
 --------------------------------------------------------------------
 
-The ForwardingEngineP component provides all the top level interfaces
-(except RootControl) which TreeCollectionC provides and an application 
-uses:: 
+The CtpForwardingEngineP component provides all the top level interfaces
+(except RootControl) which CollectionC provides and an application 
+uses. It deals with retransmissions, duplicate suppression, packet
+timing, loop detection, and also informs the LinkEstimator of the
+outcome of attempted transmissions.::
 
-  generic module ForwardingEngineP() {
+  generic module CtpForwardingEngineP() {
     provides {
       interface Init;
       interface StdControl;
@@ -311,20 +364,24 @@ uses::
       interface Intercept[collection_id_t id];
       interface Packet;
       interface CollectionPacket;
+      interface CtpPacket;
+      interface CtpCongestion;
     }
     uses {
+      interface SplitControl as RadioControl;
       interface AMSend as SubSend;
       interface Receive as SubReceive;
       interface Receive as SubSnoop;
       interface Packet as SubPacket;
       interface UnicastNameFreeRouting;
-      interface SplitControl as RadioControl;
       interface Queue<fe_queue_entry_t*> as SendQueue;
       interface Pool<fe_queue_entry_t> as QEntryPool;
       interface Pool<message_t> as MessagePool;
       interface Timer<TMilli> as RetxmitTimer;
-      interface Cache<uint32_t> as SentCache;
-      interface TreeRoutingInspect;
+      interface LinkEstimator;
+      interface Timer<TMilli> as CongestionTimer;
+      interface Cache<message_t*> as SentCache;
+      interface CtpInfo;
       interface PacketAcknowledgements;
       interface Random;
       interface RootControl;
@@ -334,13 +391,14 @@ uses::
     }
   }
 
-ForwardingEngineP uses a large number of interfaces, which can be
+
+CtpForwardingEngineP uses a large number of interfaces, which can be
 broken up into a few groups of functionality:
 
   * Single hop communication: SubSend, SubReceive, SubSnoop,
     SubPacket, PacketAcknowledgments, AMPacket
-  * Routing: UnicastNameFreeRouting, TreeRoutingInspect, 
-    RootControl, CollectionId, SentCache
+  * Routing: UnicastNameFreeRouting, RootControl, CtpInfo,
+    CollectionId, SentCache
   * Queue and buffer management: SendQueue, MessagePool,
     QEntryPool
   * Packet timing: Random, RetxmitTimer
@@ -388,4 +446,5 @@ broken up into a few groups of functionality:
 ====================================================================
 
 .. [1] TEP 116: Packet Protocols
+.. [2] TEP 124: The Collection Tree Protocol (CTP) - (upcoming)
  
index 2d6b60d4ebf9c1c4f988f10603695d1a0d848508..46a2c57a958c3335d9a71d28ecce62b12fb21662 100644 (file)
@@ -483,33 +483,34 @@ standardized interfaces that allows such technology to interoperate.
 9. Funding
 ====================================================================
 
-As with the IETF, individuals are responsible for their own costs,
-which primarily involve meetings, travel, and generation of work
-products.  Membership participation will involve attendance at
-Alliance meetings.  Registration fees will be charged to cover costs
-associated with adminstration of the meetings.  
-
-Companies and institutions are encouraged to contribute financial and
-in-kind support.  It will be essential that companies provide initial
-funding to create the legal structure and to establish basic IT
-capabilities to host the web site and working groups.
-
 Initially, we expect that there are no full time employees in the
 Alliance and that funding needs are limited to such items as lawyer's
 fees, web site costs, and insurance. If the Alliance eventually
 requires full time support personnel, the funding structure will have
 to be re-visited.
 
+As with the IETF, individuals are responsible for their own costs,
+which primarily involve meetings, travel, and generation of work
+products.  The Alliance is predominantly a volunteer organization.
+Membership participation will involve attendance at
+Alliance meetings.  Registration fees will be charged to cover costs
+associated with adminstration of the meetings.  
+
 To maintain the focus on technical excellence and meritocracy, we want
 to avoid the heavy-handed quid-pro-quo seen in many industrial
 consortiums where funding determines influence.  The best use of funds
 and the best form of influence is direct contribution to the work
-products of the Alliance.  We will permit targeted contributions
-toward specific working groups or technical capabilities.
-
-We seek to keep overall structure lean, mostly volunteer.
-Focus on desired impact and recognition, rather than control.
+products of the Alliance.  
+To keep the structure of the Alliance and its operations minimalist
+and lean, membership focuses on desired impact and recognition, rather
+than control. We want the best way to influence the direction of the Alliance
+to be to contribute technical work and demonstrate leadership, rather than 
+try to control what individuals can or cannot contribute.
 
+Companies and institutions are encouraged to contribute financial and
+in-kind support.  It will be essential that companies provide initial
+funding to create the legal structure and to establish basic IT
+capabilities to host the web site and working groups.
 Institutional members
 will pay an annual membership fee. In some cases, a 
 contributing corporate member may provide in-kind services
@@ -520,55 +521,90 @@ solicited and encouraged. In this case the donator need not
 become a contributing corporate member, e.g., in those cases
 where such a membership may be prohibited or unwanted.
 The costs of meetings, such as the TinyOS
-technology exchange, will be covered through registration fees.
-
-Individuals are responsible
-for their own costs such as 
-for travel, meeting costs, or costs for contributing
-software or documentation to the Alliance. The Alliance
-is primarily a volunteer organization. 
+technology exchange, will be covered through registration fees and
+not by institutional membership fees.
 
 10. Work Products
 ====================================================================
 
-Code base
-Stable, robust core release
-Rapidly evolving, innovative extensions
-Reference Implementations
-Tools
-Data
-Documentation
-Standard proposals
-Marketing and Promotion
-Testing and Compliance
-Assessments
-Applications and uses of technology
-Educational Materials
+The broad mission of the Alliance calls for a broad range of 
+work products. 
+
+Foremost among these are a set of TEPs documenting
+systems and protocols as well as TEPs that provide guidance
+and knowledge to the community. Technical documentation will have
+robust and open reference implementations for the community to
+use, refine, improve, and discuss. These reference implementations
+will not preclude alternative, compatibile implementations which may
+have additional features or optimizations. The Alliance Working Groups
+will periodically produce periodic releases of these reference 
+implementations for the community to use and improve.
+
+The Alliance will support community contributions
+of innovative extensions and systems by providing a CVS repository 
+to store them.
+In order to keep these contributions organized for users, the
+Steering Committee may nominate one or more people to caretake
+the repository by setting minimal guidelines for the use of
+the directory structure and migrating code as it joins the core
+or falls into disuse.
+
+To make these technological resources more accessible and useful
+to a broad embedded networks community, the Alliance will be
+dedicated to providing a set of educational materials. This
+includes introductory tutorials, documentation of core systems,
+simple and complex example applications, and user guides.
+
+In addition to educational sample applications, whose purpose
+is to teach new developers about the internals and workings of
+the technology, the Alliance will develop and make available
+several end-user applications and tools. The goal is to improve
+the accessibility of the technology to end-users while 
+demonstrating its effectiveness. Historical examples of such applications
+include Surge and TinyDB. An important part of this effort is
+good documentation for users who are not expert programmers, as well
+as tools and graphical environments. 
+
 
 11. Conclusions
 ====================================================================
 
-The time has come to create an organizational structure to allow the effort to grow
-Beyond the Berkeley + Others
-It is a balancing act
-Stability vs Innovation
-Broad Participation vs Strong Requirements
-Uniform Licensing vs Institutional Differences
-Goal is to help to community to work together
-Not a forum for maneuvering and intrigue
-Focus on consensus building and technical soundness
-Minimal mechanism to resolve rare differences
-Focus on working groups and individual contributions
-with architectural and organization oversight
-Be pragmatic on participation
-Don\92t have to make deep commitments to participate
-Can\92t expect broad guarantees in return
+By focusing on consensus building and technical excellence, the 
+Alliance seeks to avoid being a forum for political and economic
+positioning. It will achieve this by focusing on working groups
+and the contributions of individuals, while not taking strong 
+positions on the benefits or drawbacks of different approaches.
+The variety of application domains sensornets are used in and
+the huge differences in requirements mean that having a suite 
+of solutions, rather than a single one, is often not only
+desirable but essential.
+
+Over the past five years, low-power embedded sensor networks have
+grown from research prototypes to working systems that are being
+actively deployed. Furthermore, there is a vibrant research community
+that actively works to deploy these systems and collaborate with
+industry, making advances quickly accessible and usable. A great
+catalyst to this growth has been the presence of a large community
+around a shared, free code base.
+
+The time has come to create an organizational structure to 
+allow the effort to grow further. As sensornets become more widespread,
+contributions and advancements will be from an increasingly broad
+demographic of users, and bringing them all together will speed
+progress and improve the potential benefit these systems can bring
+to society. This focus on bringing disparate groups together lies
+at the heart of the Alliance. Rather than depend on strong requirements,
+it depends on broad collaboration and participation, placing a minimalist
+set of expectations that will encourage the exchange of ideas and
+technology.
+
 
 12. Author's Address
 ====================================================================
 
 | Philippe Bonnet <bonnet.p@gmail.com> 
 | David Culler    <culler@cs.berkeley.edu> 
+| David Culler <dculler at archrock.com>,
 | Deborah Estrin       <destrin@cs.ucla.edu> 
 | Ramesh Govindan <ramesh@usc.edu> 
 | Mike Horton  <mhorton@xbow.com> 
@@ -580,5 +616,3 @@ Can\92t expect broad guarantees in return
 | Matt Welsh   <mdw@cs.harvard.edu> 
 | Adam Wolisz  <awo@ieee.org> 
 
-| David Culler <dculler at archrock.com>,
-
index 93e6b82076a8cf25a528091773649b70ffdc167e..7cbf5aa71f385e952215dafc54e8e863164f809f 100644 (file)
@@ -130,14 +130,14 @@ The CTP data frame format is as follows::
 
 Field definitions are as follows:
 
-  * C: Congestion notification. If a node is receiving packets faster than it can forward them, it MAY set the C field to notify other nodes. If a node hears a packet from node N with the C bit set, it MUST NOT transmit CTP data frames to N until it hears a packet from N with the C bit cleared.
-  * P: Routing pull. The P bit allows nodes to request routing information from other nodes. If a node hears a packet with the P bit set, it SHOULD transmit a routing frame in the near future if it has a valid route.
+  * C: Congestion notification. If a node is receiving packets faster than it can forward them, it MAY set the C field to notify other nodes. If a node hears a packet from node *N* with the C bit set, it MUST NOT transmit CTP data frames to *N* until it hears a packet from N with the C bit cleared.
+  * P: Routing pull. The P bit allows nodes to request routing information from other nodes. If a node with a valid route hears a packet with the P bit set, it SHOULD transmit a routing frame in the near future.
   * THL: Time Has Lived. When a node generates a CTP data frame, it MUST set THL to 0. When a node receives a CTP data frame, it MUST increment the THL. If a node receives a THL of 255, it increments it to 0.
   * ETX: The ETX routing metric of the single-hop sender. When a node transmits a CTP data frame, it MUST put the ETX value of its route through the single-hop destination in the ETX field.  If a node receives a packet with a lower gradient than its own, then it MUST schedule a routing frame in the near future.
   * origin: The originating address of the packet. A node forwarding a data frame MUST NOT modify the origin field.
   * seqno: Origin sequence number. The originating node sets this field, and a node forwarding a data frame MUST NOT modify it. 
   * collect_id: Higher-level protocol identifier. The origin sets this field, and a node forwarding a data frame MUST NOT modify it.
-  * data: the data payload, of zero or more bytes.
+  * data: the data payload, of zero or more bytes. A node forwarding a data frame MUST NOT modify the data payload.
 
 Together, the origin, seqno and collect_id fields denote a unique 
 ***origin packet.*** Together, the origin, seqno, collect_id, and
@@ -145,9 +145,9 @@ THL denote a unique ***packet instance*** within the network. The
 distinction is important for duplicate suppression in the presence
 of routing loops. If a node suppresses origin packets, then if
 asked to forward the same packet twice due to a routing loop, it will
-drop the packet. However, if it suppresses packet instances, then 
-unless the THL has wrapped around to the identical value it had 
-on previous times around.
+drop the packet. However, if it suppresses packet instances, then it
+will route succesfully in the presence of transient loops unless the
+THL happens to wrap around to a forwarded packet instance.
 
 A node MUST send CTP data frames as unicast messages with link-layer 
 acknowledgments enabled. 
@@ -184,4 +184,82 @@ below its own. When a parent hears a child advertise an ETX below its
 own, it MUST schedule a routing frame for transmission in the near
 future.
 
+6. Implementation
+==============================================================================
+
+An implementation of CTP can be found in the tos/lib/net/ctp directory
+of TinyOS 2.0. This section describes the structure of that implementation
+and is not in any way part of the specification of CTP.
+
+This implementation has three major subcomponents:
+
+1) A **link estimator**, which is responsible for estimating the
+single-hop ETX of communication with single-hop neighbors.
+
+2) A **routing engine**, which uses link estimates as well as
+network-level information to decide which neighbor is the next
+routing hop.
+
+3) A **forwarding engine**, which maintains a queue of packets
+to send. It decides when and if to send them. The name is a little
+misleading: the forwarding engine is responsible for forwarded traffic
+as well as traffic generated on the node.
+
+6.1 Link Estimation
+------------------------------------------------------------------------------
+
+The link estimator estimates the ETX to single-hop neighbors.
+The implementation uses two mechanisms to estimate the quality of a link:
+periodic broadcast packets and data packets. The estimator itself
+only generates broadcast packets. For data traffic, it depends on
+other components telling it about acknowledged and unacknowledged
+transmissions.
+
+The periodic broadcast packets have sequence numbers, which the
+estimator uses to estimate the sender-to-receiver packet reception
+rate (PRR). The data payload of periodic broadcast packets contain
+these estimates. Therefore, when node A receives a link estimation
+broadcast message from node B, it can use the packet header to
+estimate the B-to-A PRR and the packet payload to update B's
+estimate of the A-to-B PRR.
+
+Multiplying these two values gives a *bidirectional* PRR, or
+an estimate of the probability that if A transmits a packet to B,
+B will successfully hear and acknowledge the packet and A will
+hear the acknowledgment. The inverse of the bidirecitonal PRR
+is the ETX.
+
+CTP link estimation adapts its beaconing rate to be slow when
+its routing table is stable and faster when changes occur. 
+It adjusts the beaconing interval using an algorithm similar 
+to the trickle dissemination protocol[2_]. CTP sends beacons
+more often when one of three conditions occurs:
+
+ 1) The routing table is empty (this also sets the P bit)
+ 2) The node's routing ETX increases by >= 1 trasmission
+ 3) The node hears a packet with the P bit set
+
+CTP also estimates link quality using data transmissions. This
+is a direct measure of ETX. Whenever the data path transmits a
+packet, it tells the link estimator the destimation and whether
+it was successfully acknowledged. The estimator produces an ETX
+estimate every 5 such transmissions, where 0 successes has an
+ETX of 6.  
+
+The estimator combines the beacon and data estimates by incorporating
+them into an exponentially weighted moving average. Beacon-based
+estimates seed the neighbor table. The expectation is that the low
+beacon rate in a stable network means that for a selected route, 
+data estimates will outweigh beacon estimates. Additionally, as
+the rate at which CTP collects data estimates is proportional to
+the transmission rate, then it can quickly detect a broken link and
+switch to another candidate neighbor.
+
+6.2 Routing Engine
+------------------------------------------------------------------------------
+
+The 
+
+
+