【BLE】CC2541低功耗測試-系統執行篇
阿新 • • 發佈:2019-02-15
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
}