[Tinyos Core WG] Meeting: 2/7

Gilman Tolle gtolle at archrock.com
Wed Feb 7 10:36:37 PST 2007


Meeting notes are on the wiki.

http://tinyos.stanford.edu:8000/TinyOS_2.x_WG/02.07.2007

Gil

Philip Levis wrote:
> I'm sending this mail out a bit early because there are 2 TEPs to read, 
> both of which are on significant topics.
> 
> Wednesday, February 7, 2007, 09:30 AM US Pacific Time
> Bridge: 4
> Passcode: 1149804
> 
> Numbers:
> US: 1-916-356-2663 or 1-888-875-9370 (non-Intel)
> UK: +44 1793 402663
> Denmark: +45 4527 5090
> 
> Agenda:
> 
> Status
> mica timers
> CC2420 stack (low power, SACKs, cancellation)
> 6lowpan: I-Frame, T-Frame
> 
> TEP 115 (attached)
> TEP 2 (attached)
> 
> Phil
> 
> 
> 
> ------------------------------------------------------------------------
> 
> =================================
> Hardware Abstraction Architecture
> =================================
> 
> :TEP: 2
> :Group: Core Working Group 
> :Type: Best Current Practice
> :Status: Draft
> :TinyOS-Version: 2.0
> :Author: Vlado Handziski, Joseph Polastre, Jan-Hinrich Hauer, Cory Sharp, Adam Wolisz and David Culler
> 
> :Draft-Created: 14-Sep-2004
> :Draft-Version: $revision$
> :Draft-Modified: $date$
> :Draft-Discuss: TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu>
> 
> .. Note::
> 
>    This document specifies a Best Current Practices for the TinyOS
>    Community, and requests discussion and suggestions for
>    improvements.  The distribution of the memo is unlimited, provided
>    that the header information and this note are preserved. Parts of
>    this document are taken verbatim from the [HAA2005]_ paper that is
>    under IEEE copyright. This memo is in full compliance with [TEP1]_.
> 
> 
> Abstract
> ========
> 
> 
> This TEP documents the *Hardware Abstraction Architecture (HAA)* for TinyOS
> 2.0 that balances conflicting requirements of WSN applications and the
> desire for increased portability and streamlined development of
> applications. The three-layer design gradually adapts the capabilities
> of the underlying hardware platforms to the selected
> platform-independent hardware interface between the operating system
> core and the application code. At the same time, it allows the
> applications to utilize a platform's full capabilities -- exported at
> the second layer, when the performance requirements outweigh the need
> for cross-platform compatibility.
> 
> ..  
>     We demonstrate the practical value of the approach by presenting
>     how it can be applied to the most important hardware modules that
>     are found in a typical WSN platform. We support the claims using
>     concrete examples from existing hardware abstractions in TinyOS
>     and the implementation of the MSP430 platform that follows the
>     architecture proposed in this paper.
> 
> 
> Table of Contents
> =================
> 
> .. contents:: 
> .. sectnum::
> 
> 
> Introduction
> ============
> 
> 
> The introduction of hardware abstraction in modern operating systems
> has proved valuable for increasing portability and simplifying
> application development by hiding the hardware intricacies from the
> rest of the system. Although enabling portability, hardware
> abstractions come into conflict with the performance and
> energy-efficiency requirements of WSN applications. 
> 
> We need a *Hardware Abstraction Architecture (HAA)* that can strike a
> balance between the above conflicting goals. The component-based model
> of TinyOS has the functionality required for resolving this
> tension. The main challenge is to select an appropriate organization
> of abstraction functionality in form of components to support
> reusability while maintaining energy-efficiency through access to the
> full hardware capabilities when it is needed.
> 
> Based on the experience in porting TinyOS to new platforms we believe
> that an effective organization is possible when the strengths of the
> component-based approach are combined with a flexible, three-tier
> organization of the hardware abstraction architecture.
> 
> 
> Architecture
> ============
> 
> In the proposed architecture (Fig.1_), the hardware abstraction
> functionality is organized in three distinct layers of components.
> Each layer has clearly defined responsibilities and is dependent on
> interfaces provided by lower layers.  The capabilities of the
> underlying hardware are gradually adapted to the established
> platform-independent interface between the operating system and the
> applications. As we move from the hardware towards this top interface,
> the components become less and less hardware dependent, giving the
> developer more freedom in the design and the implementation of
> reusable applications.
> 
> .. _Fig.1:
> 
> ::
> 
>                                  +-----------------------------+
>                                  |                             |
>                                  | Cross-platform applications |
>                                  |                             |
>                                  +--------------+--------------+
>  +-----------------+                            |                            +-----------------+
>  |Platform-specific|                            |                            |Platform-specific|
>  |  applications   |                            |                            |  applications   |
>  +--------+--------+       Platform-independent |  hardware interface        +--------+--------+
>           |          +-----------------+--------+--------+-----------------+          |
>           |          |                 |                 |                 |          |
>           |  +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+  |
>           |  |.------+------.| |.------+------.| |.------+------.| |.------+------.|  |
>           |  ||             || ||             || ||             || ||    HIL 4    ||  |
>           |  ||    HIL 1    || ||    HIL 2    || ||    HIL 3    || |`------+------'|  |
>           |  ||             || |`------+------'| |`------+------'| |       |       |  |
>           |  |`------+------'| |       |       | |       |       | |       |  +----+--+
>           +--+----+  |       | |.------+------.| |       |       | |       |  |    |
>              |    |  |       | ||             || |.------+------.| |.------+--+---.|
>              |.---+--+------.| ||             || ||             || ||             ||
>              ||             || ||    HAL 2    || ||             || ||             ||
>              ||             || ||             || ||    HAL 3    || ||    HAL 4    ||
>              ||    HAL 1    || |`------+------'| ||             || ||             ||
>              ||             || |       |       | ||             || ||             ||
>              ||             || |       |       | |`------+------'| |`------+------'|
>              |`------+------'| |.------+------.| |       |       | |       |       |
>              |       |       | ||             || |.------+------.| |       |       |
>              |.------+------.| ||    HPL 2    || ||             || |.------+------.|
>              ||    HPL 1    || ||             || ||    HPL 3    || ||    HPL 4    ||
>              |`------+------'| |`------+------'| |`------+------'| |`------+------'|
>              +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+  HW/SW
>                      |                 |                 |                 |          boundary
>         ************************************************************************************
>               +------+------+   +------+------+   +------+------+   +------+------+
>               |HW Platform 1|   |HW Platform 2|   |HW Platform 3|   |HW Platform 4|
>               +-------------+   +-------------+   +-------------+   +-------------+
> 
>                     
>                        Fig.1: The proposed Hardware Abstraction Architecture
> 
> 
> 
> Hardware Presentation Layer (HPL)
> ---------------------------------
> 
> The components belonging to the *HPL* are positioned directly over
> the HW/SW interface. As the name suggests, their major task is to
> "present" the capabilities of the hardware using the native concepts
> of the operating system.  They access the hardware in the usual way,
> either by memory or by port mapped I/O. In the reverse direction, the
> hardware can request servicing by signaling an interrupt. Using these
> communication channels internally, the *HPL* hides the hardware
> intricacies and exports a more usable interface (simple function
> calls) for the rest of the system.
> 
> The *HPL* components SHOULD be stateless and expose an interface
> that is fully determined by the capabilities of the hardware module
> that is abstracted. This tight coupling with the hardware leaves
> little freedom in the design and the implementation of the components.
> Even though each *HPL* component will be as unique as the underlying
> hardware, all of them will have a similar general structure. For
> optimal integration with the rest of the architecture, each *HPL*
> component SHOULD have:
> 
> - commands for initialization, starting, and stopping of the
>   hardware module that are necessary for effective power management
>   policy
> - "get" and "set" commands for the register(s) that control
>   the operation of the hardware
> - separate commands with descriptive names for the most
>   frequently used flag-setting/testing operations
> - commands for enabling and disabling of the interrupts generated by
>   the hardware module
> - service routines for the interrupts that are generated by the
>   hardware module
> 
> The interrupt service routines in the *HPL* components perform only
> the most time critical operations (like copying a single value,
> clearing some flags, etc.), and delegate the rest of the processing to
> the higher level components that possess extended knowledge about the
> state of the system.
> 
> The above *HPL* structure eases manipulation of the hardware.
> Instead of using cryptic macros and register names whose definitions
> are hidden deep in the header files of compiler libraries, the
> programmer can now access hardware through a familiar interface.
> 
> This *HPL* does not provide any substantial abstraction over the
> hardware beyond automating frequently used command
> sequences. Nonetheless, it hides the most hardware-dependent code and
> opens the way for developing higher-level abstraction components.
> These higher abstractions can be used with different *HPL*
> hardware-modules of the same class.  For example, many of the
> microcontrollers used on the existing WSN platforms have two USART
> modules for serial communication.  They have the same functionality
> but are accessed using slightly different register names and generate
> different interrupt vectors. The *HPL* components can hide these
> small differences behind a consistent interface, making the
> higher-level abstractions resource independent.  The programmer can
> then switch between the different USART modules by simple rewiring
> (*not* rewriting) the *HPL* components, without any changes to the
> implementation code.
> 
>   
> Hardware Adaptation Layer (HAL)
> -------------------------------
> 
> The adaptation layer components represent the core of the
> architecture. They use the raw interfaces provided by the *HPL*
> components to build useful abstractions hiding the complexity
> naturally associated with the use of hardware resources. In contrast
> to the *HPL* components, they are allowed to maintain state that can
> be used for performing arbitration and resource control.
> 
> Due to the efficiency requirements of WSN, abstractions at the *HAL*
> level are tailored to the concrete device class and platform. Instead
> of hiding the individual features of the hardware class behind generic
> models, *HAL* interfaces expose specific features and provide the
> "best" possible abstraction that streamlines application development
> while maintaining effective use of resources.
> 
> For example, rather than using a single "file-like" abstraction for
> all devices, we propose domain specific models like *Alarm*, *ADC
> channel*, *EEPROM*. According to the model, *HAL* components SHOULD
> provide access to these abstractions via rich, customized interfaces,
> and not via standard narrow ones that hide all the functionality
> behind few overloaded commands.
> 
> Hardware Interface Layer (HIL)
> ------------------------------
> 
> The final tier in the architecture is formed by the *HIL* components
> that take the platform-specific abstractions provided by the *HAL* and
> convert them to hardware-independent interfaces used by cross-platform
> applications.  These interfaces provide a platform independent
> abstraction over the hardware that simplifies the development of the
> application software by hiding the hardware differences.  To be
> successful, this API "contract" SHOULD reflect the *typical*
> hardware services that are required in a WSN application.
> 
> The complexity of the *HIL* components mainly depends on how advanced
> the capabilities of the abstracted hardware are with respect to the
> platform-independent interface. When the capabilities of the hardware
> exceed the current API contract, the *HIL* "downgrades" the
> platform-specific abstractions provided by the *HAL* until they are
> leveled-off with the chosen standard interface. Consequently, when the
> underlying hardware is inferior, the *HIL* might have to resort to
> software simulation of the missing hardware capabilities.  As newer
> and more capable platforms are introduced in the system, the pressure
> to break the current API contract will increase. When the performance
> requirements outweigh the benefits of the stable interface, a discrete
> jump will be made that realigns the API with the abstractions provided
> in the newer *HAL*.  The evolution of the platform-independent interface
> will force a reimplementation of the affected *HIL* components. For
> newer platforms, the *HIL* will be much simpler because the API contract
> and their *HAL* abstractions are tightly related. On the other extreme,
> the cost of boosting up (in software) the capabilities of the old
> platforms will rise.
> 
> Since we expect *HIL* interfaces to evolve as new platforms are
> designed, we must determine when the overhead of software emulation of
> hardware features can no longer be sustained.  At this point, we
> introduce *versioning* of *HIL* interfaces.  By assigning a version
> number to each iteration of an *HIL* interface, we can design
> applications using a legacy interface to be compatible with previously
> deployed devices.  This is important for WSNs since they execute
> long-running applications and may be deployed for years.  An *HIL* MAY
> also branch, providing multiple different *HIL* interfaces with
> increasing levels of functionality.
> 
> 
> Selecting the level of abstraction
> ----------------------------------
> 
> The platform-dependence of the *HAL* in the architecture leads to the
> more general question about why we have opted for a three-layered
> design. In other words, why we do not expose the platform-independent
> hardware interface directly from the *HAL* components. The main reason
> behind this decision is the increased *flexibility* that arises from
> separating the platform-specific abstractions and the adaptation
> wrappers that upgrade or downgrade them to the current
> platform-independent interface.  In this way, for maximum performance,
> the platform specific applications can circumvent the *HIL* components
> and directly tap to the *HAL* interfaces that provide access to the full
> capabilities of the hardware module.
> 
> Selecting the "right" level--whether an application should use the *HIL*
> or directly access the *HAL*--can sometimes cause one hardware asset to
> be accessed using two levels of abstraction from different parts of
> the application or the OS libraries.
> 
> Let us take an application similar to the standard OscilloscopeRF
> application in TinyOS as an example.  The application uses the ADC to
> sample several values from a temperature sensor and sends them in the
> form of a message over the radio.  If the observed phenomenon does not
> have a large signal bandwidth and the time between subsequent
> conversions is long, for the sake of cross-platform compatibility, the
> programmer might decide to use the standard ``ADCSingle``
> interface. This interface is exported by the *HIL* sensor wrapper
> (Fig.2_) using the services of the platform-specific *HAL*
> component. When enough samples are collected in the message buffer,
> the application passes the message to the networking stack.  The MAC
> protocol used for message exchange over the radio uses clear channel
> assessment to determine when it is safe to send the message. This
> usually requires taking several samples of the RSSI signal provided by
> the radio hardware. Since this is a very time critical operation in
> which the correlation between the consecutive samples has a
> significant influence, the programmer of the MAC might directly use
> the ``MSP430ADC12Multiple`` interface of the *HAL* component as it
> provides much finer control over the conversion process.
> 
> .. _Fig.2:
> 
> ::
> 
> 
>      StdControl                        
>             | ADCSingle            
>             |    |  ADCMultiple                 
>             |    |    |                             
>      +------|----|----|------------------------------------------+
>      |      |    |    |                            Temperature   |
>      |      v    v    v                                          |  
>      | +--------------------+ MSP430ADC12Single   +------------+ |
>      | |   TemperatureM     |-------------------->|MSP430ADC12C| |
>      | |                    | MSP430ADC12Multiple |            | |
>      | |                    |-------------------->|            | |
>      | +--------------------+                     +------------+ |
>      +-----------------------------------------------------------+
>  
>                 Fig.2: The ADC HIL sensor wrapper
> 
> 
> As a result of this chain of decisions, we end up with a concurrent
> use of the ADC hardware module using two different levels of
> abstraction. To support this type of "vertical" flexibility we include
> more complex arbitration and resource control functionality in the *HAL*
> components so that a safe shared access to the *HPL* exported resources
> can be guaranteed.
> 
> 
> Reference
> =========
> 
> The proposed HAA was applied for the first time during the
> implementation of the `MSP430 platform`_ that abstracts the
> capabilities of the TI MSP430 microcontroller in `TinyOS 1.1.7`_. The
> implementation is currently being used by four hardware platforms
> (TelosA, TelosB, eyesIFX and eyesIFXv2) and has quite successfully
> satisfied the requirements of a large range of applications.
> 
> In the following we illustrate the properties of the proposed
> architecture using real-world examples from the planned hardware
> abstraction functionality in TinyOS 2.0.
> 
> 
> Processing unit
> ---------------
> 
> In TinyOS most of the variability between the processing units is
> hidden from the OS simply by using a nesC/C based programming language
> with a common compiler suite (GCC). For example, the standard library
> distributed with the compiler creates the necessary start-up code for
> initializing the global variables, the stack pointer and the interrupt
> vector table, shielding the OS from these MCU-specific tasks.
> 
> To unify things further, TinyOS provides mechanisms for declaring
> reentrant and non-reentrant interrupt service routines and critical
> code-sections.  For the MCU's external pins, it provides macros that
> permit setting and clearing the pin, as well as changing its direction
> and function.  For example, the TI~MSP430's ADC pins may be used as
> either general I/O or as an analog input to the ADC hardware module.
> Macros are also provided for timed spin loops at microsecond
> resolution, independent of the microcontroller. These macros are
> defined in each platform's ``hardware.h`` descriptor file. Finally,
> the *HPL* components deal with the different ways of accessing
> registers (memory-mapped or port-mapped I/O) using the definitions in
> the standard library header files.
> 
> The three-layer architecture is not intended to abstract the features
> of the different MCU cores. For the currently supported MCUs, the
> combination of the compiler suite support with the thin abstraction in
> the ``hardware.h`` files is sufficient. Nevertheless, if new cores
> with radically different architectures need to be supported by TinyOS
> in the future, this part of the hardware abstraction functionality
> will have to be explicitly addressed.
> 
> 
> Power management
> ----------------
> 
> On both the MSP430 and the Atmel, before entering a sleep mode, a
> component checks if any hardware modules require that the MCU core is
> active.  Additionally, all services including *HPL* and *HAL*
> components have a start and stop function.  When a service is no
> longer using a hardware module, it may call the stop function of the
> *HPL* or *HAL* component.  Doing so disables the module for power
> savings, but also removes the MCU's dependence on that hardware module
> to enter sleep mode.  For example, the ADC module may be clocked from
> a high speed oscillator.  When a sample is not in progress, the ADC
> module may be shut down and it will no longer use the high speed
> oscillator.  As a result, when the MCU is idle, it may enter low power
> mode.
> 
> This rather efficient way of implementing the power management
> functionality is made possible by the fact that most of the hardware
> modules are on-chip, attached directly to the MCU system bus, and that
> there is no hardware memory protection hindering the access to their
> status registers. As TinyOS platforms add more external devices
> connected via the peripheral buses, this task will get increasingly
> complicated.  Ultimately, keeping some state in the form of device
> enumeration or reference counting mechanisms might be needed for
> proper power management.
> 
> 
> Clocks and timers
> -----------------
> 
> The application of the HAA for abstracting the clock and timer
> modules is documented in [TEP102]_.
> 
> 
> Analog-to-digital converters
> ----------------------------
> 
> The application of the HAA for abstracting the analog-to-digital
> converter modules is documented in [TEP101]_.
> 
> Data busses
> -----------
> 
> The *HPL* functionality for the data busses includes two paths--one
> for data and a second for control. The control path allows the clock
> source, prescaler, and baud rate to be set. Interrupts may be enabled
> or disabled and various hardware flags may be read, set, or cleared,
> useful for polling or blocking implementations. Through the control
> path, the entire module may be started or stopped for power control.
> The data interface simply consists of sending and receiving a byte
> through the hardware's data registers, as well as interrupt based
> reporting of received data. Here is an example of the interfaces used
> in the MSP430 platform::
> 
>   interface HPLUSARTControl {
>     async command void enableUART();
>     async command void disableUART();
>     async command void enableUARTTx();
>     async command void disableUARTTx();
>     async command void enableUARTRx();
>     async command void disableUARTRx();
>     async command void enableSPI();
>     async command void disableSPI();
>     async command void setModeSPI();
>     async command void setModeUART_TX();
>     async command void setModeUART_RX();
>     async command void setModeUART();
>     async command void setClockSource(
>           uint8_t source);
>     async command void setClockRate(
>           uint16_t baudrate, uint8_t mctl);
>     async command result_t disableRxIntr();
>     async command result_t disableTxIntr();
>     async command result_t enableRxIntr();
>     async command result_t enableTxIntr();
>     async command result_t isTxIntrPending();
>     async command result_t isRxIntrPending();
>     async command result_t isTxEmpty();
>     async command result_t tx(uint8_t data);
>     async command uint8_t rx();
>   }
> 
>   interface HPLUSARTFeedback {
>     async event result_t txDone();
>     async event result_t rxDone(uint8_t data);
>   }
> 
> Sometimes functionality for more than one bus protocol are supported
> through a single hardware module. In these cases, wrappers for each
> bus provide standard application interfaces for using the bus.
> Sharing the bus amongst different hardware devices or protocols may be
> done through a bus arbitration component. Bus arbitration allows
> higher level services to attain exclusive use of the bus, complete its
> operations, and then release the bus to the next service::
> 
>   interface BusArbitration {
>     async command result_t getBus();
>     async command result_t releaseBus();
>     event result_t busFree();
>   }
> 
> 
> External storage
> ----------------
> 
> The application of the HAA for abstracting the external storage
> modules is documented in [TEP103]_.
> 
> 
> Radios
> ------
> 
> The application of the HAA for abstracting the radio modules is
> documented in [TEP104]_ and [TEP105]_.
> 
> 
> Conclusion
> ==========
> 
> The referenced TEPs in the previous section show that the three-layer
> design can be successfully used for exposing to the applications the
> functionality of the main hardware modules. The proposed architecture
> provides a set of core services that eliminate duplicated code and
> provide a coherent view of the system across different architectures
> and platforms. It supports the concurrent use of platform-independent
> and the platform-dependent interfaces in the same application. In this
> way, applications can localize their platform dependence to only the
> places where performance matters, while using standard cross-platform
> hardware interfaces for the remainder of the application.
> 
> 
> Author's Address
> ================
> 
> | Vlado Handziski (handzisk at tkn.tu-berlin.de) [1]_ 
> | Joseph Polastre (polastre at cs.berkeley.edu) [2]_ 
> | Jan-Hinrich Hauer (hauer at tkn.tu-berlin.de) [1]_
> | Cory Sharp (cssharp at eecs.berkeley.edu) [2]_
> | Adam Wolisz (awo at ieee.org) [1]_
> | David Culler (culler at eecs.berkeley.edu) [2]_
> 
> 
> .. [1] Technische Universitaet Berlin   
>        Telecommunication Networks Group                    
>        Sekr. FT 5, Einsteinufer 25                        
>        10587 Berlin, Germany           
> 
> .. [2] University of California, Berkeley
>        Computer Science Department                
>        Berkeley, CA 94720 USA
> 
> Citations
> =========
> 
> .. [HAA2005] V. Handziski, J.Polastre, J.H.Hauer, C.Sharp,
>    A.Wolisz and D.Culler, "Flexible Hardware Abstraction for Wireless
>    Sensor Networks", in *Proceedings of the 2nd European Workshop on
>    Wireless Sensor Networks (EWSN 2005)*, Istanbul, Turkey, 2005.
> 
> .. _MSP430 platform: http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/tos/platform/msp430/
> 
> .. _TinyOS 1.1.7: http://www.tinyos.net/scoop/section/Releases
> 
> .. [TEP1] P. Levis, "TEP structure and key words" 
>    
> .. [TEP101] J.H. Hauer, V. Handziski, J. Polastre, L. Nachman, 
>    "Analog-to-digital Converter Abstraction"
> 
> .. [TEP102] C. Sharp, "Clock and Timers Abstraction"
> 
> .. [TEP103] D. Gay, J. Hui, "Non-volatile Storage Abstraction"
> 
> .. [TEP104] K. Klues, "Radio Hardware Abstraction"
> 
> .. [TEP105] J. Polastre, "Link Layer Primitives in TinyOS"
> 
> ..
>    Local Variables:
>    mode: indented-text
>    indent-tabs-mode: nil
>    sentence-end-double-space: t
>    fill-column: 70
>    End:
> 
> 
> ------------------------------------------------------------------------
> 
> ======================================================================
> Power Management of Non-Virtualised Devices
> ======================================================================
> 
> :TEP: 115
> :Group: Core Working Group
> :Type: Documentary
> :Status: Draft
> :TinyOS-Version: 2.x
> :Author: Kevin Klues, Vlado Handziski, Jan-Hinrich Hauer, Phil Levis
> 
> :Draft-Created: 11-Jan-2006
> :Draft-Version: $Revision: 1.6 $
> :Draft-Modified: $Date: 2007/02/01 17:44:49 $
> :Draft-Discuss: TinyOS Developer List 
>                 <tinyos-devel at mail.millennium.berkeley.edu>
> 
> .. Note::
> 
>    This memo documents a part of TinyOS for the TinyOS Community, and
>    requests discussion and suggestions for improvements.  Distribution
>    of this memo is unlimited. This memo is in full compliance with TEP
>    1.
> 
> Abstract
> ======================================================================
> 
> This memo documents how TinyOS 2.x manages the power state of physical
> (not virtualised) abstractions.
> 
> 1. Introduction
> ======================================================================
> 
> The energy resources on a typical TinyOS platform are limited, so
> every effort should be made to put all devices on a given platform
> into their lowest possible power state as often as
> possible. Depending on the device type, selecting the correct
> power state could be as simple as switching between on and
> off states, or involve selecting the optimum state from among
> several. Choosing the best possible power state requires making
> tradeoffs between various factors such as power consumption, fidelity,
> performance, and wake-up latency.
> 
> Unfortunately, it is not feasible do design a unified one size-fits-all power
> management strategy for use by all types of devices. Some devices 
> (particularly microcontollers) have direct access to internal registers that 
> allow them to efficiently calculate their lowest possible power state
> very quickly.  Other devices do not have this information readily available and 
> would have to calculate it on the fly if other mechanisms were not in place to 
> prevent this.  Designing a general system wide power control algorithm to handle 
> all such devices would most likely be overly complex and in some cases even 
> suboptimal. TinyOS 2.x, therefore, takes the approach of defining two different
> classes of devices for which different power-management strategies have been 
> optimized: microcontrollers and peripheral devices. As opposed to microcontrollers, 
> which normally contain a number of different valid power states, peripheral devices 
> tend to have only two distinct states they can be switched to (*on* and *off*).  Even 
> in the rare case where a device of this type happens to contain multiple power 
> states, TinyOS has traditionally used just the two most useful power states and 
> designated them to mean either *on* or *off*.  This TEP is dedicated to 
> describing power management for peripheral devices of this type.  Details on the 
> mechanisms used to perform microcontroller power management can be found in [TEP112]_.
> 
> The term "peripheral device" specifically refers to any hardware device for which 
> the mechanisms described in [TEP108]_ can be used to provide resource arbitration
> for them.  These devices are considered *non-virtualised* in the sense that 
> access to them must be explicitly requested and released by higher level
> components wishing to use them.  Various policies can be implemented on top of 
> this class of devices to decide exactly when they should be powered on or off.
> The simplest policy involves leaving it up to the programmer
> to ensure that a device is switched on or off whenever it should be. 
> Other policies involve automatically powering a device up or down
> by monitoring whether any clients are currently connected to it 
> or not.  Depending on the type of power management policy desired, 
> different models should be followed when designing drivers for devices
> of this class.
> 
> 2. Power Management Models
> ======================================================================
> 
> In order to support both manual and automatic power management of 
> non-virtualised devices in TinyOS, two different power management models have 
> been defined: *explicit power management* and *implicit power management*.  
> 
> The *explicit power management* model provides a means for a single 
> client to manually control the power state of a dedicated physical device 
> (as defined by [TEP108]_).  Whenever this client tells the device to
> power up or down it does so without delay.  This model can be
> particularly useful when the control information driving the selection
> of the proper power state of a device relies on external logic contained in 
> higher level components.  The following section discusses the ``StdControl``, 
> ``SplitControl``, and ``AsyncStdControl`` interfaces used to perform power 
> management of this type.  
> 
> The *implicit power management* model, on the other hand, provides a
> means for allowing the power state of a device to be controlled from
> within the driver for that device itself.  Device drivers following 
> this model are never explicitly powered up or down by some external 
> client, but rather *require* some internal policy to be defined that 
> decides exactly when their power states should be changed.  This policy 
> could exist natively on the hardware of the physical device itself, or 
> be implemented on top of some lower level abstraction of a physical 
> device adhering to the *explicit power management* model.
> 
> For shared devices (as defined by [TEP108]_), the information required to
> determine if a device's clients require it to be powered on or not can
> be inferred through the set of interfaces they provide.
> Because of this fact, no StdControl-like interface needs to be provided 
> to any higher level components, and the *implicit power management* policy 
> in use can act accordingly whenever clients request or release the device.
> Section 4.2 discusses this in more detail.::
> 
> 
>                  /|\                                    /|\
>                   |                                      |
>             Data Interface                            Resource
>                   |                                      |  
>   -----------------------------------------------------------------------
>   |             Shared Device (implicitly power managed)                |
>   -----------------------------------------------------------------------
>                  /|\                                    /|\
>                   |                                      |
>             Data Interface                            Resource
>                   |                                      |
>                   |        ----------------------        |
>                   |        |    Power Manager   |        |
>                   |        ----------------------        |
>                   |          /|\            /|\          |
>                   |           |              |           |
>                   |      StdControl ResourceDefaultOwner |
>                   |           |              |           |
>   ---------------------------------      --------------------------------
>   |        Dedicated Device       |      |            Arbiter           |
>   |  (explicitly power managed)   |      |                              |
>   ---------------------------------      --------------------------------
>       
> 
> 3. Explicit Power Management 
> ======================================================================
> 
> Just as in TinyOS 1.x, ``StdControl`` and ``SplitControl`` interfaces have
> been defined for TinyOS 2.x in order to control the on and off power
> states of devices adhering to the *explicit power management* model.
> A third interface called ``AsyncStdControl`` has also been introduced
> for components in which it is critical to have the ability to power
> them on or off while running in asynchronous context. One of these
> three interfaces MUST be provided by components wrapping a hardware
> device that supports switching between the devices on and off power
> states. The selection of the right interface depends on the latencies
> involved in changing between these two states as well as the nature of
> the code (sync or async) executing any of the interfaces commands.
> 
> 3.1 Power Management with ``StdControl``
> ----------------------------------------------------------------------
> 
> Whenever the powerup and powerdown times of a non-virtualised device
> are negligible, they SHOULD provide the ``StdControl`` interface as 
> defined below::
> 
>    interface StdControl {
>      command error_t start();
>      command error_t stop();
>    }
>    
> .. Note::
>    
>   Powerup and powerdown times on the order of a few microseconds have 
>   traditionally been considered negligible, and can be waited on using one of the 
>   *BusyWait* interfaces described in [TEP102]_.  Powerup and powerdown
>   times on the order of a few milliseconds, however, should not be
>   ignored, and MUST be hidden behind the use of the ``SplitControl`` interface
>   described later on in this section. 
> 
> An external component MUST call ``StdControl.start()`` to power a
> device on and ``StdControl.stop()`` to power a device off.  Calls to
> either command MUST return either SUCCESS or FAIL. 
> 
> Upon the successful return of a call to ``StdControl.start()``, a
> device MUST be completely powered on, allowing calls to commands of other
> interfaces implemented by the device to succeed.
> 
> Upon the successful return of a call to ``StdControl.stop()``, a
> device MUST be completely powered down, and any calls to commands 
> of other interfaces implemented by that device MUST return FAIL or EOFF.
> 
> If a device is not able to complete the ``StdControl.start()`` or
> ``StdControl.stop()`` request for any reason, it MUST return FAIL.
> 
> Based on these specifications, the following matrix has been created
> to describe the valid return values for any call made through the
> ``StdControl`` interface in one of the devices valid power states:
> 
> +---------------------+-----------------+-----------------+
> | Call                | Device On       | Device Off      |
> +=====================+=================+=================+
> | StdControl.start()  | SUCCESS         | SUCCESS or FAIL |
> +---------------------+-----------------+-----------------+
> | StdControl.stop()   | SUCCESS or FAIL | SUCCESS         |
> +---------------------+-----------------+-----------------+
> | operation           | depends         | FAIL or EOFF    |
> +---------------------+-----------------+-----------------+
> 
> Devices providing this interface would do so as shown below::
> 
>    configuration DeviceC {
>      provides {
>        interface Init;
>        interface StdControl;  //For Power Management
>        ....
>      }
>    }
> 
> 
> 3.2 Power Management with ``SplitControl``
> ----------------------------------------------------------------------
> 
> When a device's powerup and powerdown times are non-negligible, the
> *``SplitControl``* interface MUST be used in place of the *``StdControl``*
> interface.  The definition of this interface can be seen below::
> 
>    interface SplitControl {
>      command error_t start();
>      event void startDone(error_t error);
>      command error_t stop();
>      event void stopDone(error_t error);
>    }
>    
> 
> An external component MUST call ``SplitControl.start()`` to power a
> device on and ``SplitControl.stop()`` to power a device off.  Calls to
> either command return one of SUCCESS or FAIL.
> 
> Successful calls to ``SplitControl.start()`` MUST signal one of
> ``SplitControl.startDone(SUCCESS)`` or ``SplitControl.startDone(FAIL)``.
> 
> Successful calls to ``SplitControl.stop()`` MUST signal one of
> ``SplitControl.stopDone(SUCCESS)`` or ``SplitControl.stopDone(FAIL)``.
> 
> Upon signaling a ``SplitControl.startDone(SUCCESS)``, a device MUST
> be completely powered on, and operation requests through calls to commands 
> of other interfaces implemented by the device MAY succeed.  
> 
> Upon signalling a ``SplitControl.stopDone(SUCCESS)``, a device MUST be 
> completely powered down, and any subsequent calls to commands of other 
> interfaces implemented by the device MUST return EOFF or FAIL.
> 
> If a device is powered on and a successful call to ``SplitControl.stop()``
> signals a ``SplitControl.stopDone(FAIL)``, the device MUST still be fully 
> powered on, and operation requests through calls to commands of other 
> interfaces implemented by the device MAY succeed.
> 
> If a device is powered down and a successful call to ``SplitControl.start()`` 
> signals a ``SplitControl.startDone(FAIL)``, the device MUST still be fully 
> powered down, and operation requests through calls to commands of other 
> interfaces implemented by the device MUST return EOFF or FAIL.
> 
> If a device is not able to complete the ``SplitControl.start()`` or
> ``SplitControl.stop()`` requests for any reason, they MUST return
> FAIL.
> 
> Calls to either ``StdControl.start()`` or ``StdControl.stop()`` while
> a start or stop operation is pending MUST return SUCCESS, with the 
> anticipation that a corresponding ``StdControl.startDone()`` or 
> ``StdControl.stopDone()`` will be signaled in the future.
> 
> +----------------------+-----------+------------+----------+----------+ 
> | Call                 | Device On | Device Off | Starting | Stopping |
> +======================+===========+============+==========+==========+
> | SplitControl.start() |  SUCCESS  |  SUCCESS   | SUCCESS  | SUCCESS  |
> |                      |           |  FAIL      |          |          |
> +----------------------+-----------+------------+----------+----------+
> | SplitControl.stop()  |  SUCCESS  |  SUCCESS   | SUCCESS  | SUCCESS  |
> |                      |  FAIL     |            |          |          |
> +----------------------+-----------+------------+----------+----------+
> | operation            |  depends  |  FAIL      | FAIL     | FAIL     |
> |                      |           |  EOFF      | EOFF     | EOFF     |
> |                      |           |  EOFF      | SUCCESS  |          |
> +----------------------+-----------+------------+----------+----------+
> 
> Devices providing this interface would do so as shown below::
> 
>    configuration DeviceC {
>      provides {
>        interface Init;
>        interface SplitControl; \\ For Power Management
>        ....
>      }
>    }
> 
> 
> 3.3 Power Management with ``AsyncStdControl`` 
> ----------------------------------------------------------------------
> 
> The commands and the events of the *``StdControl``* and the *``SplitControl``*
> interfaces are synchronous and can not be called from within
> asynchronous code (such as interrupt service routines, etc.). For the
> cases when the power state of the device needs to be controlled from
> within asynchronous code, the *``AsyncStdControl``* interface MUST be used
> in place of the *``StdControl``* interface.  The definition of this
> interface can be seen below::
> 
>    interface AsyncStdControl {
>      async command error_t start();
>      async command error_t stop();
>    }
>    
> 
> All of the semantics that hold true for devices providing the
> ``StdControl`` interface also hold for this interface.
>    
> Devices providing this interface would do so as shown below::
> 
>    configuration DeviceC {
>      provides {
>        interface Init;
>        interface AsyncStdControl; \\ For Power Management
>        ....
>      }
>    }
>    
> .. Note::
> 
>   The ``AsyncStdControl`` interface should be provided whenever it might be
>   necessary to allow a device to be powered on or off while running in 
>   async context.  If it is anticipated that a device *will* not (or more 
>   likely *should* not) be powered on or off while in asynchronous context,
>   then the ``StdControl`` interface SHOULD be provided instead.  Components 
>   that wish to power the device on or off from within async context would
>   then be required to post a task before doing so.  In practice, 
>   ``AsyncStdControl`` is provided by low-level hardware resources, while 
>   ``StdControl`` is provided by higher level services built on top of these 
>   resources.
> 
> 
> 4. Implicit Power Management
> ======================================================================
> 
> While the *explicit power management* model provides the basic means
> for controlling the power state of a device, it is void of any
> policy about when, or how the power state of the device should be changed.
> This does not represent a large problem for the simple case
> of *dedicated* devices, but can become crucial for non-trivial cases 
> involving complex interdependencies between devices controlled by multiple 
> clients.
> 
> For example, if component *A* is a client of both component *B* 
> and component *C*, what happens with *B* and *C* if
> ``StdControl.stop()`` is called on component *A* ? Should components
> *B* and *C* also be stopped?  What about the reverse case where both 
> *B* and *C* are clients of the single shared component, *A*?  If 
> devices *B* and *C* are shut off, should *A* be shut off as well?  
> How can one decide when it is appropriate to cascade such powerup
> and powerdown requests?
> 
> The complex nature of the problem is evident from the number of
> unexpected behaviors in TinyOS 1.x involving ``StdControl``. On several
> platforms, one of the SPI buses is shared between the radio and the
> flash device. On some of them, issuing ``StdControl.stop()`` on the
> radio results in a series of cascaded calls that result in SPI bus 
> becoming disabled, rendering the communication with the flash impossible. 
> Of course, the right policy would involve tracking the clients of the 
> SPI bus and powering it off only once both the radio and the flash 
> devices were no longer using it. Conversely, the SPI bus should be
> powered on whenever there is at least one active client.
> 
> The selection of the right power management policy to use is a complex 
> task that depends on the nature of the devices in use, their 
> interdependency, as well as on any specific application requirements. 
> For cases when some of these features are known a-priori or are 
> restricted in some sense, it is preferable that the system provide 
> architectural support for enforcing a meaningful *default* power-management 
> policy instead of passing that task on to the application programmer to be 
> solved on a case-by-case basis.
> 
> 
> 4.1. Power Management Policies
> ----------------------------------------------------------------------------
> 
> Just as generic arbiters are offered in TinyOS 2.x to provide the arbitration 
> functionality required by shared resources, generic power management policies are
> also offered to allow the power management of non-virtualised devices to 
> be automatically control.  
> 
> Through the use of the arbiter components described in [TEP108]_, device
> drivers implemented as shared resources provide the type of restricted 
> resource interdependency where default power-management policies can be offered.
> The shared resource class defined in Section 2.3 of [TEP108]_, provides a 
> well defined component interdependency, where a single resource is shared 
> among multiple clients. This relationship enables the definition of 
> default power-management policies that can be used to automatically power
> the resource on and off.
> 
> The *Power Manager* component implementing one of these polices acts as
> the *default owner* of the shared resource device and interacts with it
> through the use of the ResourceDefaultOwner interface::
> 
>   interface ResourceDefaultOwner {
>     async event void granted();
>     async command error_t release();
>     async command bool isOwner();
>     async event void requested();
>     async event void immediateRequested();
>   }
>     
> Acting as the default owner, the *Power Manager* waits for the
> ``ResourceDefaultOwner.granted()`` event to be signaled in order to
> gain ownership over the resource device.
> 
> Once it owns the device, the *Power Manager* is free to execute its
> power-management policy using the StdControl-like interface provided by the 
> underlying resource. Different power managers can implement different 
> policies. In the simplest case, this would involve an immediate power-down
> via one of the ``stop()`` commands. When the power-state transition 
> involves non-negligible costs in terms of wake-up latency or power 
> consumption, the *PowerManager* might revert to a more intelligent 
> strategy that tries to reduce these effects. As pointed out in the 
> introduction, one such strategy might involve the use of a timer to defer 
> the power-down of the resource to some later point in time, giving any 
> resource clients a window of opportunity to put in requests before the 
> device is fully shut down.
> 
> Regardless of the power management policy in use, the *Power Manager* 
> remains owner of the resource as long as the resource is not requested 
> by one of its clients.  Whenever a client puts in a request, the
> *Power Manager* will receive a ``ResourceDefaultOwner.requested()`` event 
> (or ``immediateRequested()`` event) from the arbiter it is associated with. 
> Upon receiving this event, the *Power Manager* MUST power up the 
> resource through the StdControl-like interface provided by the lower level
> abstraction of the physical device. The *Power Manager* SHOULD release the
> ownership of the resource (using the ``ResourceDefaultOwner.release()``
> command) but MUST wait until after the resource has been fully powered on 
> before doing so.
> 
> Modeling devices as shared resources and allowing them to be
> controlled in the way described here, solves the problems outlined in
> section 3 regarding how to keep track of when and how the
> powerdown of nested resources should proceed.  The *Power Manager*
> component answers the question of how, and the combination of the power
> management policy being used and the reception of the
> ``ResourceDefaultOwner.granted()`` and ``ResourceDefaultOwner.requested()``
> events answers the question of when.  As long as the resource at
> the bottom of a large set of nested resource clients has been fully released,
> the power mananger will be able to power down the resource appropriately.
> 
> Using the model described above, a resource that uses one of these policies 
> according to the *implicitly power management* model could be built as shown below::
> 
>   module MyFlashP {
>     provides {
>       interface Init;
>       interface SplitControl;
> 	  interface Resource;
> 	  interface FlashCommands;
> 	  ...
>     }
>   }
>   implementation {
>     ...
>   }     
> 
>   generic module PowerManagerC(uint8_t POWERDOWN_DELAY) {
>     provides {
> 	  interface Init;
>     }
>     uses {
> 	  interface SplitControl;
> 	  interface ResourceDefaultOwner;
>     }
>   }
>   implementation {
>     ...
>   }
> 
>   #define MYFLASH_RESOURCE "MyFlash.resource"
>   #define MYFLASH_POWERDOWN_DELAY	1000
>   configuration MyFlashC {
>     provides {
> 	  interface Init;
> 	  interface Resource;
> 	  interface FlashCommands;
>     }
>   }
>   implementation {
>     components new PowerManagerC(MYFLASH_POWERDOWN_DELAY)
> 	, FcfsArbiter(MYFLASH_RESOURCE)
> 	, MyFlashP;
> 
>     Init = MyFlashP;
>     Resource = FcfsArbiter; 
>     FlashCommands = MyFlashP;
> 
>     PowerManagerC.ResourceDefaultUser -> FcfsArbiter;
>     PowerManagerC.SplitControl -> MyFlashP;
>     
>   }
>      
> 
> This example implementation is built out of three components.  The
> first component (``MyFlashP``) follows the *explicit power management*
> model for defining the interfaces to the physical flash device.  The
> second component (``PowerManagerC``) is the generic *Power Manager*
> component that will be used to implement the specific power management
> policy for this device.  The third component (``MyFlashC``) is the
> configuration file that wires together all of the components required
> by the implementation of of the device as it adheres to the *implicit power
> management* model.  It includes the ``MyflashP`` and ``PowerManagerC``
> components, as well as an arbiter component for managing shared clients
> of the device.  Notice how the *Power Manager* is wired to both the
> ``ResourceDefaultUser`` interface provided by the arbiter, and the
> ``SplitControl`` interface provided by the flash.  All clients of this flash 
> device are directly connected to the resource interface provided by
> the arbiter.  As outlined above, the ``PowerManagerC`` component will use
> the events signaled through the ``ResourceDefaultUser`` interface to determine 
> when to make calls to power the device up and power it down through
> the ``SplitControl`` interface.
> 
> 
> 4.2. Example Power Managers: PowerManagerC and DeferredPowerManagerC
> ----------------------------------------------------------------------------
> 
> TinyOS 2.x currently has two default power management policies
> that it provides.  These policies are implemented by the various 
> components located under tinyos-2.x/lib/power. The first policy 
> is implemented using an *immediate* power control scheme, whereby
> devices are powered on and off immediately after they have been
> requested and released.  The second policy is implemented using
> a *deferred* power control scheme, whereby devices are powered 
> on immediately after being requested, but powered off after
> some small delay from being released.  
> 
> Each policy has three different implementations for use by each of 
> the ``StdControl``, ``SplitControl``, and ``AsyncStdControl``
> interfaces.
> 
> For reference, each of the available components are listed below
> 
> Immediate Power Management:
>  - ``StdControlPowerManagerC``
>  - ``SplitControlPowerManagerC``
>  - ``AsyncStdControlPowerManagerC``
>  
> Deferred Power Management:
>  - ``StdControlDeferredPowerManagerC``
>  - ``SplitControlDeferredPowerManagerC``
>  - ``AsyncStdControlDeferredPowerManagerC``
>  
> 
> 5. Author's Address
> ====================================================================
> | Kevin Klues
> | 503 Bryan Hall
> | Washington University
> | St. Louis, MO 63130
> |
> | phone - +1-314-935-6355
> | email - klueska at cs.wustl.edu
> |
> | Vlado Handziski
> | Sekr FT5
> | Einsteinufer 25
> | 10587 Berlin
> | GERMANY
> |
> | phone - +49 30 314 23831
> | email - handzisk at tkn.tu-berlin.de
> |
> | Jan-Hinrich Hauer
> | Sekr FT5
> | Einsteinufer 25
> | 10587 Berlin
> | GERMANY
> |
> | phone - +49 30 314 23813
> | email - hauer at tkn.tu-berlin.de
> |
> | Philip Levis
> | 358 Gates Hall
> | Stanford University
> | Stanford, CA 94305-9030
> |
> | phone - +1 650 725 9046
> | email - pal at cs.stanford.edu 
> 
> 6. Citations
> ====================================================================
> 
> .. [TEP102] TEP 102: Timers.
> .. [TEP108] TEP 108: Resource Arbitration.
> .. [TEP112] TEP 112: Microcontroller Power Management.
> 
> 
> 
> ------------------------------------------------------------------------
> 
> 
>   Power Management of Non-Virtualised Devices
> 
> TEP:	115
> Group:	Core Working Group
> Type:	Documentary
> Status: 	Draft
> TinyOS-Version:	2.x
> Author: 	Kevin Klues, Vlado Handziski, Jan-Hinrich Hauer, Phil Levis
> Draft-Created:	11-Jan-2006
> Draft-Version:	1.5
> Draft-Modified:	2006-12-12
> Draft-Discuss:	TinyOS Developer List <tinyos-devel at 
> mail.millennium.berkeley.edu>
> 
> Note
> 
> This memo documents a part of TinyOS for the TinyOS Community, and 
> requests discussion and suggestions for improvements. Distribution of 
> this memo is unlimited. This memo is in full compliance with TEP 1.
> 
> 
>   Abstract
> 
> This memo documents how TinyOS 2.x manages the power state of physical 
> (not virtualised) abstractions.
> 
> 
>   1. Introduction
> 
> The energy resources on a typical TinyOS platform are limited, so every 
> effort should be made to put all devices on a given platform into their 
> lowest possible power state as often as possible. Depending on the 
> device type, selecting the correct power state could be as simple as 
> switching between on and off states, or involve selecting the optimum 
> state from among several. Choosing the best possible power state 
> requires making tradeoffs between various factors such as power 
> consumption, fidelity, performance, and wake-up latency.
> 
> Unfortunately, it is not feasible do design a unified one size-fits-all 
> power management strategy for use by all types of devices. Some devices 
> (particularly microcontollers) have direct access to internal registers 
> that allow them to efficiently calculate their lowest possible power 
> state very quickly. Other devices do not have this information readily 
> available and would have to calculate it on the fly if other mechanisms 
> were not in place to prevent this. Designing a general system wide power 
> control algorithm to handle all such devices would most likely be overly 
> complex and in some cases even suboptimal. TinyOS 2.x, therefore, takes 
> the approach of defining two different classes of devices for which 
> different power-management strategies have been optimized: 
> microcontrollers and peripheral devices. As opposed to microcontrollers, 
> which normally contain a number of different valid power states, 
> peripheral devices tend to have only two distinct states they can be 
> switched to (/on/ and /off/). Even in the rare case where a device of 
> this type happens to contain multiple power states, TinyOS has 
> traditionally used just the two most useful power states and designated 
> them to mean either /on/ or /off/. This TEP is dedicated to describing 
> power management for peripheral devices of this type. Details on the 
> mechanisms used to perform microcontroller power management can be found 
> in [TEP112] <#tep112>.
> 
> The term "peripheral device" specifically refers to any hardware device 
> for which the mechanisms described in [TEP108] <#tep108> can be used to 
> provide resource arbitration for them. These devices are considered 
> /non-virtualised/ in the sense that access to them must be explicitly 
> requested and released by higher level components wishing to use them. 
> Various policies can be implemented on top of this class of devices to 
> decide exactly when they should be powered on or off. The simplest 
> policy involves leaving it up to the programmer to ensure that a device 
> is switched on or off whenever it should be. Other policies involve 
> automatically powering a device up or down by monitoring whether any 
> clients are currently connected to it or not. Depending on the type of 
> power management policy desired, different models should be followed 
> when designing drivers for devices of this class.
> 
> 
>   2. Power Management Models
> 
> In order to support both manual and automatic power management of 
> non-virtualised devices in TinyOS, two different power management models 
> have been defined: /explicit power management/ and /implicit power 
> management/.
> 
> The /explicit power management/ model provides a means for a single 
> client to manually control the power state of a dedicated physical 
> device (as defined by [TEP108] <#tep108>). Whenever this client tells 
> the device to power up or down it does so without delay. This model can 
> be particularly useful when the control information driving the 
> selection of the proper power state of a device relies on external logic 
> contained in higher level components. The following section discusses 
> the StdControl, SplitControl, and AsyncStdControl interfaces used to 
> perform power management of this type.
> 
> The /implicit power management/ model, on the other hand, provides a 
> means for allowing the power state of a device to be controlled from 
> within the driver for that device itself. Device drivers following this 
> model are never explicitly powered up or down by some external client, 
> but rather /require/ some internal policy to be defined that decides 
> exactly when their power states should be changed. This policy could 
> exist natively on the hardware of the physical device itself, or be 
> implemented on top of some lower level abstraction of a physical device 
> adhering to the /explicit power management/ model.
> 
> For shared devices (as defined by [TEP108] <#tep108>), the information 
> required to determine if a device's clients require it to be powered on 
> or not can be inferred through the set of interfaces they provide. 
> Because of this fact, no StdControl-like interface needs to be provided 
> to any higher level components, and the /implicit power management/ 
> policy in use can act accordingly whenever clients request or release 
> the device. Section 4.2 discusses this in more detail.:
> 
>                /|\                                    /|\
>                 |                                      |
>           Data Interface                            Resource
>                 |                                      |
> -----------------------------------------------------------------------
> |             Shared Device (implicitly power managed)                |
> -----------------------------------------------------------------------
>                /|\                                    /|\
>                 |                                      |
>           Data Interface                            Resource
>                 |                                      |
>                 |        ----------------------        |
>                 |        |    Power Manager   |        |
>                 |        ----------------------        |
>                 |          /|\            /|\          |
>                 |           |              |           |
>                 |      StdControl ResourceDefaultOwner |
>                 |           |              |           |
> ---------------------------------      --------------------------------
> |        Dedicated Device       |      |            Arbiter           |
> |  (explicitly power managed)   |      |                              |
> ---------------------------------      --------------------------------
> 
> 
>   3. Explicit Power Management
> 
> Just as in TinyOS 1.x, StdControl and SplitControl interfaces have been 
> defined for TinyOS 2.x in order to control the on and off power states 
> of devices adhering to the /explicit power management/ model. A third 
> interface called AsyncStdControl has also been introduced for components 
> in which it is critical to have the ability to power them on or off 
> while running in asynchronous context. One of these three interfaces 
> MUST be provided by components wrapping a hardware device that supports 
> switching between the devices on and off power states. The selection of 
> the right interface depends on the latencies involved in changing 
> between these two states as well as the nature of the code (sync or 
> async) executing any of the interfaces commands.
> 
> 
>     3.1 Power Management with StdControl
> 
> Whenever the powerup and powerdown times of a non-virtualised device are 
> negligible, they SHOULD provide the StdControl interface as defined below:
> 
> interface StdControl {
>   command error_t start();
>   command error_t stop();
> }
> 
> Note
> 
> Powerup and powerdown times on the order of a few microseconds have 
> traditionally been considered negligible, and can be waited on using one 
> of the /BusyWait/ interfaces described in [TEP102] <#tep102>. Powerup 
> and powerdown times on the order of a few milliseconds, however, should 
> not be ignored, and MUST be hidden behind the use of the SplitControl 
> interface described later on in this section.
> 
> An external component MUST call StdControl.start() to power a device on 
> and StdControl.stop() to power a device off. Calls to either command 
> MUST return either SUCCESS or FAIL.
> 
> Upon the successful return of a call to StdControl.start(), a device 
> MUST be completely powered on, allowing calls to commands of other 
> interfaces implemented by the device to succeed.
> 
> Upon the successful return of a call to StdControl.stop(), a device MUST 
> be completely powered down, and any calls to commands of other 
> interfaces implemented by that device MUST return FAIL or EOFF.
> 
> If a device is not able to complete the StdControl.start() or 
> StdControl.stop() request for any reason, it MUST return FAIL.
> 
> Based on these specifications, the following matrix has been created to 
> describe the valid return values for any call made through the 
> StdControl interface in one of the devices valid power states:
> 
> Call 	Device On 	Device Off
> StdControl.start() 	SUCCESS 	SUCCESS or FAIL
> StdControl.stop() 	SUCCESS or FAIL 	SUCCESS
> operation 	depends 	FAIL or EOFF
> 
> Devices providing this interface would do so as shown below:
> 
> configuration DeviceC {
>   provides {
>     interface Init;
>     interface StdControl;  //For Power Management
>     ....
>   }
> }
> 
> 
>     3.2 Power Management with SplitControl
> 
> When a device's powerup and powerdown times are non-negligible, the 
> /``SplitControl``/ interface MUST be used in place of the 
> /``StdControl``/ interface. The definition of this interface can be seen 
> below:
> 
> interface SplitControl {
>   command error_t start();
>   event void startDone(error_t error);
>   command error_t stop();
>   event void stopDone(error_t error);
> }
> 
> An external component MUST call SplitControl.start() to power a device 
> on and SplitControl.stop() to power a device off. Calls to either 
> command return one of SUCCESS or FAIL.
> 
> Successful calls to SplitControl.start() MUST signal one of 
> SplitControl.startDone(SUCCESS) or SplitControl.startDone(FAIL).
> 
> Successful calls to SplitControl.stop() MUST signal one of 
> SplitControl.stopDone(SUCCESS) or SplitControl.stopDone(FAIL).
> 
> Upon signaling a SplitControl.startDone(SUCCESS), a device MUST be 
> completely powered on, and operation requests through calls to commands 
> of other interfaces implemented by the device MAY succeed.
> 
> Upon signalling a SplitControl.stopDone(SUCCESS), a device MUST be 
> completely powered down, and any subsequent calls to commands of other 
> interfaces implemented by the device MUST return EOFF or FAIL.
> 
> If a device is powered on and a successful call to SplitControl.stop() 
> signals a SplitControl.stopDone(FAIL), the device MUST still be fully 
> powered on, and operation requests through calls to commands of other 
> interfaces implemented by the device MAY succeed.
> 
> If a device is powered down and a successful call to 
> SplitControl.start() signals a SplitControl.startDone(FAIL), the device 
> MUST still be fully powered down, and operation requests through calls 
> to commands of other interfaces implemented by the device MUST return 
> EOFF or FAIL.
> 
> If a device is not able to complete the SplitControl.start() or 
> SplitControl.stop() requests for any reason, they MUST return FAIL.
> 
> Calls to either StdControl.start() or StdControl.stop() while a start or 
> stop operation is pending MUST return SUCCESS, with the anticipation 
> that a corresponding StdControl.startDone() or StdControl.stopDone() 
> will be signaled in the future.
> 
> Call 	Device On 	Device Off 	Starting 	Stopping
> SplitControl.start() 	SUCCESS 	SUCCESS FAIL 	SUCCESS 	SUCCESS
> SplitControl.stop() 	SUCCESS FAIL 	SUCCESS 	SUCCESS 	SUCCESS
> operation 	depends 	FAIL EOFF EOFF 	FAIL EOFF SUCCESS 	FAIL EOFF
> 
> Devices providing this interface would do so as shown below:
> 
> configuration DeviceC {
>   provides {
>     interface Init;
>     interface SplitControl; \\ For Power Management
>     ....
>   }
> }
> 
> 
>     3.3 Power Management with AsyncStdControl
> 
> The commands and the events of the /``StdControl``/ and the 
> /``SplitControl``/ interfaces are synchronous and can not be called from 
> within asynchronous code (such as interrupt service routines, etc.). For 
> the cases when the power state of the device needs to be controlled from 
> within asynchronous code, the /``AsyncStdControl``/ interface MUST be 
> used in place of the /``StdControl``/ interface. The definition of this 
> interface can be seen below:
> 
> interface AsyncStdControl {
>   async command error_t start();
>   async command error_t stop();
> }
> 
> All of the semantics that hold true for devices providing the StdControl 
> interface also hold for this interface.
> 
> Devices providing this interface would do so as shown below:
> 
> configuration DeviceC {
>   provides {
>     interface Init;
>     interface AsyncStdControl; \\ For Power Management
>     ....
>   }
> }
> 
> Note
> 
> The AsyncStdControl interface should be provided whenever it might be 
> necessary to allow a device to be powered on or off while running in 
> async context. If it is anticipated that a device /will/ not (or more 
> likely /should/ not) be powered on or off while in asynchronous context, 
> then the StdControl interface SHOULD be provided instead. Components 
> that wish to power the device on or off from within async context would 
> then be required to post a task before doing so. In practice, 
> AsyncStdControl is provided by low-level hardware resources, while 
> StdControl is provided by higher level services built on top of these 
> resources.
> 
> 
>   4. Implicit Power Management
> 
> While the /explicit power management/ model provides the basic means for 
> controlling the power state of a device, it is void of any policy about 
> when, or how the power state of the device should be changed. This does 
> not represent a large problem for the simple case of /dedicated/ 
> devices, but can become crucial for non-trivial cases involving complex 
> interdependencies between devices controlled by multiple clients.
> 
> For example, if component /A/ is a client of both component /B/ and 
> component /C/, what happens with /B/ and /C/ if StdControl.stop() is 
> called on component /A/ ? Should components /B/ and /C/ also be stopped? 
> What about the reverse case where both /B/ and /C/ are clients of the 
> single shared component, /A/? If devices /B/ and /C/ are shut off, 
> should /A/ be shut off as well? How can one decide when it is 
> appropriate to cascade such powerup and powerdown requests?
> 
> The complex nature of the problem is evident from the number of 
> unexpected behaviors in TinyOS 1.x involving StdControl. On several 
> platforms, one of the SPI buses is shared between the radio and the 
> flash device. On some of them, issuing StdControl.stop() on the radio 
> results in a series of cascaded calls that result in SPI bus becoming 
> disabled, rendering the communication with the flash impossible. Of 
> course, the right policy would involve tracking the clients of the SPI 
> bus and powering it off only once both the radio and the flash devices 
> were no longer using it. Conversely, the SPI bus should be powered on 
> whenever there is at least one active client.
> 
> The selection of the right power management policy to use is a complex 
> task that depends on the nature of the devices in use, their 
> interdependency, as well as on any specific application requirements. 
> For cases when some of these features are known a-priori or are 
> restricted in some sense, it is preferable that the system provide 
> architectural support for enforcing a meaningful /default/ 
> power-management policy instead of passing that task on to the 
> application programmer to be solved on a case-by-case basis.
> 
> 
>     4.1. Power Management Policies
> 
> Just as generic arbiters are offered in TinyOS 2.x to provide the 
> arbitration functionality required by shared resources, generic power 
> management policies are also offered to allow the power management of 
> non-virtualised devices to be automatically control.
> 
> Through the use of the arbiter components described in [TEP108] 
> <#tep108>, device drivers implemented as shared resources provide the 
> type of restricted resource interdependency where default 
> power-management policies can be offered. The shared resource class 
> defined in Section 2.3 of [TEP108] <#tep108>, provides a well defined 
> component interdependency, where a single resource is shared among 
> multiple clients. This relationship enables the definition of default 
> power-management policies that can be used to automatically power the 
> resource on and off.
> 
> The /Power Manager/ component implementing one of these polices acts as 
> the /default owner/ of the shared resource device and interacts with it 
> through the use of the ResourceDefaultOwner interface:
> 
> interface ResourceDefaultOwner {
>   async event void granted();
>   async command error_t release();
>   async command bool isOwner();
>   async event void requested();
>   async event void immediateRequested();
> }
> 
> Acting as the default owner, the /Power Manager/ waits for the 
> ResourceDefaultOwner.granted() event to be signaled in order to gain 
> ownership over the resource device.
> 
> Once it owns the device, the /Power Manager/ is free to execute its 
> power-management policy using the StdControl-like interface provided by 
> the underlying resource. Different power managers can implement 
> different policies. In the simplest case, this would involve an 
> immediate power-down via one of the stop() commands. When the 
> power-state transition involves non-negligible costs in terms of wake-up 
> latency or power consumption, the /PowerManager/ might revert to a more 
> intelligent strategy that tries to reduce these effects. As pointed out 
> in the introduction, one such strategy might involve the use of a timer 
> to defer the power-down of the resource to some later point in time, 
> giving any resource clients a window of opportunity to put in requests 
> before the device is fully shut down.
> 
> Regardless of the power management policy in use, the /Power Manager/ 
> remains owner of the resource as long as the resource is not requested 
> by one of its clients. Whenever a client puts in a request, the /Power 
> Manager/ will receive a ResourceDefaultOwner.requested() event (or 
> immediateRequested() event) from the arbiter it is associated with. Upon 
> receiving this event, the /Power Manager/ MUST power up the resource 
> through the StdControl-like interface provided by the lower level 
> abstraction of the physical device. The /Power Manager/ SHOULD release 
> the ownership of the resource (using the ResourceDefaultOwner.release() 
> command) but MUST wait until after the resource has been fully powered 
> on before doing so.
> 
> Modeling devices as shared resources and allowing them to be controlled 
> in the way described here, solves the problems outlined in section 3 
> regarding how to keep track of when and how the powerdown of nested 
> resources should proceed. The /Power Manager/ component answers the 
> question of how, and the combination of the power management policy 
> being used and the reception of the ResourceDefaultOwner.granted() and 
> ResourceDefaultOwner.requested() events answers the question of when. As 
> long as the resource at the bottom of a large set of nested resource 
> clients has been fully released, the power mananger will be able to 
> power down the resource appropriately.
> 
> Using the model described above, a resource that uses one of these 
> policies according to the /implicitly power management/ model could be 
> built as shown below:
> 
> module MyFlashP {
>   provides {
>     interface Init;
>     interface SplitControl;
>         interface Resource;
>         interface FlashCommands;
>         ...
>   }
> }
> implementation {
>   ...
> }
> 
> generic module PowerManagerC(uint8_t POWERDOWN_DELAY) {
>   provides {
>         interface Init;
>   }
>   uses {
>         interface SplitControl;
>         interface ResourceDefaultOwner;
>   }
> }
> implementation {
>   ...
> }
> 
> #define MYFLASH_RESOURCE "MyFlash.resource"
> #define MYFLASH_POWERDOWN_DELAY       1000
> configuration MyFlashC {
>   provides {
>         interface Init;
>         interface Resource;
>         interface FlashCommands;
>   }
> }
> implementation {
>   components new PowerManagerC(MYFLASH_POWERDOWN_DELAY)
>       , FcfsArbiter(MYFLASH_RESOURCE)
>       , MyFlashP;
> 
>   Init = MyFlashP;
>   Resource = FcfsArbiter;
>   FlashCommands = MyFlashP;
> 
>   PowerManagerC.ResourceDefaultUser -> FcfsArbiter;
>   PowerManagerC.SplitControl -> MyFlashP;
> 
> }
> 
> This example implementation is built out of three components. The first 
> component (MyFlashP) follows the /explicit power management/ model for 
> defining the interfaces to the physical flash device. The second 
> component (PowerManagerC) is the generic /Power Manager/ component that 
> will be used to implement the specific power management policy for this 
> device. The third component (MyFlashC) is the configuration file that 
> wires together all of the components required by the implementation of 
> of the device as it adheres to the /implicit power management/ model. It 
> includes the MyflashP and PowerManagerC components, as well as an 
> arbiter component for managing shared clients of the device. Notice how 
> the /Power Manager/ is wired to both the ResourceDefaultUser interface 
> provided by the arbiter, and the SplitControl interface provided by the 
> flash. All clients of this flash device are directly connected to the 
> resource interface provided by the arbiter. As outlined above, the 
> PowerManagerC component will use the events signaled through the 
> ResourceDefaultUser interface to determine when to make calls to power 
> the device up and power it down through the SplitControl interface.
> 
> 
>     4.2. Example Power Managers: PowerManagerC and DeferredPowerManagerC
> 
> TinyOS 2.x currently has two default power management policies that it 
> provides. These policies are implemented by the various components 
> located under tinyos-2.x/lib/power. The first policy is implemented 
> using an /immediate/ power control scheme, whereby devices are powered 
> on and off immediately after they have been requested and released. The 
> second policy is implemented using a /deferred/ power control scheme, 
> whereby devices are powered on immediately after being requested, but 
> powered off after some small delay from being released.
> 
> Each policy has three different implementations for use by each of the 
> StdControl, SplitControl, and AsyncStdControl interfaces.
> 
> For reference, each of the available components are listed below
> 
> Immediate Power Management:
> 
>         * StdControlPowerManagerC
>         * SplitControlPowerManagerC
>         * AsyncStdControlPowerManagerC
> 
> Deferred Power Management:
> 
>         * StdControlDeferredPowerManagerC
>         * SplitControlDeferredPowerManagerC
>         * AsyncStdControlDeferredPowerManagerC
> 
> 
>   5. Author's Address
> 
> Kevin Klues
> 503 Bryan Hall
> Washington University
> St. Louis, MO 63130
> 
> phone - +1-314-935-6355
> email - klueska at cs.wustl.edu <mailto:klueska at cs.wustl.edu>
> 
> Vlado Handziski
> Sekr FT5
> Einsteinufer 25
> 10587 Berlin
> GERMANY
> 
> phone - +49 30 314 23831
> email - handzisk at tkn.tu-berlin.de <mailto:handzisk at tkn.tu-berlin.de>
> 
> Jan-Hinrich Hauer
> Sekr FT5
> Einsteinufer 25
> 10587 Berlin
> GERMANY
> 
> phone - +49 30 314 23813
> email - hauer at tkn.tu-berlin.de <mailto:hauer at tkn.tu-berlin.de>
> 
> Philip Levis
> 358 Gates Hall
> Stanford University
> Stanford, CA 94305-9030
> 
> phone - +1 650 725 9046
> email - pal at cs.stanford.edu <mailto:pal at cs.stanford.edu>
> 
> 
>   6. Citations
> 
> [TEP102] <#id5>	TEP 102: Timers.
> 
> [TEP108]	/(1 <#id2>, 2 <#id3>, 3 <#id4>, 4 <#id6>, 5 <#id7>)/ TEP 108: 
> Resource Arbitration.
> 
> [TEP112] <#id1>	TEP 112: Microcontroller Power Management.
> 
> 
> ------------------------------------------------------------------------
> 
> 
>   Hardware Abstraction Architecture
> 
> TEP:	2
> Group:	Core Working Group
> Type:	Best Current Practice
> Status: 	Draft
> TinyOS-Version:	2.0
> Author: 	Vlado Handziski, Joseph Polastre, Jan-Hinrich Hauer, Cory 
> Sharp, Adam Wolisz and David Culler
> Draft-Created:	14-Sep-2004
> Draft-Version:	$revision$
> Draft-Modified:	$date$
> Draft-Discuss:	TinyOS Developer List <tinyos-devel at 
> mail.millennium.berkeley.edu>
> 
> Note
> 
> This document specifies a Best Current Practices for the TinyOS 
> Community, and requests discussion and suggestions for improvements. The 
> distribution of the memo is unlimited, provided that the header 
> information and this note are preserved. Parts of this document are 
> taken verbatim from the [HAA2005] <#haa2005> paper that is under IEEE 
> copyright. This memo is in full compliance with [TEP1] <#tep1>.
> 
> 
>   1   Abstract <#id16>
> 
> This TEP documents the /Hardware Abstraction Architecture (HAA)/ for 
> TinyOS 2.0 that balances conflicting requirements of WSN applications 
> and the desire for increased portability and streamlined development of 
> applications. The three-layer design gradually adapts the capabilities 
> of the underlying hardware platforms to the selected 
> platform-independent hardware interface between the operating system 
> core and the application code. At the same time, it allows the 
> applications to utilize a platform's full capabilities -- exported at 
> the second layer, when the performance requirements outweigh the need 
> for cross-platform compatibility.
> 
> 
>   2   Table of Contents <#id17>
> 
> Contents
> 
>     * 1   Abstract <#abstract>
>     * 2   Table of Contents <#table-of-contents>
>     * 3   Introduction <#introduction>
>     * 4   Architecture <#architecture>
>           o 4.1   Hardware Presentation Layer (HPL)
>             <#hardware-presentation-layer-hpl>
>           o 4.2   Hardware Adaptation Layer (HAL)
>             <#hardware-adaptation-layer-hal>
>           o 4.3   Hardware Interface Layer (HIL)
>             <#hardware-interface-layer-hil>
>           o 4.4   Selecting the level of abstraction
>             <#selecting-the-level-of-abstraction>
>     * 5   Reference <#reference>
>           o 5.1   Processing unit <#processing-unit>
>           o 5.2   Power management <#power-management>
>           o 5.3   Clocks and timers <#clocks-and-timers>
>           o 5.4   Analog-to-digital converters
>             <#analog-to-digital-converters>
>           o 5.5   Data busses <#data-busses>
>           o 5.6   External storage <#external-storage>
>           o 5.7   Radios <#radios>
>     * 6   Conclusion <#conclusion>
>     * 7   Author's Address <#author-s-address>
>     * 8   Citations <#citations>
> 
> 
>   3   Introduction <#id18>
> 
> The introduction of hardware abstraction in modern operating systems has 
> proved valuable for increasing portability and simplifying application 
> development by hiding the hardware intricacies from the rest of the 
> system. Although enabling portability, hardware abstractions come into 
> conflict with the performance and energy-efficiency requirements of WSN 
> applications.
> 
> We need a /Hardware Abstraction Architecture (HAA)/ that can strike a 
> balance between the above conflicting goals. The component-based model 
> of TinyOS has the functionality required for resolving this tension. The 
> main challenge is to select an appropriate organization of abstraction 
> functionality in form of components to support reusability while 
> maintaining energy-efficiency through access to the full hardware 
> capabilities when it is needed.
> 
> Based on the experience in porting TinyOS to new platforms we believe 
> that an effective organization is possible when the strengths of the 
> component-based approach are combined with a flexible, three-tier 
> organization of the hardware abstraction architecture.
> 
> 
>   4   Architecture <#id19>
> 
> In the proposed architecture (Fig.1 <#fig-1>), the hardware abstraction 
> functionality is organized in three distinct layers of components. Each 
> layer has clearly defined responsibilities and is dependent on 
> interfaces provided by lower layers. The capabilities of the underlying 
> hardware are gradually adapted to the established platform-independent 
> interface between the operating system and the applications. As we move 
> from the hardware towards this top interface, the components become less 
> and less hardware dependent, giving the developer more freedom in the 
> design and the implementation of reusable applications.
> 
>                                 +-----------------------------+
>                                 |                             |
>                                 | Cross-platform applications |
>                                 |                             |
>                                 +--------------+--------------+
> +-----------------+                            |                            +-----------------+
> |Platform-specific|                            |                            |Platform-specific|
> |  applications   |                            |                            |  applications   |
> +--------+--------+       Platform-independent |  hardware interface        +--------+--------+
>          |          +-----------------+--------+--------+-----------------+          |
>          |          |                 |                 |                 |          |
>          |  +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+  |
>          |  |.------+------.| |.------+------.| |.------+------.| |.------+------.|  |
>          |  ||             || ||             || ||             || ||    HIL 4    ||  |
>          |  ||    HIL 1    || ||    HIL 2    || ||    HIL 3    || |`------+------'|  |
>          |  ||             || |`------+------'| |`------+------'| |       |       |  |
>          |  |`------+------'| |       |       | |       |       | |       |  +----+--+
>          +--+----+  |       | |.------+------.| |       |       | |       |  |    |
>             |    |  |       | ||             || |.------+------.| |.------+--+---.|
>             |.---+--+------.| ||             || ||             || ||             ||
>             ||             || ||    HAL 2    || ||             || ||             ||
>             ||             || ||             || ||    HAL 3    || ||    HAL 4    ||
>             ||    HAL 1    || |`------+------'| ||             || ||             ||
>             ||             || |       |       | ||             || ||             ||
>             ||             || |       |       | |`------+------'| |`------+------'|
>             |`------+------'| |.------+------.| |       |       | |       |       |
>             |       |       | ||             || |.------+------.| |       |       |
>             |.------+------.| ||    HPL 2    || ||             || |.------+------.|
>             ||    HPL 1    || ||             || ||    HPL 3    || ||    HPL 4    ||
>             |`------+------'| |`------+------'| |`------+------'| |`------+------'|
>             +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+  HW/SW
>                     |                 |                 |                 |          boundary
>        ************************************************************************************
>              +------+------+   +------+------+   +------+------+   +------+------+
>              |HW Platform 1|   |HW Platform 2|   |HW Platform 3|   |HW Platform 4|
>              +-------------+   +-------------+   +-------------+   +-------------+
> 
> 
>                       Fig.1: The proposed Hardware Abstraction Architecture
> 
> 
>     4.1   Hardware Presentation Layer (HPL) <#id20>
> 
> The components belonging to the /HPL/ are positioned directly over the 
> HW/SW interface. As the name suggests, their major task is to "present" 
> the capabilities of the hardware using the native concepts of the 
> operating system. They access the hardware in the usual way, either by 
> memory or by port mapped I/O. In the reverse direction, the hardware can 
> request servicing by signaling an interrupt. Using these communication 
> channels internally, the /HPL/ hides the hardware intricacies and 
> exports a more usable interface (simple function calls) for the rest of 
> the system.
> 
> The /HPL/ components SHOULD be stateless and expose an interface that is 
> fully determined by the capabilities of the hardware module that is 
> abstracted. This tight coupling with the hardware leaves little freedom 
> in the design and the implementation of the components. Even though each 
> /HPL/ component will be as unique as the underlying hardware, all of 
> them will have a similar general structure. For optimal integration with 
> the rest of the architecture, each /HPL/ component SHOULD have:
> 
>     * commands for initialization, starting, and stopping of the
>       hardware module that are necessary for effective power management
>       policy
>     * "get" and "set" commands for the register(s) that control the
>       operation of the hardware
>     * separate commands with descriptive names for the most frequently
>       used flag-setting/testing operations
>     * commands for enabling and disabling of the interrupts generated by
>       the hardware module
>     * service routines for the interrupts that are generated by the
>       hardware module
> 
> The interrupt service routines in the /HPL/ components perform only the 
> most time critical operations (like copying a single value, clearing 
> some flags, etc.), and delegate the rest of the processing to the higher 
> level components that possess extended knowledge about the state of the 
> system.
> 
> The above /HPL/ structure eases manipulation of the hardware. Instead of 
> using cryptic macros and register names whose definitions are hidden 
> deep in the header files of compiler libraries, the programmer can now 
> access hardware through a familiar interface.
> 
> This /HPL/ does not provide any substantial abstraction over the 
> hardware beyond automating frequently used command sequences. 
> Nonetheless, it hides the most hardware-dependent code and opens the way 
> for developing higher-level abstraction components. These higher 
> abstractions can be used with different /HPL/ hardware-modules of the 
> same class. For example, many of the microcontrollers used on the 
> existing WSN platforms have two USART modules for serial communication. 
> They have the same functionality but are accessed using slightly 
> different register names and generate different interrupt vectors. The 
> /HPL/ components can hide these small differences behind a consistent 
> interface, making the higher-level abstractions resource independent. 
> The programmer can then switch between the different USART modules by 
> simple rewiring (/not/ rewriting) the /HPL/ components, without any 
> changes to the implementation code.
> 
> 
>     4.2   Hardware Adaptation Layer (HAL) <#id21>
> 
> The adaptation layer components represent the core of the architecture. 
> They use the raw interfaces provided by the /HPL/ components to build 
> useful abstractions hiding the complexity naturally associated with the 
> use of hardware resources. In contrast to the /HPL/ components, they are 
> allowed to maintain state that can be used for performing arbitration 
> and resource control.
> 
> Due to the efficiency requirements of WSN, abstractions at the /HAL/ 
> level are tailored to the concrete device class and platform. Instead of 
> hiding the individual features of the hardware class behind generic 
> models, /HAL/ interfaces expose specific features and provide the "best" 
> possible abstraction that streamlines application development while 
> maintaining effective use of resources.
> 
> For example, rather than using a single "file-like" abstraction for all 
> devices, we propose domain specific models like /Alarm/, /ADC channel/, 
> /EEPROM/. According to the model, /HAL/ components SHOULD provide access 
> to these abstractions via rich, customized interfaces, and not via 
> standard narrow ones that hide all the functionality behind few 
> overloaded commands.
> 
> 
>     4.3   Hardware Interface Layer (HIL) <#id22>
> 
> The final tier in the architecture is formed by the /HIL/ components 
> that take the platform-specific abstractions provided by the /HAL/ and 
> convert them to hardware-independent interfaces used by cross-platform 
> applications. These interfaces provide a platform independent 
> abstraction over the hardware that simplifies the development of the 
> application software by hiding the hardware differences. To be 
> successful, this API "contract" SHOULD reflect the /typical/ hardware 
> services that are required in a WSN application.
> 
> The complexity of the /HIL/ components mainly depends on how advanced 
> the capabilities of the abstracted hardware are with respect to the 
> platform-independent interface. When the capabilities of the hardware 
> exceed the current API contract, the /HIL/ "downgrades" the 
> platform-specific abstractions provided by the /HAL/ until they are 
> leveled-off with the chosen standard interface. Consequently, when the 
> underlying hardware is inferior, the /HIL/ might have to resort to 
> software simulation of the missing hardware capabilities. As newer and 
> more capable platforms are introduced in the system, the pressure to 
> break the current API contract will increase. When the performance 
> requirements outweigh the benefits of the stable interface, a discrete 
> jump will be made that realigns the API with the abstractions provided 
> in the newer /HAL/. The evolution of the platform-independent interface 
> will force a reimplementation of the affected /HIL/ components. For 
> newer platforms, the /HIL/ will be much simpler because the API contract 
> and their /HAL/ abstractions are tightly related. On the other extreme, 
> the cost of boosting up (in software) the capabilities of the old 
> platforms will rise.
> 
> Since we expect /HIL/ interfaces to evolve as new platforms are 
> designed, we must determine when the overhead of software emulation of 
> hardware features can no longer be sustained. At this point, we 
> introduce /versioning/ of /HIL/ interfaces. By assigning a version 
> number to each iteration of an /HIL/ interface, we can design 
> applications using a legacy interface to be compatible with previously 
> deployed devices. This is important for WSNs since they execute 
> long-running applications and may be deployed for years. An /HIL/ MAY 
> also branch, providing multiple different /HIL/ interfaces with 
> increasing levels of functionality.
> 
> 
>     4.4   Selecting the level of abstraction <#id23>
> 
> The platform-dependence of the /HAL/ in the architecture leads to the 
> more general question about why we have opted for a three-layered 
> design. In other words, why we do not expose the platform-independent 
> hardware interface directly from the /HAL/ components. The main reason 
> behind this decision is the increased /flexibility/ that arises from 
> separating the platform-specific abstractions and the adaptation 
> wrappers that upgrade or downgrade them to the current 
> platform-independent interface. In this way, for maximum performance, 
> the platform specific applications can circumvent the /HIL/ components 
> and directly tap to the /HAL/ interfaces that provide access to the full 
> capabilities of the hardware module.
> 
> Selecting the "right" level--whether an application should use the /HIL/ 
> or directly access the /HAL/--can sometimes cause one hardware asset to 
> be accessed using two levels of abstraction from different parts of the 
> application or the OS libraries.
> 
> Let us take an application similar to the standard OscilloscopeRF 
> application in TinyOS as an example. The application uses the ADC to 
> sample several values from a temperature sensor and sends them in the 
> form of a message over the radio. If the observed phenomenon does not 
> have a large signal bandwidth and the time between subsequent 
> conversions is long, for the sake of cross-platform compatibility, the 
> programmer might decide to use the standard ADCSingle interface. This 
> interface is exported by the /HIL/ sensor wrapper (Fig.2 <#fig-2>) using 
> the services of the platform-specific /HAL/ component. When enough 
> samples are collected in the message buffer, the application passes the 
> message to the networking stack. The MAC protocol used for message 
> exchange over the radio uses clear channel assessment to determine when 
> it is safe to send the message. This usually requires taking several 
> samples of the RSSI signal provided by the radio hardware. Since this is 
> a very time critical operation in which the correlation between the 
> consecutive samples has a significant influence, the programmer of the 
> MAC might directly use the MSP430ADC12Multiple interface of the /HAL/ 
> component as it provides much finer control over the conversion process.
> 
> StdControl
>        | ADCSingle
>        |    |  ADCMultiple
>        |    |    |
> +------|----|----|------------------------------------------+
> |      |    |    |                            Temperature   |
> |      v    v    v                                          |
> | +--------------------+ MSP430ADC12Single   +------------+ |
> | |   TemperatureM     |-------------------->|MSP430ADC12C| |
> | |                    | MSP430ADC12Multiple |            | |
> | |                    |-------------------->|            | |
> | +--------------------+                     +------------+ |
> +-----------------------------------------------------------+
> 
>            Fig.2: The ADC HIL sensor wrapper
> 
> As a result of this chain of decisions, we end up with a concurrent use 
> of the ADC hardware module using two different levels of abstraction. To 
> support this type of "vertical" flexibility we include more complex 
> arbitration and resource control functionality in the /HAL/ components 
> so that a safe shared access to the /HPL/ exported resources can be 
> guaranteed.
> 
> 
>   5   Reference <#id24>
> 
> The proposed HAA was applied for the first time during the 
> implementation of the MSP430 platform 
> <http://cvs.sourceforge.net/viewcvs.py/tinyos/tinyos-1.x/tos/platform/msp430/> 
> that abstracts the capabilities of the TI MSP430 microcontroller in 
> TinyOS 1.1.7 <http://www.tinyos.net/scoop/section/Releases>. The 
> implementation is currently being used by four hardware platforms 
> (TelosA, TelosB, eyesIFX and eyesIFXv2) and has quite successfully 
> satisfied the requirements of a large range of applications.
> 
> In the following we illustrate the properties of the proposed 
> architecture using real-world examples from the planned hardware 
> abstraction functionality in TinyOS 2.0.
> 
> 
>     5.1   Processing unit <#id25>
> 
> In TinyOS most of the variability between the processing units is hidden 
> from the OS simply by using a nesC/C based programming language with a 
> common compiler suite (GCC). For example, the standard library 
> distributed with the compiler creates the necessary start-up code for 
> initializing the global variables, the stack pointer and the interrupt 
> vector table, shielding the OS from these MCU-specific tasks.
> 
> To unify things further, TinyOS provides mechanisms for declaring 
> reentrant and non-reentrant interrupt service routines and critical 
> code-sections. For the MCU's external pins, it provides macros that 
> permit setting and clearing the pin, as well as changing its direction 
> and function. For example, the TI~MSP430's ADC pins may be used as 
> either general I/O or as an analog input to the ADC hardware module. 
> Macros are also provided for timed spin loops at microsecond resolution, 
> independent of the microcontroller. These macros are defined in each 
> platform's hardware.h descriptor file. Finally, the /HPL/ components 
> deal with the different ways of accessing registers (memory-mapped or 
> port-mapped I/O) using the definitions in the standard library header files.
> 
> The three-layer architecture is not intended to abstract the features of 
> the different MCU cores. For the currently supported MCUs, the 
> combination of the compiler suite support with the thin abstraction in 
> the hardware.h files is sufficient. Nevertheless, if new cores with 
> radically different architectures need to be supported by TinyOS in the 
> future, this part of the hardware abstraction functionality will have to 
> be explicitly addressed.
> 
> 
>     5.2   Power management <#id26>
> 
> On both the MSP430 and the Atmel, before entering a sleep mode, a 
> component checks if any hardware modules require that the MCU core is 
> active. Additionally, all services including /HPL/ and /HAL/ components 
> have a start and stop function. When a service is no longer using a 
> hardware module, it may call the stop function of the /HPL/ or /HAL/ 
> component. Doing so disables the module for power savings, but also 
> removes the MCU's dependence on that hardware module to enter sleep 
> mode. For example, the ADC module may be clocked from a high speed 
> oscillator. When a sample is not in progress, the ADC module may be shut 
> down and it will no longer use the high speed oscillator. As a result, 
> when the MCU is idle, it may enter low power mode.
> 
> This rather efficient way of implementing the power management 
> functionality is made possible by the fact that most of the hardware 
> modules are on-chip, attached directly to the MCU system bus, and that 
> there is no hardware memory protection hindering the access to their 
> status registers. As TinyOS platforms add more external devices 
> connected via the peripheral buses, this task will get increasingly 
> complicated. Ultimately, keeping some state in the form of device 
> enumeration or reference counting mechanisms might be needed for proper 
> power management.
> 
> 
>     5.3   Clocks and timers <#id27>
> 
> The application of the HAA for abstracting the clock and timer modules 
> is documented in [TEP102] <#tep102>.
> 
> 
>     5.4   Analog-to-digital converters <#id28>
> 
> The application of the HAA for abstracting the analog-to-digital 
> converter modules is documented in [TEP101] <#tep101>.
> 
> 
>     5.5   Data busses <#id29>
> 
> The /HPL/ functionality for the data busses includes two paths--one for 
> data and a second for control. The control path allows the clock source, 
> prescaler, and baud rate to be set. Interrupts may be enabled or 
> disabled and various hardware flags may be read, set, or cleared, useful 
> for polling or blocking implementations. Through the control path, the 
> entire module may be started or stopped for power control. The data 
> interface simply consists of sending and receiving a byte through the 
> hardware's data registers, as well as interrupt based reporting of 
> received data. Here is an example of the interfaces used in the MSP430 
> platform:
> 
> interface HPLUSARTControl {
>   async command void enableUART();
>   async command void disableUART();
>   async command void enableUARTTx();
>   async command void disableUARTTx();
>   async command void enableUARTRx();
>   async command void disableUARTRx();
>   async command void enableSPI();
>   async command void disableSPI();
>   async command void setModeSPI();
>   async command void setModeUART_TX();
>   async command void setModeUART_RX();
>   async command void setModeUART();
>   async command void setClockSource(
>         uint8_t source);
>   async command void setClockRate(
>         uint16_t baudrate, uint8_t mctl);
>   async command result_t disableRxIntr();
>   async command result_t disableTxIntr();
>   async command result_t enableRxIntr();
>   async command result_t enableTxIntr();
>   async command result_t isTxIntrPending();
>   async command result_t isRxIntrPending();
>   async comma