zigbee協議棧中osal_start_timerEx()函數的使用方法

osal_start_timerEx是一個用來設置定時器,使某任務能夠定時運行的函數。但是想要了解這個函數,需要層層上推,瞭解到更深層次,才能夠明白它工作的原理。

首先了解一下osal_start_timerEx函數的原型:

uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )
{
  halIntState_t intState;
  osalTimerRec_t *newTimer;

  HAL_ENTER_CRITICAL_SECTION( intState );  

  newTimer = osalAddTimer( taskID, event_id, timeout_value );   //添加新定時器

  HAL_EXIT_CRITICAL_SECTION( intState );   

  return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
}

 

 

其中,參數的含義是:

taskID:要設定定時器的任務ID號;

event_id:事件的類型(我的理解是要設定定時器的事件是個什麼類型的事件);

timeout_value:定時時間,即發送週期信息的時間週期。

 

函數裏需要注意的是osalAddTimer函數,這個函數的功能就是添加一個新定時器。但是新的定時器添加到哪裏了呢?我們先來了解一下定時器的數據結構:

typedef struct

{

  void   *next;

  uint16 timeout;  

  uint16 event_flag;

  uint8  task_id;

  uint16 reloadTimeout;

} osalTimerRec_t;

數據結構中包括timeout、event_flag、task_id和reloadTimeout,除此之外,還有一個next指針。瞭解數據結構的話都知道,這項的存在說明這個結構體能夠組成一個鏈表,因此實際上是存在一個由定時器結構體組成的鏈表,這個鏈表叫做軟件定時器數據鏈表。

因此osalAddTimer函數就是在這個鏈表中新增添了一個定時器節點,那麼這個鏈表是由哪個函數來管理的呢?是由osalTimerUpdate函數管理的。由osalTimerUpdate以ms爲單位對這些“軟定時器”減計數,當定時器溢出,即調用osal_set_event函數。Osal_set_event是專門用來設置tasksEvents,而tasksEvents數組存放了一個任務是否該被運行的序列(tasksEvents不清楚的話似乎應該先從頭學起)。

所以總結起來是這樣子的:osal_start_timerEx通過osalAddTimer向鏈表中添加定時器,由osalTimerUpdate來減計數,當這個定時器溢出後,則會對taskID對應的task設置一個event_id,從而讓這個任務在後面的主循環中運行到。能夠在主循環中運行到的原因是會調用osal_set_event函數來實現主循環裏對此項任務的調用。

舉例:

osal_start_timerEx( SampleApp_TaskID,

SAMPLEAPP_SEND_PERIODIC_MSG_EVT,

SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF) );

SampleApp_TaskID:任務優先級ID,在任務初始化函數SampleApp_Init()中被初始化,ID號是由協議棧的操作系統OSAL分配;

SAMPLEAPP_SEND_PERIODIC_MSG_EVT:發送週期信息事件;

SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT:定時時間,在自己的應用文件夾App中定義。

(如:#define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT   3000      //每隔3秒)

 

當網絡組建成功後,每隔SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF),即3秒的時間就會去執行SAMPLEAPP_SEND_PERIODIC_MSG_EVT觸發的函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章