Freertos——软件定时器 软件定时器FreeRTOS 软件定时器是纯软件实现、基于系统节拍SysTick计时的定时机制不需要占用硬件定时器资源由内核统一调度管理。它的核心定位是提供低精度、低开销、数量不限的定时能力适合处理秒级 / 百毫秒级的非高精度定时任务如 LED 闪烁、按键超时、通信超时检测等。定时器结构体flag是一次性还是周期性的定时器period周期fun函数param可传入参数链表项将所有的定时器串在一个链表上实现机制本质上是内核自动创建了一个专门的后台守护任务完全靠系统时钟节拍计时不占用硬件定时器资源。我们平时调用启动、停止、修改周期这类 API并不是直接操作定时器本身而是向这个守护任务的命令队列里发一条控制指令守护任务手里维护着一份按 “下次到期时间” 从小到大排好序的活跃定时器清单它平时就阻塞等待要么收到新的控制指令就更新清单要么等到最早的定时器到期就依次调用到期定时器的回调函数回调执行完后如果是周期定时器就按固定周期算出下次到期时间、重新插回清单如果是单次定时器就直接移除之后继续循环等待下一次指令或超时因为所有回调都在这同一个守护任务里串行执行所以单个回调不能耗时太久不然会耽误后面定时器的触发时机函数本质修改函数本质为写队列在写队列后触发的事件里去修改这个定时器的参数创建/*使用动态分配内存的方法创建定时器 * pcTimerName:定时器名字,用处不大,尽在调试时用到 * xTimerPeriodInTicks:周期,以Tick为单位 * uxAutoReload:类型, pdTRUE表示自动加载, pdFALSE表示一次性* pvTimerID:回调函数可以使用此参数,比如分辨是哪个定时器 * pxCallbackFunction:回调函数 *返回值:成功则返回TimerHandle_t,否则返回NULL */TimerHandle_txTimerCreate(constchar*constpcTimerName,constTickType_txTimerPeriodInTicks,constUBaseType_tuxAutoReload,void*constpvTimerID,TimerCallbackFunction_t pxCallbackFunction);/*使用静态分配内存的方法创建定时器 * pcTimerName:定时器名字,用处不大,尽在调试时用到 * xTimerPeriodInTicks:周期,以Tick为单位 * uxAutoReload:类型, pdTRUE表示自动加载, pdFALSE表示一次性 * pvTimerID:回调函数可以使用此参数,比如分辨是哪个定时器 * pxCallbackFunction:回调函数 * pxTimerBuffer:传入一个StaticTimer_t结构体,将在上面构造定时器 *返回值:成功则返回TimerHandle_t,否则返回NULL */TimerHandle_txTimerCreateStatic(constchar*constpcTimerName,TickType_t xTimerPeriodInTicks,UBaseType_t uxAutoReload,void*pvTimerID,TimerCallbackFunction_t pxCallbackFunction,StaticTimer_t*pxTimerBuffer);删除/*删除定时器 * xTimer:要删除哪个定时器 * xTicksToWait:超时时间 *返回值: pdFAIL表示删除命令在xTicksToWait个Tick内无法写入队列 * pdPASS表示成功 */BaseType_txTimerDelete(TimerHandle_t xTimer,TickType_t xTicksToWait);启动/停止/*启动定时器 * xTimer:哪个定时器 * xTicksToWait:超时时间 *返回值: pdFAIL表示启动命令在xTicksToWait个Tick内无法写入队列pdPASS表示成功 */BaseType_txTimerStart(TimerHandle_t xTimer,TickType_t xTicksToWait);/*启动定时器(ISR版本) * xTimer:哪个定时器 * pxHigherPriorityTaskWoken:向队列发出命令使得守护任务被唤醒, * 如果守护任务的优先级比当前任务的高, * 则*pxHigherPriorityTaskWoken pdTRUE, * 表示需要进行任务调度 *返回值: pdFAIL表示启动命令无法写入队列 * pdPASS表示成功 */BaseType_txTimerStartFromISR(TimerHandle_t xTimer,BaseType_t*pxHigherPriorityTaskWoken);/*停止定时器 * xTimer:哪个定时器 * xTicksToWait:超时时间 *返回值: pdFAIL表示停止命令在xTicksToWait个Tick内无法写入队列 * pdPASS表示成功 */BaseType_txTimerStop(TimerHandle_t xTimer,TickType_t xTicksToWait);/*停止定时器(ISR版本) * xTimer:哪个定时器* pxHigherPriorityTaskWoken:向队列发出命令使得守护任务被唤醒, * 如果守护任务的优先级比当前任务的高, * 则*pxHigherPriorityTaskWoken pdTRUE, * 表示需要进行任务调度 *返回值: pdFAIL表示停止命令无法写入队列 * pdPASS表示成功 */BaseType_txTimerStopFromISR(TimerHandle_t xTimer,BaseType_t*pxHigherPriorityTaskWoken);复位*复位定时器*xTimer:哪个定时器*xTicksToWait:超时时间*返回值:pdFAIL表示复位命令在xTicksToWait个Tick内无法写入队列pdPASS表示成功*/BaseType_txTimerReset(TimerHandle_t xTimer,TickType_t xTicksToWait);/*复位定时器(ISR版本) * xTimer:哪个定时器 * pxHigherPriorityTaskWoken:向队列发出命令使得守护任务被唤醒, * 如果守护任务的优先级比当前任务的高, * 则*pxHigherPriorityTaskWoken pdTRUE, * 表示需要进行任务调度 *返回值: pdFAIL表示停止命令无法写入队列 * pdPASS表示成功 */BaseType_txTimerResetFromISR(TimerHandle_t xTimer,BaseType_t*pxHigherPriorityTaskWoken);修改周期/*修改定时器的周期 * xTimer:哪个定时器 * xNewPeriod:新周期 * xTicksToWait:超时时间,命令写入队列的超时时间*返回值: pdFAIL表示修改周期命令在xTicksToWait个Tick内无法写入队列 * pdPASS表示成功 */BaseType_txTimerChangePeriod(TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait);/*修改定时器的周期 * xTimer:哪个定时器 * xNewPeriod:新周期 * pxHigherPriorityTaskWoken:向队列发出命令使得守护任务被唤醒, * 如果守护任务的优先级比当前任务的高, * 则*pxHigherPriorityTaskWoken pdTRUE, * 表示需要进行任务调度 *返回值: pdFAIL表示修改周期命令在xTicksToWait个Tick内无法写入队列 * pdPASS表示成功 */BaseType_txTimerChangePeriodFromISR(TimerHandle_t xTimer,TickType_t xNewPeriod,BaseType_t*pxHigherPriorityTaskWoken);注意事项注意定时器任务的优先级要足够高