【ART-Pi与RT-Thread入门】⑧软件定时器

完整目录

本系列文章完整目录链接

软件定时器简介

软件定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上(系统滴答定时器)。软件定时器使系统能够提供不受数目限制的定时器服务。

RT-Thread操作系统提供的软件定时器,以系统节拍(OS Tick)的时间长度为定时单位,提供了基于系统节拍整数倍的定时能力,即定时数值是OSTick的整数倍。例如一个OS Tick是10ms,那么上层软件定时器只能提供10ms,20ms, 100ms 等时间精度的定时服务,而不能定时为15ms、25ms、35ms等。

当软件定时器所设定的定时时间到了后,会调用用户设置的定时器timeout回调函数,用户需要定时运行的程序会在回调函数中得到处理。

定时器的两种模式

  • HARDTIMER模式

    HARDTIMER模式的定时器超时函数在中断上下文环境中执行,此模式在定时器初始化时指定。在中断上下文环境中执行时,对于超时函数的要求与中断服务例程的要求相同:执行时间应该尽量短,执行时不应导致当前上下文挂起。HARDTIMER 模式是RT-Thread软件定时器的默认方式。

  • SOFTTIMER模式

    SOFTTIMER模式的定时器超时函数在系统的timer线程的线程上下文中执行。通过宏定义RT_ USING_ TIMER_ SOFT 来决定是否启用该模式。当启用SOFTTIMER 模式后,我们可以在定时器初始化时指定定时器工作在SOFTTIMER模式。

软件定时器控制块

在RT-Thread中,软件定时器控制块是操作系统用于管理软件定时器的一个数据结构。

struct  rt_timer
{
    struct  rt_object  parent;
    rt_list_t       row[RT_TIMER_SKIP_LIST_LEVEL];//定时器列表节点
    void (*timeout_func)(void *parameter);  //超时函数的函数指针,传入函数给指针
    void          *parameter;              //超时函数的参数,不用时赋值0
    rt_tick_t      init_tick;         //定时器超时 时间,超时时间到了就调用超时函数。以系统节拍为时间单位
    rt_tick_t      timeout_tick;  
}
typedef  struct  rt_timer  *rt_time_t

定义静态软件定时器:

struct  rt_timer  static_timer;

定义动态软件定时器:

rt_timer_t  dynamic_timer;

定时器操作API

  • 静态定时器的初始化与脱离
/*
参数1:定时器控制块的地址。
参数2:名称
参数3:定时器timeout回调函数。
参数4:回调函数的参数,如没有就写RT_NULL。
参数5: 定时器超时时间,以系统节拍为单位。
参数6: 定时器工作模式选择.
RT_TIMER_FLAG_ONE_SHOT(只执行一次超时回调函数),RT_TIMER_FLAG_PERIODIC(周期性执行超时回调函数);
RT_TIME_FLAG_HARD_TIMER(软件定时器工作在HARDTIMER模式,可以省略,省略时即为默认的HARDTIMER模式),RT_TIMER_FLAG_SOFT_TIMER(SOFTTIMER模式)。
如需指定HADTIMER/SOFTTIMER模式则在ONE_SHOT/PERIODIC之后用逻辑或来指定*/

void  rt_timer_init(rt_timer_t  timer,const char *name,void (*timeout)(void *parameter),
                    void *parameter,rt_tick_t  time,rt_uint8_t  flag)

rt_err_t  rt_timer_detach(rt_timer_t  timer)



  • 动态定时器的创建与删除
rt_timer_t  rt_rimer_creater(const char*name,void (*timeout)(void *parameter),
                            void *parameter,rt_tick_t time,rt_uint8_t flag)

rt_err_t  rt_timer_delete(rt_timer_t  timer)

//例子:创建一个SOFTTIMER模式的重复执行的定时器,定时器间隔为10个系统节拍
timer1 = rt_timer_create("timer1", timeout_cb1, //回调函数为timeout_cb1
                             RT_NULL, 10,
                             RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER);//重复执行,而且是SOFTTIMER模式。
  • 定时器的启动
rt_err_t  rt_timer_start(rt_timer_t  timer)
  • 定时器的停止
rt_err_t  rt_timer_stop(rt_timer_t  timer)

例程

/*
* 程序清单:定时器例程
*
* 这个例程会创建两个动态定时器,一个是单次定时,一个是周期性定时
* 并让周期定时器运行一段时间(10次)后停止运行
*/
#include <rtthread.h>
 
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_timer_t timer2;
static int cnt = 0;
 
/* 定时器1超时函数 */
static void timeout1(void *parameter)
{
    rt_kprintf("periodic timer is timeout %d\n", cnt);
 
    /* 运行第10次,停止周期定时器 */
    if (cnt++ >= 9)
    {
        rt_timer_stop(timer1);
        rt_kprintf("periodic timer was stopped! \n");
    }
}
 
/* 定时器2超时函数 */
static void timeout2(void *parameter)
{
    rt_kprintf("one shot timer is timeout\n");
}
 
int timer_sample(void)
{
    /* 创建定时器1  周期定时器 */
    timer1 = rt_timer_create("timer1", timeout1, //回调函数为timeout1
                             RT_NULL, 10,
                             RT_TIMER_FLAG_PERIODIC);//周期执行会回调函数。
 
    /* 启动定时器1 */
    if (timer1 != RT_NULL) rt_timer_start(timer1);
 
    /* 创建定时器2 单次定时器 */
    timer2 = rt_timer_create("timer2", timeout2,//回调函数timeout2
                             RT_NULL,  30,
                             RT_TIMER_FLAG_ONE_SHOT);//执行一次回调函数
 
    /* 启动定时器2 */
    if (timer2 != RT_NULL) rt_timer_start(timer2);
    return 0;
}
 
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(timer_sample, timer sample);
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值