You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.1 KiB
210 lines
7.1 KiB
/**************************************************************************** |
|
* drivers/power/pm_internal.h |
|
* |
|
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. |
|
* Author: Gregory Nutt <gnutt@nuttx.org> |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in |
|
* the documentation and/or other materials provided with the |
|
* distribution. |
|
* 3. Neither the name NuttX nor the names of its contributors may be |
|
* used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGE. |
|
* |
|
****************************************************************************/ |
|
|
|
#ifndef __DRIVERS_POWER_PM_INTERNAL_H |
|
#define __DRIVERS_POWER_PM_INTERNAL_H |
|
|
|
/**************************************************************************** |
|
* Included Files |
|
****************************************************************************/ |
|
|
|
#include <nuttx/config.h> |
|
|
|
#include <semaphore.h> |
|
#include <queue.h> |
|
|
|
#include <nuttx/power/pm.h> |
|
#include <nuttx/wqueue.h> |
|
|
|
#ifdef CONFIG_PM |
|
|
|
/**************************************************************************** |
|
* Definitions |
|
****************************************************************************/ |
|
/* Configuration ************************************************************/ |
|
|
|
#ifndef CONFIG_SCHED_WORKQUEUE |
|
# warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)" |
|
#endif |
|
|
|
/* Convert the time slice interval into system clock ticks. |
|
* |
|
* CONFIG_PM_SLICEMS provides the duration of one time slice in milliseconds. |
|
* CLOCKS_PER_SEC provides the number of timer ticks in one second. |
|
* |
|
* slice ticks = (CONFIG_PM_SLICEMS msec / 1000 msec/sec) / |
|
* (CLOCKS_PER_SEC ticks/sec) |
|
*/ |
|
|
|
#define TIME_SLICE_TICKS ((CONFIG_PM_SLICEMS * CLOCKS_PER_SEC) / 1000) |
|
|
|
/* Function-like macros *****************************************************/ |
|
/**************************************************************************** |
|
* Name: pm_lock |
|
* |
|
* Descripton: |
|
* Lock the power management registry. NOTE: This function may return |
|
* an error if a signal is received while what (errno == EINTR). |
|
* |
|
****************************************************************************/ |
|
|
|
#define pm_lock() sem_wait(&g_pmglobals.regsem); |
|
|
|
/**************************************************************************** |
|
* Name: pm_unlock |
|
* |
|
* Descripton: |
|
* Unlock the power management registry. |
|
* |
|
****************************************************************************/ |
|
|
|
#define pm_unlock() sem_post(&g_pmglobals.regsem); |
|
|
|
/**************************************************************************** |
|
* Public Types |
|
****************************************************************************/ |
|
/* This structure encapsulates all of the global data used by the PM module */ |
|
|
|
struct pm_global_s |
|
{ |
|
/* state - The current state (as determined by an explicit call to |
|
* pm_changestate() |
|
* recommended - The recommended state based on the PM algorithm in |
|
* function pm_update(). |
|
* mndex - The index to the next slot in the memory[] array to use. |
|
* mcnt - A tiny counter used only at start up. The actual |
|
* algorithm cannot be applied until CONFIG_PM_MEMORY |
|
* samples have been collected. |
|
*/ |
|
|
|
uint8_t state; |
|
uint8_t recommended; |
|
uint8_t mndx; |
|
uint8_t mcnt; |
|
|
|
/* accum - The accumulated counts in this time interval |
|
* thrcnt - The number of below threshold counts seen. |
|
*/ |
|
|
|
int16_t accum; |
|
uint16_t thrcnt; |
|
|
|
/* This is the averaging "memory." The averaging algorithm is simply: |
|
* Y = (An*X + SUM(Ai*Yi))/SUM(Aj), where i = 1..n-1 and j= 1..n, n is the |
|
* length of the "memory", Ai is the weight applied to each value, and X is |
|
* the current activity. |
|
* |
|
* CONFIG_PM_MEMORY provides the memory for the algorithm. Default: 2 |
|
* CONFIG_PM_COEFn provides weight for each sample. Default: 1 |
|
*/ |
|
|
|
#if CONFIG_PM_MEMORY > 1 |
|
int16_t memory[CONFIG_PM_MEMORY-1]; |
|
#endif |
|
|
|
/* stime - The time (in ticks) at the start of the current time slice */ |
|
|
|
uint32_t stime; |
|
|
|
/* This semaphore manages mutually exclusive access to the power management |
|
* registry. It must be initialized to the value 1. |
|
*/ |
|
|
|
sem_t regsem; |
|
|
|
/* For work that has been deferred to the worker thread */ |
|
|
|
struct work_s work; |
|
|
|
/* registry is a singly-linked list of registered power management |
|
* callback structures. To ensure mutually exclusive access, this list |
|
* must be locked by calling pm_lock() before it is accessed. |
|
*/ |
|
|
|
sq_queue_t registry; |
|
}; |
|
|
|
/**************************************************************************** |
|
* Public Data |
|
****************************************************************************/ |
|
|
|
#undef EXTERN |
|
#if defined(__cplusplus) |
|
# define EXTERN extern "C" |
|
extern "C" |
|
{ |
|
#else |
|
# define EXTERN extern |
|
#endif |
|
|
|
/* All PM global data: */ |
|
|
|
EXTERN struct pm_global_s g_pmglobals; |
|
|
|
/************************************************************************************ |
|
* Public Function Prototypes |
|
************************************************************************************/ |
|
|
|
/**************************************************************************** |
|
* Name: pm_update |
|
* |
|
* Description: |
|
* This internal function is called at the end of a time slice in order to |
|
* update driver activity metrics and recommended states. |
|
* |
|
* Input Parameters: |
|
* accum - The value of the activity accumulator at the end of the time |
|
* slice. |
|
* |
|
* Returned Value: |
|
* None. |
|
* |
|
* Assumptions: |
|
* This function may be called from a driver, perhaps even at the interrupt |
|
* level. It may also be called from the IDLE loop at the lowest possible |
|
* priority level. To reconcile these various conditions, all work is |
|
* performed on the worker thread at a user-selectable priority. |
|
* |
|
****************************************************************************/ |
|
|
|
EXTERN void pm_update(int16_t accum); |
|
|
|
#undef EXTERN |
|
#if defined(__cplusplus) |
|
} |
|
#endif |
|
|
|
#endif /* CONFIG_PM */ |
|
#endif /* #define __DRIVERS_POWER_PM_INTERNAL_H */
|
|
|