【RT-Thread】自我学习笔记→第五章→时钟管理→定时器→动态定时器

前言

学完了时间节拍的获取,接下来学习动态定时器的创建与使用。

定时器

1.定时器的介绍

RT-Thread 的定时器提供两类定时器机制:
☐ 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。
☐ 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动的停止,否则将永远持续执行下去

根据定时器超时函数执行时所处的上下文环境,RT-Thread的定时器可以分为HARD_TIMER模式和SOFT_TIMER模式。
HARD_TIMER模式:中断上下文
定时器超时函数的要求:执行时间应该尽量短,执行时不应导致当前上下文挂起、等待。例如在中断上下文中执行的超时函数它不应该试图去申请动态内存、释放动态内存等
SOFT_TIMER模式:线程上下文
该模式被启用后,系统会在初始化时创建一个 timer 线程,然后 SOFT_TIMER 模式的定时器超时函数在都会在timer线程的上下文环境中执行
(该部分摘抄教学视频的教学文档)

2.定时器的工作机制

下面以一个例子来说明 RT-Thread 定时器的工作机制。在 RT-Thread 定时器模块中维护着两个重要的全局变量:
☐ 当前系统经过的 tick 时间 rt_tick(当硬件定时器中断来临时,它将加 1) ;
☐ 定时器链表 rt_timer_list。系统新创建并激活的定时器都会按照以超时时间排序的方式插入到rt_timer_list 链表中。
如下图所示,系统当前tick值为20,在当前系统中已经创建并启动了三个定时器,分别是定时时间为50个tick的Timer1、100个tick的Timer2和500个tick的Timer3,这三个定时器分别加上系统
当前时间 rt_tick=20,从小到大排序链接在 rt_timer_list 链表中,形成如图所示的定时器链表结构。
在这里插入图片描述

而 rt_tick 随着硬件定时器的触发一直在增长(每一次硬件定时器中断来临,rt_tick 变量会加 1) ,50个tick以后,rt_tick从20增长到70,与Timer1的timeout值相等,这时会触发与Timer1定时器相关联的超时函数,同时将Timer1从rt_timer_list链表上删除。同理,100个tick和500个tick过去后,与Timer2 和 Timer3 定时器相关联的超时函数会被触发,接着将 Time2 和 Timer3 定时器从 rt_timer_list链表中删除。
如果系统当前定时器状态在 10 个 tick 以后(rt_tick=30)有一个任务新创建了一个 tick 值为 300 的Timer4定时器,由于Timer4定时器的timeout=rt_tick+300=330,因此它将被插入到Timer2和Timer3定时器中间,形成如下图所示链表结构:
在这里插入图片描述
(该部分摘抄教学视频的教学文档)

实例代码

在这里插入图片描述
对于rt_timer_create(),第三行注释的"第四个参数"应该为"第五个参数"

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

rt_timer_t tm; //生成一个定时器指针以存放动态定时器的地址

void tm_callback(void *parameter)
{
    rt_kprintf("tm_callback running ...\n"); //打印运行信息
}

int main(void)
{
    tm = rt_timer_create("tm_demo", tm_callback, NULL, 3000,
            RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); //第一个参数为定时器的名字,第二个参数为定时器回调函数的指针,
                                                                //第三个参数为回调函数中所传入的形参,第四个参数为每多少个tick触发一次回调函数
                                                                //第五个参数为功能标志位, RT_TIMER_FLAG_PERIODIC为多次执行回调函数,
                                                                //RT_TIMER_FLAG_SOFT_TIMER为使用软件定时器。
    if(tm == RT_NULL) //如果rt_timer_create创建失败则返回RT_NULL
    {
        LOG_E("rt_timer_create failed\n"); //打印错误信息
        return -ENOMEM;
    }
    LOG_D("rt_timer_create successed...\n");//打印成功创建信息
    rt_timer_start(tm); //记得启动定时器,不然定时器的回调函数不会运行的

    return RT_EOK;
}

实现效果

使用SecureCRT打印为:
在这里插入图片描述

总结

以上就是动态定时器的实验过程。
博客编辑方法:如何写好一篇CSDN博客——小白入门(自用)
参考的学习视频:2021最新RT-Thread实时操作系统教程,入门到精通全套完整版
以前的学习笔记(从上到下按照时间从早到晚):
【RT-Thread】自我学习笔记→第零章→创建项目
【RT-Thread】自我学习笔记→第五章→时钟管理→时钟节拍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值