rt-thread的定時器管理源碼分析

1 前言

rt-thread可以採用軟件定時器或硬件定時器來實現定時器管理的,所謂軟件定時器是指由操作系統提供的一類系統接口,它構建在硬件定時器基礎之上,使系統能夠提供不受數目限制的定時器服務。而硬件定時器是芯片本身提供的定時功能。一般是由外部晶振提供給芯片輸入時鐘,芯片向軟件模塊提供一組配置寄存器,接受控制輸入,到達設定時間值後芯片中斷控制器產生時鐘中斷。硬件定時器的精度一般很高,可以達到納秒級別,並且是中斷觸發方式。軟件定時器的精度取決於它使用的硬件定時器精度。而rt-thread操作系統在默認情況下是採用的硬件定時器的方式,用戶可以通過修改宏定義#ifdef RT_USING_TIMER_SOFT來修改採用哪種。

2 rt-thread的定時器的基本工作原理

在RT-Thread定時器模塊維護兩個重要的全局變量,一個是當前系統的時間rt_tick(當硬件定時器中斷來臨時,它將加1),另一個是定時器鏈表rt_timer_list,系統中新創建的定時期都會被以排序的方式插入到rt_timer_list(硬件定時器模式下使用)鏈表中,rt_timer_list的每個節點保留了一個定時器的信息,並且在這個節點加入鏈表時就計算好了產生時間到達時的時間點,即tick,在rt-thread系統中如果採用軟件定時器模式,則存在一定時器線程rt_thread_timer_entry,不斷獲取當前TICK值並與定時器鏈表rt_timer_list上的定時器對比判斷是否時間已到,一旦發現就調用對應的回調函數,即事件處理函數進行處理,而如果採用硬件定時器管理模式的話,則該檢查過程放到系統時鐘中斷例程中進行處理,此時,是不存在定時器線程的。如下圖:注:如果採用軟件定時器軟件定時器,則該定時器鏈表爲rt_soft_timer_list。

3 源碼分析

3.1 數據定義

[cpp] view plain copy
  1. /** 
  2.  * timer structure 
  3.  */  
  4. struct rt_timer  
  5. {  
  6.     struct rt_object parent; //內核對象  
  7.   
  8.     rt_list_t        list;      //鏈表節點  
  9.   
  10.     void (*timeout_func)(void *parameter);  //定時器超時例程  
  11.     void            *parameter;       //定時器例程的傳入參數  
  12.   
  13.     rt_tick_t        init_tick;       //定時器的超時時間,即總共多長時間將產生超時事件  
  14.     rt_tick_t        timeout_tick;     //定時器超時的時間點,即產生超時事件時那一該的時間點  
  15. };  
  16. typedef struct rt_timer *rt_timer_t;  

3.2 rt-thread的軟件定時器模式

軟件定時器線程初始化及啓動:

[cpp] view plain copy
  1. /** 
  2.  * @ingroup SystemInit 
  3.  * 
  4.  * This function will initialize system timer thread 
  5.  */  
  6. void rt_system_timer_thread_init(void)  
  7. {  
  8. #ifdef RT_USING_TIMER_SOFT//如果採用軟件定時器管理模式,則啓動定時器線程  
  9.     rt_list_init(&rt_soft_timer_list);//初始化軟件定時器鏈表  
  10.   
  11.     /* start software timer thread */  
  12.     rt_thread_init(&timer_thread,//初始化軟件定時器線程,並啓動  
  13.                    "timer",  
  14.                    rt_thread_timer_entry,  
  15.                    RT_NULL,  
  16.                    &timer_thread_stack[0],  
  17.                    sizeof(timer_thread_stack),  
  18.                    RT_TIMER_THREAD_PRIO,  
  19.                    10);  
  20.   
  21.     /* startup */  
  22.     rt_thread_startup(&timer_thread);  
  23. #endif  
  24. }  

