当前位置: 首页 > news >正文

第三章 拼凑内核(3) -- 软件定时器解析

前言

这篇文章的内容是关于软件定时器的解析分析。解析每个源码的时候,就只有2个方向

  • 数据结构

  • 程序运行逻辑

其实不存在严格先后顺序,了解数据结构才能容易理解程序是如何运行的;而不了解程序逻辑只看数据结构就像在看天书一样。

那就让我们来慢慢解析FreeRTOS中的软件定时器组件

软件定时器简介

在具体解析前,我们要先预设一些知识背景,能很好的过渡到数据结构和程序逻辑。

软件定时器管理

软件定时器也是通过列表管理的,所以软件定时器就存在软件定时器活动列表,进行所有定时器的管理

那对于软件定时器本身呢,要被列表管理,说明其内嵌了列表项,才能被列表管理。

同时软件定时器分为:

  • 一次性定时器: 只执行一次后,就自动销毁

  • 周期性定时器:周期性时间性执行,不自动销毁

不论周期或者一次性的定时器,时间到了。都要执行一些事情,这个事情的处理就是一个函数,那也就说明想要回调函数指针了。

对于定时器的开始,不是说创建好一个定时器后就自动开始的,定时器的启动需要"命令"驱动,而对于实际场景,可能一次性好几个定时器开启,对于这些消息定时器任务使用队列进行消息缓冲,实现异步处理

如何实现

软件定时器不是什么一个很新的东西,但是使用的也是很频繁的。

软件定时器是基于一个软件定时器任务来实现的,它的"地基"任务队列列表,而它的功能都是基于这以条件搭建起来的。

  • 创建的新定时器放入定时器列表管理

  • 定时器命令传入通过队列接收

  • 软件定时器任务处理:定时器装载回调函数处理时间判断

这就是软件定时器在运行过程中的地基,也就是软件定时器任务运行的图例。有了这幅图我们就能清楚的知道,软件定时器不断运行的背后存在着什么

软件定时器解析

数据结构

typedef struct tmrTimerControl { const char *pcTimerName; //定时器名 ListItem_t xTimerListItem; //定时器列表 TickType_t xTimerPeriodInTicks; //定时器周期 UBaseType_t uxAutoReload; //定时器自动重装 void *pvTimerID; //定时器ID TimerCallbackFunction_t pxCallbackFunction; //定时器函数 } xTIMER;

又来到枯燥的数据结构环节

  • 定时器名:定时器使用列表管理,所以定时器中会存在一个定时器列表项
  • 定时器列表项

  • 定时器周期时间定时器存在周期使用或者一次性使用,所以就有一个"我要多久的周期运行定时器或者多久之后只运行一次定时器"

  • 定时器自动重装周期运行的需要自动重装,而一次性的不用

  • 定时器ID用于区分不同定时器

  • 回调函数需要运行的程序逻辑

这些数据结构和我们的图例是相呼应的

主要程序逻辑

主要的程序逻辑有3方面

定时器任务
static void prvTimerTask( void *pvParameters ) //定时器任务函数

对于定时器任务前面也有简介,记住图例会更容易去理解

  • 看看定时器列表中有没有定时器

  • 有定时器到期就运行,并且进行重装,没有定时器或者时间未到就阻塞

  • 定时器消息队列命令处理

定时器创建
TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction )

对于定时器的创建就比较简单了,主要就是定时器数据结构的初始化和将定时器放入列表中

定时器命令
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) //定时器命令

定时器命令也是在操作定时器队列,唯一要注意的点是队列元素是自定义的消息格式

定时器队列消息

typedef struct tmrTimerQueueMessage { BaseType_t xMessageID; union { TimerParameter_t xTimerParameters; #if ( INCLUDE_xTimerPendFunctionCall == 1 ) CallbackParameters_t xCallbackParameters; #endif } u; } DaemonTaskMessage_t;

包含定时器ID和参数信息,这就是定时器队列的元素。

软件定时器应用

简单500ms闪烁灯应用

其实闪烁灯可以直接用任务延时来实现,简单又快捷,但是为了突出本章主题,所以用软件定时器实现

实现逻辑

闪烁灯函数:用于定时器周期回调

闪烁灯软件定时器

闪烁灯软件定时器开始命令

程序逻辑只要实现这3个流程就实现软件定时器的运行

http://www.jsqmd.com/news/612958/

相关文章:

  • 聊一聊 C# 中的闭包陷阱:foreach 循环的坑你还记得吗?痉
  • 3个突破性功能:开源工具实现Cursor限制解除与效率提升完全指南
  • 如何用这款原神辅助工具提升90%游戏效率?
  • 如何快速掌握DeepXDE:物理信息神经网络的完整入门指南
  • 3大战略优势:如何通过Axure本地化解决方案提升团队设计效率与协作效能
  • 2026年4月论文降AI工具实测:10款横评后这款能降至0.12%
  • gitee默认仓库初始化命令
  • 终极指南:如何用PoeCharm中文版轻松规划你的《流放之路》角色构建
  • 终极指南:OpenTabletDriver开源数位板驱动的完整配置与深度使用
  • 一键部署PyTorch/TensorFlow:Miniconda-Python3.8镜像AI框架安装指南
  • 如何永久保存番茄小说?3个强力方案告别网络依赖
  • CentOS下载torrent文件的工具aria2的安装
  • SLG网页游戏|三国回合游戏|602三国传说玩法与攻略全面解析
  • cad文件选项卡不见了怎么办?
  • 工业缺陷检测数据标注的五大关键实践
  • 终极游戏模组管理革命:XXMI启动器让二次元游戏体验全面升级
  • Cursor Pro 终极破解:开源工具cursor-free-vip实现永久免费使用完整指南
  • 零门槛如何快速制作专业演示文稿?这款开源工具让PPT设计效率提升60%
  • 先觉多肽:凝胶搭档促血管化核心材料
  • 强力解锁:Browsershot - PHP开发者必备的网页截图与PDF生成神器
  • 重构流放之路角色构建:PoeCharm如何通过量化决策引擎重塑玩家认知
  • 嵌入式Linux智能家居系统开发实践
  • 为什么你的PHP 8.9仍卡在100MB瓶颈?揭秘opcache.preload+FFI内存映射的隐藏开关
  • OpenClaw配置备份指南:Qwen3-14b_int4_awq模型迁移与环境复原
  • Z-Image-Turbo镜像实战:9步推理生成高清图,电商海报轻松做
  • STEP3-VL-10B多场景落地:法律合同截图→关键条款提取+风险点标注
  • 论文降AI工具实测:高AI率最低可降至0.12%,靠谱工具推荐
  • DeerFlow代码生成实战:SpringBoot微服务自动开发
  • 轻量级工具G-Helper:华硕笔记本性能调校的效率工具
  • GLM-4v-9B学习笔记:9B参数轻量模型,性能却超越多个大模型