📄 tep115.txt
字号:
built on top of a driver unambiguously know exactly why a call to
``start()`` or ``stop()`` did not succeed, and can take action accordingly.
Since only ONE component should ever implement the ``SplitControl``
interface for a given device, it isn't unreasonable to expect them
to keep track of this return value themselves. There is, of course,
nothing preventing someone from creating a component
on top of each driver implementation that implements things differently.
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 explicit power management provides the mechanism for changing
power states, it does not specify a policy.
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. The following section discusses these power
management policies and the components that implement them in greater detail.
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 controlled.
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* MUST release the
ownership of the resource (using the ``ResourceDefaultOwner.release()``
command) and 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. This delay is configurable
to meet the varying needs of different device drivers.
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
| 444 Gates Hall
| Stanford University
| Stanford, CA 94305-9030
|
| email - klueska@cs.stanford.edu
|
| Vlado Handziski
| Sekr FT5
| Einsteinufer 25
| 10587 Berlin
| GERMANY
|
| phone - +49 30 314 23831
| email - handzisk@tkn.tu-berlin.de
|
| Jan-Hinrich Hauer
| Sekr FT5
| Einsteinufer 25
| 10587 Berlin
| GERMANY
|
| phone - +49 30 314 23813
| email - hauer@tkn.tu-berlin.de
|
| Philip Levis
| 358 Gates Hall
| Stanford University
| Stanford, CA 94305-9030
|
| phone - +1 650 725 9046
| email - pal@cs.stanford.edu
6. Citations
====================================================================
.. [TEP102] TEP 102: Timers.
.. [TEP108] TEP 108: Resource Arbitration.
.. [TEP112] TEP 112: Microcontroller Power Management.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -