1. 程式人生 > >【BLE】CC2541低功耗測試-系統執行篇

【BLE】CC2541低功耗測試-系統執行篇

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
}