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

📄 power.cxx

📁 eCos操作系统源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
    // the policy callback will be changed while the system is running,    // but just in case somebody installs a null pointer between the    // check and the call...    void        (*callback)(PowerController*, PowerMode, PowerMode, PowerMode, PowerMode) = __power_policy_callback;    if (0 != callback) {        (*callback)(controller, old_mode, controller->mode, desired_mode, controller->desired_mode);    }}// power_doit() is responsible for a single iteration over the various controllers,// aborting if there is a global mode change during the current iteration. The// calling code, either power_thread_fn() or power_nothread_doit(), will take// care of the higher-level iterating while there is work to be done.//// If a global mode change has been requested then the order in which the controllers// are invoked is significant: front->back for lowering power modes, back->front for// a higher power mode. If there are individual changes to be processed then// arbitrarily front->back is used as well.static inline voidpower_doit(){    PowerController*    controller;    abort_mode_change   = false;    if (__power_desired_mode < __power_mode) {        // The new mode is more active than the old one, so start with        // the power controllers at the back of the table.        for (controller = &(__POWER_END__) - 1; !abort_mode_change && (controller >= &(__POWER__[0])); controller--) {            PowerMode   desired_mode;            cyg_bool    change_this;            #ifdef CYGPKG_POWER_THREAD            // Read the desired_mode and change_this flags atomically.            cyg_scheduler_lock();            desired_mode = controller->desired_mode;            change_this  = controller->change_this;            cyg_scheduler_unlock();#else            desired_mode = controller->desired_mode;            change_this  = controller->change_this;#endif            // If this controller is not running at the desired mode, change it.            if (desired_mode != controller->mode) {                power_change_controller_mode(controller, desired_mode, change_this);            }        }    } else {    // __power_desired_mode >= __power_mode.        // Either a global mode change to a less active mode, or        // one or more individual controller changes. Other than        // iterating in a different direction, the code is the same        // as above.        for (controller = &(__POWER__[0]); !abort_mode_change && (controller != &(__POWER_END__)); controller++) {            PowerMode   desired_mode;            cyg_bool    change_this;            #ifdef CYGPKG_POWER_THREAD            cyg_scheduler_lock();            desired_mode = controller->desired_mode;            change_this  = controller->change_this;            cyg_scheduler_unlock();#else            desired_mode = controller->desired_mode;            change_this  = controller->change_this;#endif            if (desired_mode != controller->mode) {                power_change_controller_mode(controller, desired_mode, change_this);            }        }    }    // All of the controllers have been invoked. If there have been no    // intervening calls to power_set_mode() (which would have updated    // abort_mode_change) then we must now be running at the desired    // global mode.    if (!abort_mode_change) {        __power_mode = __power_desired_mode;    }}#ifdef CYGPKG_POWER_THREADstatic voidpower_thread_fn(cyg_addrword_t param){    for (;;) {        // Currently idle. Wait for a request to change power modes.        cyg_semaphore_wait(&power_thread_action);        power_doit();    }}#elsestatic inline voidpower_nothread_doit(){    power_todo_count++;    if (!power_doing_it) {        power_doing_it = true;        do {            power_doit();        } while (--power_todo_count > 0);        power_doing_it = false;    }}#endif// ----------------------------------------------------------------------------// The exported calls.extern "C" voidpower_set_controller_mode(PowerController* controller, PowerMode new_mode){#ifdef CYGPKG_POWER_THREAD    cyg_scheduler_lock();   // Protect against concurrent calls#endif        controller->desired_mode    = new_mode;    controller->change_this     = true;#ifdef CYGPKG_POWER_THREAD        cyg_scheduler_unlock();    cyg_semaphore_post(&power_thread_action);#else    power_nothread_doit();#endif    }extern "C" voidpower_set_mode(PowerMode new_mode){    PowerController*        controller;#ifdef CYGPKG_POWER_THREAD    cyg_scheduler_lock();#endif        __power_desired_mode    = new_mode;    abort_mode_change       = true;    // Update each controller. Most importantly, clear the    // "change_this" flag in every power controller. The net result is    // that power_set_mode() overrides any power_set_controller_mode()    // operations that have not yet been processed, but future    // power_set_controller_mode() calls will have the desired effect.    for (controller = &(__POWER__[0]); controller != &(__POWER_END__); controller++) {        if (controller->attached) {            controller->change_this     = 0;            controller->desired_mode    = new_mode;        }    }#ifdef CYGPKG_POWER_THREAD        cyg_scheduler_unlock();    cyg_semaphore_post(&power_thread_action);#else    power_nothread_doit();#endif    }// ----------------------------------------------------------------------------// Power management initialization. This gets called from// power_data.cxx using a prioritized constructors. Doing this way// minimizes the amount of data that is going to end up in libextras.a// and hence in the final executable, allowing linker garbage collection// to clean up as much as possible. The main operation here is to start// up a separate power management thread when configured to do so.//// If no separate thread is being used then no run-time initialization// is needed.#ifdef CYGPKG_POWER_THREADextern "C" voidpower_init(void){    cyg_semaphore_init(&power_thread_action, 0);    cyg_thread_create(CYGNUM_POWER_THREAD_PRIORITY,                      &power_thread_fn,                      (cyg_addrword_t) 0,                      "Power management thread",                      power_thread_stack,                      CYGNUM_POWER_THREAD_STACKSIZE,                      &power_thread_handle,                      &power_thread        );    cyg_thread_resume(power_thread_handle);}#endif    

⌨️ 快捷键说明

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