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

📄 power.cxx

📁 eCos操作系统源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      power.cxx////      Main implementation of power management support.////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    bartv// Contributors: bartv// Date:         2001-06-18////####DESCRIPTIONEND####////==========================================================================// Provide the external (non-inline) definitions of the inline functions// in power.h so there's something available in C code when the compiler// chooses not to inline#define POWER_INLINE extern "C"#include <pkgconf/power.h>#include <cyg/power/power.h>#include <cyg/infra/cyg_type.h>#include <cyg/infra/cyg_ass.h>#include <cyg/hal/hal_tables.h>// ----------------------------------------------------------------------------// Statics. Most of these are only relevant when a separate power// management thread is being used. Some of these are exported, e.g.// to allow the use of inline functions.// The current power mode for the system as a whole.PowerMode       __power_mode            = PowerMode_Active;// The mode that the system should be running at.PowerMode       __power_desired_mode    = PowerMode_Active;// The policy callback function, if any.__power_policy_callback_t __power_policy_callback = 0;// This flag is used to abort a mode change. It allows a controller to// call power_set_mode() while the mode is already being changed.static volatile cyg_bool abort_mode_change = false;#ifdef CYGPKG_POWER_THREADstatic unsigned char    power_thread_stack[CYGNUM_POWER_THREAD_STACKSIZE];static cyg_thread       power_thread;// The power management thread's handle is exported to support// operations like changing the thread's priority.cyg_handle_t     power_thread_handle;// This semaphore is used to wake up the power management thread when there// is work to be done.static cyg_sem_t        power_thread_action;#elsestatic cyg_bool         power_doing_it      = false;static cyg_uint32       power_todo_count    = 0;#endif// ----------------------------------------------------------------------------// Synchronisation.//// There are two exported functions to worry about: power_set_mode()// and power_set_controller_mode(). There are also two main scenarios:// CYGPKG_POWER_THREAD enabled and CYGPKG_POWER_THREAD_DISABLED.//// If CYGPKG_POWER_THREAD is enabled then any external code may at any// time invoke the exported functions. These are asynchronous calls.// In addition when the power management thread invokes a power// controller that controller may also call the exported functions,// synchronously. In either scenario the calls can return before the// operation has completed, hence the policy callback functionality.//// If CYGPKG_POWER_THREAD is disabled then there may be only one// external call to the exported functions, and the operation must// complete before that call returns. If there are multiple concurrent// external calls then the behaviour of the system is undefined.// Really. It is still possible for power controllers to call the// exported functions synchronously, which complicates things// somewhat.//// The CYGPKG_POWER_THREAD case is the easier to handle. The power// management thread simply loops forever, waiting on a semaphore// until there is some work to be done and then checking internal// state to figure out what that work should be. Some care has to be// taken that the internal state gets updated and read atomically,// which can be achieved by cyg_scheduler_lock() and unlock() calls in// strategic places. Obviously it is undesirable to keep these locks// longer than is absolutely necessary since that would impact// dispatch latency, and in particular power controllers must not be// invoked with the scheduler locked because there are no specific// restrictions on what a controller may or may not do.//// The call graph is something like://    power_thread_fn()     - the thread entry point, loops waiting on the semaphore//    power_doit()          - do the real work. This can be either a global mode//                            change or one or more individual controller mode changes.//                            Either operation involves iterating through the controllers.//    power_change_controller_mode() - manipulate an individual controller.//// There is one little complication. If during a power_doit()// set_mode() loop there is a call to power_set_mode() then the// current loop should be aborted. This is especially important when// switching to off mode and a controller has decided to cancel this// via another call to set_mode().//// If no separate thread is used then there will only ever be one// external call. That will result in an invocation of// power_nothread_doit(), which in turn calls power_doit() and// power_change_controller_mode() as in the threaded case. A flag is// used so that it is possible to distinguish between external and// synchronous calls, and a counter ensures that synchronous calls are// processed correctly. Recursion is avoided so that stack usage// remains deterministic.//    power_set_mode()/power_set_controller_mode()//    power_nothread_doit()//    power_doit()//    power_change_controller_mode();//// The main fields in the power controller data structures to worry// about are "mode", "desired_mode", and "change_this". "mode" is only// manipulated by the power controller itself, and since all power// controller accesses are serialized no problems arise.// "desired_mode" and "change_this" are updated by power_set_mode()// and power_set_controller_mode(), and read by power_doit(). If a separate// thread is in use then the scheduler lock protects access to thse fields.// Without a separate thread concurrency is not an issue. Obviously there// are other fields and variables, but most of these will only be set during// system start-up and the rest do not require any special attention.// ----------------------------------------------------------------------------// Do the real work.//// power_change_controller_mode() acts on a single controller. It is invoked only// from power_doit(), either for a global mode change or for an individual mode change.// It should be invoked with the scheduler unlocked - power_doit() is responsible for// synchronizing with the external calls.static inline voidpower_change_controller_mode(PowerController* controller, PowerMode desired_mode, cyg_bool change_this){    // The policy callback will want to know the previous power mode.    PowerMode old_mode = controller->mode;    // Invoke the mode change operation. Note that    // controller->change_this and controller->desired_mode may have    // been updated by now, but at some point they did have values    // which required a mode change.    (*controller->change_mode)(controller, desired_mode, change_this ? PowerModeChange_Controller : PowerModeChange_Global);    // Report the results to higher-level code. It is unlikely that

⌨️ 快捷键说明

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