【问题标题】:Timed task list定时任务列表
【发布时间】:2011-06-28 05:15:49
【问题描述】:

我正在寻求有关 16 位设备上的嵌入式应用程序的帮助。 我需要通过函数指针运行几个简单的“任务/函数”。这些任务以预定的时间间隔运行。

typedef struct
{
  int  timeToRun;
  void (*fcn)(void);

} task_t;

task_t tasks[] =
{
  { 13_MSEC,  fcn1 },
  { 50_MSEC,  fcn2 },
  { 0, NULL }
};

volatile unsigned int time;   

main()
{

  for (ptr = tasks; ptr->timeToRun !=0; ptr++)
  {
    if (!(time % ptr->timeToRun))
       (ptr->fcn)();
  }
}

我有可能在 1ms 运行定时器中断。

interrupt void TimerTick(void)
{
 time++;
}

知道如何计算经过的时间吗?如果时间溢出,如何确保 %(模)以定义的速率工作。无论如何如何避免时间溢出并通过 %(模数)获得正确的时间?

【问题讨论】:

    标签: timer embedded task 16-bit


    【解决方案1】:

    这是我的一个非常相似的应用程序的一些代码,适用于小型 MCU 应用程序,并且符合 MISRA-C。它基于调用应用程序中静态分配的“软件计时器”。项目中的多个模块可以使用同一个计时器模块,因为它在内部使用链表来跟踪所有计时器。

    从您的 1ms 中断中调用 tim_traverse_timers()。如果你有很高的精度要求,你可能需要在调用函数之前清除中断源,这样函数本身的“代码抖动”开销就不会影响定时器。

    如果您需要比 65535 毫秒更长的延迟,只需将计数器和间隔更改为 uint32。

        typedef struct timer
        {
          struct timer* next;                            /* Next timer in the linked list   */
    
          uint16 counter;                                /* 16-bit timer counter            */
          uint16 interval;                               /* The interval between triggers   */
          BOOL   is_enabled;                             /* Timer enabled/disabled          */
    
          void (*callback_func)(void);                   /* Callback timer function         */
    
        } Timer;
    
    
    
        static Timer* timer_list;
    
    
        void tim_init (void)
        {
          timer_list = NULL;
        }
    
        void tim_add (Timer*   timer,
                      void (*  callback_func)(void),
                      uint16   interval_ms,
                      BOOL     enabled)
        {
          tim_enable_interrupt (FALSE);                  /* hardware function disabling timer interrupt */
    
          timer->callback_func  = callback_func;
          timer->counter        = 0U;
          timer->interval       = interval_ms;
          timer->is_enabled     = enabled;
    
          timer->next           = timer_list;
          timer_list            = timer;
    
          tim_enable_interrupt (TRUE);
        }
    
    
    
        void tim_enable (Timer* timer, BOOL enable)
        {
          if(enable)
          {
            timer->counter    = 0U;                      /* Reset counter each time function is called */
          }
    
          timer->is_enabled = enable;
        }
    
        void tim_traverse_timers  (void)
        {
          Timer* timer;
    
          for(timer=timer_list; timer!=NULL; timer=timer->next)
          {
            if(timer->is_enabled == TRUE)
            {
              timer->counter++;
    
              if(timer->counter == timer->interval)
              {
                timer->counter = 0U;
                timer->callback_func();
              }
    
            }
          }
        }
    

    #include "timer.h"
    
    void my_func (void);  /* lights some LED etc... */
    void my_other_func (void);
    
    void main (void)
    {
      Timer some_task;
      Timer some_other_task;
      ...
    
      tim_init();
      ...
    
      tim_add(&some_task, &my_func, SOME_DELAY_IN_MS, TRUE);
      tim_add(&some_other_task, &my_other_func, SOME_OTHER_DELAY_IN_MS, TRUE);
      ...
    
    
    }
    

    【讨论】:

      【解决方案2】:

      我会这样做:

      typedef struct
      {
        unsigned int nextRunTime
        int  period;
        unsigned int  rollover;
        void (*fcn)(void);
      } task_t;
      
      
      main()
      {
        //setup goes here
        /*...*/
        //loop
        while (1)
        {
           for (ptr = tasks; ptr->period!=0; ptr++)
           {
             if ((time > ptr->nextRunTime) && (time <= ptr->rollover) )
             {
                 ptr->nextRunTime+=ptr->period;
                 ptr->rollover = (ptr->nextRunTime < ptr->period)? 2*ptr->period : 0xFFFF;
                 (ptr->fcn)();
             }
             ptr->nextRunTime = timeToRun;
           }
        }
      }
      

      只要您可以保证 a) 没有周期大于翻转时间 (0x8000 毫秒) 的一半,并且 b) 您可以在最短的周期内执行所有功能,这应该可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-30
        • 1970-01-01
        • 1970-01-01
        • 2021-03-28
        • 2012-12-23
        • 1970-01-01
        相关资源
        最近更新 更多