--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
+<title>Creating a New Platform for TinyOS 2.x</title>
+<meta name="author" content="Martin Leopold" />
+<style type="text/css">
+
+/*
+:Author: David Goodger
+:Contact: goodger@users.sourceforge.net
+:Date: $Date$
+:Revision: $Revision$
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin-left: 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left {
+ clear: left }
+
+img.align-right {
+ clear: right }
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font-family: serif ;
+ font-size: 100% }
+
+pre.literal-block, pre.doctest-block {
+ margin-left: 2em ;
+ margin-right: 2em ;
+ background-color: #eeeeee }
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+tt.docutils {
+ background-color: #eeeeee }
+
+ul.auto-toc {
+ list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="creating-a-new-platform-for-tinyos-2-x">
+<h1 class="title">Creating a New Platform for TinyOS 2.x</h1>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">131</td>
+</tr>
+<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">TinyOS 8051 Working Group</td>
+</tr>
+<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Informational</td>
+</tr>
+<tr><th class="docinfo-name">Status:</th>
+<td>Draft</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>Martin Leopold</td></tr>
+<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">6-Nov-2007</td>
+</tr>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1</td>
+</tr>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">6-Nov-2007</td>
+</tr>
+<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu></td>
+</tr>
+</tbody>
+</table>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">This memo is informational. It will hopefully be a basis for
+discussions and suggestions for improvements. Distribution of this
+memo is unlimited. This memo is in full compliance with TEP 1.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id4" id="abstract" name="abstract">Abstract</a></h1>
+<p>The purpose of this TEP is to provide on overview of how to build a
+new TinyOS 2 platform. While the purpose of most TEPs is to describe
+TinyOS 2 entities, we will present concrete suggestions on how to
+implement a new TinyOS 2 platform. We will use examples and briefly
+cover the relevant TEPs to present a platform that adheres to the
+current TinyOS standards. We will not cover the TEPs in detail, but to
+the full text of each TEP for further information.</p>
+<p>This TEP will go through the tool chain setup and the most basic
+components for a functional TinyOS platform. We consider only TinyOS
+version 2.x (from now on TinyOS).</p>
+<p>Before venturing on this quest we will take a diversion and introduce
+general TinyOS 2 concepts and terminology (Section 1), readers
+familiar to TinyOS 2 can skip this section. This document will
+introduce the TinyOS 2 platform (Section 2) and describes the 3
+elements that make up a platform: the tool chain (Section 3) the
+platform definitions (Section 4) and the chips definitions (Section
+5).</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id5" id="table-of-content" name="table-of-content">Table of Content</a></h1>
+<div class="contents topic">
+<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
+<ul class="simple">
+<li><a class="reference" href="#abstract" id="id4" name="id4">Abstract</a></li>
+<li><a class="reference" href="#table-of-content" id="id5" name="id5">Table of Content</a></li>
+<li><a class="reference" href="#tinyos-overview" id="id6" name="id6">1. TinyOS Overview</a><ul>
+<li><a class="reference" href="#tinyos-2-architecture" id="id7" name="id7">1.1 TinyOS 2 architecture</a></li>
+<li><a class="reference" href="#tinyos-contrib" id="id8" name="id8">1.2 TinyOS Contrib</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#a-tinyos-platform" id="id9" name="id9">2. A TinyOS Platform</a><ul>
+<li><a class="reference" href="#a-new-platform" id="id10" name="id10">2.1 A New Platform</a></li>
+<li><a class="reference" href="#the-chips" id="id11" name="id11">2.2 The Chips</a></li>
+<li><a class="reference" href="#the-platform-directory" id="id12" name="id12">2.3 The Platform Directory</a></li>
+<li><a class="reference" href="#the-tool-chain-make-system" id="id13" name="id13">2.4 The Tool-Chain (Make System)</a></li>
+<li><a class="reference" href="#the-minimal-platform" id="id14" name="id14">2.5 The Minimal Platform</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#tool-chain" id="id15" name="id15">3. Tool Chain</a><ul>
+<li><a class="reference" href="#compiling-using-nesc" id="id16" name="id16">3.1 Compiling using nesC</a></li>
+<li><a class="reference" href="#the-make-system" id="id17" name="id17">3.2 The Make System</a><ul>
+<li><a class="reference" href="#the-target-file" id="id18" name="id18">3.2.1 The .target file</a></li>
+<li><a class="reference" href="#the-rules-file" id="id19" name="id19">3.2.2 The .rules file</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference" href="#the-platform" id="id20" name="id20">4. The Platform</a><ul>
+<li><a class="reference" href="#platform-file" id="id21" name="id21">4.1 .platform file</a></li>
+<li><a class="reference" href="#platformp-and-platformc" id="id22" name="id22">4.2 PlatformP and PlatformC</a><ul>
+<li><a class="reference" href="#platformc" id="id23" name="id23">4.2.1 PlatformC</a></li>
+<li><a class="reference" href="#platformp" id="id24" name="id24">4.2.1 PlatformP</a></li>
+<li><a class="reference" href="#init-example-platformledsc" id="id25" name="id25">4.2.3 Init example: PlatformLedsC</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#platform-specific-code" id="id26" name="id26">3.3 Platform Specific Code</a><ul>
+<li><a class="reference" href="#platform-headers" id="id27" name="id27">4.3.1 Platform Headers</a><ul>
+<li><a class="reference" href="#hardware-h" id="id28" name="id28">hardware.h</a></li>
+<li><a class="reference" href="#platform-message-h" id="id29" name="id29">platform_message.h</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#platform-specific-components" id="id30" name="id30">4.3.2 Platform Specific Components</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference" href="#id2" id="id31" name="id31">5. The chips</a><ul>
+<li><a class="reference" href="#mcu-internals" id="id32" name="id32">5.1 MCU Internals</a><ul>
+<li><a class="reference" href="#mcuxardware-h" id="id33" name="id33">5.1.1 mcuXardware.h</a></li>
+<li><a class="reference" href="#mcusleepc" id="id34" name="id34">5.1.2 MCUSleepC</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#generalio" id="id35" name="id35">5.2 GeneralIO</a><ul>
+<li><a class="reference" href="#example-msp430" id="id36" name="id36">5.2.1 Example MSP430</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#leds" id="id37" name="id37">5.3 LEDs</a><ul>
+<li><a class="reference" href="#example-mica2dot" id="id38" name="id38">5.3.1 Example Mica2dot</a></li>
+<li><a class="reference" href="#leds-implementation-discussion" id="id39" name="id39">5.3.2 LEDs implementation discussion</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#timers" id="id40" name="id40">5.4 Timers</a><ul>
+<li><a class="reference" href="#timer-layers" id="id41" name="id41">5.4.1 Timer Layers</a><ul>
+<li><a class="reference" href="#hpl" id="id42" name="id42">HPL</a></li>
+<li><a class="reference" href="#hal" id="id43" name="id43">HAL</a></li>
+<li><a class="reference" href="#hil" id="id44" name="id44">HIL</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#timer-implementation" id="id45" name="id45">5.4.2 Timer Implementation</a></li>
+<li><a class="reference" href="#example-atmega128l" id="id46" name="id46">5.4.3 Example: ATMega128l</a></li>
+<li><a class="reference" href="#id3" id="id47" name="id47">5.4.4 Example: MSP430</a></li>
+<li><a class="reference" href="#example-pxa27x" id="id48" name="id48">5.4.5 Example: PXA27x</a></li>
+<li><a class="reference" href="#timer-discussion" id="id49" name="id49">5.4.6 Timer Discussion</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#i-o-buses-uart-spi-i2c" id="id50" name="id50">5.5 I/O buses (UART, SPI, I2C)</a><ul>
+<li><a class="reference" href="#serial-communication" id="id51" name="id51">5.5.1 Serial Communication</a></li>
+<li><a class="reference" href="#i2c-spi" id="id52" name="id52">5.5.2 I2C, SPI</a><ul>
+<li><a class="reference" href="#spibyte-spipacket" id="id53" name="id53">SpiByte, SpiPacket</a></li>
+<li><a class="reference" href="#i2cpacket" id="id54" name="id54">I2CPacket</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#example" id="id55" name="id55">5.5.3 Example</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference" href="#authors" id="id56" name="id56">6. Authors</a></li>
+<li><a class="reference" href="#citations" id="id57" name="id57">7. Citations</a></li>
+</ul>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id6" id="tinyos-overview" name="tinyos-overview">1. TinyOS Overview</a></h1>
+<p>Before describing the process of writing TinyOS platforms we will
+briefly sum up the TinyOS ecosystem and the terminology required in
+this TEP. To learn more visit the TinyOS website <a class="reference" href="http://www.tinyos.net">http://www.tinyos.net</a>.</p>
+<p>A systems overview is depicted below. In this TEP we will primarily
+concern our selves with the platform portion of figure and briefly
+cover the tool chain. This involves writing the necessary drivers and
+writing rules to pass the code to the TinyOS tool chain. We will not
+cover sensor boards in this TEP refer to, see [<a class="reference" href="#tep109">TEP109</a>] for details.</p>
+<pre class="literal-block">
++------------------------------------------+
+| Application |
++------------------------------------------+
++--------+ +----------+ +--------------+
+| TinyOS | + | Platform | + | Sensor board |
++--------+ +----------+ +--------------+
+ |
+ V
+ +-------------------+
+ | TinyOS tool chain |
+ +-------------------+
+ |
+ Target platform V
+ +-------------------------------------+
+ | +-------+ +-----+ +-------+ |
+ | | Radio |----| MCU |----|Sensors| |
+ | +-------+ +-----+ +-------+ |
+ +-------------------------------------+
+</pre>
+<div class="section">
+<h2><a class="toc-backref" href="#id7" id="tinyos-2-architecture" name="tinyos-2-architecture">1.1 TinyOS 2 architecture</a></h2>
+<p>TinyOS 2.x is built on a tree-layered hardware abstraction
+architecture (HAA)[<a class="reference" href="#tep2">TEP2</a>]. This architecture separates the code for
+each platform into distinct layers:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>the Hardware Independent Layer (HIL)</li>
+<li>the Hardware Adaptation Layer (HAL)</li>
+<li>the Hardware Presentation Layer (HPL)</li>
+</ol>
+</blockquote>
+<p>A platform is built from bottom up, starting with the HPL level,
+building HAL and HIL layers on top. Platform independent applications
+are written using HIL level interfaces, allowing them to move easily
+from platform to platform. While applications can target a platform
+specific HAL layer for finer control of hardware specific features,
+this will could prohibit such an application from being easily
+portable. An overview of the TinyOS 2 architecture is given in
+[<a class="reference" href="#tos2-0view">tos2.0view</a>].</p>
+<p>The requirements for the platform implementation is described in
+TinyOS Enhancement Proposals (TEP). Each TEP covers a particular area
+and specifies the recommendations within that area, some of which are
+relevant for platforms. While no specific label or designation is
+given to platforms adhering to the set of TEPs, [<a class="reference" href="#tep1">TEP1</a>] states:
+"Developers desiring to add code (or TEPs) to TinyOS SHOULD follow all
+current BCPs (Best Current Practice)". At the time of writing no TEP
+has been awarded this designation or been finalized and we will refer
+to the drafts as they are.</p>
+<p>This document will not go through each of the requirements, but merely
+outline how to build a basic functional platform. For further
+information see "TinyOS 2.0 Overview" [<a class="reference" href="#tos2-0view">tos2.0view</a>] or the TEP list on
+the TinyOS website <a class="reference" href="http://www.tinyos.net">http://www.tinyos.net</a>.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id8" id="tinyos-contrib" name="tinyos-contrib">1.2 TinyOS Contrib</a></h2>
+<p>The core of TinyOS is maintained by a set of working groups that
+govern specific parts of the source code. New project can benefit from
+the <em>contrib</em> section of TinyOS. This is a separate section of the
+website and source repository maintained more loosely than the core of
+TinyOS. It is intended for sharing code at an early stage or code that
+may not gain the same popularity as the core.</p>
+<p>New projects request a directory in this repository by following a
+simple procedure on the <a class="reference" href="http://tinyos.cvs.sourceforge.net/*checkout*/tinyos/tinyos-2.x-contrib/contrib.html">TinyOS contrib web page</a></p>
+<p>In contrib is a skeleton project <em>skel</em> that provides the most basic
+framework for setting up a new platform, MCU, etc.</p>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id9" id="a-tinyos-platform" name="a-tinyos-platform">2. A TinyOS Platform</a></h1>
+<p>A TinyOS platform provides the code and tool chain definitions that
+enable an application writer to implement an application for a mote. A
+platform in TinyOS exposes some or all of the features of a particular
+physical mote device to TinyOS applications - it refers to an entire
+system, not a single chip. In order to write programs for a device
+using TinyOS a platform for that device must exist within TinyOS.</p>
+<p>A physical platform is comprised of a set of chips. Similarly a TinyOS
+platform is the collection of the components representing these chips
+(corresponding to drivers) Common chips can be shared among platforms
+and implementing a new platform could simply mean wiring existing
+components in a new way. If the chips that make up the platform are
+not supported by TinyOS implementing the new platform consists if
+implementing components for those chips (much like implementing
+drivers).</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id10" id="a-new-platform" name="a-new-platform">2.1 A New Platform</a></h2>
+<p>Platforms are discovered at compile time by the TinyOS tool
+chain and a new platform placed in the search path will be discovered
+automatically. In addition sensor boards can be defined in a very
+similar manner, however we will not cover sensor boards, see [<a class="reference" href="#tep109">TEP109</a>]
+for details. Defining a new platform boils down to 3 things:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>definitions of the chips that make up the platform,</li>
+<li>platform definitions (combining chips to a platform) and,</li>
+<li>the tool chain or make definitions.</li>
+</ol>
+</blockquote>
+<p>The code for a TinyOS platform is spread out in a few locations of the
+TinyOS tree depending based on those 3 categories. Below is an
+overview of the locations and some of the files we will be needing in
+the following (for further information see see "Coding Conventions"
+[<a class="reference" href="#tep3">TEP3</a>] and the "README" files in each directory).</p>
+<p>Through this TEP we will use the terms PlatformX and MCUX to denote
+the new generic platform and MCU being created:</p>
+<pre class="literal-block">
+tos
+ +--chips 1. Chip definitions
+ | +--chipX
+ +--platforms
+ | +--platformX 2. Platform definitions
+ | +--PlatformP/PlatformC
+ | +--PlatformLeds example component
+ | +--.platform
+ | +--hardware.h
+ | +--chips
+ | +--MCUX Platform specific features
+ | +--chipX
+ +--sensorboards
+ | +--boardX
+ | +--.sensor
+ +--support
+ +--make 3. Make definitions
+ +--platformX.target platformX make targets
+ +--MCUX
+ +--MCUX.rules make rules for MCUX
+ +--install.extra additional target for MCUX
+</pre>
+<p>In the following we will briefly introduce each of the parts and
+describe them in more detail in sections 2 through 4.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id11" id="the-chips" name="the-chips">2.2 The Chips</a></h2>
+<p>Each of the chips that provide software accessible functionality must
+have definitions present in the chips directory sensors, radios,
+micro controllers (MCU) alike. Each chip is assigned a separate
+directory under <tt class="docutils literal"><span class="pre">tos/chips</span></tt>. This directory contains chip specific
+interfaces (HPL and HAL interfaces) and their implementations as well
+as implementations of the hardware independent interface (HIL).</p>
+<p>Some chips, MCUs in particular, contain distinct subsystems, such as
+uart, timer, A/D converter, SPI, and so forth. These subsystems are
+often put in a sub directory of their own within the chip-specific
+directory.</p>
+<p>If some feature of a chip is available or used only on a particular
+platform, the platform directory can contain code that is specific to
+this combination of chip and platform, say pin assignments, interrupt
+assignments, etc. For example such additions would be placed in
+<tt class="docutils literal"><span class="pre">tos/platforms/platformX/chips/chipX</span></tt> for PlatformX.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id12" id="the-platform-directory" name="the-platform-directory">2.3 The Platform Directory</a></h2>
+<p>The platform is the piece of the puzzle that ties the components
+corresponding to physical chips (drivers) together to form a
+platform. The platform ties together the code that exposes the
+features of the platform to TinyOS programs. In practise this is done
+by i) including code for each of the chips and ii) by providing any
+additional code that is specific to this particular platform.</p>
+<p>A platform <em>PlatformX</em> would be placed in the directory
+<tt class="docutils literal"><span class="pre">tos/platforms/platformX/</span></tt> and code for subsystems reside in further
+sub directories. Also in this directory is the <tt class="docutils literal"><span class="pre">.platform</span></tt> file that
+sets up include paths and more (see Section 3).</p>
+<p>An empty platform with no code (null) is provided and serves as an
+example for other platforms.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id13" id="the-tool-chain-make-system" name="the-tool-chain-make-system">2.4 The Tool-Chain (Make System)</a></h2>
+<p>The build system for TinyOS is written using GNU Make <a class="footnote-reference" href="#make" id="id1" name="id1">[1]</a>. The
+build system controls the process from pre-processing a TinyOS
+application into a single C file and to pass this file to the
+appropriate compiler and other tools. The make system is documented in
+<tt class="docutils literal"><span class="pre">support/make/README</span></tt> and in TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>].</p>
+<p>The make system is located in the <tt class="docutils literal"><span class="pre">support</span></tt> directory. This
+directory contains a platform definition and Make rules to build an
+application for this platform (see Section 2).</p>
+<table class="docutils footnote" frame="void" id="make" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id1" name="make">[1]</a></td><td><a class="reference" href="http://www.gnu.org/software/make/">http://www.gnu.org/software/make/</a></td></tr>
+</tbody>
+</table>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id14" id="the-minimal-platform" name="the-minimal-platform">2.5 The Minimal Platform</a></h2>
+<p>Before describing each of the subsystems, we will show a simple check
+list. The absolute minimal TinyOS platform would have to provide the
+following resources, given a <em>PlatformX</em> with <em>MCUX</em>:</p>
+<ul class="simple">
+<li>a platform directory <tt class="docutils literal"><span class="pre">tos/platform/PlatformX/</span></tt> with the following<ul>
+<li>a platform definition (<em>.platform</em> file)</li>
+<li>a <em>hardware.h</em> header</li>
+</ul>
+</li>
+<li>a <em>platformX.target</em> in <tt class="docutils literal"><span class="pre">tos/support/make</span></tt></li>
+<li>a <em>MCUX.rules</em> in <tt class="docutils literal"><span class="pre">tos/support/make/MCUX</span></tt></li>
+<li>a <em>MCUX</em> directory in <tt class="docutils literal"><span class="pre">tos/chips/MCUX</span></tt>, containing<ul>
+<li>a <em>McuSleepC</em> (must enable interrupts)</li>
+<li>a <em>mcuxhardware.h</em> (defines <em>nesc_atomic_start</em>/<em>nesc_atomic_end</em>)</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id15" id="tool-chain" name="tool-chain">3. Tool Chain</a></h1>
+<p>The major components in the tool chain of TinyOS are i) the compiler
+and ii) the build system that uses the compiler to produce an
+executable binary or hex file. The first is installed separately,
+while the second is part of the TinyOS source code. The compile
+process transforms a set of nesC files into a binary executable or hex
+file. Involved in this process is set of separate tools that are
+linked in a chain. We will briefly cover this chain in a moment, but a
+detailed description is beyond the scope of this TEP.</p>
+<p>The make system is split in two: a general part and a platform
+specific part. Section 3.1 will introduce the general mechanism and
+Section 3.2 will cover how to introduce a new platform in the tool
+chain.</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id16" id="compiling-using-nesc" name="compiling-using-nesc">3.1 Compiling using nesC</a></h2>
+<p>The process of the build system is depicted below. This system feeds
+the source code through the tools to produce an executable or hex file
+for uploading to the platform. The nesC pre-compiler is split in two
+tools ncc an nescc. These two tools are used to assemble nesC source
+files into a single C file which is compiled using a regular C
+compiler. This requires that a C compiler is available for a given
+platform and that this compiler accepts the dialect produced by nesC.</p>
+<pre class="literal-block">
+ TinyOS
+application
+ |
+ |
+ V
++------+ +-----+ +---------+ +------------+
+| ncc | app.c | | Binary | | app.hex | |
+| + |------>| GCC |------->| objdump |-------->| programmer |
+| nesC | | | | | | |
++------+ +-----+ +---------+ +------------+
+ |
+ |
+ V
+ Target
+ platform
+</pre>
+<p>The core TinyOS platforms are centered around GCC, this includes the
+telos family, mica family and intelmote2. The nesC compiler expects
+code resembling GCC C-dialect and also outputs code in GCC
+C-dialect. The current TinyOS platforms are supported by GCC, but for
+some processor architectures GCC is not available (e.g. Motorola HCS08,
+Intel MCS51).</p>
+<p>Porting to platforms that are GCC supported can benefit from the
+existing tool flow, while porting to other platforms requires some
+effort. A straight forward solution adopted for these platforms is to
+post-process the C files produced by nesC to fit the needs of a
+specific compiler, see TEP121 for an example of such a solution.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id17" id="the-make-system" name="the-make-system">3.2 The Make System</a></h2>
+<p>TinyOS controls the build process using make. The global make file
+searches certain locations to find make definitions for all available
+platforms. In order to make a new platform available to the TinyOS
+make system, a few files must be created in particular locations. These
+files will be read by the global make system and exposed to the users
+by make targets. Often the required rules are tied to a particular MCU
+that is shared among several platforms and TinyOS leverages this fact
+by creating a light-weight <em>.target</em> file pointing to the appropriate
+rules in a <em>.rules</em> file. The make system is documented in
+<tt class="docutils literal"><span class="pre">support/make/README</span></tt> and in TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>].</p>
+<p>The make system looks for <em>.target</em> files in <tt class="docutils literal"><span class="pre">support/make</span></tt> and the
+directories listed in the environment variable <tt class="docutils literal"><span class="pre">TOSMAKE_PATH</span></tt>. Each
+of the files found contain make targets for one TinyOS platform. The
+target files usually do not contain the rules to build the binary
+files, but include the appropriate rules from a <em>.rules</em> file, located
+in a sub directory for the appropriate MCU architecture (e.g. avr for
+the ATMega128 used by Mica). In this way many platforms share the
+build rules, but have different <em>.target</em> files. In addition <em>.extra</em>
+targets can be used to define helper targets such as install or clean.</p>
+<p>Setting up the make system, requires two steps (Section 3.2.1 gives an
+example):</p>
+<blockquote>
+<ol class="arabic simple">
+<li>Creating a <em>platformX.target</em> file that allows the make system to
+discover the new platform. This file must contain a make rule with
+the name of the platform. Further this target must depend on the
+targets given in the variable <tt class="docutils literal"><span class="pre">BUILD_DEPS</span></tt> - this variable
+contains the remainder of targets to be build during the build
+process.</li>
+<li>Creating a <em>.rules</em> file in a sub diretory of
+<tt class="docutils literal"><span class="pre">support/make</span></tt>. Each file contain the actual target for
+producing the binaries, hex files, etc. for one platform. They are
+assembled in the <tt class="docutils literal"><span class="pre">BUILD_DEPS</span></tt> variable.</li>
+</ol>
+</blockquote>
+<p>We will cover these two files next.</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id18" id="the-target-file" name="the-target-file">3.2.1 The .target file</a></h3>
+<p>As mentioned above TinyOS searches for targets in the <tt class="docutils literal"><span class="pre">support/make</span></tt>
+directory of the TinyOS source code and in the directories listed in
+the environment variable <tt class="docutils literal"><span class="pre">TOSMAKE_PATH</span></tt>. A <em>.target</em> file for the
+platform must exist in one of these locations. The <em>.target</em> usually
+only sets up variables related to this platform and provide a target
+named after the platform, this target depend on other rules to build
+the binaries. These rules are included by calling
+<em>TOSMake_include_platform</em>. As an example the <tt class="docutils literal"><span class="pre">mica2.target</span></tt> is
+listed below:</p>
+<pre class="literal-block">
+PLATFORM = mica2
+SENSORBOARD ?= micasb
+PROGRAMMER_PART ?= -dpart=ATmega128 --wr_fuse_e=ff
+PFLAGS += -finline-limit=100000
+
+AVR_FUSE_H ?= 0xd9
+
+$(call TOSMake_include_platform,avr)
+
+mica2: $(BUILD_DEPS)
+ @:
+</pre>
+<p>Pay attention to the call to <em>TOSMake_include_platform,avr</em> this call
+includes <tt class="docutils literal"><span class="pre">.rules</span></tt> files in <tt class="docutils literal"><span class="pre">support/make</span></tt> or any sub directory of
+<tt class="docutils literal"><span class="pre">TOSHMAKE_PATH</span></tt> named <em>avr</em>.</p>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id19" id="the-rules-file" name="the-rules-file">3.2.2 The .rules file</a></h3>
+<p>The <em>.rules</em> file contain the make rules for building the target
+binary. If a MCU implementation already exists for a new platform,
+simply pointing to this <em>.rules</em> from the corresponding <em>.target</em> is
+sufficient. If not the <em>.rules</em> file must be built for a new MCU
+architecture.</p>
+<p><tt class="docutils literal"><span class="pre">TOSMake_include_platform</span></tt> expects a sub directory with a rule file
+of the form <tt class="docutils literal"><span class="pre">avr/avr.rules</span></tt>. The call also includes additional
+<em>.rules</em> and <em>.extra</em> files present in that sub directory. See
+<tt class="docutils literal"><span class="pre">support/make/README</span></tt> for details.</p>
+<p>For example a simplified .rules file could look like this (from
+<em>avr/avr.rules</em>):</p>
+<pre class="literal-block">
+...
+
+ BUILD_DEPS = srec tosimage
+
+srec: exe FORCE
+ $(OBJCOPY) --output-target=srec $(MAIN_EXE) $(MAIN_SREC)
+
+tosimage: ihex build_tosimage FORCE
+ @:
+
+exe: builddir $(BUILD_EXTRA_DEPS) FORCE
+ @echo " compiling $(COMPONENT) to a $(PLATFORM) binary"
+ $(NCC) -o $(MAIN_EXE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS)
+ $(COMPONENT).nc $(LIBS) $(LDFLAGS)
+...
+</pre>
+</div>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id20" id="the-platform" name="the-platform">4. The Platform</a></h1>
+<p>A TinyOS platform is a collection of components corresponding to a
+physical devices (a collection of drivers). A platform is constructed
+by defining which components make up the platform and by providing any
+additional platform specific components. The content of a platform is
+not covered by a TEP at the time of writing and the following is based
+on the available tutorials, <em>READMEs</em> and the current consensus.</p>
+<p>The platform definitions for a <em>PlatformX</em> are located in
+<tt class="docutils literal"><span class="pre">tos/platforms/platformX</span></tt> and contain 3 major elements:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>The <em>.platform</em> file containing include paths and other arguments
+for nesC</li>
+<li>Platform boot procedure: PlatformP/PlatformC</li>
+<li>Platform specific code, including a header for hardware specific
+funtions (hardware.h) and code that is specific to the combination
+of chip and platform (e.g. pin assignments, modifications, etc.).</li>
+</ol>
+</blockquote>
+<p>In the following we will describe each of these in more detail, below
+is a depiction of a fictuous platform and the required definitions.</p>
+<pre class="literal-block">
+Platform: .platform
+ include MCU driver
+ +-------------------------+ include Radio driver
+ | | include Sensors driver
+ | Chips: |
+ | +-------+ | PlatformP
+ | | Radio | | Initialize MCU
+ | +--+----+ | Initialize Sensor
+ | +-----+ | | Initialize Radio
+ | | MCU +------+ |
+ | +-----+ | | hardware.h
+ | +--+----+ | Include MCU HW macros
+ | | Leds | |
+ | +-------+ | HIL interfaces, eg:
+ | | PlatformLeds
+ +-------------------------+
+</pre>
+<p>All the files we describe here must be found in a common directory
+named after the platform; we call this a platform directory. This
+directory must be found in the TinyOS tool chain search path for
+example <tt class="docutils literal"><span class="pre">tos/platforms</span></tt> (or found in <tt class="docutils literal"><span class="pre">TOSHMAKE_PATH</span></tt> see Section
+3.2.1). For example a platform named PlatformX could be placed in the
+directory <tt class="docutils literal"><span class="pre">tos/platforms/platformX</span></tt>.</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id21" id="platform-file" name="platform-file">4.1 .platform file</a></h2>
+<p>All platform directories must carry a <tt class="docutils literal"><span class="pre">.platform</span></tt> file, this file
+defines what makes up the platform. This file carries instructions for
+the make system on where to locate the drivers for each of the
+components of the platform. The definitions are read in a two step
+process: the file is read by the ncc script that passes the
+appropriate arguments to the nesC pre-processor[<a class="reference" href="#nescman">nescman</a>]. The
+.platform file is written as a Perl script interpreted by ncc.</p>
+<p>The file is documented in form of the README file in the platforms
+directory (<em>tos/platforms</em>), and the source code of the ncc script
+found in the TinyOS distribution. Valuable information can also be
+found in [<a class="reference" href="#tep106">TEP106</a>], [<a class="reference" href="#tep109">TEP109</a>], TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>].</p>
+<p>In addition to setting up include paths for nesC other arguments can
+be passed on. In particular the components to be used for the
+scheduler are selected with the '-fnesc-scheduler' command line
+argument (see [<a class="reference" href="#tep106">TEP106</a>]). The include paths are passed on using the
+'-I' command line argument covered in [<a class="reference" href="#tep109">TEP109</a>].</p>
+<p>As an example, an abbreviated <em>.platform</em> file for the mica2 platform
+looks like this:</p>
+<pre class="literal-block">
+push( @includes, qw(
+ %T/platforms/mica
+ %T/platforms/mica2/chips/cc1000
+ %T/chips/cc1000
+ %T/chips/atm128
+ %T/chips/atm128/adc
+ %T/chips/atm128/pins
+ %T/chips/atm128/spi
+ %T/chips/atm128/timer
+ %T/lib/timer
+ %T/lib/serial
+ %T/lib/power
+) );
+
+@opts = qw(
+ -gcc=avr-gcc
+ -mmcu=atmega128
+ -fnesc-target=avr
+ -fnesc-no-debug
+ -fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask
+);
+</pre>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id22" id="platformp-and-platformc" name="platformp-and-platformc">4.2 PlatformP and PlatformC</a></h2>
+<p>The PlatformP and PlatformC components are responsible for booting
+this platform to a usable state. In general this usually means things
+like calibrating clock and initializing I/O pins. If this platform
+requires that some devices are initialized in a particular order this
+can be implemented in a platform dependent way here. The boot process
+covered in [<a class="reference" href="#tep107">TEP107</a>].</p>
+<p>Most hardware peripherals require an initialization procedure of some
+sort. For most peripheral devices this procedure is only required when
+the device is in use and can be left out if the device is
+unused. TinyOS accomplishes this by providing a few initialization
+call backs interfaces. When a given component is included it wires an
+initialization procedure to one of these interfaces. In this way the
+procedure will only be included when the component is included, this
+process is known as auto wiring[<a class="reference" href="#tosprg">TOSPRG</a>].</p>
+<p>The boot sequence calls two initialization interfaces in the following
+order: <tt class="docutils literal"><span class="pre">PlatformC.Init</span></tt> and <tt class="docutils literal"><span class="pre">MainC.SoftwareInit</span></tt>.
+<tt class="docutils literal"><span class="pre">PlatformC.Init</span></tt> must take care of initializing the hardware to an
+operable state and initialization that has hidden dependencies must
+occur here. Other components are initialized as part of
+<tt class="docutils literal"><span class="pre">SoftwareInit</span></tt> and the orderign is determined at compile
+time.</p>
+<p>Common tasks in <tt class="docutils literal"><span class="pre">PlatformC.Init</span></tt> include clock calibration and IO
+pins. However this component can be used to provide greater control of
+the boot process if required. Consider for example that some component
+which is initialized in SoftwareInit requires that some other
+component has been initialized previously - lets say that the radio
+must be initialized prior to the radio stack or that a component
+prints a message to the UART during boot. How can this order be
+ensured? One solution is to provide an additional initialization
+handle prior to SoftwareInit and wire such procedures to this
+handle. Below is an example from the Mica mote family using the
+<tt class="docutils literal"><span class="pre">MoteInit</span></tt> interface. Components that must be initialized early in
+the boot process is wired to this interface. If greater level of
+control is required this strategy can be trivially be expanded to
+further levels of interfaces for example MoteInit1 being initialized
+prior to MoteInit2, this strategy is chosen by the MSP430
+implementation.</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id23" id="platformc" name="platformc">4.2.1 PlatformC</a></h3>
+<p>Below is depicted the PlatformC component from the Mica family of platforms.</p>
+<pre class="literal-block">
+#include "hardware.h"
+
+configuration PlatformC {
+ provides {
+ interface Init;
+ /**
+ * Provides calibration information for other components.
+ */
+ interface Atm128Calibrate;
+ }
+ uses interface Init as SubInit;
+} implementation {
+ components PlatformP, MotePlatformC, MeasureClockC;
+
+ Init = PlatformP;
+ Atm128Calibrate = MeasureClockC;
+
+ PlatformP.MeasureClock -> MeasureClockC;
+ PlatformP.MoteInit -> MotePlatformC;
+ MotePlatformC.SubInit = SubInit;
+}
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id24" id="platformp" name="platformp">4.2.1 PlatformP</a></h3>
+<p>Below is depicted the PlatformP component from the Mica family of platforms.</p>
+<pre class="literal-block">
+module PlatformP
+{
+ provides interface Init;
+ uses interface Init as MoteInit;
+ uses interface Init as MeasureClock;
+
+}
+implementation
+{
+ void power_init() {
+ ...
+ }
+
+ command error_t Init.init()
+ {
+ error_t ok;
+
+ ok = call MeasureClock.init();
+ ok = ecombine(ok, call MoteInit.init());
+ return ok;
+ }
+}
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id25" id="init-example-platformledsc" name="init-example-platformledsc">4.2.3 Init example: PlatformLedsC</a></h3>
+<p>Below is an example from mica/PlatformLedsC.nc wiring to the platform
+specific <em>MoteInit</em> interface.</p>
+<pre class="literal-block">
+configuration PlatformLedsC {
+ provides interface GeneralIO as Led0;
+...
+ uses interface Init;
+} implementation {
+ components HplAtm128GeneralIOC as IO;
+ components PlatformP;
+
+ Init = PlatformP.MoteInit;
+...
+</pre>
+</div>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id26" id="platform-specific-code" name="platform-specific-code">3.3 Platform Specific Code</a></h2>
+<p>In addition to PlatformP/PlatformC the platform directory contain
+additional code that is specific to this platform. First this could be
+code that ties platform independent resources to particular instances
+on this platform, second it could be code that is only relevant on
+this particular platform (e.g. the clock rate of this platform). For
+example the LEDs are a an example of the first: most platform have a
+few LEDs, and the particular pin on this platform is tied to the
+platform independent implementation using PlatformLedsC.</p>
+<p>TinyOS requires that the header <tt class="docutils literal"><span class="pre">hardware.h</span></tt> is present while other
+component can be named freely.</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id27" id="platform-headers" name="platform-headers">4.3.1 Platform Headers</a></h3>
+<p>TinyOS relies on a few C-header files being present for each
+platform. These headers are then automatically included from the
+respective parts of the TinyOS system. TinyOS expects that the
+following files are present and that certain properties are defined in
+them.</p>
+<div class="section">
+<h4><a class="toc-backref" href="#id28" id="hardware-h" name="hardware-h">hardware.h</a></h4>
+<p>The <tt class="docutils literal"><span class="pre">hardware.h</span></tt> header file is included by <tt class="docutils literal"><span class="pre">tos/system/MainC.nc</span></tt>
+and usually in turn includes a MCU specific header file, with a few
+required macros (such as avr128hardware.h, see Section 5.1.1). The
+header is documented in TinyOS 2 Tutorial Lesson 10[<a class="reference" href="#tut10">TUT10</a>]</p>
+<p>In addition the hardware.h file can set flags that are not related to
+the hardware in general, but to this platform (e.g. clock rate). Below
+is a snippet from <tt class="docutils literal"><span class="pre">mica2/hardware.h</span></tt></p>
+<pre class="literal-block">
+#ifndef MHZ
+/* Clock rate is ~8MHz except if specified by user
+ (this value must be a power of 2, see MicaTimer.h and MeasureClockC.nc) */
+#define MHZ 8
+#endif
+
+#include <atm128hardware.h>
+
+enum {
+ PLATFORM_BAUDRATE = 57600L
+};
+...
+</pre>
+</div>
+<div class="section">
+<h4><a class="toc-backref" href="#id29" id="platform-message-h" name="platform-message-h">platform_message.h</a></h4>
+<p>As part of the TinyOS 2 message buffer abstraction[<a class="reference" href="#tep111">TEP111</a>], TinyOS
+includes the header <em>platform_message.h</em> from the internal TinyOS
+header <em>message.h</em>. This header is only strictly required for
+platforms wishing to use the message_t abstraction - this is not
+described further in this TEP, but is used widely throughout TinyOS
+(See [<a class="reference" href="#tep111">TEP111</a>] for details). The is expected to define the structures:
+<em>message_header_t</em>, <em>message_footer_t</em>, and <em>message_metadata_t</em> which
+are used to fill out the generic <em>message_t</em> structure.</p>
+<p>Below is an example from the <tt class="docutils literal"><span class="pre">mica2</span></tt> <em>platform_message.h</em></p>
+<pre class="literal-block">
+typedef union message_header {
+ cc1000_header_t cc1k;
+ serial_header_t serial;
+} message_header_t;
+
+typedef union message_footer {
+ cc1000_footer_t cc1k;
+} message_footer_t;
+
+typedef union message_metadata {
+ cc1000_metadata_t cc1k;
+} message_metadata_t;
+</pre>
+</div>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id30" id="platform-specific-components" name="platform-specific-components">4.3.2 Platform Specific Components</a></h3>
+<p>The code for platform dependent features also resides in the platform
+directory. If the code can be tied to a particular chip it can be
+placed in a separate directory below the <tt class="docutils literal"><span class="pre">chips</span></tt> directory. As an
+example the following section of
+<tt class="docutils literal"><span class="pre">micaz/chips/cc2420/HplCC2420PinsC.nc</span></tt> ties specific pins to general
+names on the MicaZ platform.</p>
+<pre class="literal-block">
+configuration HplCC2420PinsC {
+ provides {
+ interface GeneralIO as CCA;
+ interface GeneralIO as CSN;
+ interface GeneralIO as FIFO;
+ interface GeneralIO as FIFOP;
+ interface GeneralIO as RSTN;
+ interface GeneralIO as SFD;
+ interface GeneralIO as VREN;
+ }
+}
+
+implementation {
+
+ components HplAtm128GeneralIOC as IO;
+
+ CCA = IO.PortD6;
+ CSN = IO.PortB0;
+ FIFO = IO.PortB7;
+ FIFOP = IO.PortE6;
+ RSTN = IO.PortA6;
+ SFD = IO.PortD4;
+ VREN = IO.PortA5;
+
+}
+</pre>
+</div>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id31" id="id2" name="id2">5. The chips</a></h1>
+<p>The functionality of each chip is provided by a set of one or more
+interfaces and one or more components, in traditional terms this makes
+up a driver. Each chip is assigned a sub directory in the the
+<tt class="docutils literal"><span class="pre">tos/chips</span></tt> directory. All code that define the functionality of a
+chip is located here regardless of the type of chip (MCU, radio,
+etc.). In addition MCU's group the code related to separate sub
+systems into further sub directories (e.g. <tt class="docutils literal"><span class="pre">tos/chips/atm128/timer</span></tt>).</p>
+<p>In this section we will go trough some of the peripherals commonly
+built into MCUs, but we will not go trough other chips such as sensors
+or radio.</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id32" id="mcu-internals" name="mcu-internals">5.1 MCU Internals</a></h2>
+<p>Apart from the drivers for each of the peripheral units, a few
+additional definitions are required for the internals of the MCU. This
+includes i) atomic begin/end and ii) low power mode. The first is
+defined in the header <em>hardware.h</em> and the latter component
+<em>MCUSleepC</em>.</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id33" id="mcuxardware-h" name="mcuxardware-h">5.1.1 mcuXardware.h</a></h3>
+<p>Each architecture defines a set of required and useful macros in a
+header filed named after the architecture (for example
+<em>atm128hardware.h</em> for ATMega128). This header is then in turn
+included from <em>hardware.h</em> in the platform directory (See Section
+4.3.1).</p>
+<p>A few of the macros are required by nesC code generation. nesC will
+output code using these macros and they must be defined in advance,
+other useful macros such as interrupt handlers on this particular
+platform can be defined here as well. The required macros are:</p>
+<blockquote>
+<ul class="simple">
+<li><em>__nesc_enable_interrupt</em> / <em>__nesc_disable_interrupt</em></li>
+<li><em>__nesc_atomic_start</em> / <em>__nesc_atomic_end</em></li>
+</ul>
+</blockquote>
+<p>Below is a few examples from <em>atm128hardware.h</em></p>
+<pre class="literal-block">
+/* We need slightly different defs than SIGNAL, INTERRUPT */
+#define AVR_ATOMIC_HANDLER(signame) \
+ void signame() __attribute__ ((signal)) @atomic_hwevent() @C()
+
+#define AVR_NONATOMIC_HANDLER(signame) \
+ void signame() __attribute__ ((interrupt)) @hwevent() @C()
+
+...
+
+inline void __nesc_enable_interrupt() { sei(); }
+inline void __nesc_disable_interrupt() { cli(); }
+
+...
+
+inline __nesc_atomic_t
+__nesc_atomic_start(void) @spontaneous() {
+ __nesc_atomic_t result = SREG;
+ __nesc_disable_interrupt();
+ asm volatile("" : : : "memory");
+ return result;
+}
+
+/* Restores interrupt mask to original state. */
+inline void
+__nesc_atomic_end(__nesc_atomic_t original_SREG) @spontaneous() {
+ asm volatile("" : : : "memory");
+ SREG = original_SREG;
+}
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id34" id="mcusleepc" name="mcusleepc">5.1.2 MCUSleepC</a></h3>
+<p>TinyOS manages the power state of the MCU through a few
+interfaces. These interfaces allow components to signal how and when
+this platform should enter low power mode. Each new MCU in TinyOS must
+implement the <em>MCUSleepC</em> component that provide the <em>McuSleep</em> and
+<em>McuPowerState</em> interfaces.</p>
+<p>The TinyOS scheduler calls <em>McuSleep.sleep()</em> when it runs out of
+tasks to start. The purpose of this function is to make the MCU enter
+the appropriate sleep mode. The call to <em>McuSleep.sleep()</em> is made
+from within an atomic section making it essential that sleep() enables
+interrupts before entering sleep mode! If the interrupts not enabled
+prior to entering sleep mode the MCU will not be able to power back up.</p>
+<p>A dummy MCU sleep component that does not enter sleep mode, but merely
+switches interrupts on and off is shown below. This ensures that the
+platform will not lock up even without proper sleep support.</p>
+<pre class="literal-block">
+#include "hardware.h"
+
+module McuSleepC {
+ provides interface McuSleep;
+ provides interface McuPowerState;
+ uses interface McuPowerOverride;
+} implementation {
+ async command void McuSleep.sleep() {
+ __nesc_enable_interrupt();
+ // Enter sleep here
+ __nesc_disable_interrupt();
+ }
+
+ async command void McuPowerState.update() { }
+}
+</pre>
+</div>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id35" id="generalio" name="generalio">5.2 GeneralIO</a></h2>
+<p>Virtually all micro controllers feature a set of input output (I/O)
+pins. The features of these pins is often configurable and often some
+pins only support a subset of features. The HIL level interface for
+TinyOS is described in [<a class="reference" href="#tep117">TEP117</a>] and uses two interface to describe
+general purpose I/O pins common to many MCUs:</p>
+<ul class="simple">
+<li><strong>GeneralIO</strong>: Digital input/output. The GeneralIO interface
+describes a digital pin with a state of either <em>clr</em> or <em>set</em>, the
+pin must be capable of both input and output. Some MCUs provide pins
+with different capabilities: more modes (e.g. an alternate
+peripheral mode), less modes (e.g. only input) or a third
+"tri-state" mode. Such chip specific additional features are not
+supported. Some chips group a set of pins into "ports" that can be
+read or written simultaneously, the HIL level interface does not
+support reading or setting an entire port.</li>
+<li><strong>GpioInterrupt</strong>: Edge triggered interrupts. GpioInterrupt support
+a single pin providing an interrupt triggered on a rising or falling
+edge. Pins capable of triggering on an input level or only
+triggering on one edge is not supported.</li>
+</ul>
+<p>While these interfaces are aimed at the HIL level some platforms use
+the GeneralIO and GpioInterrupt interface to represent the HPL level
+(atm128 for example) and others platforms define their own interface
+to capture the entire functionality (msp430, pxa27x for example).</p>
+<p>[<a class="reference" href="#tep117">TEP117</a>] states that each platform must provide the general IO pins of
+that platform through the <em>GeneralIO</em> interface and should do this
+though the component <em>GeneralIOC</em>. It is however not clear how the
+entire set of pins should be provided - this could be in the form of a
+list of pins, group of pins, a generic component, etc.</p>
+<p>The pin implementations are usually found in the <em>pins</em> sub directory
+for a particular MCU (e.g. <em>msp430/pins</em> for MSP430 pin
+implementation).</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id36" id="example-msp430" name="example-msp430">5.2.1 Example MSP430</a></h3>
+<p>The MSP430 implementation builds the platform independent pin
+implementation as a stack of components starting with a platform
+specific component for each pin.</p>
+<pre class="literal-block">
+ | GeneralIO
++---------------------+
+| Msp430GpioC |
++---------------------+
+ | HplMsp430GeneralIO
++---------------------+
+| HplMsp430GeneralIOC |
++---------------------+
+ | HplMsp430GeneralIO
++---------------------+
+| HplMsp430GeneralIOP |
++---------------------+
+</pre>
+<p>At the bottom the component <tt class="docutils literal"><span class="pre">HplMsp430GeneralIOP</span></tt> provides a general
+implementation of one Msp430 pin using the <tt class="docutils literal"><span class="pre">HplMsp430GeneralIO</span></tt>
+interface. The generic component <tt class="docutils literal"><span class="pre">HplMsp430GeneralIOP</span></tt> is then
+instantiated for each pin by <tt class="docutils literal"><span class="pre">HplMsp430GeneralIOC</span></tt>.</p>
+<pre class="literal-block">
+interface HplMsp430GeneralIO {
+ async command void set();
+ async command void clr();
+ async command void toggle();
+ async command uint8_t getRaw();
+ async command bool get();
+ async command void makeInput();
+ async command bool isInput();
+ async command void makeOutput();
+ async command bool isOutput();
+ async command void selectModuleFunc();
+ async command bool isModuleFunc();
+ async command void selectIOFunc();
+ async command bool isIOFunc();
+}
+</pre>
+<p>This interface is implemented in the generic component
+HplMsp430GeneralIOP (abbreviated):</p>
+<pre class="literal-block">
+ generic module HplMsp430GeneralIOP(uint8_t port_in_addr, ...) {
+ provides interface HplMsp430GeneralIO as IO;
+ } implementation {
+ #define PORTx (*(volatile TYPE_PORT_OUT*)port_out_addr)
+
+ async command void IO.set() { atomic PORTx |= (0x01 << pin); }
+ async command void IO.clr() { atomic PORTx &= ~(0x01 << pin); }
+ async command void IO.toggle() { atomic PORTx ^= (0x01 << pin); }
+
+...
+</pre>
+<p>These are then instantiated from HplMsp430GeneralIOC (abbreviated):</p>
+<pre class="literal-block">
+configuration HplMsp430GeneralIOC {
+ provides interface HplMsp430GeneralIO as Port10;
+ provides interface HplMsp430GeneralIO as Port11;
+...
+} implementation {
+ components
+ new HplMsp430GeneralIOP(P1IN_, P1OUT_, P1DIR_, P1SEL_, 0) as P10,
+ new HplMsp430GeneralIOP(P1IN_, P1OUT_, P1DIR_, P1SEL_, 1) as P11,
+...
+ Port10 = P10;
+ Port11 = P11;
+...
+</pre>
+<p>And finally these are transformed from the interface
+HplMsp430GeneralIO to the platform independent GeneralIO using the
+generic component Msp430GpioC (abbreviated):</p>
+<pre class="literal-block">
+generic module Msp430GpioC() {
+ provides interface GeneralIO;
+ uses interface HplMsp430GeneralIO as HplGeneralIO;
+} implementation {
+ async command void GeneralIO.set() { call HplGeneralIO.set(); }
+ async command void GeneralIO.clr() { call HplGeneralIO.clr(); }
+ async command void GeneralIO.toggle() { call HplGeneralIO.toggle(); }
+...
+</pre>
+</div>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id37" id="leds" name="leds">5.3 LEDs</a></h2>
+<p>Having a few leds on a platform is quite common and TinyOS supports
+three leds in a platform independent manner. Three leds are provided
+through the <em>LedsC</em> component regardless of the amount of leds
+available on the platform. The LED implementation is not covered by a
+TEP at the time of writing, but the general consensus between most
+platforms seems to be to provide access to 3 LEDs through the
+component <em>PlatformLedsC</em>. This component is then used by <em>LedC</em> and
+<em>LedP</em> (from <tt class="docutils literal"><span class="pre">tos/system</span></tt>) to provide a platform independent Led
+interface.</p>
+<p>The PlatformLedsC implementation is found in the platform directory of
+each platform (e.g. <em>tos/platforms/mica2</em> for mica2). The consensus is
+as follows:</p>
+<ul class="simple">
+<li>Each platform provides the component PlatformLedsC</li>
+<li>PlatformLedsC provides Led0, Led1, Led2 using the GeneralIO
+interface. If the platform has less than 3 Leds these are wired to
+the component NoPinC</li>
+<li>PlatformLedsC <em>uses</em> the Init interface and usually it wired back to
+an initialization in PlatformP - this way when LedC is included in
+an application it will be initialized when PlatformP call this
+interface</li>
+</ul>
+<div class="section">
+<h3><a class="toc-backref" href="#id38" id="example-mica2dot" name="example-mica2dot">5.3.1 Example Mica2dot</a></h3>
+<pre class="literal-block">
+configuration PlatformLedsC
+{
+ provides interface GeneralIO as Led0;
+ provides interface GeneralIO as Led1;
+ provides interface GeneralIO as Led2;
+ uses interface Init;
+}
+implementation {
+ components HplAtm128GeneralIOC as IO;
+ components new NoPinC();
+ components PlatformP;
+
+ Init = PlatformP.MoteInit;
+
+ Led0 = IO.PortA2; // Pin A2 = Red LED
+ Led1 = NoPinC;
+ Led2 = NoPinC;
+}
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id39" id="leds-implementation-discussion" name="leds-implementation-discussion">5.3.2 LEDs implementation discussion</a></h3>
+<p>The Led interface described above is not specified in a TEP, though at
+the time of writing most platforms seem to follow this pattern. Not
+being covered by a TEP leads to a few uncertainties:</p>
+<ul class="simple">
+<li><em>PlatformLedsC</em> exports leds using the <em>GeneralIO</em> interface. The
+intention is of course that a led is connected to a pin and this pin
+is used to turn the led on. <em>LedC</em> uses this assumption to calls the
+appropriate <em>makeOutput</em> and <em>set</em>/<em>clr</em> calls. However this might
+not be the case - a led could be connected differently making the
+semantics of, say <em>makeOutput</em> unclear. Furthermore it is assumed
+that the set call turns the led on, while the actual pin might have
+to be cleared (active low). And what is the semantics of <em>makeInput</em>
+on a LED? Abstracting these differences into on/off, enable/disable
+semantics would clear up the uncertainties.</li>
+<li>Initializing the Leds is important - the Leds can consume power even
+when turned off, if the corresponding pins are configured
+inappropriately. Including the LedsC component initializes the Leds
+as output when this component is used, if not they must be
+initialized elsewhere (e.g. PlatformP). It would seem elegant to
+group related code (e.g. one Leds component).</li>
+<li>The interface does not provide a uniform way of accessing any
+additional LEDs other than the 3 found on the Mica motes. While this
+is inherently platform specific, having a common consensus would be
+useful, say for example exporting an array of Led. In this way a
+program requiring say 4 leds could be compiled if 4 leds are available.</li>
+</ul>
+</div>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id40" id="timers" name="timers">5.4 Timers</a></h2>
+<p>The timer subsystem in TinyOS 2 is described in [<a class="reference" href="#tep102">TEP102</a>] the TEP
+specifies interfaces at HAL and HIL levels that a platform must adhere
+to. The timer does not cover the possible design choices at the HPL
+level. The timers defined in this TEP are described in terms of
+<em>width</em> of the underlying counters (e.g. 8, 16, 32 bit) and in the
+tick period or frequency denoted <em>precision</em> (e.g. 10 kHz, 1 ms, 1
+us). The timer subsystem is provided through a set of hardware
+independent interfaces and a set of recommended configuration modules.
+As such some features of a particular device may not be available in a
+device independent manner.</p>
+<p>The functionality commonly seen in MCU timer units is often split in 3
+parts: control, timer/counter, capture/compare(trigger). Timer control
+in is inherently platform specific and is not covered by a TEP. The
+timer [<a class="reference" href="#tep102">TEP102</a>] covers timer/counter while capture/compare is covered
+by [<a class="reference" href="#tep117">TEP117</a>]. From the TEPs it is not clear how capture/compare and
+timer/counter relate to each other even though they are likely to
+refer to the same time base. The calibration of the system clock is
+often connected with the timer system and lives in the timer
+directory, but it is not covered in [<a class="reference" href="#tep102">TEP102</a>].</p>
+<p>The timer implementation for a given MCU is placed in the <em>timer</em> sub
+directory of the directory for a given MCU
+(e.g. <em>tos/chips/avr/timer</em>). Often clock initialization components
+are placed in the same directory, but these are not covered by the
+TEPs.</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id41" id="timer-layers" name="timer-layers">5.4.1 Timer Layers</a></h3>
+<p><a class="reference" href="#tep117">TEP117</a> follows the 3 layer architecture and separates the platform
+dependent and independent abstractions. It poses not restrictions on
+the HPL layer, but provides a suggested HAL layer and requirements at
+the HIL level. It defines a set of interfaces and precisions that are
+used at the HAL and HIL levels.</p>
+<p>The common features of a timer are separated into a set of interfaces,
+corresponding roughly to common features in MCU timer units. The
+interfaces covered by the [<a class="reference" href="#tep102">TEP102</a>] are (capture from [<a class="reference" href="#tep117">TEP117</a>]):</p>
+<ul class="simple">
+<li><strong>BusyWait<precision_tag,size_type></strong> Short synchronous delays</li>
+<li><strong>Counter<precision_tag, size_type></strong> Current time, and overflow events</li>
+<li><strong>Alarm<precision_tag,size_type></strong> Extend Counter with at a given time</li>
+<li><strong>Timer<precision_tag></strong> 32 bit current time, one shot and periodic events</li>
+<li><strong>LocalTime<precision_tag></strong> 32 bit current time without overflow</li>
+<li><strong>GpioCapture</strong> 16 bit time value on an external event (precision unspecified)</li>
+</ul>
+<p>The precisions defined in [<a class="reference" href="#tep117">TEP117</a>] are defined as "binary" meaning
+1024 parts of a second. Platforms must provide these precisions (if
+possible) regardless of the underlying system frequency (i.e. this
+could be a power of 10).</p>
+<ul class="simple">
+<li><strong>TMilli</strong> 1024 Hz (period 0.98 ms)</li>
+<li><strong>TMicro</strong> 1048576 Hz (period 0.95 us)</li>
+<li><strong>T32khz</strong> 32.768 kHz (period 30.5 us)</li>
+</ul>
+<div class="section">
+<h4><a class="toc-backref" href="#id42" id="hpl" name="hpl">HPL</a></h4>
+<p>The features of the underlying hardware timers are generally exposed
+using one or more hardware specific interfaces. Many MCU provide a
+rich a set of different timer units varying in timer width, frequency
+and features.</p>
+<p>Many MCUs provides features that are quite close to the features
+described by the interfaces above. The HPL layer exposes these
+features and the layers above utilize the available hardware and
+virtualize the features if necessary.</p>
+<p>Consider for example generating events at a specific time. Often a
+timer unit has a single counter and a few compare registers that
+generate interrupts. The counter and compare registers often translate
+relative straightforward to Counter and Alarm interfaces.</p>
+</div>
+<div class="section">
+<h4><a class="toc-backref" href="#id43" id="hal" name="hal">HAL</a></h4>
+<p>Each platform should expose a hardware timer of precision P and width W
+as Counter${P}${W}C, Alarm${P}${W}C(). For example an 8 bit, 32.768 kHz
+timer should be exposed as Counter32khz8C and Alarm32khz8C</p>
+<p>Alarm/Counters come in pairs and refer to a particular hardware unit,
+while there is only one counter there is commonly multiple compare
+registers. Alarm is a generic component and each instantiation must
+provide an independent alarm allocating more Alarm components than
+available compare register should provide a compile time error.</p>
+</div>
+<div class="section">
+<h4><a class="toc-backref" href="#id44" id="hil" name="hil">HIL</a></h4>
+<p>Each platform must expose the following components that provide
+specific width and precision that are guaranteed to exist on TEP
+compliant platforms.</p>
+<blockquote>
+<ul class="simple">
+<li><strong>HilTimerMilliC</strong> A 32 bit Timer interface of TMilli precision</li>
+<li><strong>BusyWaitMicroC</strong> A BusyWait interface of TMicro precision</li>
+</ul>
+</blockquote>
+</div>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id45" id="timer-implementation" name="timer-implementation">5.4.2 Timer Implementation</a></h3>
+<p>Implementing the timers for TinyOS in short consists of utilizing the
+available HW timer features to provide TinyOS style timers
+interfaces. In general the approach taken by existing platforms is to
+create a set of HPL level timer and control interfaces that export the
+available hardware features and adapt these to specific precisions and
+widths at the HAL level. However the specific HPL level design choices
+differ from platform to platform.</p>
+<p>For example one could export all timers as a simple list, a component
+for each timer, a parameterised interface, etc. Similarly for the
+control features this could be provided with the timer interfaces or
+kept as a separate interface. In the following we will go through a
+few examples and point out their differences.</p>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id46" id="example-atmega128l" name="example-atmega128l">5.4.3 Example: ATMega128l</a></h3>
+<p>The ATMega128l implementation (atm128) exports the system timers one
+component each. Each component provide 4 interfaces - one for each of
+the functions of the unit: timer, capture, compare and control. The
+timer, capture, and compare interfaces are generic based on the width
+(either 8 or 16 bit) while two separate control interfaces are
+provided.</p>
+<p>Depicted below is a diagram of how <tt class="docutils literal"><span class="pre">HplAtm128Timer1C</span></tt> could be stacked
+to provide platform independent interfaces (not shown are
+<tt class="docutils literal"><span class="pre">HplAtm128Timer0Async</span></tt>, <tt class="docutils literal"><span class="pre">HplAtm128Timer2</span></tt>, <tt class="docutils literal"><span class="pre">HplAtm128Timer3</span></tt>):</p>
+<pre class="literal-block">
+ +------------------------------------------------+
+ | HplAtm128Timer1C |
+ +-----+-------------------+-----------------+----+
+HplAtm128Capture| HplAtm128Timer| HplAtm128Compare|
+ | | |
+ +----------+---------+ | |
+ | Atm128GpioCaptureC | | |
+ +----------+---------+ | |
+ | +-+-----------------+--+
+ GpioCapture| | Atm128AlarmC |
+ | +----------+-----------+
+ | Alarm|
+</pre>
+<p>The hardware features is exported using 3 interfaces:
+<tt class="docutils literal"><span class="pre">HplAtm128Timer</span></tt>, <tt class="docutils literal"><span class="pre">HplAtm128Compare</span></tt> and <tt class="docutils literal"><span class="pre">HplAtm128Capture</span></tt>.</p>
+<pre class="literal-block">
+interface HplAtm128Timer<timer_size>
+{
+ async command timer_size get();
+ async command void set( timer_size t );
+ async event void overflow();
+ async command void reset();
+ async command void start();
+...
+
+interface HplAtm128Compare<size_type>
+{
+ async command size_type get();
+ async command void set(size_type t);
+ async event void fired(); //<! Signalled on compare interrupt
+ async command void reset();
+...
+
+interface HplAtm128Capture<size_type>
+{
+ async command size_type get();
+ async command void set(size_type t);
+ async event void captured(size_type t);
+ async command void reset();
+</pre>
+<dl class="docutils">
+<dt>In addition to the timer related interfaces two control interfaces are</dt>
+<dd>provided: 'HplAtm128TimerCtrl16' and 'HplAtm128TimerCtrl8' (below).</dd>
+</dl>
+<pre class="literal-block">
+#include <Atm128Timer.h>
+
+interface HplAtm128TimerCtrl8
+{
+ /// Timer control register: Direct access
+ async command Atm128TimerControl_t getControl();
+ async command void setControl( Atm128TimerControl_t control );
+
+ /// Interrupt mask register: Direct access
+ async command Atm128_TIMSK_t getInterruptMask();
+ async command void setInterruptMask( Atm128_TIMSK_t mask);
+
+ /// Interrupt flag register: Direct access
+ async command Atm128_TIFR_t getInterruptFlag();
+ async command void setInterruptFlag( Atm128_TIFR_t flags );
+}
+</pre>
+<p>Each of the hardware timers are exported in one component for example
+'HplAtm128Timer1P':</p>
+<pre class="literal-block">
+#include <Atm128Timer.h>
+
+module HplAtm128Timer1P
+{
+ provides {
+ // 16-bit Timers
+ interface HplAtm128Timer<uint16_t> as Timer;
+ interface HplAtm128TimerCtrl16 as TimerCtrl;
+ interface HplAtm128Capture<uint16_t> as Capture;
+ interface HplAtm128Compare<uint16_t> as CompareA;
+ interface HplAtm128Compare<uint16_t> as CompareB;
+ interface HplAtm128Compare<uint16_t> as CompareC;
+ }
+ uses interface HplAtm128TimerCtrl8 as Timer0Ctrl;
+}
+implementation
+{
+ //=== Read the current timer value. ===================================
+ async command uint16_t Timer.get() { return TCNT1; }
+
+ //=== Set/clear the current timer value. ==============================
+ async command void Timer.set(uint16_t t) { TCNT1 = t; }
+...
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id47" id="id3" name="id3">5.4.4 Example: MSP430</a></h3>
+<p>The MSP430 features two very similar (but not identical) timers. Both
+timers are provided through the same interfaces in a way similar to
+ATMega128l: 'Msp430Timer', 'Msp430Capture' 'Msp430Compare',
+'Msp430TimerControl'. All timer interfaces (for both timers) are
+accessed through the component Msp430TimerC.</p>
+<p>The <tt class="docutils literal"><span class="pre">Msp430TimerControl</span></tt> is show below. It is slightly different
+than the ATMega equivalent - notice that 'setControl' accepts a struct
+with configuration parameters instead of setting these with a command
+each.</p>
+<pre class="literal-block">
+#include "Msp430Timer.h"
+
+interface Msp430TimerControl
+{
+ async command msp430_compare_control_t getControl();
+ async command bool isInterruptPending();
+ async command void clearPendingInterrupt();
+
+ async command void setControl(msp430_compare_control_t control );
+ async command void setControlAsCompare();
+ async command void setControlAsCapture(bool low_to_high);
+
+ async command void enableEvents();
+ async command void disableEvents();
+ async command bool areEventsEnabled();
+}
+</pre>
+<p>Each timer is implemented through the generic component 'Msp430TimerP'
+that is instantiated for each timer in 'Msp430TimerC':</p>
+<pre class="literal-block">
+configuration Msp430TimerC
+{
+ provides interface Msp430Timer as TimerA;
+ provides interface Msp430TimerControl as ControlA0;
+ provides interface Msp430TimerControl as ControlA1;
+ provides interface Msp430TimerControl as ControlA2;
+ provides interface Msp430Compare as CompareA0;
+ provides interface Msp430Compare as CompareA1;
+ provides interface Msp430Compare as CompareA2;
+ provides interface Msp430Capture as CaptureA0;
+ provides interface Msp430Capture as CaptureA1;
+ provides interface Msp430Capture as CaptureA2;
+...
+}
+implementation
+{
+ components new Msp430TimerP( TAIV_, TAR_, TACTL_, TAIFG, TACLR, TAIE,
+ TASSEL0, TASSEL1, FALSE ) as Msp430TimerA
+ , new Msp430TimerP( TBIV_, TBR_, TBCTL_, TBIFG, TBCLR, TBIE,
+ TBSSEL0, TBSSEL1, TRUE ) as Msp430TimerB
+ , new Msp430TimerCapComP( TACCTL0_, TACCR0_ ) as Msp430TimerA0
+ , new Msp430TimerCapComP( TACCTL1_, TACCR1_ ) as Msp430TimerA1
+ , new Msp430TimerCapComP( TACCTL2_, TACCR2_ ) as Msp430TimerA2
+...
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id48" id="example-pxa27x" name="example-pxa27x">5.4.5 Example: PXA27x</a></h3>
+<p>The PXA27x (XScale) platform provides a component for each of the
+timers classes on the system. Each component provides a few interfaces
+that exposes all features of that unit. Each interface combines timer
+and control interface features. For example 'HplPXA27xOSTimerC'
+provides 12 instances of the 'HplPXA27xOSTimer' interface and one
+instace 'HplPXA27xOSTimerWatchdog'. Similarly for 'HplPXA27xSleep' and
+'HplPXA27xWatchdog'.</p>
+<pre class="literal-block">
+interface HplPXA27xOSTimer
+{
+ async command void setOSCR(uint32_t val);
+ async command uint32_t getOSCR();
+...
+
+
+ async event void fired();
+}
+</pre>
+<p>All the OS timers are exported through HplPXA27xOSTimerC</p>
+<pre class="literal-block">
+configuration HplPXA27xOSTimerC {
+
+ provides {
+ interface Init;
+ interface HplPXA27xOSTimer as OST0;
+ interface HplPXA27xOSTimer as OST0M1;
+ interface HplPXA27xOSTimer as OST0M2;
+ interface HplPXA27xOSTimer as OST0M3;
+...
+implementation {
+ components HplPXA27xOSTimerM, HplPXA27xInterruptM;
+
+ Init = HplPXA27xOSTimerM;
+
+ OST0 = HplPXA27xOSTimerM.PXA27xOST[0];
+ OST0M1 = HplPXA27xOSTimerM.PXA27xOST[1];
+ OST0M2 = HplPXA27xOSTimerM.PXA27xOST[2];
+ OST0M3 = HplPXA27xOSTimerM.PXA27xOST[3];
+...
+</pre>
+<p>These interfaces are further abstracted through 'HalPXA27xOSTimerMapC'
+as a parameterised interface:</p>
+<pre class="literal-block">
+configuration HalPXA27xOSTimerMapC {
+ provides {
+ interface Init;
+ interface HplPXA27xOSTimer as OSTChnl[uint8_t id];
+ }
+} implementation {
+ components HplPXA27xOSTimerC;
+
+ Init = HplPXA27xOSTimerC;
+
+ OSTChnl[0] = HplPXA27xOSTimerC.OST4;
+ OSTChnl[1] = HplPXA27xOSTimerC.OST5;
+ OSTChnl[2] = HplPXA27xOSTimerC.OST6;
+ ...
+</pre>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id49" id="timer-discussion" name="timer-discussion">5.4.6 Timer Discussion</a></h3>
+<p>While the TEP is clear on many points there are few that are left up
+to the implementer. The relation between timers and capture events is
+unclear and covered in two TEPs. Capture refers to timers[<a class="reference" href="#tep102">TEP102</a>] but
+the reverse is not clear[<a class="reference" href="#tep102">TEP102</a>]. This has a few implications for the
+timer/capture relationship:</p>
+<ul class="simple">
+<li>Many devices feature multiple timers of the same width and
+precision. It is not clear how this is provided. In particular how
+this relates to a capture event - e.g. how does a capture event from
+timer 2 relate to a time value from timer 1. Presumably TinyOS has
+one system time based on a single timer which is used by all timer
+capture interfaces and visualized if necessary.</li>
+<li>The interfaces provide a an elegant way to expand a 16 bit timer to
+a 32 bit interface. However this is not the case for capture events.</li>
+</ul>
+</div>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id50" id="i-o-buses-uart-spi-i2c" name="i-o-buses-uart-spi-i2c">5.5 I/O buses (UART, SPI, I2C)</a></h2>
+<p>Most modern microprocessors provide a selection of standard I/O bus
+units such as serial (UART or USART), I2C, SPI, etc. The drivers for
+the available buses are usually put in a sub directory for the MCU
+(e.g. <em>chip/atm128/spi</em> for SPI on ATMega128l).</p>
+<p>There are a few TEP that cover different buses in TinyOS, and low
+level serial communication:</p>
+<ul class="simple">
+<li><a class="reference" href="#tep113">TEP113</a> Serial Communication: Serial</li>
+<li><a class="reference" href="#tep117">TEP117</a> Low-Level I/O: Serial, SPI, I2C</li>
+</ul>
+<p>On some hardware platforms a single I/O unit is shared among a number
+of buses. The MSP430 for example implements SPI, I2C and USART in a
+single USART unit that can only operate in one mode at a time. In such
+cases the single hardware unit must be shared among the drivers.</p>
+<div class="section">
+<h3><a class="toc-backref" href="#id51" id="serial-communication" name="serial-communication">5.5.1 Serial Communication</a></h3>
+<p>Serial communication in TinyOS 2.x is implemented as a serial
+communications stack with a UART or USART at the bottom. The bottom
+layer is covered in [<a class="reference" href="#tep113">TEP113</a>] and [<a class="reference" href="#tep117">TEP117</a>]. TEP117 states that each
+platform must provide access to a serial port through the
+'SerialByteComm' interface from the component UartC. However UartC is
+not provided by any platforms at the time of writing. There seems to
+be a consensus to build the component 'PlatformSerialC' providing the
+'UartStream' and 'StdControl' interfaces. Either component will be
+placed in the platform directory (e.g. <em>tos/platforms/mica2</em> for
+mica2). The serial stack is built upon 'PlatformSerialC' and this
+component will be required to take advantage of the serial stack.</p>
+<p>[<a class="reference" href="#tep117">TEP117</a>] defines 'UartStream' and 'UartByte' to access the a UART
+multiple bytes at a time and one byte at a time (synchronously), while
+[<a class="reference" href="#tep113">TEP113</a>] defines 'UartByte' to send and receive one byte at a time
+(asynchronously).</p>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id52" id="i2c-spi" name="i2c-spi">5.5.2 I2C, SPI</a></h3>
+<p>SPI and I2C buses are provided through straightforward interfaces that
+match the functionality of the buses closely.</p>
+<div class="section">
+<h4><a class="toc-backref" href="#id53" id="spibyte-spipacket" name="spibyte-spipacket">SpiByte, SpiPacket</a></h4>
+<pre class="literal-block">
+interface SpiByte {
+ async command uint8_t write( uint8_t tx );
+}
+</pre>
+<pre class="literal-block">
+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 );
+}
+</pre>
+</div>
+<div class="section">
+<h4><a class="toc-backref" href="#id54" id="i2cpacket" name="i2cpacket">I2CPacket</a></h4>
+<pre class="literal-block">
+interface I2CPacket<addr_size> {
+ async command error_t read(i2c_flags_t flags, 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 readDone(error_t error, 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>
+</div>
+</div>
+<div class="section">
+<h3><a class="toc-backref" href="#id55" id="example" name="example">5.5.3 Example</a></h3>
+<dl class="docutils">
+<dt>..ATMega128</dt>
+<dd>-> does not provide SerialByteComm</dd>
+<dt>..MSP430</dt>
+<dd>-> Uart1C provides SerialByteComm along with Init and StdControl
+-> sender det meste videre til Msp430Uart1C (som mangler Init!?!?)
+Msp430Uart0C
+-> SerialByteComm, Msp430UartControl, Msp430UartConfigure, Resurce
+-> Sender videre til Msp430Uart1P & Msp430Usart1C
+-> Sender videre til HplMsp430Usart1C->HplMsp430Usart1P</dd>
+<dt>..PXA27</dt>
+<dd>Parametriseret m. HplPXA27xUARTP (Init && HplPXA27xUART)
+-> init sætter en masse registre og enabler interrupt
+HalPXA27xSerialP: HplPXA27xUART, Init, noget DMA noget</dd>
+</dl>
+</div>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id56" id="authors" name="authors">6. Authors</a></h1>
+<div class="line-block">
+<div class="line">Martin Leoold</div>
+<div class="line">University of Copenhagen, Dept. of Computer Science</div>
+<div class="line">Universitetsparken 1</div>
+<div class="line">DK-2100 København Ø</div>
+<div class="line">Denmark</div>
+<div class="line"><br /></div>
+<div class="line">Phone +45 3532 1464</div>
+<div class="line"><br /></div>
+<div class="line">email - <a class="reference" href="mailto:leopold@diku.dk">leopold@diku.dk</a></div>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id57" id="citations" name="citations">7. Citations</a></h1>
+<table class="docutils citation" frame="void" id="tep1" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep1">[TEP1]</a></td><td>TEP 1: TEP Structure and Keywords
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep1.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep1.html</a>></td></tr>
+</tbody>
+</table>
+<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://www.tinyos.net/tinyos-2.x/doc/html/tep2.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep2.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep3" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep3">[TEP3]</a></td><td>TEP 3: Coding Standard
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep3.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep3.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep102" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep102">[TEP102]</a></td><td>TEP 102: Timers
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep102.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep102.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep106" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep106">[TEP106]</a></td><td>TEP 106: Schedulers and Tasks
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep106.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep106.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep107" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep107">[TEP107]</a></td><td>TEP 107: TinyOS 2.x Boot Sequence
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep107.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep107.html</a>></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 name="tep109">[TEP109]</a></td><td>TEP 109: Sensors and Sensor Boards
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep109.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep109.html</a>></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://www.tinyos.net/tinyos-2.x/doc/html/tep111.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep111.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep113" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep113">[TEP113]</a></td><td>TEP 113: Serial Communication
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep113.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep113.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep117" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep117">[TEP117]</a></td><td>TEP 117: Low-Level I/O
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep117.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep117.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tep121" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tep121">[TEP121]</a></td><td>TEP 121: Towards TinyOS for 8051
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tep121.html">http://www.tinyos.net/tinyos-2.x/doc/html/tep121.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tosprg" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tosprg">[TOSPRG]</a></td><td>Philip Levis: TinyOS Programming
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/pdf/tinyos-programming.pdf">http://www.tinyos.net/tinyos-2.x/doc/pdf/tinyos-programming.pdf</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tos2-0view" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tos2-0view">[tos2.0view]</a></td><td>Philip Levis. "TinyOS 2.0 Overview" <em>Feb 8 2006</em>
+<<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/overview.html">http://www.tinyos.net/tinyos-2.x/doc/html/overview.html</a>></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="nescman" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="nescman">[nescman]</a></td><td>David Gay, Philip Levis, David Culler, Eric Brewer. "NesC 1.2 Language Reference Manual" <em>August 2005</em></td></tr>
+</tbody>
+</table>
+<table class="docutils citation" frame="void" id="tut10" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="tut10">[TUT10]</a></td><td><dl class="first docutils">
+<dt>TinyOS 2 Tutorial Lesson 10</dt>
+<dd><<a class="reference" href="http://www.tinyos.net/tinyos-2.x/doc/html/tutorial/lesson10.html">http://www.tinyos.net/tinyos-2.x/doc/html/tutorial/lesson10.html</a>></dd>
+</dl>
+<p class="last">LocalWords: TinyOS TEP TEPs nesC</p>
+</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+</body>
+</html>
--- /dev/null
+
+======================================
+Creating a New Platform for TinyOS 2.x
+======================================
+
+:TEP: 131
+:Group: TinyOS 8051 Working Group
+:Type: Informational
+:Status: Draft
+:TinyOS-Version: 2.x
+:Author: Martin Leopold
+
+:Draft-Created: 6-Nov-2007
+:Draft-Version: 1
+:Draft-Modified: 6-Nov-2007
+:Draft-Discuss: TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu>
+
+.. Note::
+ This memo is informational. It will hopefully be a basis for
+ discussions and suggestions for improvements. Distribution of this
+ memo is unlimited. This memo is in full compliance with TEP 1.
+
+Abstract
+====================================================================
+
+The purpose of this TEP is to provide on overview of how to build a
+new TinyOS 2 platform. While the purpose of most TEPs is to describe
+TinyOS 2 entities, we will present concrete suggestions on how to
+implement a new TinyOS 2 platform. We will use examples and briefly
+cover the relevant TEPs to present a platform that adheres to the
+current TinyOS standards. We will not cover the TEPs in detail, but to
+the full text of each TEP for further information.
+
+This TEP will go through the tool chain setup and the most basic
+components for a functional TinyOS platform. We consider only TinyOS
+version 2.x (from now on TinyOS).
+
+Before venturing on this quest we will take a diversion and introduce
+general TinyOS 2 concepts and terminology (Section 1), readers
+familiar to TinyOS 2 can skip this section. This document will
+introduce the TinyOS 2 platform (Section 2) and describes the 3
+elements that make up a platform: the tool chain (Section 3) the
+platform definitions (Section 4) and the chips definitions (Section
+5).
+
+Table of Content
+====================================================================
+
+.. contents::
+
+1. TinyOS Overview
+====================================================================
+
+Before describing the process of writing TinyOS platforms we will
+briefly sum up the TinyOS ecosystem and the terminology required in
+this TEP. To learn more visit the TinyOS website http://www.tinyos.net.
+
+A systems overview is depicted below. In this TEP we will primarily
+concern our selves with the platform portion of figure and briefly
+cover the tool chain. This involves writing the necessary drivers and
+writing rules to pass the code to the TinyOS tool chain. We will not
+cover sensor boards in this TEP refer to, see [TEP109_] for details.
+
+::
+
+ +------------------------------------------+
+ | Application |
+ +------------------------------------------+
+ +--------+ +----------+ +--------------+
+ | TinyOS | + | Platform | + | Sensor board |
+ +--------+ +----------+ +--------------+
+ |
+ V
+ +-------------------+
+ | TinyOS tool chain |
+ +-------------------+
+ |
+ Target platform V
+ +-------------------------------------+
+ | +-------+ +-----+ +-------+ |
+ | | Radio |----| MCU |----|Sensors| |
+ | +-------+ +-----+ +-------+ |
+ +-------------------------------------+
+
+
+1.1 TinyOS 2 architecture
+--------------------------------------------------------------------
+
+TinyOS 2.x is built on a tree-layered hardware abstraction
+architecture (HAA)[TEP2_]. This architecture separates the code for
+each platform into distinct layers:
+
+ 1. the Hardware Independent Layer (HIL)
+ 2. the Hardware Adaptation Layer (HAL)
+ 3. the Hardware Presentation Layer (HPL)
+
+A platform is built from bottom up, starting with the HPL level,
+building HAL and HIL layers on top. Platform independent applications
+are written using HIL level interfaces, allowing them to move easily
+from platform to platform. While applications can target a platform
+specific HAL layer for finer control of hardware specific features,
+this will could prohibit such an application from being easily
+portable. An overview of the TinyOS 2 architecture is given in
+[tos2.0view_].
+
+The requirements for the platform implementation is described in
+TinyOS Enhancement Proposals (TEP). Each TEP covers a particular area
+and specifies the recommendations within that area, some of which are
+relevant for platforms. While no specific label or designation is
+given to platforms adhering to the set of TEPs, [TEP1_] states:
+"Developers desiring to add code (or TEPs) to TinyOS SHOULD follow all
+current BCPs (Best Current Practice)". At the time of writing no TEP
+has been awarded this designation or been finalized and we will refer
+to the drafts as they are.
+
+This document will not go through each of the requirements, but merely
+outline how to build a basic functional platform. For further
+information see "TinyOS 2.0 Overview" [tos2.0view_] or the TEP list on
+the TinyOS website http://www.tinyos.net.
+
+
+1.2 TinyOS Contrib
+--------------------------------------------------------------------
+
+The core of TinyOS is maintained by a set of working groups that
+govern specific parts of the source code. New project can benefit from
+the *contrib* section of TinyOS. This is a separate section of the
+website and source repository maintained more loosely than the core of
+TinyOS. It is intended for sharing code at an early stage or code that
+may not gain the same popularity as the core.
+
+New projects request a directory in this repository by following a
+simple procedure on the `TinyOS contrib web page
+<http://tinyos.cvs.sourceforge.net/*checkout*/tinyos/tinyos-2.x-contrib/contrib.html>`_
+
+In contrib is a skeleton project *skel* that provides the most basic
+framework for setting up a new platform, MCU, etc.
+
+2. A TinyOS Platform
+====================================================================
+
+A TinyOS platform provides the code and tool chain definitions that
+enable an application writer to implement an application for a mote. A
+platform in TinyOS exposes some or all of the features of a particular
+physical mote device to TinyOS applications - it refers to an entire
+system, not a single chip. In order to write programs for a device
+using TinyOS a platform for that device must exist within TinyOS.
+
+A physical platform is comprised of a set of chips. Similarly a TinyOS
+platform is the collection of the components representing these chips
+(corresponding to drivers) Common chips can be shared among platforms
+and implementing a new platform could simply mean wiring existing
+components in a new way. If the chips that make up the platform are
+not supported by TinyOS implementing the new platform consists if
+implementing components for those chips (much like implementing
+drivers).
+
+
+2.1 A New Platform
+--------------------------------------------------------------------
+
+Platforms are discovered at compile time by the TinyOS tool
+chain and a new platform placed in the search path will be discovered
+automatically. In addition sensor boards can be defined in a very
+similar manner, however we will not cover sensor boards, see [TEP109_]
+for details. Defining a new platform boils down to 3 things:
+
+ 1. definitions of the chips that make up the platform,
+ 2. platform definitions (combining chips to a platform) and,
+ 3. the tool chain or make definitions.
+
+The code for a TinyOS platform is spread out in a few locations of the
+TinyOS tree depending based on those 3 categories. Below is an
+overview of the locations and some of the files we will be needing in
+the following (for further information see see "Coding Conventions"
+[TEP3_] and the "README" files in each directory).
+
+Through this TEP we will use the terms PlatformX and MCUX to denote
+the new generic platform and MCU being created:
+
+::
+
+ tos
+ +--chips 1. Chip definitions
+ | +--chipX
+ +--platforms
+ | +--platformX 2. Platform definitions
+ | +--PlatformP/PlatformC
+ | +--PlatformLeds example component
+ | +--.platform
+ | +--hardware.h
+ | +--chips
+ | +--MCUX Platform specific features
+ | +--chipX
+ +--sensorboards
+ | +--boardX
+ | +--.sensor
+ +--support
+ +--make 3. Make definitions
+ +--platformX.target platformX make targets
+ +--MCUX
+ +--MCUX.rules make rules for MCUX
+ +--install.extra additional target for MCUX
+
+
+In the following we will briefly introduce each of the parts and
+describe them in more detail in sections 2 through 4.
+
+
+2.2 The Chips
+--------------------------------------------------------------------
+
+Each of the chips that provide software accessible functionality must
+have definitions present in the chips directory sensors, radios,
+micro controllers (MCU) alike. Each chip is assigned a separate
+directory under ``tos/chips``. This directory contains chip specific
+interfaces (HPL and HAL interfaces) and their implementations as well
+as implementations of the hardware independent interface (HIL).
+
+Some chips, MCUs in particular, contain distinct subsystems, such as
+uart, timer, A/D converter, SPI, and so forth. These subsystems are
+often put in a sub directory of their own within the chip-specific
+directory.
+
+If some feature of a chip is available or used only on a particular
+platform, the platform directory can contain code that is specific to
+this combination of chip and platform, say pin assignments, interrupt
+assignments, etc. For example such additions would be placed in
+``tos/platforms/platformX/chips/chipX`` for PlatformX.
+
+2.3 The Platform Directory
+--------------------------------------------------------------------
+
+The platform is the piece of the puzzle that ties the components
+corresponding to physical chips (drivers) together to form a
+platform. The platform ties together the code that exposes the
+features of the platform to TinyOS programs. In practise this is done
+by i) including code for each of the chips and ii) by providing any
+additional code that is specific to this particular platform.
+
+A platform *PlatformX* would be placed in the directory
+``tos/platforms/platformX/`` and code for subsystems reside in further
+sub directories. Also in this directory is the ``.platform`` file that
+sets up include paths and more (see Section 3).
+
+An empty platform with no code (null) is provided and serves as an
+example for other platforms.
+
+
+2.4 The Tool-Chain (Make System)
+--------------------------------------------------------------------
+
+The build system for TinyOS is written using GNU Make [#make]_. The
+build system controls the process from pre-processing a TinyOS
+application into a single C file and to pass this file to the
+appropriate compiler and other tools. The make system is documented in
+``support/make/README`` and in TinyOS 2 Tutorial Lesson 10[TUT10_].
+
+The make system is located in the ``support`` directory. This
+directory contains a platform definition and Make rules to build an
+application for this platform (see Section 2).
+
+.. [#make] http://www.gnu.org/software/make/
+
+2.5 The Minimal Platform
+--------------------------------------------------------------------
+
+Before describing each of the subsystems, we will show a simple check
+list. The absolute minimal TinyOS platform would have to provide the
+following resources, given a *PlatformX* with *MCUX*:
+
+* a platform directory ``tos/platform/PlatformX/`` with the following
+
+ - a platform definition (*.platform* file)
+ - a *hardware.h* header
+
+* a *platformX.target* in ``tos/support/make``
+* a *MCUX.rules* in ``tos/support/make/MCUX``
+* a *MCUX* directory in ``tos/chips/MCUX``, containing
+
+ - a *McuSleepC* (must enable interrupts)
+ - a *mcuxhardware.h* (defines *nesc_atomic_start*/*nesc_atomic_end*)
+
+
+3. Tool Chain
+====================================================================
+
+The major components in the tool chain of TinyOS are i) the compiler
+and ii) the build system that uses the compiler to produce an
+executable binary or hex file. The first is installed separately,
+while the second is part of the TinyOS source code. The compile
+process transforms a set of nesC files into a binary executable or hex
+file. Involved in this process is set of separate tools that are
+linked in a chain. We will briefly cover this chain in a moment, but a
+detailed description is beyond the scope of this TEP.
+
+The make system is split in two: a general part and a platform
+specific part. Section 3.1 will introduce the general mechanism and
+Section 3.2 will cover how to introduce a new platform in the tool
+chain.
+
+3.1 Compiling using nesC
+--------------------------------------------------------------------
+
+The process of the build system is depicted below. This system feeds
+the source code through the tools to produce an executable or hex file
+for uploading to the platform. The nesC pre-compiler is split in two
+tools ncc an nescc. These two tools are used to assemble nesC source
+files into a single C file which is compiled using a regular C
+compiler. This requires that a C compiler is available for a given
+platform and that this compiler accepts the dialect produced by nesC.
+
+::
+
+ TinyOS
+ application
+ |
+ |
+ V
+ +------+ +-----+ +---------+ +------------+
+ | ncc | app.c | | Binary | | app.hex | |
+ | + |------>| GCC |------->| objdump |-------->| programmer |
+ | nesC | | | | | | |
+ +------+ +-----+ +---------+ +------------+
+ |
+ |
+ V
+ Target
+ platform
+
+
+The core TinyOS platforms are centered around GCC, this includes the
+telos family, mica family and intelmote2. The nesC compiler expects
+code resembling GCC C-dialect and also outputs code in GCC
+C-dialect. The current TinyOS platforms are supported by GCC, but for
+some processor architectures GCC is not available (e.g. Motorola HCS08,
+Intel MCS51).
+
+Porting to platforms that are GCC supported can benefit from the
+existing tool flow, while porting to other platforms requires some
+effort. A straight forward solution adopted for these platforms is to
+post-process the C files produced by nesC to fit the needs of a
+specific compiler, see TEP121 for an example of such a solution.
+
+3.2 The Make System
+--------------------------------------------------------------------
+
+TinyOS controls the build process using make. The global make file
+searches certain locations to find make definitions for all available
+platforms. In order to make a new platform available to the TinyOS
+make system, a few files must be created in particular locations. These
+files will be read by the global make system and exposed to the users
+by make targets. Often the required rules are tied to a particular MCU
+that is shared among several platforms and TinyOS leverages this fact
+by creating a light-weight *.target* file pointing to the appropriate
+rules in a *.rules* file. The make system is documented in
+``support/make/README`` and in TinyOS 2 Tutorial Lesson 10[TUT10_].
+
+The make system looks for *.target* files in ``support/make`` and the
+directories listed in the environment variable ``TOSMAKE_PATH``. Each
+of the files found contain make targets for one TinyOS platform. The
+target files usually do not contain the rules to build the binary
+files, but include the appropriate rules from a *.rules* file, located
+in a sub directory for the appropriate MCU architecture (e.g. avr for
+the ATMega128 used by Mica). In this way many platforms share the
+build rules, but have different *.target* files. In addition *.extra*
+targets can be used to define helper targets such as install or clean.
+
+Setting up the make system, requires two steps (Section 3.2.1 gives an
+example):
+
+ 1. Creating a *platformX.target* file that allows the make system to
+ discover the new platform. This file must contain a make rule with
+ the name of the platform. Further this target must depend on the
+ targets given in the variable ``BUILD_DEPS`` - this variable
+ contains the remainder of targets to be build during the build
+ process.
+
+ 2. Creating a *.rules* file in a sub diretory of
+ ``support/make``. Each file contain the actual target for
+ producing the binaries, hex files, etc. for one platform. They are
+ assembled in the ``BUILD_DEPS`` variable.
+
+We will cover these two files next.
+
+3.2.1 The .target file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned above TinyOS searches for targets in the ``support/make``
+directory of the TinyOS source code and in the directories listed in
+the environment variable ``TOSMAKE_PATH``. A *.target* file for the
+platform must exist in one of these locations. The *.target* usually
+only sets up variables related to this platform and provide a target
+named after the platform, this target depend on other rules to build
+the binaries. These rules are included by calling
+*TOSMake_include_platform*. As an example the ``mica2.target`` is
+listed below:
+
+::
+
+ PLATFORM = mica2
+ SENSORBOARD ?= micasb
+ PROGRAMMER_PART ?= -dpart=ATmega128 --wr_fuse_e=ff
+ PFLAGS += -finline-limit=100000
+
+ AVR_FUSE_H ?= 0xd9
+
+ $(call TOSMake_include_platform,avr)
+
+ mica2: $(BUILD_DEPS)
+ @:
+
+Pay attention to the call to *TOSMake_include_platform,avr* this call
+includes ``.rules`` files in ``support/make`` or any sub directory of
+``TOSHMAKE_PATH`` named *avr*.
+
+
+3.2.2 The .rules file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The *.rules* file contain the make rules for building the target
+binary. If a MCU implementation already exists for a new platform,
+simply pointing to this *.rules* from the corresponding *.target* is
+sufficient. If not the *.rules* file must be built for a new MCU
+architecture.
+
+``TOSMake_include_platform`` expects a sub directory with a rule file
+of the form ``avr/avr.rules``. The call also includes additional
+*.rules* and *.extra* files present in that sub directory. See
+``support/make/README`` for details.
+
+For example a simplified .rules file could look like this (from
+*avr/avr.rules*):
+
+
+::
+
+ ...
+
+ BUILD_DEPS = srec tosimage
+
+ srec: exe FORCE
+ $(OBJCOPY) --output-target=srec $(MAIN_EXE) $(MAIN_SREC)
+
+ tosimage: ihex build_tosimage FORCE
+ @:
+
+ exe: builddir $(BUILD_EXTRA_DEPS) FORCE
+ @echo " compiling $(COMPONENT) to a $(PLATFORM) binary"
+ $(NCC) -o $(MAIN_EXE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS)
+ $(COMPONENT).nc $(LIBS) $(LDFLAGS)
+ ...
+
+
+4. The Platform
+====================================================================
+
+A TinyOS platform is a collection of components corresponding to a
+physical devices (a collection of drivers). A platform is constructed
+by defining which components make up the platform and by providing any
+additional platform specific components. The content of a platform is
+not covered by a TEP at the time of writing and the following is based
+on the available tutorials, *READMEs* and the current consensus.
+
+The platform definitions for a *PlatformX* are located in
+``tos/platforms/platformX`` and contain 3 major elements:
+
+ 1. The *.platform* file containing include paths and other arguments
+ for nesC
+
+ 2. Platform boot procedure: PlatformP/PlatformC
+
+ 3. Platform specific code, including a header for hardware specific
+ funtions (hardware.h) and code that is specific to the combination
+ of chip and platform (e.g. pin assignments, modifications, etc.).
+
+In the following we will describe each of these in more detail, below
+is a depiction of a fictuous platform and the required definitions.
+
+::
+
+ Platform: .platform
+ include MCU driver
+ +-------------------------+ include Radio driver
+ | | include Sensors driver
+ | Chips: |
+ | +-------+ | PlatformP
+ | | Radio | | Initialize MCU
+ | +--+----+ | Initialize Sensor
+ | +-----+ | | Initialize Radio
+ | | MCU +------+ |
+ | +-----+ | | hardware.h
+ | +--+----+ | Include MCU HW macros
+ | | Leds | |
+ | +-------+ | HIL interfaces, eg:
+ | | PlatformLeds
+ +-------------------------+
+
+
+All the files we describe here must be found in a common directory
+named after the platform; we call this a platform directory. This
+directory must be found in the TinyOS tool chain search path for
+example ``tos/platforms`` (or found in ``TOSHMAKE_PATH`` see Section
+3.2.1). For example a platform named PlatformX could be placed in the
+directory ``tos/platforms/platformX``.
+
+4.1 .platform file
+--------------------------------------------------------------------
+
+All platform directories must carry a ``.platform`` file, this file
+defines what makes up the platform. This file carries instructions for
+the make system on where to locate the drivers for each of the
+components of the platform. The definitions are read in a two step
+process: the file is read by the ncc script that passes the
+appropriate arguments to the nesC pre-processor[nescman_]. The
+.platform file is written as a Perl script interpreted by ncc.
+
+The file is documented in form of the README file in the platforms
+directory (*tos/platforms*), and the source code of the ncc script
+found in the TinyOS distribution. Valuable information can also be
+found in [TEP106_], [TEP109_], TinyOS 2 Tutorial Lesson 10[TUT10_].
+
+In addition to setting up include paths for nesC other arguments can
+be passed on. In particular the components to be used for the
+scheduler are selected with the '-fnesc-scheduler' command line
+argument (see [TEP106_]). The include paths are passed on using the
+'-I' command line argument covered in [TEP109_].
+
+As an example, an abbreviated *.platform* file for the mica2 platform
+looks like this:
+
+::
+
+ push( @includes, qw(
+ %T/platforms/mica
+ %T/platforms/mica2/chips/cc1000
+ %T/chips/cc1000
+ %T/chips/atm128
+ %T/chips/atm128/adc
+ %T/chips/atm128/pins
+ %T/chips/atm128/spi
+ %T/chips/atm128/timer
+ %T/lib/timer
+ %T/lib/serial
+ %T/lib/power
+ ) );
+
+ @opts = qw(
+ -gcc=avr-gcc
+ -mmcu=atmega128
+ -fnesc-target=avr
+ -fnesc-no-debug
+ -fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask
+ );
+
+
+4.2 PlatformP and PlatformC
+--------------------------------------------------------------------
+
+The PlatformP and PlatformC components are responsible for booting
+this platform to a usable state. In general this usually means things
+like calibrating clock and initializing I/O pins. If this platform
+requires that some devices are initialized in a particular order this
+can be implemented in a platform dependent way here. The boot process
+covered in [TEP107_].
+
+Most hardware peripherals require an initialization procedure of some
+sort. For most peripheral devices this procedure is only required when
+the device is in use and can be left out if the device is
+unused. TinyOS accomplishes this by providing a few initialization
+call backs interfaces. When a given component is included it wires an
+initialization procedure to one of these interfaces. In this way the
+procedure will only be included when the component is included, this
+process is known as auto wiring[TOSPRG_].
+
+The boot sequence calls two initialization interfaces in the following
+order: ``PlatformC.Init`` and ``MainC.SoftwareInit``.
+``PlatformC.Init`` must take care of initializing the hardware to an
+operable state and initialization that has hidden dependencies must
+occur here. Other components are initialized as part of
+``SoftwareInit`` and the orderign is determined at compile
+time.
+
+Common tasks in ``PlatformC.Init`` include clock calibration and IO
+pins. However this component can be used to provide greater control of
+the boot process if required. Consider for example that some component
+which is initialized in SoftwareInit requires that some other
+component has been initialized previously - lets say that the radio
+must be initialized prior to the radio stack or that a component
+prints a message to the UART during boot. How can this order be
+ensured? One solution is to provide an additional initialization
+handle prior to SoftwareInit and wire such procedures to this
+handle. Below is an example from the Mica mote family using the
+``MoteInit`` interface. Components that must be initialized early in
+the boot process is wired to this interface. If greater level of
+control is required this strategy can be trivially be expanded to
+further levels of interfaces for example MoteInit1 being initialized
+prior to MoteInit2, this strategy is chosen by the MSP430
+implementation.
+
+4.2.1 PlatformC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Below is depicted the PlatformC component from the Mica family of platforms.
+
+::
+
+ #include "hardware.h"
+
+ configuration PlatformC {
+ provides {
+ interface Init;
+ /**
+ * Provides calibration information for other components.
+ */
+ interface Atm128Calibrate;
+ }
+ uses interface Init as SubInit;
+ } implementation {
+ components PlatformP, MotePlatformC, MeasureClockC;
+
+ Init = PlatformP;
+ Atm128Calibrate = MeasureClockC;
+
+ PlatformP.MeasureClock -> MeasureClockC;
+ PlatformP.MoteInit -> MotePlatformC;
+ MotePlatformC.SubInit = SubInit;
+ }
+
+4.2.1 PlatformP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Below is depicted the PlatformP component from the Mica family of platforms.
+
+::
+
+ module PlatformP
+ {
+ provides interface Init;
+ uses interface Init as MoteInit;
+ uses interface Init as MeasureClock;
+
+ }
+ implementation
+ {
+ void power_init() {
+ ...
+ }
+
+ command error_t Init.init()
+ {
+ error_t ok;
+
+ ok = call MeasureClock.init();
+ ok = ecombine(ok, call MoteInit.init());
+ return ok;
+ }
+ }
+
+4.2.3 Init example: PlatformLedsC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Below is an example from mica/PlatformLedsC.nc wiring to the platform
+specific *MoteInit* interface.
+
+::
+
+ configuration PlatformLedsC {
+ provides interface GeneralIO as Led0;
+ ...
+ uses interface Init;
+ } implementation {
+ components HplAtm128GeneralIOC as IO;
+ components PlatformP;
+
+ Init = PlatformP.MoteInit;
+ ...
+
+3.3 Platform Specific Code
+--------------------------------------------------------------------
+
+In addition to PlatformP/PlatformC the platform directory contain
+additional code that is specific to this platform. First this could be
+code that ties platform independent resources to particular instances
+on this platform, second it could be code that is only relevant on
+this particular platform (e.g. the clock rate of this platform). For
+example the LEDs are a an example of the first: most platform have a
+few LEDs, and the particular pin on this platform is tied to the
+platform independent implementation using PlatformLedsC.
+
+TinyOS requires that the header ``hardware.h`` is present while other
+component can be named freely.
+
+4.3.1 Platform Headers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TinyOS relies on a few C-header files being present for each
+platform. These headers are then automatically included from the
+respective parts of the TinyOS system. TinyOS expects that the
+following files are present and that certain properties are defined in
+them.
+
+hardware.h
+**********************
+
+The ``hardware.h`` header file is included by ``tos/system/MainC.nc``
+and usually in turn includes a MCU specific header file, with a few
+required macros (such as avr128hardware.h, see Section 5.1.1). The
+header is documented in TinyOS 2 Tutorial Lesson 10[TUT10_]
+
+In addition the hardware.h file can set flags that are not related to
+the hardware in general, but to this platform (e.g. clock rate). Below
+is a snippet from ``mica2/hardware.h``
+
+::
+
+ #ifndef MHZ
+ /* Clock rate is ~8MHz except if specified by user
+ (this value must be a power of 2, see MicaTimer.h and MeasureClockC.nc) */
+ #define MHZ 8
+ #endif
+
+ #include <atm128hardware.h>
+
+ enum {
+ PLATFORM_BAUDRATE = 57600L
+ };
+ ...
+
+platform_message.h
+**********************
+
+As part of the TinyOS 2 message buffer abstraction[TEP111_], TinyOS
+includes the header *platform_message.h* from the internal TinyOS
+header *message.h*. This header is only strictly required for
+platforms wishing to use the message_t abstraction - this is not
+described further in this TEP, but is used widely throughout TinyOS
+(See [TEP111_] for details). The is expected to define the structures:
+*message_header_t*, *message_footer_t*, and *message_metadata_t* which
+are used to fill out the generic *message_t* structure.
+
+Below is an example from the ``mica2`` *platform_message.h*
+
+::
+
+ typedef union message_header {
+ cc1000_header_t cc1k;
+ serial_header_t serial;
+ } message_header_t;
+
+ typedef union message_footer {
+ cc1000_footer_t cc1k;
+ } message_footer_t;
+
+ typedef union message_metadata {
+ cc1000_metadata_t cc1k;
+ } message_metadata_t;
+
+
+4.3.2 Platform Specific Components
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The code for platform dependent features also resides in the platform
+directory. If the code can be tied to a particular chip it can be
+placed in a separate directory below the ``chips`` directory. As an
+example the following section of
+``micaz/chips/cc2420/HplCC2420PinsC.nc`` ties specific pins to general
+names on the MicaZ platform.
+
+::
+
+ configuration HplCC2420PinsC {
+ provides {
+ interface GeneralIO as CCA;
+ interface GeneralIO as CSN;
+ interface GeneralIO as FIFO;
+ interface GeneralIO as FIFOP;
+ interface GeneralIO as RSTN;
+ interface GeneralIO as SFD;
+ interface GeneralIO as VREN;
+ }
+ }
+
+ implementation {
+
+ components HplAtm128GeneralIOC as IO;
+
+ CCA = IO.PortD6;
+ CSN = IO.PortB0;
+ FIFO = IO.PortB7;
+ FIFOP = IO.PortE6;
+ RSTN = IO.PortA6;
+ SFD = IO.PortD4;
+ VREN = IO.PortA5;
+
+ }
+
+
+
+5. The chips
+====================================================================
+
+The functionality of each chip is provided by a set of one or more
+interfaces and one or more components, in traditional terms this makes
+up a driver. Each chip is assigned a sub directory in the the
+``tos/chips`` directory. All code that define the functionality of a
+chip is located here regardless of the type of chip (MCU, radio,
+etc.). In addition MCU's group the code related to separate sub
+systems into further sub directories (e.g. ``tos/chips/atm128/timer``).
+
+In this section we will go trough some of the peripherals commonly
+built into MCUs, but we will not go trough other chips such as sensors
+or radio.
+
+5.1 MCU Internals
+--------------------------------------------------------------------
+
+Apart from the drivers for each of the peripheral units, a few
+additional definitions are required for the internals of the MCU. This
+includes i) atomic begin/end and ii) low power mode. The first is
+defined in the header *hardware.h* and the latter component
+*MCUSleepC*.
+
+5.1.1 mcuXardware.h
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each architecture defines a set of required and useful macros in a
+header filed named after the architecture (for example
+*atm128hardware.h* for ATMega128). This header is then in turn
+included from *hardware.h* in the platform directory (See Section
+4.3.1).
+
+A few of the macros are required by nesC code generation. nesC will
+output code using these macros and they must be defined in advance,
+other useful macros such as interrupt handlers on this particular
+platform can be defined here as well. The required macros are:
+
+ * *__nesc_enable_interrupt* / *__nesc_disable_interrupt*
+ * *__nesc_atomic_start* / *__nesc_atomic_end*
+
+Below is a few examples from *atm128hardware.h*
+
+::
+
+ /* We need slightly different defs than SIGNAL, INTERRUPT */
+ #define AVR_ATOMIC_HANDLER(signame) \
+ void signame() __attribute__ ((signal)) @atomic_hwevent() @C()
+
+ #define AVR_NONATOMIC_HANDLER(signame) \
+ void signame() __attribute__ ((interrupt)) @hwevent() @C()
+
+ ...
+
+ inline void __nesc_enable_interrupt() { sei(); }
+ inline void __nesc_disable_interrupt() { cli(); }
+
+ ...
+
+ inline __nesc_atomic_t
+ __nesc_atomic_start(void) @spontaneous() {
+ __nesc_atomic_t result = SREG;
+ __nesc_disable_interrupt();
+ asm volatile("" : : : "memory");
+ return result;
+ }
+
+ /* Restores interrupt mask to original state. */
+ inline void
+ __nesc_atomic_end(__nesc_atomic_t original_SREG) @spontaneous() {
+ asm volatile("" : : : "memory");
+ SREG = original_SREG;
+ }
+
+
+5.1.2 MCUSleepC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TinyOS manages the power state of the MCU through a few
+interfaces. These interfaces allow components to signal how and when
+this platform should enter low power mode. Each new MCU in TinyOS must
+implement the *MCUSleepC* component that provide the *McuSleep* and
+*McuPowerState* interfaces.
+
+The TinyOS scheduler calls *McuSleep.sleep()* when it runs out of
+tasks to start. The purpose of this function is to make the MCU enter
+the appropriate sleep mode. The call to *McuSleep.sleep()* is made
+from within an atomic section making it essential that sleep() enables
+interrupts before entering sleep mode! If the interrupts not enabled
+prior to entering sleep mode the MCU will not be able to power back up.
+
+A dummy MCU sleep component that does not enter sleep mode, but merely
+switches interrupts on and off is shown below. This ensures that the
+platform will not lock up even without proper sleep support.
+
+::
+
+ #include "hardware.h"
+
+ module McuSleepC {
+ provides interface McuSleep;
+ provides interface McuPowerState;
+ uses interface McuPowerOverride;
+ } implementation {
+ async command void McuSleep.sleep() {
+ __nesc_enable_interrupt();
+ // Enter sleep here
+ __nesc_disable_interrupt();
+ }
+
+ async command void McuPowerState.update() { }
+ }
+
+
+5.2 GeneralIO
+--------------------------------------------------------------------
+
+Virtually all micro controllers feature a set of input output (I/O)
+pins. The features of these pins is often configurable and often some
+pins only support a subset of features. The HIL level interface for
+TinyOS is described in [TEP117_] and uses two interface to describe
+general purpose I/O pins common to many MCUs:
+
+* **GeneralIO**: Digital input/output. The GeneralIO interface
+ describes a digital pin with a state of either *clr* or *set*, the
+ pin must be capable of both input and output. Some MCUs provide pins
+ with different capabilities: more modes (e.g. an alternate
+ peripheral mode), less modes (e.g. only input) or a third
+ "tri-state" mode. Such chip specific additional features are not
+ supported. Some chips group a set of pins into "ports" that can be
+ read or written simultaneously, the HIL level interface does not
+ support reading or setting an entire port.
+
+* **GpioInterrupt**: Edge triggered interrupts. GpioInterrupt support
+ a single pin providing an interrupt triggered on a rising or falling
+ edge. Pins capable of triggering on an input level or only
+ triggering on one edge is not supported.
+
+While these interfaces are aimed at the HIL level some platforms use
+the GeneralIO and GpioInterrupt interface to represent the HPL level
+(atm128 for example) and others platforms define their own interface
+to capture the entire functionality (msp430, pxa27x for example).
+
+[TEP117_] states that each platform must provide the general IO pins of
+that platform through the *GeneralIO* interface and should do this
+though the component *GeneralIOC*. It is however not clear how the
+entire set of pins should be provided - this could be in the form of a
+list of pins, group of pins, a generic component, etc.
+
+The pin implementations are usually found in the *pins* sub directory
+for a particular MCU (e.g. *msp430/pins* for MSP430 pin
+implementation).
+
+5.2.1 Example MSP430
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The MSP430 implementation builds the platform independent pin
+implementation as a stack of components starting with a platform
+specific component for each pin.
+
+::
+
+ | GeneralIO
+ +---------------------+
+ | Msp430GpioC |
+ +---------------------+
+ | HplMsp430GeneralIO
+ +---------------------+
+ | HplMsp430GeneralIOC |
+ +---------------------+
+ | HplMsp430GeneralIO
+ +---------------------+
+ | HplMsp430GeneralIOP |
+ +---------------------+
+
+At the bottom the component ``HplMsp430GeneralIOP`` provides a general
+implementation of one Msp430 pin using the ``HplMsp430GeneralIO``
+interface. The generic component ``HplMsp430GeneralIOP`` is then
+instantiated for each pin by ``HplMsp430GeneralIOC``.
+
+::
+
+ interface HplMsp430GeneralIO {
+ async command void set();
+ async command void clr();
+ async command void toggle();
+ async command uint8_t getRaw();
+ async command bool get();
+ async command void makeInput();
+ async command bool isInput();
+ async command void makeOutput();
+ async command bool isOutput();
+ async command void selectModuleFunc();
+ async command bool isModuleFunc();
+ async command void selectIOFunc();
+ async command bool isIOFunc();
+ }
+
+This interface is implemented in the generic component
+HplMsp430GeneralIOP (abbreviated):
+
+::
+
+ generic module HplMsp430GeneralIOP(uint8_t port_in_addr, ...) {
+ provides interface HplMsp430GeneralIO as IO;
+ } implementation {
+ #define PORTx (*(volatile TYPE_PORT_OUT*)port_out_addr)
+
+ async command void IO.set() { atomic PORTx |= (0x01 << pin); }
+ async command void IO.clr() { atomic PORTx &= ~(0x01 << pin); }
+ async command void IO.toggle() { atomic PORTx ^= (0x01 << pin); }
+
+ ...
+
+These are then instantiated from HplMsp430GeneralIOC (abbreviated):
+
+::
+
+ configuration HplMsp430GeneralIOC {
+ provides interface HplMsp430GeneralIO as Port10;
+ provides interface HplMsp430GeneralIO as Port11;
+ ...
+ } implementation {
+ components
+ new HplMsp430GeneralIOP(P1IN_, P1OUT_, P1DIR_, P1SEL_, 0) as P10,
+ new HplMsp430GeneralIOP(P1IN_, P1OUT_, P1DIR_, P1SEL_, 1) as P11,
+ ...
+ Port10 = P10;
+ Port11 = P11;
+ ...
+
+
+And finally these are transformed from the interface
+HplMsp430GeneralIO to the platform independent GeneralIO using the
+generic component Msp430GpioC (abbreviated):
+
+::
+
+ generic module Msp430GpioC() {
+ provides interface GeneralIO;
+ uses interface HplMsp430GeneralIO as HplGeneralIO;
+ } implementation {
+ async command void GeneralIO.set() { call HplGeneralIO.set(); }
+ async command void GeneralIO.clr() { call HplGeneralIO.clr(); }
+ async command void GeneralIO.toggle() { call HplGeneralIO.toggle(); }
+ ...
+
+
+5.3 LEDs
+--------------------------------------------------------------------
+
+Having a few leds on a platform is quite common and TinyOS supports
+three leds in a platform independent manner. Three leds are provided
+through the *LedsC* component regardless of the amount of leds
+available on the platform. The LED implementation is not covered by a
+TEP at the time of writing, but the general consensus between most
+platforms seems to be to provide access to 3 LEDs through the
+component *PlatformLedsC*. This component is then used by *LedC* and
+*LedP* (from ``tos/system``) to provide a platform independent Led
+interface.
+
+The PlatformLedsC implementation is found in the platform directory of
+each platform (e.g. *tos/platforms/mica2* for mica2). The consensus is
+as follows:
+
+* Each platform provides the component PlatformLedsC
+
+* PlatformLedsC provides Led0, Led1, Led2 using the GeneralIO
+ interface. If the platform has less than 3 Leds these are wired to
+ the component NoPinC
+
+* PlatformLedsC *uses* the Init interface and usually it wired back to
+ an initialization in PlatformP - this way when LedC is included in
+ an application it will be initialized when PlatformP call this
+ interface
+
+5.3.1 Example Mica2dot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ configuration PlatformLedsC
+ {
+ provides interface GeneralIO as Led0;
+ provides interface GeneralIO as Led1;
+ provides interface GeneralIO as Led2;
+ uses interface Init;
+ }
+ implementation {
+ components HplAtm128GeneralIOC as IO;
+ components new NoPinC();
+ components PlatformP;
+
+ Init = PlatformP.MoteInit;
+
+ Led0 = IO.PortA2; // Pin A2 = Red LED
+ Led1 = NoPinC;
+ Led2 = NoPinC;
+ }
+
+
+
+
+5.3.2 LEDs implementation discussion
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Led interface described above is not specified in a TEP, though at
+the time of writing most platforms seem to follow this pattern. Not
+being covered by a TEP leads to a few uncertainties:
+
+* *PlatformLedsC* exports leds using the *GeneralIO* interface. The
+ intention is of course that a led is connected to a pin and this pin
+ is used to turn the led on. *LedC* uses this assumption to calls the
+ appropriate *makeOutput* and *set*/*clr* calls. However this might
+ not be the case - a led could be connected differently making the
+ semantics of, say *makeOutput* unclear. Furthermore it is assumed
+ that the set call turns the led on, while the actual pin might have
+ to be cleared (active low). And what is the semantics of *makeInput*
+ on a LED? Abstracting these differences into on/off, enable/disable
+ semantics would clear up the uncertainties.
+
+* Initializing the Leds is important - the Leds can consume power even
+ when turned off, if the corresponding pins are configured
+ inappropriately. Including the LedsC component initializes the Leds
+ as output when this component is used, if not they must be
+ initialized elsewhere (e.g. PlatformP). It would seem elegant to
+ group related code (e.g. one Leds component).
+
+* The interface does not provide a uniform way of accessing any
+ additional LEDs other than the 3 found on the Mica motes. While this
+ is inherently platform specific, having a common consensus would be
+ useful, say for example exporting an array of Led. In this way a
+ program requiring say 4 leds could be compiled if 4 leds are available.
+
+
+5.4 Timers
+--------------------------------------------------------------------
+
+The timer subsystem in TinyOS 2 is described in [TEP102_] the TEP
+specifies interfaces at HAL and HIL levels that a platform must adhere
+to. The timer does not cover the possible design choices at the HPL
+level. The timers defined in this TEP are described in terms of
+*width* of the underlying counters (e.g. 8, 16, 32 bit) and in the
+tick period or frequency denoted *precision* (e.g. 10 kHz, 1 ms, 1
+us). The timer subsystem is provided through a set of hardware
+independent interfaces and a set of recommended configuration modules.
+As such some features of a particular device may not be available in a
+device independent manner.
+
+The functionality commonly seen in MCU timer units is often split in 3
+parts: control, timer/counter, capture/compare(trigger). Timer control
+in is inherently platform specific and is not covered by a TEP. The
+timer [TEP102_] covers timer/counter while capture/compare is covered
+by [TEP117_]. From the TEPs it is not clear how capture/compare and
+timer/counter relate to each other even though they are likely to
+refer to the same time base. The calibration of the system clock is
+often connected with the timer system and lives in the timer
+directory, but it is not covered in [TEP102_].
+
+The timer implementation for a given MCU is placed in the *timer* sub
+directory of the directory for a given MCU
+(e.g. *tos/chips/avr/timer*). Often clock initialization components
+are placed in the same directory, but these are not covered by the
+TEPs.
+
+5.4.1 Timer Layers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TEP117_ follows the 3 layer architecture and separates the platform
+dependent and independent abstractions. It poses not restrictions on
+the HPL layer, but provides a suggested HAL layer and requirements at
+the HIL level. It defines a set of interfaces and precisions that are
+used at the HAL and HIL levels.
+
+The common features of a timer are separated into a set of interfaces,
+corresponding roughly to common features in MCU timer units. The
+interfaces covered by the [TEP102_] are (capture from [TEP117_]):
+
+* **BusyWait<precision_tag,size_type>** Short synchronous delays
+* **Counter<precision_tag, size_type>** Current time, and overflow events
+* **Alarm<precision_tag,size_type>** Extend Counter with at a given time
+* **Timer<precision_tag>** 32 bit current time, one shot and periodic events
+* **LocalTime<precision_tag>** 32 bit current time without overflow
+* **GpioCapture** 16 bit time value on an external event (precision unspecified)
+
+The precisions defined in [TEP117_] are defined as "binary" meaning
+1024 parts of a second. Platforms must provide these precisions (if
+possible) regardless of the underlying system frequency (i.e. this
+could be a power of 10).
+
+* **TMilli** 1024 Hz (period 0.98 ms)
+* **TMicro** 1048576 Hz (period 0.95 us)
+* **T32khz** 32.768 kHz (period 30.5 us)
+
+HPL
+********
+The features of the underlying hardware timers are generally exposed
+using one or more hardware specific interfaces. Many MCU provide a
+rich a set of different timer units varying in timer width, frequency
+and features.
+
+Many MCUs provides features that are quite close to the features
+described by the interfaces above. The HPL layer exposes these
+features and the layers above utilize the available hardware and
+virtualize the features if necessary.
+
+Consider for example generating events at a specific time. Often a
+timer unit has a single counter and a few compare registers that
+generate interrupts. The counter and compare registers often translate
+relative straightforward to Counter and Alarm interfaces.
+
+HAL
+********
+
+Each platform should expose a hardware timer of precision P and width W
+as Counter${P}${W}C, Alarm${P}${W}C(). For example an 8 bit, 32.768 kHz
+timer should be exposed as Counter32khz8C and Alarm32khz8C
+
+Alarm/Counters come in pairs and refer to a particular hardware unit,
+while there is only one counter there is commonly multiple compare
+registers. Alarm is a generic component and each instantiation must
+provide an independent alarm allocating more Alarm components than
+available compare register should provide a compile time error.
+
+HIL
+*********
+
+Each platform must expose the following components that provide
+specific width and precision that are guaranteed to exist on TEP
+compliant platforms.
+
+ * **HilTimerMilliC** A 32 bit Timer interface of TMilli precision
+ * **BusyWaitMicroC** A BusyWait interface of TMicro precision
+
+
+5.4.2 Timer Implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Implementing the timers for TinyOS in short consists of utilizing the
+available HW timer features to provide TinyOS style timers
+interfaces. In general the approach taken by existing platforms is to
+create a set of HPL level timer and control interfaces that export the
+available hardware features and adapt these to specific precisions and
+widths at the HAL level. However the specific HPL level design choices
+differ from platform to platform.
+
+For example one could export all timers as a simple list, a component
+for each timer, a parameterised interface, etc. Similarly for the
+control features this could be provided with the timer interfaces or
+kept as a separate interface. In the following we will go through a
+few examples and point out their differences.
+
+
+5.4.3 Example: ATMega128l
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ATMega128l implementation (atm128) exports the system timers one
+component each. Each component provide 4 interfaces - one for each of
+the functions of the unit: timer, capture, compare and control. The
+timer, capture, and compare interfaces are generic based on the width
+(either 8 or 16 bit) while two separate control interfaces are
+provided.
+
+Depicted below is a diagram of how ``HplAtm128Timer1C`` could be stacked
+to provide platform independent interfaces (not shown are
+``HplAtm128Timer0Async``, ``HplAtm128Timer2``, ``HplAtm128Timer3``):
+
+::
+
+ +------------------------------------------------+
+ | HplAtm128Timer1C |
+ +-----+-------------------+-----------------+----+
+ HplAtm128Capture| HplAtm128Timer| HplAtm128Compare|
+ | | |
+ +----------+---------+ | |
+ | Atm128GpioCaptureC | | |
+ +----------+---------+ | |
+ | +-+-----------------+--+
+ GpioCapture| | Atm128AlarmC |
+ | +----------+-----------+
+ | Alarm|
+
+
+The hardware features is exported using 3 interfaces:
+``HplAtm128Timer``, ``HplAtm128Compare`` and ``HplAtm128Capture``.
+
+::
+
+ interface HplAtm128Timer<timer_size>
+ {
+ async command timer_size get();
+ async command void set( timer_size t );
+ async event void overflow();
+ async command void reset();
+ async command void start();
+ ...
+
+ interface HplAtm128Compare<size_type>
+ {
+ async command size_type get();
+ async command void set(size_type t);
+ async event void fired(); //<! Signalled on compare interrupt
+ async command void reset();
+ ...
+
+ interface HplAtm128Capture<size_type>
+ {
+ async command size_type get();
+ async command void set(size_type t);
+ async event void captured(size_type t);
+ async command void reset();
+
+
+In addition to the timer related interfaces two control interfaces are
+ provided: 'HplAtm128TimerCtrl16' and 'HplAtm128TimerCtrl8' (below).
+
+::
+
+ #include <Atm128Timer.h>
+
+ interface HplAtm128TimerCtrl8
+ {
+ /// Timer control register: Direct access
+ async command Atm128TimerControl_t getControl();
+ async command void setControl( Atm128TimerControl_t control );
+
+ /// Interrupt mask register: Direct access
+ async command Atm128_TIMSK_t getInterruptMask();
+ async command void setInterruptMask( Atm128_TIMSK_t mask);
+
+ /// Interrupt flag register: Direct access
+ async command Atm128_TIFR_t getInterruptFlag();
+ async command void setInterruptFlag( Atm128_TIFR_t flags );
+ }
+
+
+Each of the hardware timers are exported in one component for example
+'HplAtm128Timer1P':
+
+::
+
+ #include <Atm128Timer.h>
+
+ module HplAtm128Timer1P
+ {
+ provides {
+ // 16-bit Timers
+ interface HplAtm128Timer<uint16_t> as Timer;
+ interface HplAtm128TimerCtrl16 as TimerCtrl;
+ interface HplAtm128Capture<uint16_t> as Capture;
+ interface HplAtm128Compare<uint16_t> as CompareA;
+ interface HplAtm128Compare<uint16_t> as CompareB;
+ interface HplAtm128Compare<uint16_t> as CompareC;
+ }
+ uses interface HplAtm128TimerCtrl8 as Timer0Ctrl;
+ }
+ implementation
+ {
+ //=== Read the current timer value. ===================================
+ async command uint16_t Timer.get() { return TCNT1; }
+
+ //=== Set/clear the current timer value. ==============================
+ async command void Timer.set(uint16_t t) { TCNT1 = t; }
+ ...
+
+
+5.4.4 Example: MSP430
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The MSP430 features two very similar (but not identical) timers. Both
+timers are provided through the same interfaces in a way similar to
+ATMega128l: 'Msp430Timer', 'Msp430Capture' 'Msp430Compare',
+'Msp430TimerControl'. All timer interfaces (for both timers) are
+accessed through the component Msp430TimerC.
+
+The ``Msp430TimerControl`` is show below. It is slightly different
+than the ATMega equivalent - notice that 'setControl' accepts a struct
+with configuration parameters instead of setting these with a command
+each.
+
+::
+
+ #include "Msp430Timer.h"
+
+ interface Msp430TimerControl
+ {
+ async command msp430_compare_control_t getControl();
+ async command bool isInterruptPending();
+ async command void clearPendingInterrupt();
+
+ async command void setControl(msp430_compare_control_t control );
+ async command void setControlAsCompare();
+ async command void setControlAsCapture(bool low_to_high);
+
+ async command void enableEvents();
+ async command void disableEvents();
+ async command bool areEventsEnabled();
+ }
+
+Each timer is implemented through the generic component 'Msp430TimerP'
+that is instantiated for each timer in 'Msp430TimerC':
+
+::
+
+ configuration Msp430TimerC
+ {
+ provides interface Msp430Timer as TimerA;
+ provides interface Msp430TimerControl as ControlA0;
+ provides interface Msp430TimerControl as ControlA1;
+ provides interface Msp430TimerControl as ControlA2;
+ provides interface Msp430Compare as CompareA0;
+ provides interface Msp430Compare as CompareA1;
+ provides interface Msp430Compare as CompareA2;
+ provides interface Msp430Capture as CaptureA0;
+ provides interface Msp430Capture as CaptureA1;
+ provides interface Msp430Capture as CaptureA2;
+ ...
+ }
+ implementation
+ {
+ components new Msp430TimerP( TAIV_, TAR_, TACTL_, TAIFG, TACLR, TAIE,
+ TASSEL0, TASSEL1, FALSE ) as Msp430TimerA
+ , new Msp430TimerP( TBIV_, TBR_, TBCTL_, TBIFG, TBCLR, TBIE,
+ TBSSEL0, TBSSEL1, TRUE ) as Msp430TimerB
+ , new Msp430TimerCapComP( TACCTL0_, TACCR0_ ) as Msp430TimerA0
+ , new Msp430TimerCapComP( TACCTL1_, TACCR1_ ) as Msp430TimerA1
+ , new Msp430TimerCapComP( TACCTL2_, TACCR2_ ) as Msp430TimerA2
+ ...
+
+
+5.4.5 Example: PXA27x
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The PXA27x (XScale) platform provides a component for each of the
+timers classes on the system. Each component provides a few interfaces
+that exposes all features of that unit. Each interface combines timer
+and control interface features. For example 'HplPXA27xOSTimerC'
+provides 12 instances of the 'HplPXA27xOSTimer' interface and one
+instace 'HplPXA27xOSTimerWatchdog'. Similarly for 'HplPXA27xSleep' and
+'HplPXA27xWatchdog'.
+
+
+::
+
+ interface HplPXA27xOSTimer
+ {
+ async command void setOSCR(uint32_t val);
+ async command uint32_t getOSCR();
+ ...
+
+
+ async event void fired();
+ }
+
+All the OS timers are exported through HplPXA27xOSTimerC
+
+::
+
+ configuration HplPXA27xOSTimerC {
+
+ provides {
+ interface Init;
+ interface HplPXA27xOSTimer as OST0;
+ interface HplPXA27xOSTimer as OST0M1;
+ interface HplPXA27xOSTimer as OST0M2;
+ interface HplPXA27xOSTimer as OST0M3;
+ ...
+ implementation {
+ components HplPXA27xOSTimerM, HplPXA27xInterruptM;
+
+ Init = HplPXA27xOSTimerM;
+
+ OST0 = HplPXA27xOSTimerM.PXA27xOST[0];
+ OST0M1 = HplPXA27xOSTimerM.PXA27xOST[1];
+ OST0M2 = HplPXA27xOSTimerM.PXA27xOST[2];
+ OST0M3 = HplPXA27xOSTimerM.PXA27xOST[3];
+ ...
+
+These interfaces are further abstracted through 'HalPXA27xOSTimerMapC'
+as a parameterised interface:
+
+::
+
+ configuration HalPXA27xOSTimerMapC {
+ provides {
+ interface Init;
+ interface HplPXA27xOSTimer as OSTChnl[uint8_t id];
+ }
+ } implementation {
+ components HplPXA27xOSTimerC;
+
+ Init = HplPXA27xOSTimerC;
+
+ OSTChnl[0] = HplPXA27xOSTimerC.OST4;
+ OSTChnl[1] = HplPXA27xOSTimerC.OST5;
+ OSTChnl[2] = HplPXA27xOSTimerC.OST6;
+ ...
+
+
+5.4.6 Timer Discussion
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While the TEP is clear on many points there are few that are left up
+to the implementer. The relation between timers and capture events is
+unclear and covered in two TEPs. Capture refers to timers[TEP102_] but
+the reverse is not clear[TEP102_]. This has a few implications for the
+timer/capture relationship:
+
+* Many devices feature multiple timers of the same width and
+ precision. It is not clear how this is provided. In particular how
+ this relates to a capture event - e.g. how does a capture event from
+ timer 2 relate to a time value from timer 1. Presumably TinyOS has
+ one system time based on a single timer which is used by all timer
+ capture interfaces and visualized if necessary.
+
+* The interfaces provide a an elegant way to expand a 16 bit timer to
+ a 32 bit interface. However this is not the case for capture events.
+
+
+
+5.5 I/O buses (UART, SPI, I2C)
+--------------------------------------------------------------------
+
+Most modern microprocessors provide a selection of standard I/O bus
+units such as serial (UART or USART), I2C, SPI, etc. The drivers for
+the available buses are usually put in a sub directory for the MCU
+(e.g. *chip/atm128/spi* for SPI on ATMega128l).
+
+There are a few TEP that cover different buses in TinyOS, and low
+level serial communication:
+
+* TEP113_ Serial Communication: Serial
+* TEP117_ Low-Level I/O: Serial, SPI, I2C
+
+On some hardware platforms a single I/O unit is shared among a number
+of buses. The MSP430 for example implements SPI, I2C and USART in a
+single USART unit that can only operate in one mode at a time. In such
+cases the single hardware unit must be shared among the drivers.
+
+5.5.1 Serial Communication
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Serial communication in TinyOS 2.x is implemented as a serial
+communications stack with a UART or USART at the bottom. The bottom
+layer is covered in [TEP113_] and [TEP117_]. TEP117 states that each
+platform must provide access to a serial port through the
+'SerialByteComm' interface from the component UartC. However UartC is
+not provided by any platforms at the time of writing. There seems to
+be a consensus to build the component 'PlatformSerialC' providing the
+'UartStream' and 'StdControl' interfaces. Either component will be
+placed in the platform directory (e.g. *tos/platforms/mica2* for
+mica2). The serial stack is built upon 'PlatformSerialC' and this
+component will be required to take advantage of the serial stack.
+
+[TEP117_] defines 'UartStream' and 'UartByte' to access the a UART
+multiple bytes at a time and one byte at a time (synchronously), while
+[TEP113_] defines 'UartByte' to send and receive one byte at a time
+(asynchronously).
+
+5.5.2 I2C, SPI
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SPI and I2C buses are provided through straightforward interfaces that
+match the functionality of the buses closely.
+
+SpiByte, SpiPacket
+******************
+::
+
+ interface SpiByte {
+ async command uint8_t write( uint8_t tx );
+ }
+
+::
+
+ 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 );
+ }
+
+I2CPacket
+*********
+::
+
+ interface I2CPacket<addr_size> {
+ async command error_t read(i2c_flags_t flags, 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 readDone(error_t error, 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);
+ }
+
+5.5.3 Example
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+..ATMega128
+ -> does not provide SerialByteComm
+
+..MSP430
+ -> Uart1C provides SerialByteComm along with Init and StdControl
+ -> sender det meste videre til Msp430Uart1C (som mangler Init!?!?)
+ Msp430Uart0C
+ -> SerialByteComm, Msp430UartControl, Msp430UartConfigure, Resurce
+ -> Sender videre til Msp430Uart1P & Msp430Usart1C
+ -> Sender videre til HplMsp430Usart1C->HplMsp430Usart1P
+
+..PXA27
+ Parametriseret m. HplPXA27xUARTP (Init && HplPXA27xUART)
+ -> init sætter en masse registre og enabler interrupt
+ HalPXA27xSerialP: HplPXA27xUART, Init, noget DMA noget
+
+
+6. Authors
+====================================================================
+
+| Martin Leoold
+| University of Copenhagen, Dept. of Computer Science
+| Universitetsparken 1
+| DK-2100 København Ø
+| Denmark
+|
+| Phone +45 3532 1464
+|
+| email - leopold@diku.dk
+
+
+7. Citations
+====================================================================
+.. [TEP1] TEP 1: TEP Structure and Keywords
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep1.html>
+
+.. [TEP2] TEP 2: Hardware Abstraction Architecture
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep2.html>
+
+.. [TEP3] TEP 3: Coding Standard
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep3.html>
+
+.. [TEP102] TEP 102: Timers
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep102.html>
+
+.. [TEP106] TEP 106: Schedulers and Tasks
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep106.html>
+
+.. [TEP107] TEP 107: TinyOS 2.x Boot Sequence
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep107.html>
+
+.. [TEP109] TEP 109: Sensors and Sensor Boards
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep109.html>
+
+.. [TEP111] TEP 111: message_t
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep111.html>
+
+.. [TEP113] TEP 113: Serial Communication
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep113.html>
+
+.. [TEP117] TEP 117: Low-Level I/O
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep117.html>
+
+.. [TEP121] TEP 121: Towards TinyOS for 8051
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tep121.html>
+
+.. [TOSPRG] Philip Levis: TinyOS Programming
+ <http://www.tinyos.net/tinyos-2.x/doc/pdf/tinyos-programming.pdf>
+
+.. [tos2.0view] Philip Levis. "TinyOS 2.0 Overview" *Feb 8 2006*
+ <http://www.tinyos.net/tinyos-2.x/doc/html/overview.html>
+
+.. [nescman] David Gay, Philip Levis, David Culler, Eric Brewer. "NesC 1.2 Language Reference Manual" *August 2005*
+
+.. [TUT10] TinyOS 2 Tutorial Lesson 10
+ <http://www.tinyos.net/tinyos-2.x/doc/html/tutorial/lesson10.html>
+
+ LocalWords: TinyOS TEP TEPs nesC