RTT小师弟 · 2021年06月08日

【rtthread学习笔记系列】第一篇:定时器

一、定时器概念
1.1 时钟节拍

时钟节拍是系统的最小时间单位,宏RT_TICK_PER_SECOND为100时,一个时钟节拍的时间为10ms,时钟节拍也是线程时间片的最小单位。在stm32中,时钟节拍通过systick中断实现,在每次systick中断,全局变量rt_tick加1。

void SysTick_Handler(void)
{

/* 进 入 中 断 */
rt_interrupt_enter();
……
rt_tick_increase();
/* 退 出 中 断 */
rt_interrupt_leave();

}

获取当前的时钟节拍rt_tick可以通过rt_tick_get函数获得。
1.2 rtthread定时器
1.2.1 rtthread定时器概念

rtthread定时器的定时时间以时钟一个节拍的时间为单位,创建并激活的定时器会以超时时间的大小排序,链接在rt_timer_list上,在每次硬件中断执行rt_tick_increase调用 rt_timer_check时判断是否产生超时事件。
1.2.2 rtthread定时器模式

  HARD_TIMER :定时器超时函数在硬件systick中断的上下文进行,需要注意执行时间尽量短,不执行内存的申请和释放操作,不能执行会挂起的函数。
   SOFT_TIMER:通过 RT_USING_TIMER_SOFT决定是否开启此功能,系统会在初始化时创建一个timer线程,这种模式的定时器的超时函数的上下文是线程。

二、rtthread定时器api

//创建一个定时器
/*
name:定时器名称
timeout:超时函数
parameter:超时函数的参数
time:超时时间,单位:时钟节拍
flag:标志
*/
rt_timer_t rt_timer_create(const char* name,

                            void (*timeout)(void* parameter),
                            void* parameter,
                            rt_tick_t time,
                            rt_uint8_t flag);

//删除时钟
/*
timer:定时器句柄
*/
rt_err_t rt_timer_delete(rt_timer_t timer);

//初始化定时器
/*
timer:定时器句柄
name:定时器名称
timeout:超时函数
parameter:超市函数的参数
time:超时时间,单位:时钟节拍
flag:标志
*/
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);
         

脱离定时器
/*
timer:定时器句柄
*/
rt_err_t rt_timer_detach(rt_timer_t timer);

//启动定时器
/*
timer:定时器句柄
*/
rt_err_t rt_timer_start(rt_timer_t timer);

//停止定时器
/*
timer:定时器句柄
*/
rt_err_t rt_timer_stop(rt_timer_t timer);

//控制定时器
/*
timer:定时器句柄
cmd:控制命令
arg:控制命令参数
*/
rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void* arg);

定时器控制cmd:

define RT_TIMER_CTRL_SET_TIME 0x0 / 设 置 定 时 器 超 时 时 间 /

define RT_TIMER_CTRL_GET_TIME 0x1 / 获 得 定 时 器 超 时 时 间 /

define RT_TIMER_CTRL_SET_ONESHOT 0x2 / 设 置 定 时 器 为 单 次 定 时 器 /

define RT_TIMER_CTRL_SET_PERIODIC 0x3 / 设 置 定 时 器 为 周 期 型 定 时 器 /

三、示例

本示例创建了一个周期性定时器timer1,一个一次性定时器timer2,rtthread默认的定时器工作模式是HARD_TIMER模式,满足超时时间后执行timeout1和timeout2。 周期性定时器执行10次定时任务后停止定时器。

/*

  • Copyright (c) 2006-2018, RT-Thread Development Team
    *
  • SPDX-License-Identifier: Apache-2.0
    *
  • Change Logs:
  • Date Author Notes
  • 2018-08-24 yangjie the first version
    */

/*

  • 程序清单:定时器例程
    *
  • 这个例程会创建两个动态定时器,一个是单次定时,一个是周期性定时
  • 并让周期定时器运行一段时间后停止运行
    */

    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,
                         RT_NULL, 10,
                         RT_TIMER_FLAG_PERIODIC);

/* 启动定时器1 */
if (timer1 != RT_NULL)
    rt_timer_start(timer1);

/* 创建定时器2 单次定时器 */
timer2 = rt_timer_create("timer2", 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);

原文:https://club.rt-thread.org/as...

推荐阅读
关注数
8059
内容数
181
小而美的物联网操作系统,经过14年的累积发展,RT-Thread 已经拥有一个国内最大的嵌入式开源社区,同时被广泛应用于能源、车载、医疗、消费电子等多个行业,累积装机量超过4亿台,成为国人自主开发、国内最成熟稳定和装机量最大的开源 RTOS。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息