1 |
27 |
unneback |
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
|
36 |
|
|
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
|
40 |
|
|
eCos Power Management Support
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
|
45 |
|
|
|
46 |
|
|
Introduction
|
47 |
|
|
|
48 |
|
|
|
49 |
|
|
Introduction
|
50 |
|
|
eCos support for Power Management
|
51 |
|
|
|
52 |
|
|
|
53 |
|
|
|
54 |
|
|
|
55 |
|
|
|
56 |
|
|
Introduction
|
57 |
|
|
|
58 |
|
|
The eCos Power Management package provides a framework for
|
59 |
|
|
incorporating power management facilities in an embedded application.
|
60 |
|
|
However its functionality is deliberately limited.
|
61 |
|
|
|
62 |
|
|
|
63 |
|
|
|
64 |
|
|
|
65 |
|
|
The package does not contain any support for controlling the current
|
66 |
|
|
power mode of any given processor, device or board. Instead it is the
|
67 |
|
|
responsibility of the appropriate HAL or device driver package to
|
68 |
|
|
implement such support, by implementing power
|
69 |
|
|
controllers. The power management package groups these
|
70 |
|
|
power controllers together and provides an interface for manipulating
|
71 |
|
|
them.
|
72 |
|
|
|
73 |
|
|
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
The package does not contain any power management policy support.
|
77 |
|
|
Specifically, including this package in an application does not by
|
78 |
|
|
itself ever cause the system to go into low-power mode. Instead it is
|
79 |
|
|
the responsibility of a separate policy module, provided by
|
80 |
|
|
higher-level application code or by some other package, to decide when
|
81 |
|
|
it would be appropriate to switch from one power mode to another. The
|
82 |
|
|
power management package then provides the mechanisms for making it
|
83 |
|
|
happen.
|
84 |
|
|
|
85 |
|
|
|
86 |
|
|
|
87 |
|
|
|
88 |
|
|
|
89 |
|
|
|
90 |
|
|
|
91 |
|
|
|
92 |
|
|
|
93 |
|
|
Including Power Management
|
94 |
|
|
|
95 |
|
|
The power management package is never included automatically in an
|
96 |
|
|
eCos configuration: it is not part of any target specification or of
|
97 |
|
|
any template. Instead it must be added explicitly to a configuration
|
98 |
|
|
if the intended application requires power management functionality.
|
99 |
|
|
When using the command-line ecosconfig tool this
|
100 |
|
|
can be achieved using a command such as:
|
101 |
|
|
|
102 |
|
|
|
103 |
|
|
$ ecosconfig add power
|
104 |
|
|
|
105 |
|
|
|
106 |
|
|
The generic eCos user documentation should be consulted for more
|
107 |
|
|
information on how to use the various tools. The functionality
|
108 |
|
|
provided by the power management package is defined in the header file
|
109 |
|
|
. This header
|
110 |
|
|
file can be used by both C and C++ code.
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
|
115 |
|
|
|
116 |
|
|
|
117 |
|
|
|
118 |
|
|
|
119 |
|
|
Power Modes
|
120 |
|
|
|
121 |
|
|
There are four defined modes of operation:
|
122 |
|
|
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
active
|
126 |
|
|
|
127 |
|
|
|
128 |
|
|
The system is fully operational, and power consumption is expected to
|
129 |
|
|
be high.
|
130 |
|
|
|
131 |
|
|
|
132 |
|
|
|
133 |
|
|
|
134 |
|
|
idle
|
135 |
|
|
|
136 |
|
|
|
137 |
|
|
There has been little or no activity for a short period of time. It is
|
138 |
|
|
up to the policy module to determine what constitutes a short period
|
139 |
|
|
of time, but typically it will be some tenths of a second or some
|
140 |
|
|
small number of seconds. A possible action when entering idle mode is
|
141 |
|
|
to reduce the system's clock speed, thus reducing the power drawn by
|
142 |
|
|
the cpu.
|
143 |
|
|
|
144 |
|
|
|
145 |
|
|
Note that typically this power mode is not entered automatically
|
146 |
|
|
whenever the idle thread starts running. Instead it is entered when
|
147 |
|
|
the policy module discovers that for a certain period of time the
|
148 |
|
|
system has been spending most of its time in the idle thread.
|
149 |
|
|
Theoretically it is possible to implement a policy module that would
|
150 |
|
|
cause a switch to idle mode as soon as the idle thread starts running,
|
151 |
|
|
but that could result in a great many power mode changes for no
|
152 |
|
|
immediate benefit.
|
153 |
|
|
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
sleep
|
158 |
|
|
|
159 |
|
|
|
160 |
|
|
The system has been idle for a significant period of time, perhaps
|
161 |
|
|
some tens of seconds. It is desirable to shut down any hardware that
|
162 |
|
|
is drawing a significant amount of power, for example a screen
|
163 |
|
|
backlight.
|
164 |
|
|
|
165 |
|
|
|
166 |
|
|
|
167 |
|
|
|
168 |
|
|
off
|
169 |
|
|
|
170 |
|
|
|
171 |
|
|
The system is powered down. Power consumption should be minimized.
|
172 |
|
|
Some special action may be needed before the system comes back up, for
|
173 |
|
|
example the user may need to press a specific button.
|
174 |
|
|
|
175 |
|
|
|
176 |
|
|
|
177 |
|
|
|
178 |
|
|
|
179 |
|
|
|
180 |
|
|
|
181 |
|
|
The exact transitions that will happen are decided by the policy
|
182 |
|
|
module. One policy module might include transitions from active to
|
183 |
|
|
idle, from idle to sleep, from sleep to off, and from any of idle,
|
184 |
|
|
sleep or off directly back to active. Another policy module might
|
185 |
|
|
only use the active and off states, bypassing the intermediate ones.
|
186 |
|
|
|
187 |
|
|
|
188 |
|
|
|
189 |
|
|
|
190 |
|
|
|
191 |
|
|
|
192 |
|
|
|
193 |
|
|
|
194 |
|
|
Power Controllers
|
195 |
|
|
|
196 |
|
|
The power management package operates primarily on power controllers.
|
197 |
|
|
The main functionality provided by a power controller is to switch the
|
198 |
|
|
power mode for some part of the system, for example the lcd display or
|
199 |
|
|
the cpu. A power controller consists primarily of a function which
|
200 |
|
|
will be invoked to switch the power mode for the part of the overall
|
201 |
|
|
system being controlled, plus some auxiliary data. A typical system
|
202 |
|
|
will include a number of different power controllers:
|
203 |
|
|
|
204 |
|
|
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
Usually there will be one power controller
|
208 |
|
|
power_controller_cpu associated with the processor
|
209 |
|
|
or with the target platform, and provided by the corresponding HAL
|
210 |
|
|
package. It is this controller which is responsible for switching off
|
211 |
|
|
the system when entering the off mode, which makes it
|
212 |
|
|
somewhat special: attempting to switch off the cpu before other
|
213 |
|
|
devices like the lcd display does not make sense because the cpu would
|
214 |
|
|
no longer be executing any instructions for the latter operation.
|
215 |
|
|
Therefore this power controller has to be invoked last when switching
|
216 |
|
|
to a lower-power mode, and similarly when switching back to a
|
217 |
|
|
higher-power mode it will be invoked first.
|
218 |
|
|
|
219 |
|
|
|
220 |
|
|
It should be noted that providing power management support is not a
|
221 |
|
|
hard requirement when porting eCos to a new processor or platform, and
|
222 |
|
|
many eCos ports predate the availability of power management support.
|
223 |
|
|
Therefore for any given platform it is distinctly possible that
|
224 |
|
|
power_controller_cpu is not yet provided, and if
|
225 |
|
|
full power management functionality is desired then the appropriate
|
226 |
|
|
HAL package would have to be extended first. System developers should
|
227 |
|
|
examine the relevant HAL documentation and sources to determine what
|
228 |
|
|
is actually available.
|
229 |
|
|
|
230 |
|
|
|
231 |
|
|
|
232 |
|
|
|
233 |
|
|
Some or all of the device drivers will supply their own power
|
234 |
|
|
controllers, as part of the device driver package. It is not required
|
235 |
|
|
that all device drivers provide power controllers. In some cases,
|
236 |
|
|
especially for devices that are integrated with the processor,
|
237 |
|
|
power_controller_cpu will take care of the
|
238 |
|
|
integrated devices as a side effect. In other cases the hardware may
|
239 |
|
|
not provide any functionality that allows power consumption to be
|
240 |
|
|
controlled. For any given device driver it is also possible that no
|
241 |
|
|
power controller exists either because it was not required when the
|
242 |
|
|
driver was written, or because the driver predates the availability of
|
243 |
|
|
power management. Again the relevant documentation and sources should
|
244 |
|
|
be consulted for further information.
|
245 |
|
|
|
246 |
|
|
|
247 |
|
|
|
248 |
|
|
|
249 |
|
|
There may be power controllers which are not associated directly with
|
250 |
|
|
any specific hardware. For example a TCP/IP stack could provide a
|
251 |
|
|
power controller so that it gets informed when the system has been
|
252 |
|
|
reactivated: by looking at the system clock it can determine for how
|
253 |
|
|
long the system has been switched off; using this information it can
|
254 |
|
|
then recover from expired dhcp leases, or even to shut down any stream
|
255 |
|
|
connections that may have become invalid (although arguably the stack
|
256 |
|
|
should have refused to go to off mode while there were
|
257 |
|
|
open connections).
|
258 |
|
|
|
259 |
|
|
|
260 |
|
|
|
261 |
|
|
|
262 |
|
|
|
263 |
|
|
|
264 |
|
|
|
265 |
|
|
|
266 |
|
|
|
267 |
|
|
Basic Operation
|
268 |
|
|
|
269 |
|
|
By default the Power Management package creates a thread during
|
270 |
|
|
initialization. It is also possible for the package to be used without
|
271 |
|
|
such a thread, for example in configurations which do not include a
|
272 |
|
|
full kernel, and this alternative is described below. When a separate
|
273 |
|
|
thread is used the stacksize and priority for this thread can be
|
274 |
|
|
controlled by configuration options
|
275 |
|
|
CYGNUM_POWER_THREAD_STACKSIZE and
|
276 |
|
|
CYGNUM_POWER_THREAD_PRIORITY. Typically the thread
|
277 |
|
|
will just wait on a semaphore internal to the package, and will do
|
278 |
|
|
nothing until some other part of the system requests a change to the
|
279 |
|
|
power mode.
|
280 |
|
|
|
281 |
|
|
|
282 |
|
|
At some point the policy module will decide that the system should
|
283 |
|
|
move into a lower-power mode, for example from active to idle. This is
|
284 |
|
|
achieved by calling the function power_set_mode,
|
285 |
|
|
provided by the power management package and declared in
|
286 |
|
|
class="headerfile">cyg/power/power.h, with a single
|
287 |
|
|
argument, PowerMode_Idle. This function manipulates
|
288 |
|
|
some internal state and posts the semaphore, thus waking up the power
|
289 |
|
|
management thread. Note that the function returns before the mode
|
290 |
|
|
change has completed, and in fact depending on thread priorities this
|
291 |
|
|
return may happen before any power controller has been invoked.
|
292 |
|
|
|
293 |
|
|
|
294 |
|
|
When the power management thread wakes up it examines the internal
|
295 |
|
|
state to figure out what it should be doing. In this case it is
|
296 |
|
|
supposed to change the global power mode, so it will iterate over all
|
297 |
|
|
the power controllers requesting each one to switch to the
|
298 |
|
|
idle mode. It is up to each power controller to handle
|
299 |
|
|
this request appropriately. Optionally the thread will invoke a
|
300 |
|
|
callback function after processing each power controller, so that
|
301 |
|
|
higher-level code such as the policy module can more easily keep
|
302 |
|
|
track of the actual state of each controller. Once the thread has
|
303 |
|
|
iterated through all the power controllers it will again wait on the
|
304 |
|
|
internal semaphore for the next request to arrive.
|
305 |
|
|
|
306 |
|
|
|
307 |
|
|
|
308 |
|
|
At present the power management thread always runs at a single
|
309 |
|
|
priority, which defaults to a low priority. A possible future
|
310 |
|
|
enhancement would be to support two separate priorities. When
|
311 |
|
|
switching to a lower-powered mode the thread would run at a low
|
312 |
|
|
priority as before, thus allowing other threads to run and get a
|
313 |
|
|
chance to cancel this mode change. When switching to a higher-powered
|
314 |
|
|
mode the thread would run at a high priority. This could be especially
|
315 |
|
|
important when moving out of the off state: for example
|
316 |
|
|
it would ensure that all device drivers get a chance to wake up before
|
317 |
|
|
ordinary application threads get to run again and possibly attempt I/O
|
318 |
|
|
operations.
|
319 |
|
|
|
320 |
|
|
|
321 |
|
|
|
322 |
|
|
Although usually calls to power_set_mode will
|
323 |
|
|
come from just one place in the policy module, this is not a hard
|
324 |
|
|
requirement. It is possible for multiple threads to call this
|
325 |
|
|
function, with no need for any synchronization. If the power
|
326 |
|
|
management thread is in the middle of performing a mode change and a
|
327 |
|
|
new request comes in, the thread will detect this, abort the current
|
328 |
|
|
operation, and start iterating through the power controllers again
|
329 |
|
|
with the new mode. This check happens between every power controller
|
330 |
|
|
invocation. Usefully this makes it possible for power controllers
|
331 |
|
|
themselves to manipulate power modes: a power controller is invoked to
|
332 |
|
|
change mode; for some reason it determines that the new mode is
|
333 |
|
|
inappropriate; it calls power_set_mode to move
|
334 |
|
|
the system back to another mode; when the power controller returns
|
335 |
|
|
this event will be detected; the power management thread will abort
|
336 |
|
|
the current mode change, and start the new one.
|
337 |
|
|
|
338 |
|
|
|
339 |
|
|
In addition to changing the power mode for the system as a whole,
|
340 |
|
|
individual controllers can be manipulated using the function
|
341 |
|
|
power_set_controller_mode. For example, while the
|
342 |
|
|
system as a whole might be in active mode certain devices
|
343 |
|
|
might be kept in sleep mode until they are explicitly
|
344 |
|
|
activated. It is possible to mix concurrent calls to
|
345 |
|
|
power_set_mode and
|
346 |
|
|
power_set_controller_mode, and when a power
|
347 |
|
|
controller is invoked it may use
|
348 |
|
|
power_set_controller_mode to request further
|
349 |
|
|
changes to its own or to another controller's mode as required.
|
350 |
|
|
|
351 |
|
|
|
352 |
|
|
There are some scenarios where the power management package should not
|
353 |
|
|
use its own thread. One scenario is if the configuration is
|
354 |
|
|
specifically for a single-threaded application such as RedBoot.
|
355 |
|
|
Another scenario is if the policy module already involves a separate
|
356 |
|
|
thread: it may make more sense if the various power management
|
357 |
|
|
operations are synchronous with respect to the calling thread. The use
|
358 |
|
|
of a separate thread inside the power management package is controlled
|
359 |
|
|
by the configuration option CYGPKG_POWER_THREAD,
|
360 |
|
|
which is active only if the kernel package is present and enabled by
|
361 |
|
|
default.
|
362 |
|
|
|
363 |
|
|
|
364 |
|
|
If no separate power management thread is used then obviously the
|
365 |
|
|
implementations of power_set_mode and
|
366 |
|
|
power_set_controller_mode will be somewhat
|
367 |
|
|
different: instead of waking up a separate thread to do the work,
|
368 |
|
|
these functions will now manipulate the power controllers directly. If
|
369 |
|
|
the system does still involve multiple threads then only one thread
|
370 |
|
|
may call power_set_mode or
|
371 |
|
|
power_set_controller_mode at a time: the power
|
372 |
|
|
management package will not provide any synchronization, that must
|
373 |
|
|
happen at a higher level. However when a power controller is invoked
|
374 |
|
|
it can still call these functions as required.
|
375 |
|
|
|
376 |
|
|
|
377 |
|
|
|
378 |
|
|
|
379 |
|
|
|
380 |
|
|
|
381 |
|
|
|
382 |
|
|
|
383 |
|
|
|
384 |
|
|
|
385 |
|
|
|
386 |
|
|
|
387 |
|
|
Power Management Information
|
388 |
|
|
|
389 |
|
|
|
390 |
|
|
Obtaining Power Management Information
|
391 |
|
|
finding out about the various power controllers in the system
|
392 |
|
|
|
393 |
|
|
|
394 |
|
|
|
395 |
|
|
|
396 |
|
|
|
397 |
|
|
#include <cyg/power/power.h>
|
398 |
|
|
|
399 |
|
|
extern PowerController __POWER__[], __POWER_END__;
|
400 |
|
|
extern PowerController power_controller_cpu;
|
401 |
|
|
extern cyg_handle_t power_thread_handle;
|
402 |
|
|
|
403 |
|
|
|
404 |
|
|
|
405 |
|
|
|
406 |
|
|
PowerMode power_get_mode
|
407 |
|
|
|
408 |
|
|
|
409 |
|
|
|
410 |
|
|
|
411 |
|
|
|
412 |
|
|
PowerMode power_get_desired_mode
|
413 |
|
|
|
414 |
|
|
|
415 |
|
|
|
416 |
|
|
|
417 |
|
|
|
418 |
|
|
PowerMode power_get_controller_mode
|
419 |
|
|
|
420 |
|
|
|
421 |
|
|
PowerController* controller
|
422 |
|
|
|
423 |
|
|
|
424 |
|
|
|
425 |
|
|
|
426 |
|
|
PowerMode power_get_controller_desired_mode
|
427 |
|
|
|
428 |
|
|
|
429 |
|
|
PowerController* controller
|
430 |
|
|
|
431 |
|
|
|
432 |
|
|
|
433 |
|
|
|
434 |
|
|
const char* power_get_controller_id
|
435 |
|
|
|
436 |
|
|
|
437 |
|
|
PowerController* controller
|
438 |
|
|
|
439 |
|
|
|
440 |
|
|
|
441 |
|
|
|
442 |
|
|
|
443 |
|
|
|
444 |
|
|
Accessing Power Controllers
|
445 |
|
|
|
446 |
|
|
All the power controllers in a system are held in a table, filled in
|
447 |
|
|
at link-time. The symbols __POWER__ and
|
448 |
|
|
__POWER_END can be used to iterate through this
|
449 |
|
|
table, for example:
|
450 |
|
|
|
451 |
|
|
|
452 |
|
|
PowerController* controller;
|
453 |
|
|
for (controller = &(__POWER__[0]);
|
454 |
|
|
controller != &(__POWER_END__);
|
455 |
|
|
controller++) {
|
456 |
|
|
|
457 |
|
|
…
|
458 |
|
|
}
|
459 |
|
|
|
460 |
|
|
|
461 |
|
|
Each controller has an associated priority, controlling the order in
|
462 |
|
|
which they appear in the table. Typically a software-only component
|
463 |
|
|
such as a TCP/IP stack would use a small number for the priority, so
|
464 |
|
|
that it appears near the start of the table, whereas a device driver
|
465 |
|
|
would be nearer the back of the table. When switching to a
|
466 |
|
|
lower-powered mode the power management package will iterate through
|
467 |
|
|
this table from front to back, thus ensuring that for example the
|
468 |
|
|
TCP/IP stack gets a chance to shut down before the underlying ethernet
|
469 |
|
|
or other hardware that the stack depends on. Similarly when switching
|
470 |
|
|
to a higher-powered mode the power management package will iterate
|
471 |
|
|
through this table from back to front.
|
472 |
|
|
|
473 |
|
|
|
474 |
|
|
In most systems there will be one special controller,
|
475 |
|
|
power_controller_cpu, which should be provided by
|
476 |
|
|
one of the architectural, variant or platform HAL packages. This
|
477 |
|
|
controller will always be the last entry in the table. It is
|
478 |
|
|
responsible for the final power down operation when switching to
|
479 |
|
|
off mode. Other packages such as device drivers may or
|
480 |
|
|
may not declare variable identifiers for their power controllers,
|
481 |
|
|
allowing those controllers to be accessed by name as well as by their
|
482 |
|
|
entries in the global table.
|
483 |
|
|
|
484 |
|
|
|
485 |
|
|
|
486 |
|
|
|
487 |
|
|
Global Power Modes
|
488 |
|
|
|
489 |
|
|
The function power_get_mode can be called at any
|
490 |
|
|
time to determine the current power mode for the system as a whole.
|
491 |
|
|
The return value will be one of PowerMode_Active,
|
492 |
|
|
PowerMode_Idle, PowerMode_Sleep
|
493 |
|
|
or PowerMode_Off. In normal circumstances it is
|
494 |
|
|
unlikely that PowerMode_Off would be returned since
|
495 |
|
|
that mode generally means that the cpu is no longer running.
|
496 |
|
|
|
497 |
|
|
|
498 |
|
|
The function power_get_desired_mode returns the
|
499 |
|
|
power mode that the system should be running at. Most of the time this
|
500 |
|
|
will be the same value as returned by
|
501 |
|
|
power_get_mode. However a different value may be
|
502 |
|
|
returned when in the middle of changing power modes. For example, if
|
503 |
|
|
the current thread runs at a higher priority than the power management
|
504 |
|
|
thread then the latter may have been pre-empted in the middle of a
|
505 |
|
|
mode change: power_get_mode will return the mode
|
506 |
|
|
the system was running at before the mode change started, and
|
507 |
|
|
power_get_desired_mode will return the mode the
|
508 |
|
|
system should end up in when the mode change completes, barring
|
509 |
|
|
further calls to power_set_mode.
|
510 |
|
|
|
511 |
|
|
|
512 |
|
|
|
513 |
|
|
|
514 |
|
|
Individual Controller Power Modes
|
515 |
|
|
|
516 |
|
|
The power management package keeps track of the current and desired
|
517 |
|
|
modes for each power controller, as well as the modes for the system as
|
518 |
|
|
a whole. The function power_get_controller_mode
|
519 |
|
|
takes a single argument, a pointer to a power controller, and returns
|
520 |
|
|
the power mode that controller is currently running at. Similarly
|
521 |
|
|
power_get_controller_desired_mode returns the
|
522 |
|
|
power mode that controller should be running at. Most of the time the
|
523 |
|
|
current and desired modes for a given controller will be the same, and
|
524 |
|
|
will also be the same as the global power mode. However if the power
|
525 |
|
|
management thread is preeempted in the middle of a mode change then
|
526 |
|
|
some of the controllers will have been updated to the desired global
|
527 |
|
|
mode, whereas others will still be at the old mode. The power
|
528 |
|
|
management package also provides functionality for manipulating
|
529 |
|
|
|
530 |
|
|
individual controllers, and for
|
531 |
|
|
linkend="power-attached">detaching controllers from
|
532 |
|
|
global mode changes.
|
533 |
|
|
|
534 |
|
|
|
535 |
|
|
|
536 |
|
|
|
537 |
|
|
Power Controller Identification
|
538 |
|
|
|
539 |
|
|
In some scenarios the power management package will run completely
|
540 |
|
|
automated, and there is no need to identify individual power
|
541 |
|
|
controllers. Any form of identification such as a string
|
542 |
|
|
description would serve no purpose, but would still consume memory in
|
543 |
|
|
the final system. In other scenarios it may be very desirable to
|
544 |
|
|
provide some means of identification. For example, while still
|
545 |
|
|
debugging it may be useful to see a simple string when printing the
|
546 |
|
|
contents of a power controller structure. Alternatively, if the
|
547 |
|
|
application is expected to provide some sort of user interface that
|
548 |
|
|
gives control over which parts of the system are enabled or disabled,
|
549 |
|
|
a string identifier for each controller would be useful. To cope with
|
550 |
|
|
these scenarios the power management package provides a configuration
|
551 |
|
|
option CYGIMP_POWER_PROVIDE_STRINGS. When enabled,
|
552 |
|
|
each power controller will contain a pointer to a constant string
|
553 |
|
|
which can be accessed via a function
|
554 |
|
|
power_get_controller_id. When disabled the system
|
555 |
|
|
will not contain these strings, and the function will not be provided.
|
556 |
|
|
The following code illustrates how to use this function.
|
557 |
|
|
|
558 |
|
|
|
559 |
|
|
#include <stdio.h>
|
560 |
|
|
#include <pkgconf/system.h>
|
561 |
|
|
#ifndef CYGPKG_POWER
|
562 |
|
|
# error The power management package is not present.
|
563 |
|
|
#endif
|
564 |
|
|
#include <pkgconf/power.h>
|
565 |
|
|
#ifndef CYGIMP_POWER_PROVIDE_STRINGS
|
566 |
|
|
# error Power controller identifiers are not available.
|
567 |
|
|
#endif
|
568 |
|
|
#include <cyg/power/power.h>
|
569 |
|
|
|
570 |
|
|
static const char*
|
571 |
|
|
mode_to_string(PowerMode mode)
|
572 |
|
|
{
|
573 |
|
|
const char* result;
|
574 |
|
|
switch(mode) {
|
575 |
|
|
case PowerMode_Active : result = "active"; break;
|
576 |
|
|
case PowerMode_Idle : result = "idle"; break;
|
577 |
|
|
case PowerMode_Sleep : result = "sleep"; break;
|
578 |
|
|
case PowerMode_Off : result = "off"; break;
|
579 |
|
|
default : result = "<unknown>"; break;
|
580 |
|
|
}
|
581 |
|
|
return result;
|
582 |
|
|
}
|
583 |
|
|
|
584 |
|
|
int
|
585 |
|
|
main(int argc, char** argv)
|
586 |
|
|
{
|
587 |
|
|
PowerController* controller;
|
588 |
|
|
|
589 |
|
|
for (controller = &(__POWER__[0]);
|
590 |
|
|
controller != &(__POWER_END__);
|
591 |
|
|
controller++) {
|
592 |
|
|
printf("Controller @ %p: %s, %s\n", controller,
|
593 |
|
|
power_get_controller_id(controller),
|
594 |
|
|
mode_to_string(power_get_controller_mode(controller)));
|
595 |
|
|
}
|
596 |
|
|
return 0;
|
597 |
|
|
}
|
598 |
|
|
|
599 |
|
|
|
600 |
|
|
|
601 |
|
|
The Power Management Thread
|
602 |
|
|
|
603 |
|
|
If the power management package is configured to use a separate thread
|
604 |
|
|
then a handle for that thread is made available to higher-level code
|
605 |
|
|
via the variable power_thread_handle. This handle
|
606 |
|
|
can be used for a variety of purposes, including manipulating that
|
607 |
|
|
thread's priority.
|
608 |
|
|
|
609 |
|
|
|
610 |
|
|
|
611 |
|
|
|
612 |
|
|
|
613 |
|
|
|
614 |
|
|
|
615 |
|
|
|
616 |
|
|
|
617 |
|
|
|
618 |
|
|
Changing Power Modes
|
619 |
|
|
|
620 |
|
|
|
621 |
|
|
Changing Power Modes
|
622 |
|
|
reducing or increasing power consumption as needed
|
623 |
|
|
|
624 |
|
|
|
625 |
|
|
|
626 |
|
|
|
627 |
|
|
|
628 |
|
|
#include <cyg/power/power.h>
|
629 |
|
|
|
630 |
|
|
|
631 |
|
|
|
632 |
|
|
|
633 |
|
|
void power_set_mode
|
634 |
|
|
|
635 |
|
|
|
636 |
|
|
PowerMode new_mode
|
637 |
|
|
|
638 |
|
|
|
639 |
|
|
|
640 |
|
|
|
641 |
|
|
void power_set_controller_mode
|
642 |
|
|
|
643 |
|
|
|
644 |
|
|
PowerController* controller
|
645 |
|
|
|
646 |
|
|
|
647 |
|
|
PowerMode new_mode
|
648 |
|
|
|
649 |
|
|
|
650 |
|
|
|
651 |
|
|
|
652 |
|
|
void power_set_controller_mode_now
|
653 |
|
|
|
654 |
|
|
|
655 |
|
|
PowerController* controller
|
656 |
|
|
|
657 |
|
|
|
658 |
|
|
PowerMode new_mode
|
659 |
|
|
|
660 |
|
|
|
661 |
|
|
|
662 |
|
|
|
663 |
|
|
|
664 |
|
|
|
665 |
|
|
Changing the Global Power Mode
|
666 |
|
|
|
667 |
|
|
The primary functionality supported by the power management package is
|
668 |
|
|
to change the system's global power mode. This is achieved by calling
|
669 |
|
|
the function power_set_mode with a single
|
670 |
|
|
argument, which should be one of PowerMode_Active,
|
671 |
|
|
PowerMode_Idle, PowerMode_Sleep
|
672 |
|
|
or PowerMode_Off. Typically this function will only
|
673 |
|
|
be invoked in certain scenarios:
|
674 |
|
|
|
675 |
|
|
|
676 |
|
|
|
677 |
|
|
|
678 |
|
|
A typical system will contain a policy module which is primarily
|
679 |
|
|
responsible for initiating power mode changes, and a thread inside the
|
680 |
|
|
power management package. The policy module will call
|
681 |
|
|
power_set_mode, which has the effect of
|
682 |
|
|
manipulating some internal state in the power management package and
|
683 |
|
|
waking up its thread. When this thread gets scheduled to run (its
|
684 |
|
|
priority is controlled by a configuration option), it will iterate
|
685 |
|
|
over the power controllers and invoke each controller to change its
|
686 |
|
|
power mode. There is support for a
|
687 |
|
|
linkend="power-policy-callback">callback function, and for
|
688 |
|
|
detached power controllers.
|
689 |
|
|
|
690 |
|
|
|
691 |
|
|
|
692 |
|
|
|
693 |
|
|
After a call to power_set_mode but before the
|
694 |
|
|
power management thread has had a chance to iterate over all the
|
695 |
|
|
controllers, or even before the thread has been rescheduled at all,
|
696 |
|
|
the policy module may decide that a different power mode would be more
|
697 |
|
|
appropriate for the current situation and calls
|
698 |
|
|
power_set_mode again. This has the effect of
|
699 |
|
|
aborting the previous mode change, followed by the power management
|
700 |
|
|
thread iterating over the power controllers again for the new mode.
|
701 |
|
|
|
702 |
|
|
|
703 |
|
|
|
704 |
|
|
|
705 |
|
|
If there is no single policy module responsible for power mode
|
706 |
|
|
changes, any code can call power_set_mode. If
|
707 |
|
|
there are multiple calls in quick succession, earlier calls will
|
708 |
|
|
be aborted and the system should end up in the power mode
|
709 |
|
|
corresponding to the last call
|
710 |
|
|
|
711 |
|
|
|
712 |
|
|
|
713 |
|
|
|
714 |
|
|
As a special case, it is possible for a power controller to call
|
715 |
|
|
power_set_mode when invoked by the power
|
716 |
|
|
management thread. For example a power controller could decide that it
|
717 |
|
|
is inappropriate for the system to go to sleep because the device it
|
718 |
|
|
is associated with is still busy. The effect is as if the policy
|
719 |
|
|
module had called power_set_mode again before
|
720 |
|
|
the mode change had completed.
|
721 |
|
|
|
722 |
|
|
|
723 |
|
|
|
724 |
|
|
|
725 |
|
|
If the power management package has been configured not to use a
|
726 |
|
|
separate thread then obviously the behaviour is somewhat different.
|
727 |
|
|
The call to power_set_mode will now iterate over
|
728 |
|
|
the various power controllers immediately, rather than leaving this to
|
729 |
|
|
a separate thread, and the whole mode change completes before
|
730 |
|
|
power_set_mode returns. If some other thread or a
|
731 |
|
|
DSR calls power_set_mode concurrently the
|
732 |
|
|
behaviour of the system is undefined. However, it is still legal for a
|
733 |
|
|
power controller to call power_set_mode:
|
734 |
|
|
effectively this is a recursive call; it is detected by the system,
|
735 |
|
|
and internal state is updated; the recursive
|
736 |
|
|
power_set_mode call now returns, and when the
|
737 |
|
|
power controller returns back to the original
|
738 |
|
|
power_set_mode call it detects what has happened,
|
739 |
|
|
aborts the previous mode change, and starts a new mode change as
|
740 |
|
|
requested by the controller.
|
741 |
|
|
|
742 |
|
|
|
743 |
|
|
power_set_mode is normally invoked from thread
|
744 |
|
|
context. If a separate power management thread is used it can be
|
745 |
|
|
invoked safely from DSR context. If the system is configured not to
|
746 |
|
|
use such a thread, it may or may not be safe to invoke this function
|
747 |
|
|
from DSR context: essentially the function just iterates through
|
748 |
|
|
the various power controllers, and the documentation or source code of
|
749 |
|
|
each controller present in the current system will have to be examined
|
750 |
|
|
to determine whether or not this can happen safely in DSR context.
|
751 |
|
|
power_set_mode should never be invoked from
|
752 |
|
|
ISR context.
|
753 |
|
|
|
754 |
|
|
|
755 |
|
|
|
756 |
|
|
|
757 |
|
|
Manipulating an Individual Power Controller
|
758 |
|
|
|
759 |
|
|
In some cases it is desirable to set the power mode of an individual
|
760 |
|
|
controller separately from the mode for the system as a whole. For
|
761 |
|
|
example if a device is not currently being used then the associated
|
762 |
|
|
power controller could be set to PowerMode_Off,
|
763 |
|
|
even while the system as a whole is still active. This can be achieved
|
764 |
|
|
by calling the function
|
765 |
|
|
power_set_controller_mode. It takes two
|
766 |
|
|
arguments: the first identifies a particular controller; the second
|
767 |
|
|
specifies the desired new power mode for that controller. The function
|
768 |
|
|
operates in much the same way as power_set_mode,
|
769 |
|
|
for example if a separate power management thread is being used then
|
770 |
|
|
power_set_controller_mode operates by
|
771 |
|
|
manipulating some internal state and waking up that thread. The
|
772 |
|
|
limitations are also much the same as for
|
773 |
|
|
power_set_mode, so for example
|
774 |
|
|
power_set_controller_mode should not be invoked
|
775 |
|
|
from inside ISRs.
|
776 |
|
|
|
777 |
|
|
|
778 |
|
|
Manipulating individual controllers is often used in conjunction with
|
779 |
|
|
the function
|
780 |
|
|
linkend="power-attached">power_set_controller_attached,
|
781 |
|
|
allowing the policy module to specify which controllers are affected
|
782 |
|
|
by global mode changes.
|
783 |
|
|
|
784 |
|
|
|
785 |
|
|
|
786 |
|
|
|
787 |
|
|
Direct Manipulation of a Power Controller
|
788 |
|
|
|
789 |
|
|
In exceptional circumstances it may be necessary to invoke a power
|
790 |
|
|
controller directly, bypassing the power management thread and
|
791 |
|
|
higher-level functionality such as
|
792 |
|
|
linkend="power-policy-callback">callback functions. The
|
793 |
|
|
function power_set_controller_mode_now allows
|
794 |
|
|
this. It takes two arguments, a controller and a mode, just like
|
795 |
|
|
power_set_controller_mode.
|
796 |
|
|
|
797 |
|
|
|
798 |
|
|
Use of power_set_controller_mode_now is
|
799 |
|
|
dangerous. For example no attempt is made to synchronise with any
|
800 |
|
|
other power mode changes that might be happening concurrently. A
|
801 |
|
|
possible use is when the system gets woken up out of
|
802 |
|
|
sleep mode: depending on the hardware, on which power
|
803 |
|
|
controllers are present, and on the application code it may be
|
804 |
|
|
necessary to wake up some power controllers immediately before the
|
805 |
|
|
system as a whole is ready to run again.
|
806 |
|
|
|
807 |
|
|
|
808 |
|
|
|
809 |
|
|
|
810 |
|
|
|
811 |
|
|
|
812 |
|
|
|
813 |
|
|
|
814 |
|
|
|
815 |
|
|
|
816 |
|
|
Support for Policy Modules
|
817 |
|
|
|
818 |
|
|
|
819 |
|
|
Support for Policy Modules
|
820 |
|
|
closer integration with higher-level code
|
821 |
|
|
|
822 |
|
|
|
823 |
|
|
|
824 |
|
|
|
825 |
|
|
|
826 |
|
|
#include <cyg/power/power.h>
|
827 |
|
|
|
828 |
|
|
|
829 |
|
|
|
830 |
|
|
|
831 |
|
|
void power_set_policy_callback
|
832 |
|
|
|
833 |
|
|
|
834 |
|
|
void (*)(PowerController*, PowerMode, PowerMode, PowerMode, PowerMode) callback
|
835 |
|
|
|
836 |
|
|
|
837 |
|
|
|
838 |
|
|
|
839 |
|
|
void (*)(PowerController*, PowerMode, PowerMode, PowerMode, PowerMode) power_get_policy_callback
|
840 |
|
|
|
841 |
|
|
|
842 |
|
|
|
843 |
|
|
|
844 |
|
|
|
845 |
|
|
CYG_ADDRWORD power_get_controller_policy_data
|
846 |
|
|
|
847 |
|
|
|
848 |
|
|
PowerController* controller
|
849 |
|
|
|
850 |
|
|
|
851 |
|
|
|
852 |
|
|
|
853 |
|
|
void power_set_controller_policy_data
|
854 |
|
|
|
855 |
|
|
|
856 |
|
|
PowerController* controller
|
857 |
|
|
|
858 |
|
|
|
859 |
|
|
CYG_ADDRWORD data
|
860 |
|
|
|
861 |
|
|
|
862 |
|
|
|
863 |
|
|
|
864 |
|
|
|
865 |
|
|
|
866 |
|
|
|
867 |
|
|
Policy Callbacks
|
868 |
|
|
|
869 |
|
|
The use of a separate thread to perform power mode changes in typical
|
870 |
|
|
configurations can cause problems for some policy modules.
|
871 |
|
|
Specifically, the policy module can request a mode change for the
|
872 |
|
|
system as a whole or for an individual controller, but it does not
|
873 |
|
|
know when the power management thread actually gets scheduled to run
|
874 |
|
|
again and carry out the request. Although it would be possible for the
|
875 |
|
|
policy module to perform some sort of polling, in general that is
|
876 |
|
|
undesirable.
|
877 |
|
|
|
878 |
|
|
|
879 |
|
|
To avoid such problems the policy module can install a callback
|
880 |
|
|
function using power_set_policy_callback. The
|
881 |
|
|
current callback function can be retrieved using
|
882 |
|
|
power_get_policy_callback. If a callback function
|
883 |
|
|
has been installed then it will be called by the power management
|
884 |
|
|
package whenever a power controller has been invoked to perform a mode
|
885 |
|
|
change. The callback will be called in the context of the power
|
886 |
|
|
management thread, so usually it will have to make use of thread
|
887 |
|
|
synchronisation primitives to interact with the main policy module. It
|
888 |
|
|
is passed five arguments:
|
889 |
|
|
|
890 |
|
|
|
891 |
|
|
|
892 |
|
|
|
893 |
|
|
The power controller that has just been invoked to perform a mode
|
894 |
|
|
change.
|
895 |
|
|
|
896 |
|
|
|
897 |
|
|
|
898 |
|
|
|
899 |
|
|
The mode this controller was running at before the invocation.
|
900 |
|
|
|
901 |
|
|
|
902 |
|
|
|
903 |
|
|
|
904 |
|
|
The current mode this controller is now running at.
|
905 |
|
|
|
906 |
|
|
|
907 |
|
|
|
908 |
|
|
|
909 |
|
|
The desired mode before the power controller was invoked. Usually this
|
910 |
|
|
will be the same as the current mode, unless the controller has
|
911 |
|
|
decided for some reason that this was inappropriate.
|
912 |
|
|
|
913 |
|
|
|
914 |
|
|
|
915 |
|
|
|
916 |
|
|
The current desired mode. This will differ from the previous argument
|
917 |
|
|
only if there has was another call to
|
918 |
|
|
power_set_mode or
|
919 |
|
|
power_set_controller_mode while the power
|
920 |
|
|
controller was being invoked, probably by the power controller itself.
|
921 |
|
|
|
922 |
|
|
|
923 |
|
|
|
924 |
|
|
|
925 |
|
|
A simple example of a policy callback function would be:
|
926 |
|
|
|
927 |
|
|
|
928 |
|
|
static void
|
929 |
|
|
power_callback(
|
930 |
|
|
PowerController* controller,
|
931 |
|
|
PowerMode old_mode,
|
932 |
|
|
PowerMode new_mode,
|
933 |
|
|
PowerMode old_desired_mode,
|
934 |
|
|
powerMode new_desired_mode)
|
935 |
|
|
{
|
936 |
|
|
printf("Power mode change: %s, %s -> %d\n",
|
937 |
|
|
power_get_controller_id(controller),
|
938 |
|
|
mode_to_string(old_mode),
|
939 |
|
|
mode_to_string(new_mode));
|
940 |
|
|
|
941 |
|
|
CYG_UNUSED_PARAM(PowerMode, old_desired_mode);
|
942 |
|
|
CYG_UNUSED_PARAM(PowerMode, new_desired_mode);
|
943 |
|
|
}
|
944 |
|
|
|
945 |
|
|
int
|
946 |
|
|
main(int argc, char** argv)
|
947 |
|
|
{
|
948 |
|
|
…
|
949 |
|
|
power_set_policy_callback(&power_callback);
|
950 |
|
|
…
|
951 |
|
|
}
|
952 |
|
|
|
953 |
|
|
|
954 |
|
|
If power_set_controller_mode_now is used to
|
955 |
|
|
manipulate an individual controller the policy callback will not be
|
956 |
|
|
invoked. This function may get called from any context including DSRs,
|
957 |
|
|
and even if there is already a call to the policy callback happening
|
958 |
|
|
in some other context, so invoking the callback would usually be
|
959 |
|
|
unsafe.
|
960 |
|
|
|
961 |
|
|
|
962 |
|
|
If the power management package has not been configured to use a
|
963 |
|
|
separate thread then power_set_mode and
|
964 |
|
|
power_set_controller_mode will manipulate the
|
965 |
|
|
power controllers immediately and invoke the policy callback
|
966 |
|
|
afterwards. Therefore the policy callback will typically run in the
|
967 |
|
|
same context as the main policy module.
|
968 |
|
|
|
969 |
|
|
|
970 |
|
|
|
971 |
|
|
|
972 |
|
|
Policy-specific Controller Data
|
973 |
|
|
|
974 |
|
|
Some policy modules may want to associate some additional data with
|
975 |
|
|
each power controller. This could be achieved by for example
|
976 |
|
|
maintaining a hash table or similar data structure, but for
|
977 |
|
|
convenience the power management package allows higher-level code,
|
978 |
|
|
typically the policy module, to store and retrieve one word of data in
|
979 |
|
|
each power controller. The function
|
980 |
|
|
power_set_controller_policy_data takes two
|
981 |
|
|
arguments, a pointer to a power controller and a
|
982 |
|
|
CYG_ADDRWORD of data: by appropriate use of casts this
|
983 |
|
|
word could be an integer or a pointer to some data structure. The
|
984 |
|
|
matching function
|
985 |
|
|
power_get_controller_policy_data retrieves the
|
986 |
|
|
word previously installed, and can be cast back to an integer or
|
987 |
|
|
pointer. The default value for the policy data is 0.
|
988 |
|
|
|
989 |
|
|
|
990 |
|
|
For example the following code fragment stores a simple index value in
|
991 |
|
|
each power controller. This could then be retrieved by the policy
|
992 |
|
|
callback.
|
993 |
|
|
|
994 |
|
|
|
995 |
|
|
unsigned int i = 0;
|
996 |
|
|
PowerController* controller;
|
997 |
|
|
|
998 |
|
|
for (controller = &(__POWER__[0]);
|
999 |
|
|
controller != &(__POWER_END__);
|
1000 |
|
|
controller++) {
|
1001 |
|
|
power_set_controller_policy_data(controller, (CYG_ADDRWORD) i++);
|
1002 |
|
|
}
|
1003 |
|
|
|
1004 |
|
|
|
1005 |
|
|
Not all policy modules will require per-controller data. The
|
1006 |
|
|
configuration option
|
1007 |
|
|
CYGIMP_POWER_PROVIDE_POLICY_DATA can be used to
|
1008 |
|
|
control this functionality, thus avoiding wasting a small amount of
|
1009 |
|
|
memory inside each power controller structure.
|
1010 |
|
|
|
1011 |
|
|
|
1012 |
|
|
|
1013 |
|
|
|
1014 |
|
|
|
1015 |
|
|
|
1016 |
|
|
|
1017 |
|
|
|
1018 |
|
|
|
1019 |
|
|
|
1020 |
|
|
Attached and Detached Controllers
|
1021 |
|
|
|
1022 |
|
|
|
1023 |
|
|
Attached and Detached Controllers
|
1024 |
|
|
control which power controllers are affected by global changes
|
1025 |
|
|
|
1026 |
|
|
|
1027 |
|
|
|
1028 |
|
|
|
1029 |
|
|
|
1030 |
|
|
#include <cyg/power/power.h>
|
1031 |
|
|
|
1032 |
|
|
|
1033 |
|
|
|
1034 |
|
|
cyg_bool power_get_controller_attached
|
1035 |
|
|
|
1036 |
|
|
|
1037 |
|
|
PowerController* controller
|
1038 |
|
|
|
1039 |
|
|
|
1040 |
|
|
|
1041 |
|
|
|
1042 |
|
|
void power_set_controller_attached
|
1043 |
|
|
|
1044 |
|
|
|
1045 |
|
|
PowerController* controller
|
1046 |
|
|
|
1047 |
|
|
|
1048 |
|
|
cyg_bool new_state
|
1049 |
|
|
|
1050 |
|
|
|
1051 |
|
|
|
1052 |
|
|
|
1053 |
|
|
|
1054 |
|
|
|
1055 |
|
|
Detaching Power Controllers
|
1056 |
|
|
|
1057 |
|
|
By default the global operation power_set_mode
|
1058 |
|
|
affects all power controllers. There may be circumstances when this is
|
1059 |
|
|
not desirable. For example if a particular device is not currently
|
1060 |
|
|
being used then it can be left switched off: the rest of the system
|
1061 |
|
|
could be moving between active, idle and
|
1062 |
|
|
sleep modes, but there is no point in invoking the power
|
1063 |
|
|
controller for the unused device. To support this the power management
|
1064 |
|
|
package supports the concept of attached and detached controllers. By
|
1065 |
|
|
default all controllers are attached, and hence will be affected by
|
1066 |
|
|
global mode changes. A specific controller can be detached using the
|
1067 |
|
|
function power_set_controller_attached. This
|
1068 |
|
|
function takes two arguments, one to specify a particular controller
|
1069 |
|
|
and another to specify the desired new state.
|
1070 |
|
|
power_get_controller_attached can be used to
|
1071 |
|
|
determine whether or not a specific controller is currently attached.
|
1072 |
|
|
|
1073 |
|
|
|
1074 |
|
|
The attached or detached state of a controller only affects what
|
1075 |
|
|
happens during a global mode change, in other words following a call
|
1076 |
|
|
to power_set_mode. It is still possible to
|
1077 |
|
|
manipulate a detached controller using
|
1078 |
|
|
power_set_controller_mode or
|
1079 |
|
|
power_set_controller_mode_now.
|
1080 |
|
|
|
1081 |
|
|
|
1082 |
|
|
|
1083 |
|
|
|
1084 |
|
|
|
1085 |
|
|
|
1086 |
|
|
|
1087 |
|
|
|
1088 |
|
|
|
1089 |
|
|
|
1090 |
|
|
Implementing a Power Controller
|
1091 |
|
|
|
1092 |
|
|
|
1093 |
|
|
Implementing a Power Controller
|
1094 |
|
|
adding power management support to device drivers and
|
1095 |
|
|
other packages
|
1096 |
|
|
|
1097 |
|
|
|
1098 |
|
|
|
1099 |
|
|
Implementing a Power Controller
|
1100 |
|
|
|
1101 |
|
|
A system will have some number of power controllers. Usually there
|
1102 |
|
|
will be one power controller for the cpu,
|
1103 |
|
|
power_controller_cpu, typically provided by one of
|
1104 |
|
|
the HAL packages and responsible for managing the processor itself and
|
1105 |
|
|
associated critical components such as memory. Some or all of the
|
1106 |
|
|
device drivers will provide power controllers, allowing the power
|
1107 |
|
|
consumption of the associated devices to be controlled. There may be
|
1108 |
|
|
some arbitrary number of other controllers present in the system. The
|
1109 |
|
|
power management package does not impose any restrictions on the
|
1110 |
|
|
number or nature of the power controllers in the system, other than
|
1111 |
|
|
insisting that at most one power_controller_cpu be
|
1112 |
|
|
provided.
|
1113 |
|
|
|
1114 |
|
|
|
1115 |
|
|
Each power controller involves a single data structure of type
|
1116 |
|
|
PowerController, defined in the header file
|
1117 |
|
|
. These data
|
1118 |
|
|
structures should all be placed in the table
|
1119 |
|
|
__POWER__, so that the power management package and
|
1120 |
|
|
other code can easily locate all the controllers in the system. This
|
1121 |
|
|
table is constructed at link-time, avoiding code-size or run-time
|
1122 |
|
|
overheads. To facilitate this the package provides two macros which
|
1123 |
|
|
should be used to define a power controller,
|
1124 |
|
|
POWER_CONTROLLER() and
|
1125 |
|
|
POWER_CONTROLLER_CPU().
|
1126 |
|
|
|
1127 |
|
|
|
1128 |
|
|
The macro POWER_CONTROLLER takes four arguments:
|
1129 |
|
|
|
1130 |
|
|
|
1131 |
|
|
|
1132 |
|
|
|
1133 |
|
|
A variable name. This can be used to access the power controller
|
1134 |
|
|
directly, as well as via the table.
|
1135 |
|
|
|
1136 |
|
|
|
1137 |
|
|
|
1138 |
|
|
|
1139 |
|
|
A priority. The table of power controllers is sorted, such that power
|
1140 |
|
|
controllers with a numerically lower priority come earlier in the
|
1141 |
|
|
table. The special controller power_controller_cpu
|
1142 |
|
|
always comes at the end of the table. When moving from a high-power
|
1143 |
|
|
mode to a lower-powered mode, the power management package iterates
|
1144 |
|
|
through the table from front to back. When moving to a higher-powered
|
1145 |
|
|
mode the reverse direction is used. The intention is that the power
|
1146 |
|
|
controller for a software-only package such as a TCP/IP stack should
|
1147 |
|
|
appear near the start of the table, whereas the controllers for the
|
1148 |
|
|
ethernet and similar devices would be near the end of the table. Hence
|
1149 |
|
|
when the policy module initiates a mode change to a lower-powered mode
|
1150 |
|
|
the TCP/IP stack gets a chance to cancel this mode change, before the
|
1151 |
|
|
devices it depends on are powered down. Similarly when moving to a
|
1152 |
|
|
higher-powered mode the devices will be re-activated before any
|
1153 |
|
|
software that depends on those devices.
|
1154 |
|
|
|
1155 |
|
|
|
1156 |
|
|
The header file
|
1157 |
|
|
class="headerfile">cyg/power/power.h defines three
|
1158 |
|
|
priorities PowerPri_Early,
|
1159 |
|
|
PowerPri_Typical and
|
1160 |
|
|
PowerPri_Late. For most controllers one of these
|
1161 |
|
|
priorities, possibly with a small number added or subtracted, will
|
1162 |
|
|
give sufficient control. If an application developer is uncertain
|
1163 |
|
|
about the relative priorities of the various controllers, a simple
|
1164 |
|
|
test program that iterates over
|
1165 |
|
|
the table will quickly eliminate any confusion.
|
1166 |
|
|
|
1167 |
|
|
|
1168 |
|
|
|
1169 |
|
|
|
1170 |
|
|
A constant string identifier. If the system has been configured
|
1171 |
|
|
without support for such identifiers
|
1172 |
|
|
(CYGIMP_POWER_PROVIDE_STRINGS) then this identifer
|
1173 |
|
|
will be discarded at compile-time. Otherwise it will be made available
|
1174 |
|
|
to higher-level code using the function
|
1175 |
|
|
power_get_controller_id.
|
1176 |
|
|
|
1177 |
|
|
|
1178 |
|
|
|
1179 |
|
|
|
1180 |
|
|
A function pointer. This will be invoked to perform actual mode
|
1181 |
|
|
changes, as described below.
|
1182 |
|
|
|
1183 |
|
|
|
1184 |
|
|
|
1185 |
|
|
|
1186 |
|
|
A typical example of the use of the
|
1187 |
|
|
POWER_CONTROLLER macro would be as follows:
|
1188 |
|
|
|
1189 |
|
|
|
1190 |
|
|
#include <pkgconf/system.h>
|
1191 |
|
|
|
1192 |
|
|
#ifdef CYGPKG_POWER
|
1193 |
|
|
# include <cyg/power/power.h>
|
1194 |
|
|
|
1195 |
|
|
static void
|
1196 |
|
|
xyzzy_device_power_mode_change(
|
1197 |
|
|
PowerController* controller,
|
1198 |
|
|
PowerMode desired_mode,
|
1199 |
|
|
PowerModeChange change)
|
1200 |
|
|
{
|
1201 |
|
|
// Do the work
|
1202 |
|
|
}
|
1203 |
|
|
|
1204 |
|
|
static POWER_CONTROLLER(xyzzy_power_controller, \
|
1205 |
|
|
PowerPri_Late, \
|
1206 |
|
|
"xyzzy device", \
|
1207 |
|
|
&xyzzy_device_power_mode_change);
|
1208 |
|
|
#endif
|
1209 |
|
|
|
1210 |
|
|
|
1211 |
|
|
This creates a variable xyzzy_power_controller,
|
1212 |
|
|
which is a power controller data structure that will end up near the
|
1213 |
|
|
end of the table of power controllers. Higher-level code can
|
1214 |
|
|
iterate through this table and report the string "xyzzy
|
1215 |
|
|
device" to the user. Whenever there is a mode change
|
1216 |
|
|
operation that affects this controller, the function
|
1217 |
|
|
xyzzy_device_power_mode_change will be invoked.
|
1218 |
|
|
The variable is declared static so this controller cannot be
|
1219 |
|
|
manipulated by name in any other code. Alternatively, if the variable
|
1220 |
|
|
had not been declared static other code could manipulate this
|
1221 |
|
|
controller by name as well as through the table, especially if the
|
1222 |
|
|
package for the xyzzy device driver explicitly declared this
|
1223 |
|
|
variable in an exported header file. Obviously exporting the variable
|
1224 |
|
|
involves a slight risk of a name clash at link time.
|
1225 |
|
|
|
1226 |
|
|
|
1227 |
|
|
The above code explicitly checks for the presence of the power
|
1228 |
|
|
management package before including that package's header file or
|
1229 |
|
|
providing any related functionality. Since power management
|
1230 |
|
|
functionality is optional, such checks are recommended.
|
1231 |
|
|
|
1232 |
|
|
|
1233 |
|
|
The macro POWER_CONTROLLER_CPU only takes two
|
1234 |
|
|
arguments, a string identifier and a mode change function pointer.
|
1235 |
|
|
This macro always instantiates a variable
|
1236 |
|
|
power_controller_cpu so there is no need to provide
|
1237 |
|
|
a variable name. The resulting power controller structure always
|
1238 |
|
|
appears at the end of the table, so there is no need to specify a
|
1239 |
|
|
priority. Typical usage of the POWER_CONTROLLER_CPU
|
1240 |
|
|
macro would be:
|
1241 |
|
|
|
1242 |
|
|
|
1243 |
|
|
static void
|
1244 |
|
|
wumpus_processor_power_mode_change(
|
1245 |
|
|
PowerController* controller,
|
1246 |
|
|
PowerMode desired_mode,
|
1247 |
|
|
PowerModeChange change)
|
1248 |
|
|
{
|
1249 |
|
|
// Do the work
|
1250 |
|
|
}
|
1251 |
|
|
|
1252 |
|
|
POWER_CONTROLLER_CPU("wumpus processor", \
|
1253 |
|
|
&wumpus_processor_power_mode_change);
|
1254 |
|
|
|
1255 |
|
|
|
1256 |
|
|
This defines a power controller structure
|
1257 |
|
|
power_controller_cpu. It should not be declared
|
1258 |
|
|
static since higher-level code may well want to manipulate the cpu's
|
1259 |
|
|
power mode directly, and the variable is declared by the power
|
1260 |
|
|
management package's header file.
|
1261 |
|
|
|
1262 |
|
|
|
1263 |
|
|
Some care has to be taken to ensure that the power controllers
|
1264 |
|
|
actually end up in the final executable. If a power controller
|
1265 |
|
|
variable ends up in an ordinary library and is never referenced
|
1266 |
|
|
directly then typically the linker will believe that the variable is
|
1267 |
|
|
not needed and it will not end up in the executable. For eCos packages
|
1268 |
|
|
this can be achieved in the CDL, by specifying that the containing
|
1269 |
|
|
source file should end up in libextras.a rather
|
1270 |
|
|
than the default libtarget.a:
|
1271 |
|
|
|
1272 |
|
|
|
1273 |
|
|
cdl_package CYGPKG_HAL_WUMPUS_ARCH {
|
1274 |
|
|
…
|
1275 |
|
|
compile -library=libextras.a data.c
|
1276 |
|
|
}
|
1277 |
|
|
|
1278 |
|
|
|
1279 |
|
|
If the file data.c instantiates a power
|
1280 |
|
|
controller this is now guaranteed to end up in the final executable,
|
1281 |
|
|
as intended. Typically HAL and device driver packages will already
|
1282 |
|
|
have some data that must not be eliminated by the linker, so they will
|
1283 |
|
|
already contain a file that gets built into
|
1284 |
|
|
libextras.a. For power controllers defined inside
|
1285 |
|
|
application code it is important that the power controllers end up in
|
1286 |
|
|
.o object files rather than in
|
1287 |
|
|
.a library archive files.
|
1288 |
|
|
|
1289 |
|
|
|
1290 |
|
|
All the real work of a power controller is done by the mode change
|
1291 |
|
|
function. If the power management package has been configured to use a
|
1292 |
|
|
separate thread then this mode change function will be invoked by that
|
1293 |
|
|
thread (except for the special case of
|
1294 |
|
|
linkend="power-change-controller-now">power_set_controller_mode_now).
|
1295 |
|
|
If no separate thread is used then the mode change function will be
|
1296 |
|
|
invoked directly by power_set_mode or
|
1297 |
|
|
power_set_controller_mode.
|
1298 |
|
|
|
1299 |
|
|
|
1300 |
|
|
The mode change function will be invoked with three arguments. The
|
1301 |
|
|
first argument identifies the power controller. Usually this argument
|
1302 |
|
|
is not actually required since a given mode change function will only
|
1303 |
|
|
ever be invoked for a single power controller. For example,
|
1304 |
|
|
xyzzy_device_power_mode_change will only ever be
|
1305 |
|
|
used in conjunction with xyzzy_power_controller.
|
1306 |
|
|
However there may be some packages which contain multiple controllers,
|
1307 |
|
|
all of which can share a single mode change function, and in that case
|
1308 |
|
|
it is essential to identify the specific controller. The second
|
1309 |
|
|
argument specifies the mode the controller should switch to, if
|
1310 |
|
|
possible: it will be one of PowerMode_Active,
|
1311 |
|
|
PowerMode_Idle, PowerMode_Sleep
|
1312 |
|
|
or PowerMode_Off. The final argument will be one of
|
1313 |
|
|
PowerModeChange_Controller,
|
1314 |
|
|
PowerModeChange_ControllerNow, or
|
1315 |
|
|
PowerModeChange_Global, and identifies the call
|
1316 |
|
|
that caused this invocation. For example, if the mode change function
|
1317 |
|
|
was invoked because of a call to power_set_mode
|
1318 |
|
|
then this argument will be PowerModeChange_Global.
|
1319 |
|
|
It is up to each controller to decide how to interpret this final
|
1320 |
|
|
argument. A typical controller might reject a global request to switch
|
1321 |
|
|
to off mode if the associated device is still busy, but
|
1322 |
|
|
if the request was aimed specifically at this controller then it could
|
1323 |
|
|
instead abort any current I/O operations and switch off the device.
|
1324 |
|
|
|
1325 |
|
|
|
1326 |
|
|
The PowerController data structure contains
|
1327 |
|
|
one field, mode, that needs to be updated
|
1328 |
|
|
by the power mode change function. At all times it should indicate the
|
1329 |
|
|
current mode for this controller. When a mode change is requested the
|
1330 |
|
|
desired mode is passed as the second argument. The exact operation of
|
1331 |
|
|
the power mode change function depends very much on what is being
|
1332 |
|
|
controlled and the current circumstances, but some guidelines are
|
1333 |
|
|
possible:
|
1334 |
|
|
|
1335 |
|
|
|
1336 |
|
|
|
1337 |
|
|
|
1338 |
|
|
If the request can be satisfied without obvious detriment, do so and
|
1339 |
|
|
update the mode field. Reducing the power
|
1340 |
|
|
consumption of a device that is not currently being used is generally
|
1341 |
|
|
harmless.
|
1342 |
|
|
|
1343 |
|
|
|
1344 |
|
|
|
1345 |
|
|
|
1346 |
|
|
If a request is a no-op, for example if the system is switching
|
1347 |
|
|
from idle to sleep mode and the controller
|
1348 |
|
|
does not distinguish between these modes, simply act as if the request
|
1349 |
|
|
was satisfied.
|
1350 |
|
|
|
1351 |
|
|
|
1352 |
|
|
|
1353 |
|
|
|
1354 |
|
|
If a request is felt to be unsafe, for example shutting down a
|
1355 |
|
|
device that is still in use, then the controller may decide
|
1356 |
|
|
to reject this request. This is especially true if the request was a
|
1357 |
|
|
global mode change as opposed to one intended specifically for this
|
1358 |
|
|
controller: in the latter case the policy module should be given due
|
1359 |
|
|
deference. There are a number of ways in which a request can be
|
1360 |
|
|
rejected:
|
1361 |
|
|
|
1362 |
|
|
|
1363 |
|
|
|
1364 |
|
|
|
1365 |
|
|
If the request cannot be satisfied immediately but may be feasible in
|
1366 |
|
|
a short while, leave the mode field
|
1367 |
|
|
unchanged. Higher-level code in the policy module can interpret this
|
1368 |
|
|
as a hint to retry the operation a little bit later. This approach is
|
1369 |
|
|
also useful if the mode change can be started but will take some time
|
1370 |
|
|
to complete, for example shutting down a socket connection, and
|
1371 |
|
|
additional processing will be needed later on.
|
1372 |
|
|
|
1373 |
|
|
|
1374 |
|
|
|
1375 |
|
|
|
1376 |
|
|
If the request is felt to be inappropriate, for example switching off
|
1377 |
|
|
a device that is still in use, the mode change function can
|
1378 |
|
|
call power_set_controller_mode to reset the
|
1379 |
|
|
desired mode for this controller back to the current mode.
|
1380 |
|
|
Higher-level code can then interpret this as a hint that there is more
|
1381 |
|
|
activity in the system than had been apparent.
|
1382 |
|
|
|
1383 |
|
|
|
1384 |
|
|
|
1385 |
|
|
|
1386 |
|
|
For a global mode change, if the new mode is felt to be inappropriate
|
1387 |
|
|
then the power controller can call power_set_mode
|
1388 |
|
|
to indicate this. An example of this would be the policy module
|
1389 |
|
|
deciding to switch off the whole unit while there is still I/O
|
1390 |
|
|
activity.
|
1391 |
|
|
|
1392 |
|
|
|
1393 |
|
|
|
1394 |
|
|
|
1395 |
|
|
|
1396 |
|
|
|
1397 |
|
|
Mode change functions should not directly manipulate any other fields
|
1398 |
|
|
in the PowerController data structure. If it
|
1399 |
|
|
is necessary to keep track of additional data then static variables
|
1400 |
|
|
can be used.
|
1401 |
|
|
|
1402 |
|
|
|
1403 |
|
|
It should be noted that the above are only guidelines. Their
|
1404 |
|
|
application in any given situation may be unclear. In addition the
|
1405 |
|
|
detailed requirements of specific systems will vary, so even if the
|
1406 |
|
|
power controller for a given device driver follows the above
|
1407 |
|
|
guidelines exactly it may turn out that slightly different behaviour
|
1408 |
|
|
would be more appropriate for the actual system that is being
|
1409 |
|
|
developed. Fortunately the open source nature of
|
1410 |
|
|
eCos allows system developers to fine-tune
|
1411 |
|
|
power controllers to meet their exact requirements.
|
1412 |
|
|
|
1413 |
|
|
|
1414 |
|
|
|
1415 |
|
|
|
1416 |
|
|
|
1417 |
|
|
|
1418 |
|
|
|
1419 |
|
|
|
1420 |
|
|
|