前言这篇文章的内容是关于软件定时器的解析分析。解析每个源码的时候就只有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个流程就实现软件定时器的运行