在Rt-thread中,定義了一個全局的系統定時器列表,當線程需要掛起的時候,就把線程內置的定時器將線程掛起到這個系統定時器列表中。這個列表維護一條雙向鏈路,節點按照定時器的延時時間大小進行升序排列。定時器列表的定義如下:
static rt_list_t rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
struct rt_list_node
{
struct rt_list_node *next; /**< point to next node. */
struct rt_list_node *prev; /**< point to prev node. */
};
一 初始化定時器列表

在rt_list_init中進行next,prev指針的初始化

兩個指針均指向節點本身

二 定時器在線程中的定義
在線程結構體rt_thread中定義了rt_timer。rt_timer的定義如下:
struct rt_timer
{
struct rt_object parent; /**< inherit from rt_object */
rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL];
void (*timeout_func)(void *parameter); /**< timeout function */
void *parameter; /**< timeout function's parameter */
rt_tick_t init_tick; /**< timer timeout tick */
rt_tick_t timeout_tick; /**< timeout tick */
};
(1) 定時器也屬於內核對象,所以自身結構中也會包含一個內核對象rt_object。通過這個成員將定時器掛到對象容器里面
(2) rt_list_t,定時器自身的節點。通過該節點可以實現將定時器插入到系統定時器列表
(3) timeout_func:定時器超時后的回調函數
(4) init_tick:定時器實際需要延時的時間
(5) timeout_tick:定時器超時后的tick值
三 定時器的初始化
rt_timer_init對定時器進行初始化

(1) 首先調用rt_object_init將該定時器插入到對應的容器中去
(2) 初始化rt_timer變量。對回調函數,延時ticket值進行賦值。並初始化定時器的內置節點,即將節點的next和prev這兩個指針指向節點本身。當啟動定時器的時候,定時器就通過該節點將自身插入到系統定時器列表rt_timer_list中

四 開啟定時器:
定時器初始化完后,調用rt_timer_start將定時器插入到rt_timer_list中去
1 首先是計算定時器超時的tick值
timer->timeout_tick = rt_tick_get() + timer->init_tick; 當系統定時器rt_tick的值等於timeout_tick時候,表示定時器到期。另外要求定時器超時時間不能大於RT_TICK_MAX / 2。RT_TICK_MAX的值定義在rtdef.h中。默認是最大值為0xffffffff
下面的代碼首先找到需要插入的位置。定時器在列表中是以降序的方式進行排列

2 最后調用rt_list_insert_after() 將定時器插入。
五 定時器停止
調用_rt_timer_remove將timer從定時器列表中刪除


