1 <!-- Copyright (C) 2003 Red Hat, Inc. -->
2 <!-- This material may be distributed only subject to the terms -->
3 <!-- and conditions set forth in the Open Publication License, v1.0 -->
4 <!-- or later (the latest version is presently available at -->
5 <!-- http://www.opencontent.org/openpub/). -->
6 <!-- Distribution of the work or derivative of the work in any -->
7 <!-- standard (paper) book form is prohibited unless prior -->
8 <!-- permission is obtained from the copyright holder. -->
12 >Implementing a Power Controller</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
22 TITLE="eCos Power Management Support"
23 HREF="services-power.html"><LINK
25 TITLE="Attached and Detached Controllers"
26 HREF="power-attached.html"><LINK
28 TITLE="eCos USB Slave Support"
29 HREF="io-usb-slave.html"></HEAD
40 SUMMARY="Header navigation table"
49 >eCos Reference Manual</TH
57 HREF="power-attached.html"
71 HREF="io-usb-slave.html"
82 NAME="POWER-CONTROLLER">Implementing a Power Controller</H1
90 >Implementing a Power Controller -- adding power management support to device drivers and
98 >Implementing a Power Controller</H2
100 >A system will have some number of power controllers. Usually there
101 will be one power controller for the cpu,
104 >power_controller_cpu</TT
105 >, typically provided by one of
106 the HAL packages and responsible for managing the processor itself and
107 associated critical components such as memory. Some or all of the
108 device drivers will provide power controllers, allowing the power
109 consumption of the associated devices to be controlled. There may be
110 some arbitrary number of other controllers present in the system. The
111 power management package does not impose any restrictions on the
112 number or nature of the power controllers in the system, other than
113 insisting that at most one <TT
115 >power_controller_cpu</TT
119 >Each power controller involves a single data structure of type
122 >PowerController</SPAN
123 >, defined in the header file
126 >cyg/power/power.h</TT
128 structures should all be placed in the table
132 >, so that the power management package and
133 other code can easily locate all the controllers in the system. This
134 table is constructed at link-time, avoiding code-size or run-time
135 overheads. To facilitate this the package provides two macros which
136 should be used to define a power controller,
139 >POWER_CONTROLLER()</TT
143 >POWER_CONTROLLER_CPU()</TT
148 >POWER_CONTROLLER</TT
149 > takes four arguments:</P
156 >A variable name. This can be used to access the power controller
157 directly, as well as via the table.</P
161 >A priority. The table of power controllers is sorted, such that power
162 controllers with a numerically lower priority come earlier in the
163 table. The special controller <TT
165 >power_controller_cpu</TT
167 always comes at the end of the table. When moving from a high-power
168 mode to a lower-powered mode, the power management package iterates
169 through the table from front to back. When moving to a higher-powered
170 mode the reverse direction is used. The intention is that the power
171 controller for a software-only package such as a TCP/IP stack should
172 appear near the start of the table, whereas the controllers for the
173 ethernet and similar devices would be near the end of the table. Hence
174 when the policy module initiates a mode change to a lower-powered mode
175 the TCP/IP stack gets a chance to cancel this mode change, before the
176 devices it depends on are powered down. Similarly when moving to a
177 higher-powered mode the devices will be re-activated before any
178 software that depends on those devices.</P
182 >cyg/power/power.h</TT
190 >PowerPri_Typical</TT
195 >. For most controllers one of these
196 priorities, possibly with a small number added or subtracted, will
197 give sufficient control. If an application developer is uncertain
198 about the relative priorities of the various controllers, a simple
200 HREF="power-info.html#POWER-INFO-IDS"
203 the table will quickly eliminate any confusion.</P
207 >A constant string identifier. If the system has been configured
208 without support for such identifiers
211 >CYGIMP_POWER_PROVIDE_STRINGS</TT
212 >) then this identifer
213 will be discarded at compile-time. Otherwise it will be made available
214 to higher-level code using the function
217 >power_get_controller_id</TT
222 >A function pointer. This will be invoked to perform actual mode
223 changes, as described below.</P
227 >A typical example of the use of the
230 >POWER_CONTROLLER</TT
231 > macro would be as follows:</P
239 CLASS="PROGRAMLISTING"
240 >#include <pkgconf/system.h>
243 # include <cyg/power/power.h>
246 xyzzy_device_power_mode_change(
247 PowerController* controller,
248 PowerMode desired_mode,
249 PowerModeChange change)
254 static POWER_CONTROLLER(xyzzy_power_controller, \
257 &xyzzy_device_power_mode_change);
263 >This creates a variable <TT
265 >xyzzy_power_controller</TT
267 which is a power controller data structure that will end up near the
268 end of the table of power controllers. Higher-level code can
269 iterate through this table and report the string <TT
273 > to the user. Whenever there is a mode change
274 operation that affects this controller, the function
277 >xyzzy_device_power_mode_change</TT
279 The variable is declared static so this controller cannot be
280 manipulated by name in any other code. Alternatively, if the variable
281 had not been declared static other code could manipulate this
282 controller by name as well as through the table, especially if the
283 package for the xyzzy device driver explicitly declared this
284 variable in an exported header file. Obviously exporting the variable
285 involves a slight risk of a name clash at link time.</P
287 >The above code explicitly checks for the presence of the power
288 management package before including that package's header file or
289 providing any related functionality. Since power management
290 functionality is optional, such checks are recommended.</P
294 >POWER_CONTROLLER_CPU</TT
296 arguments, a string identifier and a mode change function pointer.
297 This macro always instantiates a variable
300 >power_controller_cpu</TT
301 > so there is no need to provide
302 a variable name. The resulting power controller structure always
303 appears at the end of the table, so there is no need to specify a
304 priority. Typical usage of the <TT
306 >POWER_CONTROLLER_CPU</TT
316 CLASS="PROGRAMLISTING"
318 wumpus_processor_power_mode_change(
319 PowerController* controller,
320 PowerMode desired_mode,
321 PowerModeChange change)
326 POWER_CONTROLLER_CPU("wumpus processor", \
327 &wumpus_processor_power_mode_change);</PRE
332 >This defines a power controller structure
335 >power_controller_cpu</TT
336 >. It should not be declared
337 static since higher-level code may well want to manipulate the cpu's
338 power mode directly, and the variable is declared by the power
339 management package's header file.</P
341 >Some care has to be taken to ensure that the power controllers
342 actually end up in the final executable. If a power controller
343 variable ends up in an ordinary library and is never referenced
344 directly then typically the linker will believe that the variable is
345 not needed and it will not end up in the executable. For eCos packages
346 this can be achieved in the CDL, by specifying that the containing
347 source file should end up in <TT
362 CLASS="PROGRAMLISTING"
363 >cdl_package CYGPKG_HAL_WUMPUS_ARCH {
365 compile -library=libextras.a data.c
374 > instantiates a power
375 controller this is now guaranteed to end up in the final executable,
376 as intended. Typically HAL and device driver packages will already
377 have some data that must not be eliminated by the linker, so they will
378 already contain a file that gets built into
382 >. For power controllers defined inside
383 application code it is important that the power controllers end up in
387 > object files rather than in
391 > library archive files.</P
393 >All the real work of a power controller is done by the mode change
394 function. If the power management package has been configured to use a
395 separate thread then this mode change function will be invoked by that
396 thread (except for the special case of <A
397 HREF="power-change.html#POWER-CHANGE-CONTROLLER-NOW"
400 >power_set_controller_mode_now</TT
403 If no separate thread is used then the mode change function will be
404 invoked directly by <TT
410 >power_set_controller_mode</TT
413 >The mode change function will be invoked with three arguments. The
414 first argument identifies the power controller. Usually this argument
415 is not actually required since a given mode change function will only
416 ever be invoked for a single power controller. For example,
419 >xyzzy_device_power_mode_change</TT
421 used in conjunction with <TT
423 >xyzzy_power_controller</TT
425 However there may be some packages which contain multiple controllers,
426 all of which can share a single mode change function, and in that case
427 it is essential to identify the specific controller. The second
428 argument specifies the mode the controller should switch to, if
429 possible: it will be one of <TT
431 >PowerMode_Active</TT
443 >. The final argument will be one of
446 >PowerModeChange_Controller</TT
448 PowerModeChange_ControllerNow, or
451 >PowerModeChange_Global</TT
452 >, and identifies the call
453 that caused this invocation. For example, if the mode change function
454 was invoked because of a call to <TT
458 then this argument will be <TT
460 >PowerModeChange_Global</TT
462 It is up to each controller to decide how to interpret this final
463 argument. A typical controller might reject a global request to switch
467 > mode if the associated device is still busy, but
468 if the request was aimed specifically at this controller then it could
469 instead abort any current I/O operations and switch off the device.</P
473 >PowerController</SPAN
474 > data structure contains
480 >, that needs to be updated
481 by the power mode change function. At all times it should indicate the
482 current mode for this controller. When a mode change is requested the
483 desired mode is passed as the second argument. The exact operation of
484 the power mode change function depends very much on what is being
485 controlled and the current circumstances, but some guidelines are
493 >If the request can be satisfied without obvious detriment, do so and
499 > field. Reducing the power
500 consumption of a device that is not currently being used is generally
505 >If a request is a no-op, for example if the system is switching
512 > mode and the controller
513 does not distinguish between these modes, simply act as if the request
518 >If a request is felt to be unsafe, for example shutting down a
519 device that is still in use, then the controller may decide
520 to reject this request. This is especially true if the request was a
521 global mode change as opposed to one intended specifically for this
522 controller: in the latter case the policy module should be given due
523 deference. There are a number of ways in which a request can be
531 >If the request cannot be satisfied immediately but may be feasible in
532 a short while, leave the <TT
538 unchanged. Higher-level code in the policy module can interpret this
539 as a hint to retry the operation a little bit later. This approach is
540 also useful if the mode change can be started but will take some time
541 to complete, for example shutting down a socket connection, and
542 additional processing will be needed later on.</P
546 >If the request is felt to be inappropriate, for example switching off
547 a device that is still in use, the mode change function can
550 >power_set_controller_mode</TT
552 desired mode for this controller back to the current mode.
553 Higher-level code can then interpret this as a hint that there is more
554 activity in the system than had been apparent.</P
558 >For a global mode change, if the new mode is felt to be inappropriate
559 then the power controller can call <TT
563 to indicate this. An example of this would be the policy module
564 deciding to switch off the whole unit while there is still I/O
571 >Mode change functions should not directly manipulate any other fields
574 >PowerController</SPAN
575 > data structure. If it
576 is necessary to keep track of additional data then static variables
579 >It should be noted that the above are only guidelines. Their
580 application in any given situation may be unclear. In addition the
581 detailed requirements of specific systems will vary, so even if the
582 power controller for a given device driver follows the above
583 guidelines exactly it may turn out that slightly different behaviour
584 would be more appropriate for the actual system that is being
585 developed. Fortunately the open source nature of
589 > allows system developers to fine-tune
590 power controllers to meet their exact requirements.</P
597 SUMMARY="Footer navigation table"
608 HREF="power-attached.html"
626 HREF="io-usb-slave.html"
636 >Attached and Detached Controllers</TD
642 HREF="services-power.html"
650 >eCos USB Slave Support</TD