推荐星级:
  • 1
  • 2
  • 3
  • 4
  • 5

RT-Thread快速入门-定时器管理

更新时间:2023-10-03 06:57:28 大小:201K 上传用户:sun2152查看TA发布的资源 标签:RT-Thread定时器 下载积分:1分 评价赚积分 (如何评价?) 收藏 评论(0) 举报

资料介绍

任何操作系统都需要提供一个时钟节拍,以供系统处理所有和时间有关的事件, 如延时、线程的时间片轮转调度以及定时器超时等。时钟节拍(OS Tick)是操 作系统中最小的时间单位。 时钟节拍是特定的周期性中断,这个中断之间的时间间隔取决于具体的应用,一 般是 1-100ms。时钟节拍率越快,系统的额外开销就越大。 RT-Thread 中,一个时钟节拍的时长根据 rtconfig.h 配置文件 中, RT_TICK_PER_SECOND 的 定 义 来 调 整, 等 于 1/RT_TICK_PER_SECOND 秒 。 时钟节拍的实现 时钟节拍由配置为中断触发模式的硬件定时器产 生,在中断服务程序中调用如 下函数,通知操作系统已经过去一个系统时钟: 从源代码中可以看出,每经过一个时钟节拍,全局变量 rt_tick 的值就会加 1。 然后检查当前线程的时间片是否用完,以及是否有定时器超时。如果当前线程的 时间片用完,则进行同优先级线程之间的切换。 不同的硬件定时器中断实现都不同,以 STM32 定时器中断为例: void SysTick_Handler(void) RT-Thread 提供的定时器基于系统的节拍,提供了基于节拍整数倍的定时能力, 即定时器定时以时钟节拍为单位。如此,定时器定时长短是 OS Tick 时长的整数 倍。 如果一个时钟节拍是 10ms,那么系统软件定时器时长只能是 10ms、20ms、 100 等,而不能是 15ms。 定时器介绍 RT-Thread 提供了两种类型的定时器:  单次触发定时器。这类定时器触发一次定时器事件后,会自动停止。  周期触发定时器。这类定时器会周期性地触发定时器事件,直到用户手动 停止。 另外,根据超时函数执行时所处的上下文环境,RT-Thread 的定时器有两种工 作模式:  HARD_TIMER 模式,超时函数在中断上下文环境中执行。  SOFT_TIMER 模式,在系统创建的定时器线程上下文环境中执行。 HARD_TIMER 模式的定时器 这种模式是 RT-Thread 定时器默认的工作方式,定时器超时后,超时函数在系 统时钟中断的上下文环境中执行。 这种情况下,对于超时函数的要求与中断服务例程的要求相同:执行时间应该尽 量短、执行时不应该导致当前线程挂起等。否则会导致其他中断的响应时间加长, 或抢占了其他线程执行的时间。 SOFT_TIMER 模式的定时器 这种工作模式,需要通过宏定义 RT_USING_TIMER_SOFT 来决定是否启用。启用这 个模式后,RT-Thread 会在初始化时创建一个 timer 线程,SOFT_TIMER 模式的 定时器超时函数都会在 timer 线中执行。 定时器如何工作 RT-Thread 维护着两个重要的全局变量:  rt_tick , 当前系统经过的时钟节拍个数。  rt_timer_list , 定时器链表。创建并激活的定时器都会按照超时时间从 小到大进行排序,插入到这个链表中。 如下图所示,系统当前的 rt_tick 值为 20,且已经创建并启动了三个定时器: (1)定时为 50 个节拍的 Timer1(2)定时为 100 个节拍的 timer2(3)定 时为 500 个节拍的 timer3。 这三个定时器分别加上系统当前时间 rt_tick, 从小到大排序链接 在 rt_timer_list 中: rt_tick 随着硬件定时器的触发一直在增长,50 个节拍后,rt_tick 从 20 增长 到 70,与 Timer1 的 timerout 值相同,这时会触发 Timer1 定时器关联的超 时函数,同时将其从 rt_timer_list 链表上删除。 同理,100 个节拍和 500 个节拍过去后,Timer2 和 Timer3 定时器的超时函 数会被触发执行,将定时器 Timer2 和 Timer3 从 rt_timer_list 中删除。 定时器控制块 定时器控制块是 RT-Thread 用于管理定时器的一个数据结构,由结构体 struct rt_timer 定义形成定时器内核对象,再链接到内核容器中进行管理。 定时器控制块会存储定时器的一些信息,例如初始时钟节拍数、超时到达的节拍 数、定时器之间连接用的链表结构、超时回调函数等。具体定义如下: 前面介绍了定时器相关的理论知识,那么 RT-Thread 提供了怎样的定时器操作 函数,以及如何使用它们呢? RT-Thread 提供的定时器相关的操作包括:  创建/初始化定时器  启动定时器  控制定时器  删除/脱离定时器 所有定时器会在定时超时后从定时器链表中被删除,而周期性定时器会在它再次 启动时被加入定时器链表中。 理论+实践是学习新知识最有效的方法。 举例来演示如何创建定时器。这个例程动态创建两个定时器,一个单次定时器, 一个周期定时器,并让定时器运行一段时间后停止。代码如下: 编译运行结果如下: 周期性定时器 1 的超时函数,每 10 节拍运行 1 次,共运行 10 次,之后停 止(调用 rt_timer_stop())。 单次定时器 2 的超时函数在 30 个时钟节拍后运行一次。 下面举例说明静态创建定时器,需要定义定时器控制块结构变量,然后调用初始 化函数对其初始化: 其他定时器管理函数 初学者掌握定时器创建使用即可,RT-Thread 还提供了其他的定时器管理函数, 可以了解学习。 1. 删除定时器 动态创建的定时器,可以用下面的函数删除: rt_err_t rt_timer_delete(rt_timer_t timer); 调用这个函数接口后,系统会把这个定时器从 rt_timer_list 链表中删除,然后 释放相应的定时器控制块占有的内存。 静态创建的定时器,可以用下边的函数脱离定时器: rt_err_t rt_timer_detach(rt_timer_t timer); 脱离定时器时,系统会把定时器对象从内核对象容器中脱离,但是定时器对象所 占有的内存不会被释放。 2. 控制定时器 RT-Thread 也额外提供了定时器控制函数接口,以获取或设置更多定时器的信 息。控制定时器函数接口如下: rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void* arg); 控制定时器函数接口可根据命令类型参数,来查看或改变定时器的设置。 参数 cmd 为用于控制定时器的命令,当前支持四个命令:设置定时时间、查看定 时时间、设置单次触发、设置周期触发。

部分文件列表

文件名 大小
RT-Thread快速入门-定时器管理.pdf 201K

全部评论(0)

暂无评论