SMC-RTOS之timer

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33894122/article/details/81483705

Timer

这里主要介绍SMC-RTOS实现的软件定时器Timer,一般OS软件定时器的精度都是OS系统心跳节拍的整数倍,SMC_RTOS也不例外。
软件定时器利用系统节拍进行计数定时,所以本身系统节拍时钟必须准确,否则软件定时器肯定是不准的。

  • 定时器的数据结构
typedef struct smc_timer {
    void (*timerout)(void *parameter);             /* 定时器超时处理函数 */
    void *parameter;                               /* 定时器超时处理函数的参数 */
    smc_list_node_t tlist;                         /* thread delay list node */
    smc_uint32_t    init_tick;                     /* 每次插入到smc_timer链表中计算得到的tick,在每个时钟节拍链表头节点的定时器的init_tick都会自减1 */
    smc_uint32_t    timeout_tick;                  /* 每次需要定时的时间初始化后就保持不变了,除非重新初始化 */
    smc_uint8_t     flag;                          /* 定时器process处理的方式标志 主要是为了实现单词和循环定时器而设置的*/
} smc_timer_t;
  • 定时器的操作接口
/*定时器初始化*/
void smc_timer_init(smc_timer_t *timer, smc_uint32_t tick, void (*timerout)(void *parameter), void *parameter,smc_uint8_t flag);
/*定时器参数设置,主要是定时器工作模式和定时器定时tick*/
void smc_timer_command(smc_timer_t *timer, smc_uint8_t cmd, void *arg);
/*启动定时器,定时器参数设置好了之后,并不是立刻开始工作,而是要将其加入smc_timer_list中才能正常工作*/
void smc_timer_enable(smc_timer_t *timer);
/*关闭定时器,定时器参数设置好了之后,并不是立刻开始工作,而是要将其加入smc_timer_list中才能正常工作*/
void smc_timer_disable(smc_timer_t *timer_del);
/*根据定时器flag模式处理不通模式*/
static void smc_timer_process(smc_timer_t *timer);
/*每个sys tick减少头结点定时时间,不论是单独定时器还是thread内嵌的定时器,都会调用timeout函数,如果循环定时器的话,会转换一下状态继续插入到定时器链表中去*/
void smc_timer_decrease(void);

SMC-RTOS的定时器跟其他RTOS不同,因为在thread_t中也是内嵌的定时器,所有的任务的延时和等待超时的定时都是利用软件定时器来实现的,所以跟ucosii的软件定时器不一样,ucosii中是如果使能了定时器功能就会直接在系统初始化的时候新建一个定时器task,没有systick的时候则会阻塞等待systick的信号量,一旦发生一个systick,在systick_handler的一个钩子函数中会post这个信号量,然后定时器task就会就绪,其实ucosii的软件定时器就是一个定时任务,并不太准。SMC-RTOS则是在systick的systick_handler函数中遍历所有定时器(软件定时器 thread的定时器),这就要求软件定时器的超时函数不能太长不然就会影响整个rtos的实时性能了,因为整个systick_handler期间都是会关闭中断的,这样就会导致整个系统中断延迟时间会延长了,对rtos来说就是致命的。

为了减少定时器在systick_handler中的时间,SMC-RTOS还做了其他的努力(减少中断中定时器超时回调函数的执行时间是约定熟成的,任何一个合格的coder都应该了解她),比如插入的时候按照每个定时器时间排序,按定时时间累计,在后来定时的时候,systick_handler中不需要遍历整个定时器链表,只需要给头节点的下一个元素节点的定时花时间减一就好了。

猜你喜欢

转载自blog.csdn.net/qq_33894122/article/details/81483705