rt-thread定时器介绍与使用

本文详细介绍了RT-Thread中的定时器概念、工作机制,区分了硬件和软件定时器,以及单次/周期触发类型。并通过示例展示了如何在代码中动态或静态创建定时器,以及定时器的使用方法。
摘要由CSDN通过智能技术生成

一、定时器介绍

        定时器,是指从指定的时刻开始,经过一定的指定时间后触发一个事件,定时器有硬件定时器和软件定时器之分:

硬件定时器: 芯片本身提供的定时功能。一般是由外部晶振提供给芯片输入时钟,芯片向软件模块提供一组配置寄存器,接受控制输入,到达设定时间值后芯片中断控制器产生时钟中断。硬件定时器的精度一般很高,可以达到纳秒级别,并且是中断触发方式。软件定时器: 由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受数目限制的定时器服务。RT-Thread操作系统提供软件实现的定时器,以时钟节拍(OS Tick)的时间长度为单位,即定时数值必须是OS Tick的整数倍。

RT-Thread 的定时器提供两类定时器机制:

☐ 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。

☐ 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动的停止,否则将永远持续执行下去。根据定时器超时函数执行时所处的上下文环境,RT-Thread的定时器可以分为HARD_TIMER模式和SOFT_TIMER模式。硬件定时器是有限的,取决于硬件。比如STM32F103C8T6就只有四个,软件定时器是模拟的,在硬件定时器基础之上实现的,从理论上来说,软件定时器的个数没有限制。

HARD_TIMER模式:中断上下文

定时器超时函数的要求:执行时间应该尽量短,执行时不应导致当前上下文挂起、等待。例如在中断上下文中执行的超时函数它不应该试图去申请动态内存、释放动态内存等,因为超时函数进入需要定时时间到才会触发,而动态内存不能及时释放,可能会造成内存泄漏。

SOFT_TIMER模式:线程上下文

该模式被启用后,系统会在初始化时创建一个 timer 线程,然后 SOFT_TIMER 模式的定时器超时函数在都会在timer线程的上下文环境中执行。

二、定时器工作机制

        下面以一个例子来说明 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定时器中间,形成如下图所示链表结构:

三、定时器代码使用

        看过我前面第一篇文章就知道,都是定义一个结构体指针去接收动态或静态创建返回的首地址。定时器也是,也分动态和静态创建,不止是定时器,后面的信号量、串口、DMA、ADC等都是用这种结构,都是这么用的。分动态和静态都是为了方便管理内存,按需来选择即可。

跟之前讲的创建线程代码结构是不是一样。rt_timer_create()参数依次是定时器的名,定时器的超时函数,定时器的超时函数的输入参数,定时时间,定时设置的属性。但是是tick,系统定义是1ms,所以代码中1000就是1秒。每经过1秒就进入超时函数进行点灯和关灯,现实灯交替闪烁。定时设置的属性也比较重要,RT_TIMER_FLAG_PERIODIC表示是周期定时,如何设为单词定时的话,就只执行一次。RT_TIMER_FLAG_HARD_TIMER表示是软件定时器。

#include "board.h"               //头文件合集

rt_timer_t timer;

void LED_GPIO_Config(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
} 

void fun_callback(void *parameter)
{
	if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13) == 0)
	{
		GPIO_SetBits(GPIOC, GPIO_Pin_13);
	}
	else
	{
		GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	
	}
}
int main( void )
{
    /*LED初始化*/
   LED_GPIO_Config();  
	timer = rt_timer_create("rt_demo",fun_callback,RT_NULL,\
	1000,RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_HARD_TIMER);
	if(timer != RT_NULL)
	{
		rt_timer_start(timer);
	}
	else
	{
		return -1;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蛋骗鸡~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值