【BES2500x系列 -- RTX5操作系统】深入探索CMSIS-RTOS RTX -- 定时器服务篇 -- 定时器管理 --(五)

  • 💌 所属专栏:【BES2500x系列】

  • 😀 作  者:我是夜阑的狗🐶

  • 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!

  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩

文章目录

  • 前言
  • [1 介绍](#1 介绍)
  • [2 功能特性](#2 功能特性)
  • [3 定时器服务](#3 定时器服务)
      • [3.1 定时器类型](#3.1 定时器类型)
      • [3.2 功能特性](#3.2 功能特性)
  • [4 定时器服务](#4 定时器服务)
      • [4.1 定时器管理](#4.1 定时器管理)
        • [4.1.1 定义](#4.1.1 定义)
        • [4.1.2 中断处理](#4.1.2 中断处理)
        • [4.1.3 创建](#4.1.3 创建)
        • [4.1.4 启动](#4.1.4 启动)
        • [4.1.5 停止](#4.1.5 停止)
        • [4.1.6 删除](#4.1.6 删除)
  • 总结

前言

大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第5篇文章;

今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。

专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。

如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。


<<【系列文章索引】>>

1 介绍

在嵌入式实时操作系统(RTOS)中,定时器服务是一个基本且重要的组件,它为系统和应用程序提供了定时和延时的功能。定时器服务使得开发者能够安排任务在特定时间执行、测量时间间隔、实现超时检测等功能,对于实现精确的控制循环、任务调度、周期性活动及各种实时响应机制至关重要。话不多说,那接下来就学习定时器服务,让我们原文再续,书接上回吧。

2 功能特性

在实时操作系统(RTOS)中,任务管理和同步通信是关键组件,它们确保系统的高效和有序执行。本文将探讨这些概念,特别是线程管理、信号量、互斥锁、消息队列和邮箱处理。

  • 任务管理:RTX提供任务创建、调度和优先级管理,确保任务按照优先级及时执行。
  • 同步与通信:包括信号量、互斥锁、消息队列和邮箱,促进任务间的同步和数据交换。
  • 内存管理:内存池和动态内存分配,有效管理有限的系统资源。
  • 定时器服务:虚拟和硬件定时器,支持周期性任务和一次性事件触发。
  • 中断处理:保证中断服务的快速响应,同时保持任务的上下文安全。
  • 线程安全:通过内核级保护机制,防止多线程环境下的数据竞争和死锁。

3 定时器服务

以下是嵌入式 RTOS 系统中定时器服务的几个关键方面:

3.1 定时器类型

  • 硬件定时器:基于微控制器或处理器的硬件定时器模块,提供高度精确的时间基准。硬件定时器通常能够产生中断,用于触发定时事件。

  • 软件定时器:由RTOS提供的软件抽象层实现,依赖于RTOS的时基(通常是滴答定时器)来计时。软件定时器适合于不需要极高精度的应用场景,且可以节省硬件资源。

3.2 功能特性

  • 单次触发:设定一次性的定时事件,在指定时间后触发一次中断或回调函数。

  • 周期性触发:设定定时器以固定的周期重复触发,适用于需要定期执行的任务,如心跳监测、数据采样等。

  • 延时功能:允许任务进入等待状态,直到定时器到期,这对于实现任务间的延时或简单的时间管理非常有用。

  • 超时检测:为任务操作或资源访问设置超时限制,增强系统的健壮性,防止因资源锁定等原因导致的无限等待。

综上所述,嵌入式RTOS中的定时器服务是实现定时控制、任务调度和提高系统实时性的重要手段。通过灵活运用定时器服务,开发者能够构建出更加复杂且可靠的嵌入式应用。

4 定时器服务

定时器服务在 RTOS 中用于执行周期性的任务或在预定时间点触发事件。以下是关于定时器管理的一些关键点:

4.1 定时器管理

定时器是一个软件或硬件实体,能够按照设定的时间间隔触发事件。在FreeRTOS中,定时器可以是周期性的或一次性触发。

4.1.1 定义

一般在文件开头会看到这样的定义:osTimerDef 。

  • 代码
c 复制代码
// 使用osTimerDef宏定义一个定时器,名为APP_TEST_THREAD1_TIMER,回调函数为app_test1_timer_handler
osTimerDef(APP_TEST_THREAD1_TIMER, (void (*)(void const *))app_test1_timer_handler);

// 声明一个osTimerId类型的变量app_test1_timer,用于存储定时器的ID
// 在实际使用中,需要调用osTimerCreate来创建定时器并将其句柄赋值给app_test1_timer
osTimerId app_test1_timer = NULL;

在你的代码中,你已经使用 osTimerDef 宏定义了一个名为 APP_TEST_THREAD1_TIMER 的定时器,并指定了回调函数app_test1_timer_handler 。然后,你声明了一个osTimerId 类型的变量 app_test1_timer ,它将用于存储定时器的句柄。

🚨 🚨 🚨 请注意,这段代码没有创建定时器,只是定义了定时器的结构和一个变量来存储将来创建的定时器的句柄。实际的创建过程可能需要调用 osTimerCreate 函数。

c 复制代码
/**
 * 定义一个操作系统定时器。
 * 
 * 该宏用于定义一个操作系统的定时器,通过提供定时器的名称和执行函数来创建。
 * 定义的定时器可以在操作系统级别上使用,用于执行各种定时任务。
 * 
 * @param name 定时器的名称,用于标识和访问定时器。
 * @param function 定时器触发时执行的函数。
 * 
 * @note 此宏定义了一个静态定时器结构体和相关的定时器定义。
 */
#define osTimerDef(name, function) \
static StaticTimer_t os_timer_cb_##name; \
const osTimerDef_t os_timer_def_##name = \
{ (function), { NULL, 0U, (&os_timer_cb_##name), sizeof(StaticTimer_t) } }

此注释是根据代码块的重要性和要求生成的,旨在提供对宏定义功能的清晰说明,包括其参数和作用,同时遵循了禁止行尾注释的要求。

  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerId 定义变量来存储定时器的ID
2 osTimerDef 定义静态定时器结构体
4.1.2 中断处理

定时器中断是硬件产生的,当定时器达到预设的计数值时,会触发中断服务例程。中断处理程序通常会更新定时器状态并执行相关操作,如重新装载计数值或通知RTOS。

  • 代码
c 复制代码
/**
 * @brief 定时器回调函数:app_test1_timer_handler
 *
 * 当定时器APP_TEST_THREAD1_TIMER(在osTimerDef中定义)到期时,系统将自动调用此函数。
 * 此函数是静态的,意味着它不会被其他模块直接调用,仅由操作系统内部使用。
 *
 * @param param 指针参数,可以用于传递额外的数据到回调函数。
 *              如果不需要传递额外数据,可以忽略此参数。
 * 
 * @note 实现此函数时,应包含定时器触发时需要执行的代码。
 *       示例代码如下,实际应用中请替换为实际逻辑:
 *       \code{.cpp}
 *       if (param != NULL) {
 *           MyData *data = static_cast<MyData*>(param);
 *           // 使用data进行操作...
 *       }
 *       \endcode
 */
static void app_test1_timer_handler(void const *param) 
{ 
... 
} 

这个注释详细说明了 app_test1_timer_handler 函数的作用、参数和如何在实际应用中使用。请注意,函数的具体实现(省略号部分)应当根据实际需求来编写。

  • 参数/函数讲解
序号 参数/函数 说明
1 app_test1_timer_handler 定时器中断钩子函数
4.1.3 创建

创建定时器通常涉及以下步骤:

Step 1 、定义定时器的属性,如定时器回调函数、超时值等。

Step 2 、调用定时器创建函数,如 FreeRTOSxTimerCreate()

  • 代码
c 复制代码
/**
 * @brief          初始化应用测试1的定时器
 * 
 * @description    该函数负责创建一个单次触发(one-shot)的系统定时器,
 *                 用于执行APP_TEST_THREAD1_TIMER定义的任务。
 * 
 * @param[in]      无
 * 
 * @return         无
 */
void app_test1_timer_init(void) 
{
    // 使用osTimerCreate函数创建一个一次性定时器
    // APP_TEST_THREAD1_TIMER通过宏定义指定定时器的处理函数
    // osTimerOnce参数表明定时器只运行一次
    // 第三个参数NULL表示定时器没有传递额外的数据给定时器函数
    app_test1_timer = osTimerCreate(osTimer(APP_TEST_THREAD1_TIMER), osTimerOnce, NULL); 
}
  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerCreate 创建定时器,并指定定时器的模式
4.1.4 启动

启动定时器意味着激活定时器,使其开始计时。在 FreeRTOS 中,这可以通过调用 xTimerStart()xTimerStartFromISR() 完成。

  • 代码
c 复制代码
/**
 * @brief          启动应用测试1的定时器
 * 
 * @description    此函数负责启动在之前初始化的定时器`app_test1_timer`。
 *                 定时器一旦启动,将按配置执行单次或周期性的任务。
 * 
 * @param[in]      无
 * 
 * @return         无
 *
 * @note           实现时应当考虑如下几点:
 *                 - 确保`app_test1_timer`已在初始化阶段正确定义并配置。
 *                 - 如使用RTOS环境,调用相应的API(如FreeRTOS的`osTimerStart`)来激活定时器。
 *                 - 若定时器为周期性,需在回调函数中重新启动定时器以维持周期性执行。
 */
static void app_test1_timer_start(void)
{
    // 实际启动定时器的代码实现应在此处
    // 示例代码(若使用FreeRTOS):
    // osStatus_t status = osTimerStart(app_test1_timer, timeout_ticks);
    // if (status != osOK) {
    //     // 处理启动失败的情况
    // }
}
  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerStart 启动定时器并指定定时时长
4.1.5 停止

停止定时器会暂停或取消定时器的计时。FreeRTOS 中,可以使用 xTimerStop()xTimerStopFromISR() 来停止定时器。

  • 代码
c 复制代码
/**
 * @brief          停止应用测试1的定时器
 * 
 * @description    本函数用于停止之前已启动的定时器`app_test1_timer`。
 *                 如果定时器正在运行或等待触发,它将被取消,不再执行定时任务。
 * 
 * @param[in]      无
 * 
 * @return         无
 *
 * @note           实现该函数时,应确保正确调用操作系统相关的API来安全停止定时器,
 *                 防止资源泄露或产生竞态条件。特别是当定时器用于周期性任务时,
 *                 停止操作应当确保定时器不会再次自动启动。
 */
static void app_test1_timer_stop(void)
{
    // 实际停止定时器的代码应在此处实现
    // 例如,在FreeRTOS环境下,可以使用:
    // osStatus_t status = osTimerStop(app_test1_timer);
    // if (status != osOK) {
    //     // 处理停止失败的情况
    // }
}
  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerStop 停止定时器
4.1.6 删除

当不再需要定时器时,可以删除它以释放资源。在 FreeRTOS 中,使用 vTimerDelete() 来删除定时器。

  • 代码
c 复制代码
/**
 * @brief          删除应用测试1的定时器
 * 
 * @description    该函数负责删除之前创建的`app_test1_timer`。
 *                 如果定时器正在运行,先停止定时器,然后释放与定时器相关的资源。
 *
 * @param[in]      无
 * 
 * @return         返回一个布尔值,表示定时器在删除前是否正在运行。
 *                 如果定时器正在运行,返回true;否则返回false。
 *
 * @note           实现时应确保:
 *                 - 如果定时器正在运行,先调用`app_test1_timer_stop`停止它。
 *                 - 使用操作系统提供的API(如FreeRTOS的`osTimerDelete`)来释放定时器资源。
 */
 static bool app_test1_timer_delete(void)
{
    // 使用适当的API删除定时器资源
    // 例如,在FreeRTOS环境下:
    // osStatus_t status = osTimerDelete(app_test1_timer);
    // if (status != osOK) {
    //     // 处理删除失败的情况
    // }
}
  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerDelete 释放定时器资源

定时器服务是RTOS中不可或缺的一部分,它们可以用于执行周期性任务、超时检查、心跳检测等功能,提高了系统的实时性和灵活性。

<<【系列文章索引】>>


总结

**  感谢观看,这里就是 定时器服务篇 -- 定时器管理的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹**

**  也欢迎你,关注我。👍 👍 👍**

**  原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉**

更多专栏订阅:

订阅更多,你们将会看到更多的优质内容!!

相关推荐
scan15 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Mortal_hhh6 小时前
VScode的C/C++点击转到定义,不是跳转定义而是跳转声明怎么办?(内附详细做法)
ide·vscode·stm32·编辑器
Mr.谢尔比8 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie8 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
鹿屿二向箔8 小时前
STM32外设之SPI的介绍
stm32
西瓜籽@8 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
极客小张12 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩
m0_7393128714 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章15 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
TeYiToKu15 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm