共计 2650 个字符,预计需要花费 7 分钟才能阅读完成。
一、定时器概念
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…