电器网站建设流程网站建设公司好发信息网
news/
2025/9/26 14:12:16/
文章来源:
电器网站建设流程,网站建设公司好发信息网,郑州seo优化外包顾问,广告公司门头摘要(From AI): 这篇笔记全面介绍了 FreeRTOS 软件定时器的核心概念和使用方法#xff0c;包括定时器的创建、管理、常用 API 和辅助函数#xff0c;并通过示例代码演示了如何启动、重置和更改定时器的周期。它强调了软件定时器的灵活性、平台无关性以及与硬件定时器的对比
…摘要(From AI): 这篇笔记全面介绍了 FreeRTOS 软件定时器的核心概念和使用方法包括定时器的创建、管理、常用 API 和辅助函数并通过示例代码演示了如何启动、重置和更改定时器的周期。它强调了软件定时器的灵活性、平台无关性以及与硬件定时器的对比
前言本文档是本人在依照B站UPMichael_ee的视频教程进行学习时所做的学习笔记可能存在疏漏和错误如有发现望指正。 上一篇ESP32学习笔记_FreeRTOS(2)——Queue 文章目录 Software TimerCreating a Software TimerxTimerCreate() Managing Software TimersxTimerStart()xTimerStop()pcTimerGetName()pvTimerGetTimerID()xTimerReset()xTimerChangePeriod() Example Code:Using Software Timers 参考资料 [Michael_ee视频教程] https://www.bilibili.com/video/BV1Nb4y1q7xz?spm_id_from333.788.videopod.sectionsvd_source4d8bd0ed3878ef81b239bf69bf38e741 freeRTOS官网 espressif 在线文档 Software Timer
硬件定时器会有数量等方面的限制使用较不灵活而软件定时器使用更为灵活其与硬件、平台无关在不同的 MCU 都可以使用 FreeRTOS API 进行调用
特性硬件定时器软件定时器数量固定受 MCU 硬件资源限制通常只有几个灵活可以根据需要动态创建受内存和任务管理能力限制依赖性依赖具体硬件平台配置方式和功能因芯片而异与硬件平台无关可通过 FreeRTOS API 在不同 MCU 上使用精度高精度直接由硬件计时通常用于实时性要求高的场景精度依赖于 RTOS 的调度周期tick 周期不适合极高实时性场景性能高性能独立运行不占用 CPU 资源运行在 RTOS 守护任务上下文中占用 CPU 资源适用场景适合时间敏感的应用如 PWM 信号生成、脉冲捕获、输入输出事件计时等适合通用定时功能如定时任务执行、软件超时处理等灵活性配置固定功能和用途受限灵活性高可动态调整超时时间、回调函数等使用复杂度配置复杂需根据芯片手册手动设置寄存器使用方便通过 FreeRTOS API 调用移植性差代码与硬件平台强耦合好代码与硬件无关便于跨平台移植
所有软件定时器的回调函数都在同一个RTOS守护任务也称为“定时器服务任务”的上下文中执行该任务最初被称为“定时器服务任务”因为最初它只用于执行软件定时器回调函数。现在同一任务也用于其他用途因此被改名为更通用的“RTOS 守护任务” 守护任务是一个标准的FreeRTOS任务会在调度器启动时自动创建。其优先级和堆栈大小由编译时配置常量configTIMER_TASK_PRIORITY和configTIMER_TASK_STACK_DEPTH分别设置这两个常量在FreeRTOSConfig.h中定义 需要注意软件定时器的回调函数是在 RTOS 守护任务的上下文中执行的而不是在独立的任务中运行。因此回调函数中不能调用可能使任务进入阻塞状态的 FreeRTOS API 函数因为这会阻塞整个守护任务导致系统运行异常 Creating a Software Timer
xTimerCreate()
xTimerCreate() 用于创建一个新的软件定时器并返回一个句柄以引用创建的定时器
#include “FreeRTOS.h”
#include “timers.h”TimerHandle_t xTimerCreate( const char *pcTimerName,const TickType_t xTimerPeriod,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction );参数
pcTimerName定时器的名称仅用于调试xTimerPeriod定时器周期单位为系统 tick不能为 0。可以使用 pdMS_TO_TICKS() 宏将毫秒转换为 tick。例如 100 tick直接设置为 100500ms可使用 pdMS_TO_TICKS(500)前提是 configTICK_RATE_HZ 1000 uxAutoReload设置定时器类型 pdTRUE自动重载定时器周期性触发pdFALSE一次性定时器仅触发一次可手动重新启动 pvTimerID定时器标识符用于在回调函数中区分不同的定时器或在回调调用之间存储值pxCallbackFunction定时器到期时执行的回调函数需符合 TimerCallbackFunction_t 原型
void vCallbackFunctionExample(TimerHandle_t xTimer);configTICK_RATE_HZ 是 FreeRTOS 配置文件 FreeRTOSConfig.h 中定义的一个宏它表示 每秒系统 Tick 的次数即 FreeRTOS 的调度器每秒中断的频率单位为 Hz 例如 如果 configTICK_RATE_HZ 1000表示系统每 1 毫秒触发一次 Tick 中断 如果 configTICK_RATE_HZ 100表示系统每 10 毫秒触发一次 Tick 中断 返回值
NULL 定时器创建失败原因可能是 FreeRTOS 堆内存不足其他值 定时器创建成功返回的句柄可用于引用该定时器
配置要求(一般不用动)
在 FreeRTOSConfig.h 文件中configUSE_TIMERS 和 configSUPPORT_DYNAMIC_ALLOCATION 必须都设置为 1如果 configSUPPORT_DYNAMIC_ALLOCATION 未定义其默认值为 1
创建定时器并不会立即启动。可以使用以下函数来启动或管理定时器
// 启动定时器。如果定时器已经在运行则从当前时间重新开始。
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );// 重置重新启动定时器。确保定时器启动或重新计算到期时间。
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );// 从中断上下文启动定时器。等效于 xTimerStart()用于中断中调用。
BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );// 从中断上下文重置重新启动定时器。等效于 xTimerReset()用于中断中调用。
BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );// 更改定时器的周期。如果定时器未运行则会启动定时器。
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait );// 从中断上下文更改定时器的周期。等效于 xTimerChangePeriod()用于中断中调用。
BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,TickType_t xNewPeriod,BaseType_t *pxHigherPriorityTaskWoken );Managing Software Timers
xTimerStart()
xTimerStart() 用于启动一个软件定时器的运行
如果定时器尚未运行xTimerStart() 会计算一个到期时间该时间相对于调用 xTimerStart() 的时刻如果定时器已经在运行则 xTimerStart() 相当于调用了 xTimerReset()即重置定时器定时器会在定义的周期后即 xTimerStart() 调用后 n 个 tick触发回调函数除非定时器在此期间被停止、删除或重置
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );参数
xTimer:要启动、重置或重新启动的定时器句柄xTicksToWait指定调用任务在 timer command queue 队列已满的情况下等待空间可用的最大时间单位为 tick。这是任务在进入 Blocked 状态时的阻塞时间。如果队列已满任务会被阻塞直到有足够的空间来发送命令 设置 xTicksToWait 为 portMAX_DELAY 将导致任务无限期等待直到队列中有空间如果在调度器启动之前调用 xTimerStart()则 xTicksToWait 会被忽略 当任务调用 xTimerStart() 或其他定时器相关 API 时这些命令并不会立即由任务执行而是通过一个队列传递给定时器服务任务 如果队列已满新的命令会被阻塞直到队列有空间可用。这时调用 xTimerStart() 等 API 的任务会根据指定的阻塞时间xTicksToWait进入阻塞状态等待队列空间变得可用 timer command queue 的大小由 FreeRTOS 的配置项决定。队列的大小设置影响系统可以同时处理多少个定时器命令。如果队列大小太小可能会导致命令丢失或任务阻塞 configTIMER_QUEUE_LENGTH定义了 timer command queue 队列的最大长度即可以存放多少个定时器命令 configUSE_TIMERS必须设置为 1才能启用定时器功能和相关队列 返回值
pdPASS启动命令成功发送到定时器命令队列。如果指定了阻塞时间即 xTicksToWait 不为零则可能会因为队列已满任务进入阻塞状态等待空间释放直到数据成功写入队列 定时器命令的处理时间会根据定时器服务任务的优先级而有所不同但定时器的到期时间是相对于实际调用 xTimerStart() 时刻从队列中取出命令并实际启动定时器的定时器命令的处理时间受定时器服务任务优先级的影响定时器服务任务的优先级由 configTIMER_TASK_PRIORITY 配置常量设置 pdFAIL启动命令未成功发送到定时器命令队列原因是队列已满。如果指定了阻塞时间任务会被阻塞等待队列有空间直到指定的阻塞时间过期但仍未成功写入数据到队列
注意事项(一般不用动) 在 FreeRTOSConfig.h 中configUSE_TIMERS 必须设置为 1才能使用 xTimerStart() 函数
xTimerStop()
xTimerStop() 用于停止一个运行中的软件定时器
调用 xTimerStop() 可以停止一个正在运行的定时器。如果定时器已经停止或已过期则调用 xTimerStop() 不会产生影响。xTimerStop() 向定时器命令队列发送停止命令定时器服务任务会在稍后处理该命令。
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );参数
xTimer要停止的定时器句柄。xTicksToWait指定任务在定时器命令队列已满的情况下最大等待时间单位为 ticks
返回值
pdPASSpdFAIL
pcTimerGetName()
pcTimerGetName() 用于返回在创建定时器时分配的可读文本名称
#include “FreeRTOS.h”
#include “timers.h”const char * pcTimerGetName( TimerHandle_t xTimer );返回值
返回值为一个指向定时器名称的指针。定时器名称是一个标准的以 NULL 结尾的 C 字符串。
pvTimerGetTimerID()
pvTimerGetTimerID() 用于返回与定时器关联的标识符ID
返回在创建定时器时分配的标识符该标识符可以通过 vTimerSetTimerID() API 更新在回调函数中可以使用该标识符区分哪个定时器到期特别是在多个定时器共享相同的回调函数时
#include “FreeRTOS.h”
#include “timers.h”void *pvTimerGetTimerID( TimerHandle_t xTimer );返回值
返回与指定定时器关联的标识符指针类型
xTimerReset()
xTimerReset() 用于重置、启动或重新启动一个软件定时器能够起到 Watch Dog 的作用
如果定时器正在运行xTimerReset() 会将定时器的到期时间重新计算为相对于调用时间的周期如果定时器未运行xTimerReset() 会启动定时器并将到期时间计算为相对于调用时间的周期。此时等效于 xTimerStart()无论定时器当前是否运行调用 xTimerReset() 后定时器都将开始运行
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );返回值
pdPASSpdFAIL
xTimerChangePeriod()
xTimerChangePeriod() 用于更改软件定时器的周期
更改运行中定时器的周期 如果定时器正在运行则新周期将用于重新计算到期时间。新的到期时间相对于调用 xTimerChangePeriod() 的时刻而不是定时器最初启动的时刻。 启动未运行的定时器 如果定时器未运行则定时器将使用新的周期值计算到期时间并开始运行。
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait );参数
xTimer需要更改周期的定时器句柄xNewPeriod定时器的新周期单位为 tick。可使用 pdMS_TO_TICKS() 将毫秒转换为 tickxTicksToWait阻塞任务的最大时间单位为 tick如果定时器命令队列已满则等待空间可用
返回值
pdPASSpdFAIL
Example Code:Using Software Timers
#include stdio.h
#include inttypes.h
#include sdkconfig.h
#include freertos/FreeRTOS.h
#include freertos/task.h
#include esp_chip_info.h
#include esp_flash.h
#include esp_system.h #include freertos/timers.h // 定时器头文件 void TimerCallback(TimerHandle_t xTimer)
{ const char *pcTimerName pcTimerGetName(xTimer);// 获取定时器名称 uint32_t *uiTimerID (uint32_t *)pvTimerGetTimerID(xTimer);// 获取定时器ID printf(%s expired, ID: %lu.\n, pcTimerName, *uiTimerID);// 打印定时器名称和ID
} int id1 0;
int id2 1; void app_main(void)
{ TimerHandle_t TimerHandle1 NULL; TimerHandle1 xTimerCreate(Timer1, pdMS_TO_TICKS(1000), pdTRUE, (void *)id1, TimerCallback);// 创建一个周期为1000ms的定时器 xTimerStart(TimerHandle1, 0);// 启动定时器 TimerHandle_t TimerHandle2 NULL; TimerHandle2 xTimerCreate(Timer2, pdMS_TO_TICKS(2000), pdTRUE, (void *)id2, TimerCallback);// 与Timer1公用同一个回调函数观察pcTimerGetName的输出 xTimerStart(TimerHandle2, 0);// 启动定时器 // for(int i 0; i 10; i) // { // vTaskDelay(pdMS_TO_TICKS(1000)); // xTimerReset(TimerHandle2, 0);// 重置定时器观察pcTimerGetName的输出此时Timer2不会被打印 // } vTaskDelay(pdMS_TO_TICKS(5000)); xTimerChangePeriod(TimerHandle2, pdMS_TO_TICKS(1000), 0);// 修改Timer2的周期为1000ms vTaskDelay(pdMS_TO_TICKS(5000)); xTimerStop(TimerHandle1, 0);// 停止定时器 xTimerStop(TimerHandle2, 0);// 停止定时器
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/918370.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!