軟件定時器線程如下:
[cpp] view plain copy
  1. /* system timer thread entry */  
  2. static void rt_thread_timer_entry(void *parameter)  
  3. {  
  4.     rt_tick_t next_timeout;  
  5.       
  6.     while (1)  
  7.     {  
  8.         /* get the next timeout tick */  
  9.         next_timeout = rt_timer_list_next_timeout(&rt_soft_timer_list);//得到軟件定時器鏈表上的下一個定時器的超時時間點  
  10.         if (next_timeout == RT_TICK_MAX)//如果超過範圍,則掛起當前線程,繼續線程調度  
  11.         {  
  12.             /* no software timer exist, suspend self. */  
  13.             rt_thread_suspend(rt_thread_self());  
  14.             rt_schedule();  
  15.         }  
  16.         else  
  17.         {  
  18.             rt_tick_t current_tick;  
  19.   
  20.             /* get current tick */  
  21.             current_tick = rt_tick_get();//獲取當前時間點  
  22.   
  23.             if ((next_timeout - current_tick) < RT_TICK_MAX/2)//離下箇中斷時間點還差些時候  
  24.             {  
  25.                 /* get the delta timeout tick */  
  26.                 next_timeout = next_timeout - current_tick;//計算還差多長時間  
  27.                 rt_thread_delay(next_timeout);//休眠一段時間  
  28.             }  
  29.         }  
  30.   
  31.         /* lock scheduler */  
  32.         rt_enter_critical();//時間到,進入臨界區  
  33.         /* check software timer */  
  34.         rt_soft_timer_check();//檢查是否該產生超時事件  
  35.         /* unlock scheduler */  
  36.         rt_exit_critical();//退出臨界區  
  37.     }  
  38. }  

檢查是否產生中斷函數rt_soft_timer_check函數如下定義:
[cpp] view plain copy
  1. /** 
  2.  * This function will check timer list, if a timeout event happens, the 
  3.  * corresponding timeout function will be invoked. 
  4.  */  
  5. void rt_soft_timer_check(void)  
  6. {  
  7.     rt_tick_t current_tick;  
  8.     rt_list_t *n;  
  9.     struct rt_timer *t;  
  10.   
  11.     RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n"));  
  12.   
  13.     current_tick = rt_tick_get();//得到當前時間點  
  14.   
  15.     for (n = rt_soft_timer_list.next; n != &(rt_soft_timer_list);)//得到下一定時器節點  
  16.     {  
  17.         t = rt_list_entry(n, struct rt_timer, list);//t指向rt_timer定時器  
  18.   
  19.         /* 
  20.          * It supposes that the new tick shall less than the half duration of 
  21.          * tick max. 
  22.          */  
  23.         if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)//如果當前的時間點超過定時器的超時時間點  
  24.         {  
  25.             RT_OBJECT_HOOK_CALL(rt_timer_timeout_hook, (t));//使用鉤子函數  
  26.   
  27.             /* move node to the next */  
  28.             n = n->next;//指向下一定時器  
  29.   
  30.             /* remove timer from timer list firstly */  
  31.             rt_list_remove(&(t->list));//移除當前定時器  
  32.   
  33.             /* call timeout function */  
  34.             t->timeout_func(t->parameter);//產生定時器超時事件,調用對應處理函數  
  35.   
  36.             /* re-get tick */  
  37.             current_tick = rt_tick_get();//再次獲取當前時間點  
  38.   
  39.             RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));  
  40.   
  41.             if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&//如果當前定時器是週期性定時器,則將其再次按序放入軟件定時器鏈表  
  42.                 (t->parent.flag & RT_TIMER_FLAG_ACTIVATED))  
  43.             {  
  44.                 /* start it */  
  45.                 t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;//置標誌爲非激活狀態  
  46.                 rt_timer_start(t);//再次將定時器t放入軟件定時器鏈表末尾  
  47.             }  
  48.             else  
  49.             {  
  50.                 /* stop timer */  
  51.                 t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;//置標誌爲非激活狀態  
  52.             }  
  53.         }  
  54.         else break/* not check anymore */  
  55.     }  
  56.   
  57.     RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));  
  58. }  


上面代碼中,爲什麼定時器裏判斷超時的條件是((current_tick - t→timeout_tick) < RT_TICK_MAX/2)?

因爲系統時鐘溢出後會自動迴繞。取定時器比較最大值是定時器最大值的一半,即RT_TICK_MAX/2(在比較兩個定時器值時,值是32位無符號數,相減運算將會自動迴繞)。系統支持的定時器最大長度就是RT_TICK_MAX的一半:即248天(10ms/tick),124天(5ms/tick),24.5天(1ms/tick),以下內容相同道理。

