⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power-controller.html

📁 ecos源代码包
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
<!-- This material may be distributed only subject to the terms      -->
<!-- and conditions set forth in the Open Publication License, v1.0  -->
<!-- or later (the latest version is presently available at          -->
<!-- http://www.opencontent.org/openpub/).                           -->
<!-- Distribution of the work or derivative of the work in any       -->
<!-- standard (paper) book form is prohibited unless prior           -->
<!-- permission is obtained from the copyright holder.               -->
<HTML
><HEAD
><TITLE
>Implementing a Power Controller</TITLE
><meta name="MSSmartTagsPreventParsing" content="TRUE">
<META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE="eCos Reference Manual"
HREF="ecos-ref.html"><LINK
REL="UP"
TITLE="eCos Power Management Support"
HREF="services-power.html"><LINK
REL="PREVIOUS"
TITLE="Attached and Detached Controllers"
HREF="power-attached.html"><LINK
REL="NEXT"
TITLE="eCos USB Slave Support"
HREF="io-usb-slave.html"></HEAD
><BODY
CLASS="REFENTRY"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>eCos Reference Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="power-attached.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="io-usb-slave.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><H1
><A
NAME="POWER-CONTROLLER">Implementing a Power Controller</H1
><DIV
CLASS="REFNAMEDIV"
><A
NAME="AEN15936"
></A
><H2
>Name</H2
>Implementing a Power Controller&nbsp;--&nbsp;adding power management support to device drivers and
other packages</DIV
><DIV
CLASS="REFSECT1"
><A
NAME="AEN15939"
></A
><H2
>Implementing a Power Controller</H2
><P
>A system will have some number of power controllers. Usually there
will be one power controller for the cpu,
<TT
CLASS="VARNAME"
>power_controller_cpu</TT
>, typically provided by one of
the HAL packages and responsible for managing the processor itself and
associated critical components such as memory. Some or all of the
device drivers will provide power controllers, allowing the power
consumption of the associated devices to be controlled. There may be
some arbitrary number of other controllers present in the system. The
power management package does not impose any restrictions on the
number or nature of the power controllers in the system, other than
insisting that at most one <TT
CLASS="VARNAME"
>power_controller_cpu</TT
> be
provided.</P
><P
>Each power controller involves a single data structure of type
<SPAN
CLASS="STRUCTNAME"
>PowerController</SPAN
>, defined in the header file
<TT
CLASS="FILENAME"
>cyg/power/power.h</TT
>. These data
structures should all be placed in the table
<TT
CLASS="LITERAL"
>__POWER__</TT
>, so that the power management package and
other code can easily locate all the controllers in the system. This
table is constructed at link-time, avoiding code-size or run-time
overheads. To facilitate this the package provides two macros which
should be used to define a power controller,
<TT
CLASS="LITERAL"
>POWER_CONTROLLER()</TT
> and
<TT
CLASS="LITERAL"
>POWER_CONTROLLER_CPU()</TT
>.</P
><P
>The macro <TT
CLASS="LITERAL"
>POWER_CONTROLLER</TT
> takes four arguments:</P
><P
></P
><OL
TYPE="1"
><LI
><P
>A variable name. This can be used to access the power controller
directly, as well as via the table.</P
></LI
><LI
><P
>A priority. The table of power controllers is sorted, such that power
controllers with a numerically lower priority come earlier in the
table. The special controller <TT
CLASS="VARNAME"
>power_controller_cpu</TT
>
always comes at the end of the table. When moving from a high-power
mode to a lower-powered mode, the power management package iterates
through the table from front to back. When moving to a higher-powered
mode the reverse direction is used. The intention is that the power
controller for a software-only package such as a TCP/IP stack should
appear near the start of the table, whereas the controllers for the
ethernet and similar devices would be near the end of the table. Hence
when the policy module initiates a mode change to a lower-powered mode
the TCP/IP stack gets a chance to cancel this mode change, before the
devices it depends on are powered down. Similarly when moving to a
higher-powered mode the devices will be re-activated before any
software that depends on those devices.</P
><P
>The header file <TT
CLASS="FILENAME"
>cyg/power/power.h</TT
> defines three
priorities <TT
CLASS="LITERAL"
>PowerPri_Early</TT
>,
<TT
CLASS="LITERAL"
>PowerPri_Typical</TT
> and
<TT
CLASS="LITERAL"
>PowerPri_Late</TT
>. For most controllers one of these
priorities, possibly with a small number added or subtracted, will
give sufficient control. If an application developer is uncertain
about the relative priorities of the various controllers, a simple
<A
HREF="power-info.html#POWER-INFO-IDS"
>test program</A
> that iterates over
the table will quickly eliminate any confusion.</P
></LI
><LI
><P
>A constant string identifier. If the system has been configured
without support for such identifiers
(<TT
CLASS="VARNAME"
>CYGIMP_POWER_PROVIDE_STRINGS</TT
>) then this identifer
will be discarded at compile-time. Otherwise it will be made available
to higher-level code using the function
<TT
CLASS="FUNCTION"
>power_get_controller_id</TT
>. </P
></LI
><LI
><P
>A function pointer. This will be invoked to perform actual mode
changes, as described below.</P
></LI
></OL
><P
>A typical example of the use of the
<TT
CLASS="LITERAL"
>POWER_CONTROLLER</TT
> macro would be as follows:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>#include &lt;pkgconf/system.h&gt;

#ifdef CYGPKG_POWER
# include &lt;cyg/power/power.h&gt;

static void
xyzzy_device_power_mode_change(
    PowerController* controller,
    PowerMode        desired_mode,
    PowerModeChange  change)
{
   // Do the work
}

static POWER_CONTROLLER(xyzzy_power_controller, \
                        PowerPri_Late,          \
                        "xyzzy device",         \
                        &amp;xyzzy_device_power_mode_change);
#endif</PRE
></TD
></TR
></TABLE
><P
>This creates a variable <TT
CLASS="VARNAME"
>xyzzy_power_controller</TT
>,
which is a power controller data structure that will end up near the
end of the table of power controllers. Higher-level code can
iterate through this table and report the string <TT
CLASS="LITERAL"
>"xyzzy
device"</TT
> to the user. Whenever there is a mode change
operation that affects this controller, the function
<TT
CLASS="FUNCTION"
>xyzzy_device_power_mode_change</TT
> will be invoked.
The variable is declared static so this controller cannot be
manipulated by name in any other code. Alternatively, if the variable
had not been declared static other code could manipulate this
controller by name as well as through the table, especially if the
package for the xyzzy device driver explicitly declared this
variable in an exported header file. Obviously exporting the variable
involves a slight risk of a name clash at link time.</P
><P
>The above code explicitly checks for the presence of the power
management package before including that package's header file or
providing any related functionality. Since power management
functionality is optional, such checks are recommended.</P
><P
>The macro <TT
CLASS="LITERAL"
>POWER_CONTROLLER_CPU</TT
> only takes two
arguments, a string identifier and a mode change function pointer.
This macro always instantiates a variable
<TT
CLASS="VARNAME"
>power_controller_cpu</TT
> so there is no need to provide
a variable name. The resulting power controller structure always
appears at the end of the table, so there is no need to specify a
priority. Typical usage of the <TT
CLASS="LITERAL"
>POWER_CONTROLLER_CPU</TT
>
macro would be:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>static void
wumpus_processor_power_mode_change(
    PowerController* controller,
    PowerMode        desired_mode,
    PowerModeChange  change)
{
   // Do the work
}

POWER_CONTROLLER_CPU("wumpus processor", \
                     &amp;wumpus_processor_power_mode_change);</PRE
></TD

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -