RTT学习

定时器的管理方式

在系统启动时需要初始化定时器管理系统。

c 复制代码
void rt_system_timer_init(void);

如果需要使用SOFT_TIMER,则系统初始化时,应该调用

c 复制代码
void rt_system_timer_thread_init(void);

定时器控制块中含有定时器相关的重要参数,在定时器各种状态间起到纽带的作用。

定时器的相关操作如图所示,对定时器的操作包含:创建/初始化定时器、启动定时器、运行定时器、删除/脱离定时器。

所有定时器在定时超时后都会从定时器链表中被移除,而周期性定时器会在它再次启动时被加入定时器链表,这与定时器参数设置相关。

c 复制代码
rt_timer_t rt_timer_create(const char* name,
                           void (*timeout)(void* parameter),
                           void* parameter,
                           rt_tick_t time,
                           rt_uint8_t flag);

调用该函数接口后,内核首先从动态内存堆中分配一个定时器控制块,然后对该控制块进行基本的初始化。

  • time:定时器的超时时间,单位是时钟节拍。
  • flag:定时器创建的参数,支持的值包括单次定时、周期定时、硬件定时器、软件定时器等,可以用或关系取多个值。
c 复制代码
#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     /* 软件定时器   */

上面 2 组值可以以 "或" 逻辑的方式赋给 flag。当指定的 flag 为 RT_TIMER_FLAG_HARD_TIMER 时,如果定时器超时,定时器的回调函数将在时钟中断的服务例程上下文中被调用;当指定的 flag 为 RT_TIMER_FLAG_SOFT_TIMER 时,如果定时器超时,定时器的回调函数将在系统时钟 timer 线程的上下文中被调用。

启动和停止定时器

当定时器被创建或初始化以后,并不会被立即启动,必须在调用启动定时器函数接口后,才开始工作,启动定时器函数接口如下:

c 复制代码
rt_err_t rt_timer_start(rt_timer_t timer);

调用定时器启动函数接口后,定时器的状态将更改为激活状态(RT_TIMER_FLAG_ACTIVATED),并按照超时顺序插入到 rt_timer_list 队列链表中。

启动定时器以后,若想使它停止:

c 复制代码
rt_err_t rt_timer_stop(rt_timer_t timer);

调用定时器停止函数接口后,定时器状态将更改为停止状态,并从rt_timer_list链表中脱离出来不参与定时器超时检查。
当一个周期性定时器超时时,也可以调用这个函数接口停止这个定时器。

控制定时器

c 复制代码
rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg);
c 复制代码
#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     /* 设置定时器为周期型定时器 */

定时器应用示例

这是一个创建定时器的例子,这个例程会创建两个动态定时器,一个是单次定时,一个是周期性定时并让周期定时器运行一段时间后停止运行。

c 复制代码
#include <rtthread.h>

static rt_timer_t timer1;
static rt_timer_t timer2;
static int cnt = 0;

static void timeout1(void *parameter){
	 rt_kprintf("periodic timer is timeout %d\n", cnt);
	 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){
	timer1 = rt_timer_create("timer1", timeout1, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC);
	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;
}

高精度延时

RTT定时器的最小精度是由系统时钟节拍所决定的(1OS Tick=1/RT_TICK_PER_SECOND秒),定时器设定的时间必须是OS Tick的整数倍。

当需要实现更短时间长度的系统定时时,例如OS Tick是10ms,而程序需要实现1ms的定时或延时,这种时候操作系统定时器将不能够满足要求,只能通过读取系统某个硬件定时器的计数器或直接使用硬件定时器的方式。

在Cortex-M系列中,SysTick已经被RT-Thread用于作为OS Tick使用,它被配置成1/RT_TICK_PER_SECOND秒后触发一次中断的方式。

c 复制代码
void rt_hw_us_delay(rt_uint32_t us)
相关推荐
森旺电子43 分钟前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
爱吃西瓜的小菜鸡3 小时前
【C语言】判断回文
c语言·学习·算法
不过四级不改名6773 小时前
蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)
stm32·嵌入式硬件·蓝桥杯
小A1593 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
Rorsion3 小时前
各种电机原理介绍
单片机·嵌入式硬件
岁岁岁平安3 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA3 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
qq_589568103 小时前
数据可视化echarts学习笔记
学习·信息可视化·echarts
兔C4 小时前
微信小程序的轮播图学习报告
学习·微信小程序·小程序
海海不掉头发4 小时前
苍穹外卖-day05redis 缓存的学习
学习·缓存