其上rt_timer_start函數如下定義:

[cpp] view plain copy
  1. /** 
  2.  * This function will start the timer 
  3.  * 
  4.  * @param timer the timer to be started 
  5.  * 
  6.  * @return the operation status, RT_EOK on OK, -RT_ERROR on error 
  7.  */  
  8. rt_err_t rt_timer_start(rt_timer_t timer)  
  9. {  
  10.     struct rt_timer *t;  
  11.     register rt_base_t level;  
  12.     rt_list_t *n, *timer_list;  
  13.   
  14.     /* timer check */  
  15.     RT_ASSERT(timer != RT_NULL);  
  16.     if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)//如果傳入的定時器已經激活,則直接返回錯誤  
  17.         return -RT_ERROR;  
  18.   
  19.     RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));//使用鉤子函數  
  20.   
  21.     /* 
  22.      * get timeout tick, 
  23.      * the max timeout tick shall not great than RT_TICK_MAX/2 
  24.      */  
  25.     RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2);  
  26.     timer->timeout_tick = rt_tick_get() + timer->init_tick;//得到定時器超時的時間點  
  27.   
  28.     /* disable interrupt */  
  29.     level = rt_hw_interrupt_disable();//關中斷  
  30.   
  31. #ifdef RT_USING_TIMER_SOFT//如果採用的是軟件定時器管理模式,則將定時器加入到rt_soft_timer_list中  
  32.     if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)  
  33.     {  
  34.         /* insert timer to soft timer list */  
  35.         timer_list = &rt_soft_timer_list;  
  36.     }  
  37.     else  
  38. #endif  
  39.     {  
  40.         /* insert timer to system timer list */  
  41.         timer_list = &rt_timer_list;  
  42.     }  
  43.   
  44.     for (n = timer_list->next; n != timer_list; n = n->next)//將定時器按序加入到定時器鏈表中  
  45.     {  
  46.         t = rt_list_entry(n, struct rt_timer, list);  
  47.           
  48.         /* 
  49.          * It supposes that the new tick shall less than the half duration of 
  50.          * tick max. 
  51.          */  
  52.         if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX / 2)  
  53.         {  
  54.             rt_list_insert_before(n, &(timer->list));//將定時器timer插入到t之前  
  55.             break;  
  56.         }  
  57.     }  
  58.     /* no found suitable position in timer list */  
  59.     if (n == timer_list)//沒有找到合適的位置,則放到鏈表頭  
  60.     {  
  61.         rt_list_insert_before(n, &(timer->list));  
  62.     }  
  63.   
  64.     timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;//置定時器爲激活狀態  
  65.   
  66.     /* enable interrupt */  
  67.     rt_hw_interrupt_enable(level);  
  68.   
  69. #ifdef RT_USING_TIMER_SOFT  
  70.     if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)//如果系統採用的是軟件定時器管理模式,且軟件定時器線程處理ready狀態,則恢復此線程  
  71.     {  
  72.         /* check whether timer thread is ready */  
  73.         if (timer_thread.stat != RT_THREAD_READY)  
  74.         {  
  75.             /* resume timer thread to check soft timer */  
  76.             rt_thread_resume(&timer_thread);//恢復定時器線程  
  77.             rt_schedule();//開始線程調度  
  78.         }  
  79.     }  
  80. #endif  
  81.   
  82.     return -RT_EOK;  
  83. }  

軟件定時器管理模式的源碼分析完了,接下來介紹RTT的硬件定時器管理模式。

3.3 RTT的硬件定時器管理模式

硬件定時器管理模式顧名思義,就是說與硬件相關,因此,不用的MCU,其部分源碼是不一樣的,因爲其要採用MCU的系統時鐘中斷例程來實現。

以STM32F2XX爲例,先找到其啓動彙編,位置在:RTT/bsp/stm32f2xx/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F2xx/startup/arm/startup_stm32f2xx.s

找到中斷向量:

[plain] view plain copy
  1. DCD     SysTick_Handler            ; SysTick Handler  
這是系統時鐘中斷向量,再找到其中斷例程實現:

在bsp/stm32f2xx/drivers/board.c文件中:

