软件定时器详解:RTOS 中的“软时钟”机制与源码解析

        在嵌入式实时系统开发中,定时器是不可或缺的工具。软件定时器(Software Timer) 提供了一种无需创建独立任务、便可在特定延时后执行回调函数的机制。它适用于那些不要求高精度、但需要周期性或一次性延时执行操作的场景。

一、什么是软件定时器?

        软件定时器是在 RTOS 内核中由专门的“定时器服务任务”统一管理的一类定时机制。不同于硬件定时器依赖 MCU 的定时器外设,软件定时器完全由软件实现,基于 RTOS 的节拍时钟(tick)驱动。

本质上:软件定时器就是一个在若干 tick 后触发的回调函数。

二、软件定时器的典型用途

应用场景示例
周期性任务LED 闪烁、数据上传
延时执行操作延迟关闭设备
替代硬件定时器节省资源GPIO 超时检测
防抖处理、状态切换延迟等按键防抖、状态复位

优势

  • 不占用额外任务资源

  • 系统统一调度,调试方便

  • 可动态创建、删除、启动、停止

  • 支持周期性和一次性定时

三、FreeRTOS 中软件定时器核心结构与源码解读

        FreeRTOS 软件定时器的核心结构体是 Timer_t,但对用户公开的类型为 TimerHandle_t。管理定时器的关键组件包括:

1. 创建定时器:xTimerCreate

TimerHandle_t xTimerCreate(const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction );

参数说明

  • pcTimerName:定时器名称(可调试用)

  • xTimerPeriodInTicks:周期时间(tick)

  • uxAutoReload:是否自动重装(周期性)

  • pvTimerID:用户定义的数据指针

  • pxCallbackFunction:定时器超时时调用的回调函数

TimerHandle_t myTimer = xTimerCreate("LEDTimer", pdMS_TO_TICKS(1000), pdTRUE, NULL, vLEDCallback);

2. 启动定时器:xTimerStart

xTimerStart(myTimer, 0);

将定时器放入活动链表,等待 Tick 累加触发。

3. 停止定时器:xTimerStop

xTimerStop(myTimer, 0);

可用于手动取消定时操作。

4. 回调函数定义

void vLEDCallback(TimerHandle_t xTimer) {// 执行定时任务,比如切换 LED 状态
}

注意:回调函数中不能调用阻塞操作(如 vTaskDelay),应尽可能快速完成逻辑。

5. 定时器服务任务机制

FreeRTOS 中有一个专门的任务叫做 定时器服务任务(Timer Service Task),用于处理所有软件定时器的事件。其本质是一个优先级较高、等待定时器消息队列的任务。

源码入口在 timers.c 中的 prvTimerTask

static void prvTimerTask( void *pvParameters )
{for( ;; ){// 等待来自定时器命令队列的消息(如启动/停止)xQueueReceive(xTimerQueue, &xMessage, portMAX_DELAY);switch(xMessage.xMessageID) {case tmrCOMMAND_START:// 添加定时器到活动链表break;case tmrCOMMAND_EXECUTE_CALLBACK:// 执行用户回调函数pxTimer->pxCallbackFunction((TimerHandle_t) pxTimer);break;// ...其他命令处理}}
}

其调度机制由 tick 中断驱动,在 xTaskIncrementTick() 中判断是否触发回调。

四、完整使用示例:LED 闪烁控制

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"#define LED_PIN 13TimerHandle_t ledTimer;void vLEDCallback(TimerHandle_t xTimer) {static int led_state = 0;led_state = !led_state;gpio_set_level(LED_PIN, led_state);
}void app_main() {gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);ledTimer = xTimerCreate("LEDTimer", pdMS_TO_TICKS(500), pdTRUE, NULL, vLEDCallback);xTimerStart(ledTimer, 0);
}

