rt-thread中軟件定時器組件超時界限的一點理解


@2019-01-15

【小記】

對 rt-thread 中的軟件定時器組件中超時界限的一點理解

rt_thread_timer_entry(void *parameter)函數中if ((next_timeout - current_tick) < RT_TICK_MAX / 2)  --- 條件1
rt_soft_timer_check(void)函數中if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)        --- 條件2

舉個特例:

  假定某時刻 

  next_timeout = 0xFFFFFF00;
  current_tick = 0x100;
  next_timeout - current_tick = 0xFFFFFE00  <  RT_TICK_MAX / 2 = 0x7FFFFFFF    條件1不成立
  current_tick - t->timeout_tick = 0x200   <  RT_TICK_MAX / 2 = 0x7FFFFFFF    條件2成立  (實際比0x200d大一點,因current_tick在增長)

  這樣則會出現定時器錯誤的定時到達而調用其回調函數,實際定時器計時還遠未到

 為避免以上情況出現,在函數 rt_timer_start(rt_timer_t timer) 中斷言語句 RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2) 規定了延時長度(即MSB為0)

具體代碼:

  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     /* lock scheduler */
 16     rt_enter_critical();
 17 
 18     for (n = rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next;
 19          n != &(rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]);)
 20     {
 21         t = rt_list_entry(n, struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]);
 22 
 23         /*
 24          * It supposes that the new tick shall less than the half duration of
 25          * tick max.
 26          */
 27         if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
 28         {
 29             RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
 30 
 31             /* move node to the next */
 32             n = n->next;
 33 
 34             /* remove timer from timer list firstly */
 35             _rt_timer_remove(t);
 36 
 37             /* not lock scheduler when performing timeout function */
 38             rt_exit_critical();
 39             /* call timeout function */
 40             t->timeout_func(t->parameter);
 41 
 42             /* re-get tick */
 43             current_tick = rt_tick_get();
 44 
 45             RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
 46             RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));
 47 
 48             /* lock scheduler */
 49             rt_enter_critical();
 50 
 51             if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
 52                 (t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
 53             {
 54                 /* start it */
 55                 t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
 56                 rt_timer_start(t);
 57             }
 58             else
 59             {
 60                 /* stop timer */
 61                 t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
 62             }
 63         }
 64         else break; /* not check anymore */
 65     }
 66 
 67     /* unlock scheduler */
 68     rt_exit_critical();
 69 
 70     RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
 71 }
 72 
 73 /* system timer thread entry */
 74 static void rt_thread_timer_entry(void *parameter)
 75 {
 76     rt_tick_t next_timeout;
 77 
 78     while (1)
 79     {
 80         /* get the next timeout tick */
 81         next_timeout = rt_timer_list_next_timeout(rt_soft_timer_list);
 82         if (next_timeout == RT_TICK_MAX)
 83         {
 84             /* no software timer exist, suspend self. */
 85             rt_thread_suspend(rt_thread_self());
 86             rt_schedule();
 87         }
 88         else
 89         {
 90             rt_tick_t current_tick;
 91 
 92             /* get current tick */
 93             current_tick = rt_tick_get();
 94 
 95             if ((next_timeout - current_tick) < RT_TICK_MAX / 2)
 96             {
 97                 /* get the delta timeout tick */
 98                 next_timeout = next_timeout - current_tick;
 99                 rt_thread_delay(next_timeout);
100             }
101         }
102 
103         /* check software timer */
104         rt_soft_timer_check();
105     }
106 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM