zoukankan      html  css  js  c++  java
  • 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
    "));
     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
    ", 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
    "));
     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 }
  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/skullboyer/p/10270867.html
Copyright © 2011-2022 走看看