[cpp] view plain copy
  1. /** 
  2.  * This is the timer interrupt service routine. 
  3.  * 
  4.  */  
  5. void SysTick_Handler(void)//系統時鐘中斷例程  
  6. {  
  7.     /* enter interrupt */  
  8.     rt_interrupt_enter();  
  9.   
  10.     rt_tick_increase();  
  11.   
  12.     /* leave interrupt */  
  13.     rt_interrupt_leave();  
  14. }  

其中rt_tick_increase函數在RTT/src/clock.c文件中的實現如下:
[cpp] view plain copy
  1. /** 
  2.  * This function will notify kernel there is one tick passed. Normally, 
  3.  * this function is invoked by clock ISR. 
  4.  */  
  5. void rt_tick_increase(void)  
  6. {  
  7.     struct rt_thread *thread;  
  8.   
  9.     /* increase the global tick */  
  10.     ++ rt_tick;//全局rt_tick加1  
  11.   
  12.     /* check time slice */  
  13.     thread = rt_thread_self();//得到當前正在運行的線程  
  14.   
  15.     -- thread->remaining_tick;//純種剩下時間減1  
  16.     if (thread->remaining_tick == 0)//如果線程剩餘時間爲0,即調度時間已到  
  17.     {  
  18.         /* change to initialized tick */  
  19.         thread->remaining_tick = thread->init_tick;//將線程剩餘時間重新設置初始化值  
  20.   
  21.         /* yield */  
  22.         rt_thread_yield();//調度時間到,切換到其它線程  
  23.     }  
  24.   
  25.     /* check timer */  
  26.     rt_timer_check();//檢查硬件定時器鏈表是否有定時器產生超時事件  
  27. }  

其中rt_timer_check函數在RTT/src/timer.c文件中如下定義:
[cpp] view plain copy
  1. /** 
  2.  * This function will check timer list, if a timeout event happens, the 
  3.  * corresponding timeout function will be invoked. 
  4.  * 
  5.  * @note this function shall be invoked in operating system timer interrupt. 
  6.  */  
  7. void rt_timer_check(void)  
  8. {  
  9.     struct rt_timer *t;  
  10.     rt_tick_t current_tick;  
  11.     register rt_base_t level;  
  12.   
  13.     RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));  
  14.   
  15.     current_tick = rt_tick_get();  
  16.   
  17.     /* disable interrupt */  
  18.     level = rt_hw_interrupt_disable();  
  19.   
  20.     while (!rt_list_isempty(&rt_timer_list))  
  21.     {  
  22.         t = rt_list_entry(rt_timer_list.next, struct rt_timer, list);  
  23.   
  24.         /* 
  25.          * It supposes that the new tick shall less than the half duration of 
  26.          * tick max. 
  27.          */  
  28.         if ((current_tick - t->timeout_tick) < RT_TICK_MAX/2)  
  29.         {  
  30.             RT_OBJECT_HOOK_CALL(rt_timer_timeout_hook, (t));  
  31.   
  32.             /* remove timer from timer list firstly */  
  33.             rt_list_remove(&(t->list));  
  34.   
  35.             /* call timeout function */  
  36.             t->timeout_func(t->parameter);  
  37.   
  38.             /* re-get tick */  
  39.             current_tick = rt_tick_get();  
  40.   
  41.             RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));  
  42.   
  43.             if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&  
  44.                 (t->parent.flag & RT_TIMER_FLAG_ACTIVATED))  
  45.             {  
  46.                 /* start it */  
  47.                 t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;  
  48.                 rt_timer_start(t);  
  49.             }  
  50.             else  
  51.             {  
  52.                 /* stop timer */  
  53.                 t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;  
  54.             }  
  55.         }  
  56.         else  
  57.             break;  
  58.     }  
  59.   
  60.     /* enable interrupt */  
  61.     rt_hw_interrupt_enable(level);  
  62.   
  63.     RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check leave\n"));  
  64. }  

此函數與rt_soft_timer_check基本大致相同,只不過一個是查找硬件定時器鏈表rt_timer_list,一個是查找rt_soft_timer_list.

在此,硬件定時器管理模式基本上介紹完畢,接下來介紹一些定時器接口.

4 定時器接口

4.1 定時器初始化

靜態初始化定義器

