• 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 }
  • 相关阅读:
    15.Git版本控制系统
    14.sudo 获取root权限
    13.定时任务
    12.文件权限:RWX
    相信301跳转大家都知道 rewrite
    修改mysql密码
    mod_rewrite是Apache的一个非常强大的功能
    mysql 常用命令集锦[绝对精华]
    mysql安装完之后,登陆后发现只有两个数据库
    mysql命令
  • 原文地址:https://www.cnblogs.com/skullboyer/p/10270867.html
Copyright © 2020-2023  润新知