[Tinyos Core WG] Meeting: 1/24
Philip Levis
pal at cs.stanford.edu
Tue Jan 23 22:30:02 PST 2007
Wednesday, January 24, 2007, 09:30 AM US Pacific Time
Bridge: 4, Passcode: 5151862
Numbers:
US: 1-916-356-2663 or 1-888-875-9370 (non-Intel)
UK: +44 1793 402663
Denmark: +45 4527 5090
Agenda:
Cygwin/nesC
1.x serial compatibility layer
TEP 113
TEP 115 (attached)
Phil
-------------- next part --------------
======================================================================
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.5 $
:Draft-Modified: $Date: 2006/12/12 18:22:54 $
: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-consumption states as often as
possible. Depending on the device type, selecting the correct
power-consumption state could be as simple as switching between on and
off states, or could involve selecting the optimum state from among
several. Choosing the best power-consumption state requires making
tradeoffs between various factors such as power consumption, fidelity,
performance, and wake-up latency.
Because of the large difference in the number of supported power-
consumption states that could potentially be present on any given
device, as well as the complexity in keeping track of the state
information needed for safe execution of any sort of system wide
power-control algorithm, a unified power management strategy for all
devices on all possible platforms is simply infeasible. Developing
such a solution would most likely be overly complex and in some cases
even suboptimal. TinyOS 2.x, therefore, takes the approach of
defining several different classes of devices for which several
different power-management strategies have been optimized. [TEP112]_,
for example, details how TinyOS 2.x manages the multiple power-
consumption states for *microcontrollers.* This document, in turn,
details the support for managing the *physical and dedicated* and
*physical and shared* device classes as defined in [TEP108]_. Devices
belonging to these classes often have only two power consumption
states (*on* and *off*), and can therefore be treated differently than
devices that have multiple power consumption states. Additionally, it
turns out that, in practice, TinyOS software often just uses the two
most useful of the many power states in these cases.
Various policies can be implemented on top of these two classes of
devices that decide exactly when a device should be powered on or off.
For *physical and shared* devices, for example, a power management
policy could be written that explicitly powers a device on and off
whenever the higher level component that uses it no longer requires
it. Another policy, however, might decide to defer the power down of
the device for a a few milliseconds if its wake-up time is large
enough and it is likely that the device will be needed again sometime
in the near future. A similar set of policies could be implemented
for *physical and shared* devices, except that an attempt to power
down such a device would not occur until *all* components using it had
signalled that they no longer needed it. Providing these sorts of
policies cause devices belonging to one of these two classes to become
virtualized in the sense that their power states are automatically
handled. Any higher level components connecting to one of these
*virtual* devices need only signify when they require the use of the
device and when they don't. The time at which the device actually
becomes powered on or off, is left up to the power managment policy
being used.
In order to provide the building blocks for implementing such power
managment policies on top of *physical and dedicated* and *physical
and shared* devices, TinyOS 2.x defines two different power management
models that devices belonging to one of these two classes must adhere
to: the *explicit power management* model and the *implicit power
management* model.
2. Power Management Models
======================================================================
The *explicit power management* model provides a means for explicitly
controlling the power state of a physical device by some higher level
component. Whenever this higher level component 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 is external to that device.
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 device itself. Devices following this model are never
explicitly powered up or down by some external component, but rather
*require* some 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 the physical device which adheres
to the *explicit power management* model.
Just like in TinyOS 1.x, StdControl and SplitControl interfaces have
been defined by TinyOS 2.x (along with a third interface,
AsyncStdControl) in order to control the on and off states of devices
that follow the *explicit power management* model. One of these three
interfaces SHOULD be provided by any component wrapping a hardware
device that supports switching between an on and off state. The
selection of the right interface depends on the latencies involved in
changing between these two power states as well as the nature of the
code (sync or async) executing any of the interfaces commands.
Devices implemented according to the *implicit power management*
model, on the other hand, MAY expose one of these three interfaces,
but they are not required to do so. Virtual abstractions of *physical
and dedicated* devices that implement power management policies
according to this model, will indeed provide one of the three
derivatives of the StdControl interface. The interface provided will
no longer be used to explicitly power the device on and off, but
rather allow the power management policy to determine whether the
dedicated user of the device requires the device to be powered or not.
It will then make its own decision as to which state to put the device
in.
For *physical and shared* devices, the information required to
determine if one of its many users require it to be powered or not can
be inferred through information provided by the Resource interface
they provide. Because of this, no StdControl-like interface needs to
be provided, and the power management policy can act accordingly
whenever users request of release the device.
2.1 Explicit Power Management using StdControl
----------------------------------------------------------------------
When a devices powerup and powerdown times are negligible, they SHOULD
provide the StdControl interface as defined below::
interface StdControl {
command error_t start();
command error_t stop();
}
An external component MUST call ``StdControl.start()`` to power a
device on and ``StdControl.stop()`` to power a device off. Calls to
either command return SUCCESS or FAIL.
Upon the successful return of a call to ``StdControl.start()``, a
device MUST be completely powered, and calls to commands of other
interfaces implemented by the device abstraction CAN succeed.
Upon the successful return of a call to ``StdControl.stop()``, a
device MUST be completely powered down, and any subsequent operation
requests through calls to commands of other interfaces implemented by
that device abstraction MUST return FAIL or EOFF.
If a device is not able to complete the ``StdControl.start()`` or
``StdControl.stop()`` requests for any reason, they MUST return FAIL.
Based on these specifications, this matrix describes the valid return
values of calls based on the compoenent's power state:
+---------------------+-----------------+-----------------+
| Call | On | Off |
+=====================+=================+=================+
| StdControl.start() | SUCCESS | SUCCESS or FAIL |
+---------------------+-----------------+-----------------+
| StdControl.stop() | SUCCESS or FAIL | SUCCESS |
+---------------------+-----------------+-----------------+
| operation | depends | FAIL or EOFF |
+---------------------+-----------------+-----------------+
Devices adhereing to this power management model would provide this
interface as shown below::
configuration DeviceC {
provides {
interface Init;
interface StdControl; //For Power Management
....
}
}
2.2 Power Management with SplitControl
----------------------------------------------------------------------
When a devices 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, FAIL, or EBUSY.
Successful calls to ``SplitControl.startDone()`` MUST signal one of
``SplitControl.startDone(SUCCESS)`` or
``SplitControl.startDone(FAIL)``.
Successful calls to ``SplitControl.stopDone()`` MUST signal one of
``SplitControl.stopDone(SUCCESS)`` or ``SplitControl.stopDone(FAIL)``.
Upon signalling either a ``SplitControl.startDone(SUCCESS)`` or a
``SplitControl.stopDone(FAIL)`` event, a device MUST be completely
powered, and operation requests through calls to commands of other
interfaces implemented by the device abstraction SHOULD succeed.
Upon signalling either a ``SplitControl.stopDone(SUCCESS)`` or a
``SplitControl.startDone(FAIL)`` event, a device MUST be completely
powered down, and any subsequent calls to commands of other interfaces
implemented by the device abstraction 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 top operattion is pending MUST return an EBUSY.
+----------------------+---------+---------+----------+----------+
| Call | On | Off | Starting | Stopping |
+======================+=========+=========+==========+==========+
| SplitControl.start() | SUCCESS | SUCCESS | EBUSY | EBUSY |
| | | FAIL | | |
+----------------------+---------+---------+----------+----------+
| SplitControl.stop() | SUCCESS | SUCCESS | EBUSY | EBUSY |
| | FAIL | | | |
+----------------------+---------+---------+----------+----------+
| operation | depends | FAIL | FAIL | FAIL |
| | | EOFF | EOFF | EOFF |
| | | EOFF | SUCCESS | |
+----------------------+---------+---------+----------+----------+
Devices adhereing to this power management model would provide this
interface as shown below::
configuration DeviceC {
provides {
interface Init;
interface SplitControl; \\ For Power Management
....
}
}
2.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 held true for devices providing the
StdControl interface also hold for this interface.
Devices adhereing to this power management model would provide this
interface as shown below::
configuration DeviceC {
provides {
interface Init;
interface AsyncStdControl; \\ For Power Management
....
}
}
.. Note::
Determining exactly when to use the AsyncStdControl interface
instead of simply posting a task and using the StdControl interface
can be tricky. One must consider the advantages and disadvantages
of using one interface over the other. How complex is the code
being I am trying to execute? Do I really want to execute all of
my startup code in async context? Do I gain some performance in
terms of startup latency or code size if I run my startup code in
async context? These are just a few of the factors that need to be
considered when making this decision, and unfortunately there just
is no easy answer. Note that a component with an AsyncStdControl
cannot call SplitControl or StdControl. In practice, AsyncStdControl
is used for low-level hardware resources.
3. Power management policies
======================================================================
While the *explicit power management* model provides the basic means
for controlling the power state of the device, it is void of any
*policy* about who, when, or how the power of the device should be
managed. This does not represent a large problem for the simple case
of *physical and dedicated* devices, but can become crucial for
non-trivial cases involving complex interdependencies between devices
being controlled by multiple users.
For example, if component *A* is *using* two devices, *B* and *C*,
what happens with *B* and *C* when one calls ``StdControl.stop()`` on
the top component *A*? The above problem has its dual in the case of
shared devices. Assuming that device *A* is shared by components *B*
and *C*, the question exists as to when device *A* can be powered
down?
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 cascaded SPI bus becoming disabled, rendering the
communication with the flash impossible. Of course, the right policy
would involve tracking the users of the SPI bus and powering it off
only once both the radio and the flash devices wer no longer using
it. Conversely, the SPI bus should be powered on whenever there is at
least one active user.
The selection of the right policy is a complex task that depends on
the nature of the devices, their interdependency, as well as on the
application requirements. For the 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 simply passing
the task to the application programmer to be solved on a case-by-case
basis.
TinyOS 2.x provides two contexts of restricted resource
interdependency where such a default power-management policy can be
offered. For *physical and shared* resources (defined in [TEP108]_)
(and covered by the Hardware Abstraction Architecture [TEP2]_), TinyOS
2.x provides a flexible *implicit power management* model that is
tightly coupled with the *arbiter* concept and uses the basic
mechanisms offered by the *explicit power management* scheme.
4. Implicit Power Management for Physical and Shared Resources
----------------------------------------------------------------------------
The *physical and 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 definition of a simple default power-management policy that
powers the resource off when no potential users are waiting for access
to the resource. Conversely, the resource is powered on whenever a
client requests its use. When the resource being controlled happens
to be an actual physical device, the *implicit power management* model
for physical devices as described in section two applies.
The realization of a specific power-control policy for shared reources
does not need to be resource specific. 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 devices to be automated.
The *PowerManager* component implementing one of these polices acts as
the *lowest-priority user* of the shared resource. In contrast to
"normal" clients, the *PowerManager* interacts with the resource
arbiter using the richer *ResourceController* interface::
interface ResourceController {
async command error_t request();
async command error_t immediateRequest();
event void granted();
async command void release();
async event void requested();
async event void idle();
}
Acting as a lowest priority client, the *Power Manager* waits for the
``ResourceController.idle()`` event to be signalled before trying to
gain ownership over the resource. It does so using the
``ResourceController.immediateRequest()`` command in order to gain
control of the resource as quickly as possible.
Once it owns the resource, the *PowerManager* is free to execute its
power-management policy using the mechanisms provided by the resource
via the *explicit power-management* model. Different 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.
One strategy might involve using a delayed power-down timer to defer
the powers-down of a resource to some later point in time unless some
normal-priority client requests the device in the meantime.
Regardless of the power-off policy, the *PowerManager* remains owner
of the resource as long as the resource is not requested by a normal
user. When one of these "normal" users finally makes a request, the
*PowerManager* component will receive a
``ResourceController.requested()`` from the arbiter it is associated
with. Upon receiving this event, the *PowerManager* MUST power the
resource back on (in case it was powered-off) through one of the
*explicit power-management* interfaces provided by the lower level
abstraction of the physical device. The *PowerManager* can release the
ownership of the resource (using the ``ResourceController.release()``
command) ONLY after the resource has been fully powered-on.
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 who, when, and how the
powerdown of nested resources should proceed. The *PowerManager*
component answers the question of who, the combination of the power
management policy being used and the reception of the
``ResourceController.idle()`` and ``ResourceController.requested()``
events answers the question of when, and through one of the *explicit
power-management* interfaces provided by the lower level abstraction
of the physical device answers how. As long as the device resource at
the bottom of a large set of nested resource users is released at the
proper time, the power mananger will ba ble to power down its device
appropriately.
Using the model described above, a device resource that follows the
*implicitly powere management* model could be built as shown below::
module MyFlashP {
provides {
interface Init;
interface SplitControl;
interface Resource;
...
}
}
implementation {
...
}
generic module PowerManagerC(uint8_t POWERDOWN_DELAY) {
provides {
interface Init;
}
uses {
interface SplitControl;
interface ResourceController;
}
}
implementation {
...
}
#define MYFLASH_RESOURCE "MyFlash.resource"
configuration MyFlashC {
provides {
interface Init;
interface Resource;
}
}
implementation {
components new PowerManagerC(MYFLASH_POWERDOWN_DELAY)
, FcfsArbiter(MYFLASH_RESOURCE)
, MyFlashP;
Init = MyFlashP;
Resource = FcfsArbiter;
PowerManagerC.ResourceController -> 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 *powermanager*
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 device adhereing to the *implicit power
management* model. It includes the MyflashP and PowerManagerC
components, as well as an arbiter component for managing shared users
of the device. Notice how the *powermanager* is wired to both the
resourcecontroller interface provided by the arbiter, and the
SplitControl interface provided by the flash. All normal users of the
resource are directly connected to the resource interface provided by
the arbiter. As outlined above, the PowerManagerC component will use
the events signalled through the ResourceController interface from the
arbiter to determine when to make calls to the commands provided by
the SplitControl interface coming from the FlashP component in order
to power it up and power it down.
5. Sample Power Managers: PowerManagerC and DeferredPowerManagerC
====================================================================
TinyOS 2.x currently has two sample power management policies in
lib/power. Each policy has three implementations: StdControl,
SplitControl, and AsyncStdControl. The two policies are *immediate*
and *deferred*. T
6. Author's Address
====================================================================
| Vlado Handziski
| Sekr FT5
| Einsteinufer 25
| 10587 Berlin
| GERMANY
|
| phone - +49 30 314 23831
| email - handzisk at tkn.tu-berlin.de
|
| Kevin Klues
| 503 Bryan Hall
| Washington University
| St. Louis, MO 63130
|
| phone - +1-314-935-6355
| email - klueska at cs.wustl.edu
|
| 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
====================================================================
.. [TEP2] TEP 2: Hardware Abstraction Architecture.
.. [TEP108] TEP 108: Resource Arbitration.
.. [TEP112] TEP 112: Microcontroller Power Management.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.millennium.berkeley.edu/pipermail/tinyos-2.0wg/attachments/20070123/5e1530e1/tep115-0001.html
More information about the Tinyos-2.0wg
mailing list