[cpp] view plain copy
  1. /** 
  2.  * This function will initialize a timer, normally this function is used to 
  3.  * initialize a static timer object. 
  4.  * 
  5.  * @param timer the static timer object 
  6.  * @param name the name of timer 
  7.  * @param timeout the timeout function 
  8.  * @param parameter the parameter of timeout function 
  9.  * @param time the tick of timer 
  10.  * @param flag the flag of timer 
  11.  */  
  12. void rt_timer_init(rt_timer_t  timer,  
  13.                    const char *name,  
  14.                    void (*timeout)(void *parameter),  
  15.                    void       *parameter,  
  16.                    rt_tick_t   time,  
  17.                    rt_uint8_t  flag)  
  18. {  
  19.     /* timer check */  
  20.     RT_ASSERT(timer != RT_NULL);  
  21.   
  22.     /* timer object initialization */  
  23.     rt_object_init((rt_object_t)timer, RT_Object_Class_Timer, name);//初始化內核對象  
  24.   
  25.     _rt_timer_init(timer, timeout, parameter, time, flag);  
  26. }  

_rt_timer_init函數如下定義:
[cpp] view plain copy
  1. static void _rt_timer_init(rt_timer_t timer,  
  2.                            void (*timeout)(void *parameter),  
  3.                            void      *parameter,  
  4.                            rt_tick_t  time,  
  5.                            rt_uint8_t flag)  
  6. {  
  7.     /* set flag */  
  8.     timer->parent.flag  = flag;//置flag  
  9.   
  10.     /* set deactivated */  
  11.     timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;//初始化時,設置爲非激活狀態  
  12.   
  13.     timer->timeout_func = timeout;//設置超時事件處理函數  
  14.     timer->parameter    = parameter;//超時事件處理函數的傳入參數  
  15.   
  16.     timer->timeout_tick = 0;//定時器的超時時間點初始化時爲0  
  17.     timer->init_tick    = time;//置超時時間  
  18.   
  19.     /* initialize timer list */  
  20.     rt_list_init(&(timer->list));//初始化本身節點  
  21. }  

動態創建定時器

[cpp] view plain copy
  1. /** 
  2.  * This function will create a timer 
  3.  * 
  4.  * @param name the name of timer 
  5.  * @param timeout the timeout function 
  6.  * @param parameter the parameter of timeout function 
  7.  * @param time the tick of timer 
  8.  * @param flag the flag of timer 
  9.  * 
  10.  * @return the created timer object 
  11.  */  
  12. rt_timer_t rt_timer_create(const char *name,  
  13.                            void (*timeout)(void *parameter),  
  14.                            void       *parameter,  
  15.                            rt_tick_t   time,  
  16.                            rt_uint8_t  flag)  
  17. {  
  18.     struct rt_timer *timer;  
  19.   
  20.     /* allocate a object */  
  21.     timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name);//動態分配定時器內核對象  
  22.     if (timer == RT_NULL)  
  23.     {  
  24.         return RT_NULL;  
  25.     }  
  26.   
  27.     _rt_timer_init(timer, timeout, parameter, time, flag);//調用上述的初始化接口  
  28.   
  29.     return timer;  
  30. }  


4.2 脫離和刪除

脫離:

[cpp] view plain copy
  1. /** 
  2.  * This function will detach a timer from timer management. 
  3.  * 
  4.  * @param timer the static timer object 
  5.  * 
  6.  * @return the operation status, RT_EOK on OK; RT_ERROR on error 
  7.  */  
  8. rt_err_t rt_timer_detach(rt_timer_t timer)  
  9. {  
  10.     register rt_base_t level;  
  11.   
  12.     /* timer check */  
  13.     RT_ASSERT(timer != RT_NULL);  
  14.   
  15.     /* disable interrupt */  
  16.     level = rt_hw_interrupt_disable();//關中斷  
  17.   
  18.     /* remove it from timer list */  
  19.     rt_list_remove(&(timer->list));//從定時器鏈表中移除  
  20.   
  21.     /* enable interrupt */  
  22.     rt_hw_interrupt_enable(level);//開中斷  
  23.   
  24.     rt_object_detach((rt_object_t)timer);//脫離內核對象  
  25.   
  26.     return -RT_EOK;  
  27. }  

