RTT学习笔记3-时钟定时器管理

基本知识

RT-Thread 中,时钟节拍的长度可以根据 RT_TICK_PER_SECOND 的定义来调整,等于 1/RT_TICK_PER_SECOND 秒

获取时钟节拍

rt_tick_t rt_tick_get(void);

定时器分类

  1. 硬件定时器
  2. 软件定时器

触发方式分类

  1. 单次触发
  2. 周期触发

HARD_TIMER 模式

  • HARD_TIMER 模式的定时器超时函数在中断上下文环境中执行,可以在初始化 / 创建定时器时使用参数 RT_TIMER_FLAG_HARD_TIMER 来指定。
  • 对于超时函数的要求与中断服务例程的要求相同:执行时间应该尽量短,执行时不应导致当前上下文挂起、等待
  • RT-Thread 定时器默认的方式是 HARD_TIMER 模式

SOFT_TIMER 模式

SOFT_TIMER 模式的定时器超时函数在都会在 timer 线程的上下文环境中执行

RT_USING_TIMER_SOFT 
RT_TIMER_FLAG_SOFT_TIMER

定时器控制块

struct rt_timer
{
    
    
    struct rt_object parent;
    rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL];  /* 定时器链表节点 */

    void (*timeout_func)(void *parameter);    /* 定时器超时调用的函数 */
    void      *parameter;                         /* 超时函数的参数 */
    rt_tick_t init_tick;                         /* 定时器初始超时节拍数 */
    rt_tick_t timeout_tick;                     /* 定时器实际超时时的节拍数 */
};
typedef struct rt_timer *rt_timer_t;

定时器的管理方式

在系统启动时需要初始化定时器管理系统。可以通过下面的函数接口完成

void rt_system_timer_init(void);

果需要使用 SOFT_TIMER,则系统初始化时,应该调用下面这个函数接口

void rt_system_timer_thread_init(void);

定时器常用函数

在这里插入图片描述

动态定时器

创建动态定时器

rt_timer_t rt_timer_create(const char* name,
                           void (*timeout)(void* parameter),
                           void* parameter,
                           rt_tick_t time,
                           rt_uint8_t flag);

flag可选项:

#define RT_TIMER_FLAG_ONE_SHOT      0x0     /* 单次定时     */
#define RT_TIMER_FLAG_PERIODIC      0x2     /* 周期定时     */

#define RT_TIMER_FLAG_HARD_TIMER    0x0     /* 硬件定时器   */
#define RT_TIMER_FLAG_SOFT_TIMER    0x4     /* 软件定时器   */

删除动态定时器

rt_err_t rt_timer_delete(rt_timer_t timer);

静态定时器

创建

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_err_t rt_timer_start(rt_timer_t timer);

停止

rt_err_t rt_timer_stop(rt_timer_t timer);

控制定时器

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     /* 设置定时器为周期型定时器 */

使用示例:

#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);

Guess you like

Origin blog.csdn.net/u010261063/article/details/120919670