五、常见问题与注意事项

  1. 为什么不在任务中直接用 vTaskDelay
    因为软件定时器可以统一调度,不占用额外任务资源,更适合事件驱动模型。

  2. 能不能在中断中操作软件定时器?
    是的,FreeRTOS 提供 ISR 安全版本,如 xTimerStartFromISR

  3. 软件定时器精度如何?
    精度取决于系统 tick 周期,一般不适合要求微秒级精度的应用。

  4. 最大支持多少个定时器?
    由系统内存和队列大小决定,可配置,但通常可支持上百个。

六、小结

特性软件定时器
精度Tick 周期决定
触发方式回调函数
ISR 安全性提供 FromISR 版本支持
占用资源少,无需额外任务
适用场景周期任务、延时处理、状态切换

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86317.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从Yocto中获取源码用传统的方式单独编译

要获取 Yocto 构建后的 Linux 内核和 U-Boot 源码,并进行独立编译,需获取完整的源码树(包含所有应用补丁和配置)及原始配置信息。以下是具体步骤: 获取最终源码路径确定构建目录位置: 内核工作目录 KERNEL_WORKDIR=$(bitbake -e virtual/kernel | grep ^WORKDIR= | cut…

【记录】服务器|常见的八种硬盘接口的简介和清晰的接口图片(2025年6月)

硬盘接口很多,在管服务器的时候总是要买,但是偶尔会忘记自己的服务器支持什么接口,此时就需要看引脚。 如果没插满,就可以直接拍接口的图片,与下面这些图片对照一下【文字介绍是AI直接生成的,图片是我到处…

在一个成熟产品中,如何设计数据库架构以应对客户字段多样化,确保系统的可维护性、可扩展性和高性能。

在SaaS系统、平台型应用或高度可配置的企业级软件中,我们常常会遇到一个现实问题:不同客户对同一个业务表存在差异化字段需求。例如,A客户需要一个“业务员等级”字段,B客户不需要;C客户希望订单表中增加“海外仓编码”…

社群营销应该怎么玩

现在做营销,光靠打广告可不行了。大家都喜欢扎堆儿,找志同道合的人一起玩,这就是社群的力量。那怎么用好这股力量呢?咱们慢慢聊。 首先得明白,社群不是拉个群就完事了。关键是要让大家觉得这里有意思,有收…

【论文阅读笔记】TransparentGS:当高斯溅射学会“看穿”玻璃,如何攻克透明物体重建难题?

文章目录 TransparentGS: Fast Inverse Rendering of Transparent Objects with GaussiansInfoAbstractIntroductionMethod预备知识3D GS的概念不再赘述渲染方程透明高斯Gaussian Light Field Probes多阶段重建实验结果和评估消融实验应用讨论和限制结论TransparentGS: Fast In…

某视频网站运维工程师面试题

某视频网站运维工程师面试题 1、 简单写下Xeon和Itanium这两个产品的本质区别? 2、 ECC内存每Bank的颗粒数是单数还是双数的? 3、 假如有5块1T的硬盘,要求组合成尽量多的实际使用空间并至少容忍坏2盘而不影响raid组工作。请问有几种模式来组…

Java底层原理:深入理解JVM性能调优与监控

一、JVM性能调优概述 JVM性能调优是Java应用优化的重要环节,通过合理配置JVM参数,可以提高Java应用的性能和稳定性。JVM性能调优的主要目标是减少垃圾回收的频率和时间,提高线程的运行效率,优化内存的使用。 (一&…

Joblib库多进程/线程使用(一):使用generator参数实现边响应边使用

进程与线程的基本概念 特性进程 (Process)线程 (Thread)定义 操作系统分配资源的基本单位(独立的内存空间) 多进程可真正并行(利用多核 CPU) 进程内的执行单元(共享进程资源)独立性完全独立,崩…

css上下滚动文字

效果图 取得是数组里的数据 上下滚动切换 css .notice-new {background: #222222;border-radius: 19rpx;margin-top: 28rpx;font-size: 24rpx;color: white;font-weight: 500;padding: 0 20rpx;height: 55rpx;line-height: 55rpx;overflow: hidden;.notice-scroll-wrapper {pos…

概念篇: 01-带你认识Dockerfile

在本篇文章中,我们将带你认识 Dockerfile —— 构建 Docker 镜像的"蓝图"。我们会介绍它的基本概念和常用指令,帮助你理解如何使用它来打包你的应用。 简单了解 Docker(背景知识) 在我们深入 Dockerfile 之前&#xf…

技术伦理之争:OpenAI陷抄袭风波,法院强制下架宣传视频

在AI巨头OpenAI宣布以65亿美元天价收购苹果前设计总监Jony Ive的硬件公司IO仅一个月后,一场抄袭指控将这家科技明星企业推上风口浪尖。 源自谷歌X实验室的初创企业IYO将OpenAI告上法庭,指控其窃取智能耳塞核心技术,并通过巨额收购试图掩盖抄袭…

前沿解读:缺陷如何操控二维半导体中的电子摩擦耗散超快动力学

摩擦能耗约占全球一次能源损耗的1/3,在微纳器件中尤为突出。二维半导体(如WS₂)因其独特的电子特性成为研究热点,但电子摩擦的动态机制因电子行为的超快特性长期难以捕捉。近期清华团队在Nature Communications发表的研究[1]&…

什么是物联网 (IoT)?

你家是否安装了智能恒温器?或者你属于三分之一的美国健身追踪器用户,通过设备记录运动习惯?如果是,你已在使用物联网技术。这项技术不仅融入日常生活,更深刻改变着组织的运营方式。物联网通过多种技术连接数字与物理世…

[特殊字符] Windows 查看端口占用及服务来源教程(以 9018 端口为例)

下面是一份详细的 Windows 系统中排查 某端口(如 9018)被哪个程序占用 并确定其具体服务来源的完整教程,适合用于日常运维、开发部署排障等场景。 🎯 Windows 查看端口占用及服务来源教程(以 9018 端口为例&#xff09…

异步爬虫 原理与解析

先遍历100遍一个程序 import requests import logging import timelogging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s: %(message)s) TOTAL_NUMBER 100 BASE_URL https://ssr4.scrape.center/start_time time.time() for id in range(1,TOTAL_NUM…

vscode管理go多个版本

#1.下载go安装包 https://developer.aliyun.com/mirror/golang/?spma2c6h.25603864.0.0.55ea7c45IsI4GM # 2.创建 sdk 目录(如果不存在) mkdir -p ~/sdk # 3.解压下载的 go1.16.15 到 ~/sdk/ tar -C ~/sdk -xzf go1.16.15.linux-amd64.tar.gz # 4.重…

香港维尔利健康科技集团推出AI辅助医学影像训练平台,助力医护人才数字化转型

香港维尔利健康科技集团近日正式发布其自主研发的“AI辅助医学影像训练平台(V-MedTrain)”,这一创新平台的上线,标志着医学影像教育迈入智能化辅助教学新时代。依托人工智能与大数据分析技术,香港维尔利健康科技集团在…

互联网+医疗,医疗服务的全方位革新

近年来,互联网医疗行业迅速崛起,为医疗健康服务带来了翻天覆地的变革。新模式、新业态层出不穷,不仅大幅提升了医疗健康服务的可及性,也使得群众就医体验更为舒适、便捷。互联网技术的广泛应用,不仅改变了医疗核心业务…

酒店智能门锁系统常见问题解决方法——东方仙盟

重做系统后 usb发卡器与注册时发卡器不一致 解决发方法: 用总卡重新注册软件,要可以开房间的总卡 房号不存在 2声---正确提示,表示是设置卡 3声---门锁已反锁,解决方法:用能开反锁的卡或解除反锁 6声---房号不对,解决方法&#…

从零开始理解百度语音识别API的Python实现

大家好!今天我要给大家详细讲解一个使用百度语音识别API的Python代码。这个代码可以将音频文件转换成文字,非常适合做语音转文字的应用。我会从最基础的概念开始讲起,确保没有任何编程基础的朋友也能理解。 翻译 一、代码概览 这段代码主要…