刪除動態創建的定時器

[cpp] view plain copy
  1. /** 
  2.  * This function will delete a timer and release timer memory 
  3.  * 
  4.  * @param timer the timer to be deleted 
  5.  * 
  6.  * @return the operation status, RT_EOK on OK; RT_ERROR on error 
  7.  */  
  8. rt_err_t rt_timer_delete(rt_timer_t timer)  
  9. {  
  10.     register rt_base_t level;  
  11.   
  12.     /* timer check */  
  13.     RT_ASSERT(timer != RT_NULL);  
  14.   
  15.     /* disable interrupt */  
  16.     level = rt_hw_interrupt_disable();//關中斷  
  17.   
  18.     /* remove it from timer list */  
  19.     rt_list_remove(&(timer->list));//從定時器鏈表中移除  
  20.   
  21.     /* enable interrupt */  
  22.     rt_hw_interrupt_enable(level);//開中斷  
  23.   
  24.     rt_object_delete((rt_object_t)timer);//刪除動態創建的定時器內核對象  
  25.   
  26.     return -RT_EOK;  
  27. }  

4.3 啓動定時器

[cpp] view plain copy
  1. /** 
  2.  * This function will start the timer 
  3.  * 
  4.  * @param timer the timer to be started 
  5.  * 
  6.  * @return the operation status, RT_EOK on OK, -RT_ERROR on error 
  7.  */  
  8. rt_err_t rt_timer_start(rt_timer_t timer)  
此接口已在上面介紹軟件定時器模式時已有分析,這裏就不再重複了。

4.4 停止定時器

[cpp] view plain copy
  1. /** 
  2.  * This function will stop the timer 
  3.  * 
  4.  * @param timer the timer to be stopped 
  5.  * 
  6.  * @return the operation status, RT_EOK on OK, -RT_ERROR on error 
  7.  */  
  8. rt_err_t rt_timer_stop(rt_timer_t timer)  
  9. {  
  10.     register rt_base_t level;  
  11.   
  12.     /* timer check */  
  13.     RT_ASSERT(timer != RT_NULL);  
  14.     if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))//如果定時器已經爲非激活狀態  
  15.         return -RT_ERROR;  
  16.   
  17.     RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent)));//使用鉤子函數  
  18.   
  19.     /* disable interrupt */  
  20.     level = rt_hw_interrupt_disable();//關中斷  
  21.   
  22.     /* remove it from timer list */  
  23.     rt_list_remove(&(timer->list));//從定時器鏈表中移除  
  24.   
  25.     /* enable interrupt */  
  26.     rt_hw_interrupt_enable(level);//開中斷  
  27.   
  28.     /* change stat */  
  29.     timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;//置非激活狀態  
  30.   
  31.     return RT_EOK;  
  32. }  

4.5 控制

此接口是用來修改一個定時器的參數,如下代碼:

[cpp] view plain copy
  1. /** 
  2.  * This function will get or set some options of the timer 
  3.  * 
  4.  * @param timer the timer to be get or set 
  5.  * @param cmd the control command 
  6.  * @param arg the argument 
  7.  * 
  8.  * @return RT_EOK 
  9.  */  
  10. rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg)  
  11. {  
  12.     /* timer check */  
  13.     RT_ASSERT(timer != RT_NULL);  
  14.   
  15.     switch (cmd)  
  16.     {  
  17.     case RT_TIMER_CTRL_GET_TIME://獲取時間參數  
  18.         *(rt_tick_t *)arg = timer->init_tick;  
  19.         break;  
  20.   
  21.     case RT_TIMER_CTRL_SET_TIME://修改時間參數  
  22.         timer->init_tick = *(rt_tick_t *)arg;  
  23.         break;  
  24.   
  25.     case RT_TIMER_CTRL_SET_ONESHOT://修改定時器模式爲單次觸發定時器  
  26.         timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;  
  27.         break;  
  28.   
  29.     case RT_TIMER_CTRL_SET_PERIODIC://修改定時器爲週期觸發定時器  
  30.         timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;  
  31.         break;  
  32.     }  
  33.   
  34.     return RT_EOK;  
  35. }  

完!

發佈了1 篇原創文章 · 獲贊 48 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章