1.osal_pwrmgr_powerconserve
描述: osal_pwrmgr_powerconserve()函数低功耗具体的处理函数,可以发现要想支持此功能,必须首先包含POWER_SAVING这个宏。细心的同学发现系统死循环后面会一直调用这个函数。每次调用都会检测Timeout在个Timer事件中的Timeout最小值,比如系统1ms轮训检查Timer是否需要处理,按键事件的Timeout是100,意思就是100ms才会检测是否有按键按下,假如按键事件在Timeout的各个Timer事件中Timeout最小,那么就是说有99ms毫秒不会有按键事件的处理,但是死循环一直在跑,在做无用功,为了解决这个问题,就加入了省电模式。所以说,在检测到Timer时间链表中的Timeout的最小值,假设为next,然后CPU进入休眠模式next毫秒,休眠时间到了苏醒过来就会有Timer事件需要处理这样就可以达到省电的目的。
源文件1: osal_pwrmgr.c
代码段1:
#if defined( POWER_SAVING )
/*********************************************************************
* @fn osal_pwrmgr_powerconserve
*
* @brief This function is called from the main OSAL loop when there are
* no events scheduled and shouldn't be called from anywhere else.
*
* @param none.
*
* @return none.
*/
void osal_pwrmgr_powerconserve( void )
{
uint32 next;
halIntState_t intState;
// Should we even look into power conservation
//首先检查是否允许进入低功耗的处理
if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON )
{
// Are all tasks in agreement to conserve
//是否所有的任务支持低功耗功能
if ( pwrmgr_attribute.pwrmgr_task_state == 0 )
{
// Hold off interrupts.
HAL_ENTER_CRITICAL_SECTION( intState );
// Get next time-out
//查询软件定时器链表的溢出时间间隔
next = osal_next_timeout();
// Re-enable interrupts.
HAL_EXIT_CRITICAL_SECTION( intState );
// Put the processor into sleep mode
OSAL_SET_CPU_INTO_SLEEP( next );
}
}
}
#endif /* POWER_SAVING */
源文件2: osal.c
代码段2:
void osal_run_system( void )
{
uint8 idx = 0;
#if defined (WDT_USED)
WD_KICK();
#endif
#ifndef HAL_BOARD_CC2538
osalTimeUpdate();
#endif
Hal_ProcessPoll();
do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break;
}
} while (++idx < tasksCnt);
if (idx < tasksCnt)
{
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);
events = tasksEvents[idx];
tasksEvents[idx] = 0; // Clear the Events for this task.
HAL_EXIT_CRITICAL_SECTION(intState);
activeTaskID = idx;
events = (tasksArr[idx])( idx, events );
activeTaskID = TASK_NO_TASK;
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState);
}
#if defined( POWER_SAVING )
else // Complete pass through all task events with no activity?
{
osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
}
#endif
/* Yield in case cooperative scheduling is being used. */
#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
{
osal_task_yield();
}
#endif
}