时钟与定时器
阅读须知
定义与作用
定义
系统时钟
- 系统时钟在RT-Thread中用于管理时间,为系统运行提供时间基准。
- 系统时钟由硬件计时器(通常是CPU的内部定时器或外部定时器)提供时钟节拍,这些时钟节拍通常以固定频率中断CPU,更新系统时间。
- 在RT-Thread中,系统时钟的节拍频率可以配置,这直接影响了操作系统的调度精度和定时器的分辨率。
- 例如,如果系统时钟的节拍频率设置为1000Hz,那么系统的时间精度为1ms。
定时器
RT-Thread 提供了两种类型的定时器:一次性定时器和周期性定时器。
- 一次性定时器:设置一定的延迟时间后执行一次指定的回调函数。一次性定时器在执行回调函数后自动停止。
- 周期性定时器:以固定的周期重复执行回调函数。周期性定时器在启动后会按照预设的周期不断地重复执行,直到被手动停止。
定时器的使用通常包括以下几个步骤:
- 定义并创建定时器:指定定时器的回调函数、回调函数的参数、定时器的类型(一次性或周期性)、以及定时器的时间周期。
- 启动定时器:根据定时器的配置,启动定时器。一旦启动,定时器将在指定的延迟或周期后执行其回调函数。
- 停止定时器(如果需要):可以在任何时候停止定时器,阻止其再次回调。
- 删除定时器:当不再需要定时器时,可以删除它,释放相关资源。
定时器可用于多种场景,如周期性检查资源状态、延迟执行任务、实现非阻塞等待等。
举例-通俗
- 在解释系统时钟和定时器之间的关系时,我们可以将其比作 Leon的工作任务和时间管理。
系统时钟
- Leon有块手表 | 嵌入式系统有个时钟 -> 想象一下,系统时钟就像是办公室里的墙钟,它为整个工作环境提供了统一的时间基准。
- Leon看着手表确定干活方式 | 嵌入式系统根据时钟安排任务执行 -> 墙钟每走一秒,Leon就会根据这个时间来安排和调整自己的工作和休息。在嵌入式系统中,系统时钟(通常通过硬件定时器实现)为整个系统提供这样的时间基准。
- Leon的手表每秒走的一样快 | 嵌入式系统的时钟运行在一个可设置的固定的频率 -> 嵌入式系统以固定的频率(称为"时钟节拍")更新系统时间,帮助系统调度任务和管理时间。
- 系统中的所有时间相关活动,比如任务切换、时间延迟等,都是根据这个系统时钟来进行的。
定时器
- Leon 有一个任务清单,按照任务清单对照手表执行任务 | 嵌入式板 有一个定时器,按照定时器对照系统时钟 执行任务 -> 定时器是日程安排者,它根据你的代码描述的需求设定特定时间点或时间段来催动嵌入式板卡执行任务
- Leon的任务清单可以设置每天任务也可以设置一次性任务 -> 定时器可以是一次性的,或者可以是周期性的
两者之间的关系
- 系统时钟和定时器之间的关系可以看作是时间基准与个人时间管理工具之间的关系。
- 系统时钟提供了一个持续的时间流,就像不断前进的墙钟,而定时器则利用这个时间流来安排特定的活动或任务。
- 没有系统时钟(墙钟),定时器就无法准确知道当前时间,也就无法准确地安排活动。
- 同时,如果没有定时器(日程安排者),你可能会错过重要的任务或会议,因为你没有一个工具来提醒你在特定时间做特定的事情。
在嵌入式系统中,这种关系允许开发者创建可以精确控制何时启动任务或触发事件的应用程序,从而使系统能够有效地管理时间和资源。
示例代码
- 在这个示例中,创建了一个周期性定时器,每秒钟打印一次"Timeout!"。这展示了如何在RT-Thread系统中使用定时器来实现周期性任务。
#include <rtthread.h> // 定时器的回调函数 static void timeout_cb(void* parameter) { rt_kprintf("Timeout!\n"); } int main(void) { // 创建定时器 static rt_timer_t timer; timer = rt_timer_create("demo", // 定时器名称 timeout_cb, // 定时器回调函数 RT_NULL, // 传递给回调函数的参数 RT_TICK_PER_SECOND, // 定时时间,这里是1秒 RT_TIMER_FLAG_PERIODIC); // 定时器类型,周期性 // 启动定时器 if (timer != RT_NULL) { rt_timer_start(timer); } return 0; }
逐行解释 代码
#include <rtthread.h> // 引入RT-Thread头文件,提供RTOS的功能支持。 // 定时器的回调函数定义。 static void timeout_cb(void* parameter) { rt_kprintf("Timeout!\n"); // 当定时器到时间时,输出"Timeout!"。 } int main(void) { // 定义一个定时器变量。 static rt_timer_t timer; // 创建一个定时器: // "demo"为定时器的名称; // timeout_cb为定时到期时调用的回调函数; // RT_NULL表示没有传递参数给回调函数; // RT_TICK_PER_SECOND定义了定时时间,这里设置为1秒,即每秒触发一次; // RT_TIMER_FLAG_PERIODIC表示定时器是周期性的,即会重复触发。 timer = rt_timer_create("demo", timeout_cb, RT_NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC); // 启动定时器 // 检查定时器是否创建成功,如果成功,则启动它。 if (timer != RT_NULL) { rt_timer_start(timer); // 启动定时器,定时器开始计时。 } return 0; // 程序正常结束。 }