FreeRTOS学习六(软件定时器)
软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数,被定时器调用的这个功能函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期,简而言之,当定时器的定时周期到了以后就会执行回调函数。
软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何会阻塞任务的API函数。比如,定时器回调函数中不能调佣vTaskDelay()、vTaskDelayUnti(),还有一些访问队列或者信号量的非零阻塞时间的API函数。
软件定时器时一个可选项,不属于FreeRTOS内核的功能,它是由定时器服务(或Daemon)任务来提供的。FreeRTOS中所使用的定时器相关API函数,大部分是使用FreeRTOS的队列发送命令给定时器服务任务的。这个队列叫做定时器命令队列。定时器命令队列是提供给FreeRTOS的软件定时器使用的,用户不能直接使用。
软件定时器的相关宏定义配置在FreeRTOSConfig.h文件中。
#define configUSE_TIMERS 1 //软件定时器开启#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) //优先级#define configTIMER_QUEUE_LENGTH 10 //定时器命令队列长度#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) //定时器服务任务的任务堆栈大小。
软件定时器分为两种:单次定时器和周期定时器,单次定时器的话定时器回调函数就执行一次,然后定时器就会停止。单次定时器可以再次手动重新启动,但是不能自动重启。周期定时器一旦启动后,当定时器超时执行完回调函数以后会自动重新启动,这样回调函数就会周期性的执行。
有时候需要在定时器运行的时候重新复位软件定时器,复位软件定时器的话会清零计数,并且重新计算定时周期到达的时间点。
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:软件定时器的定时器周期,单位是时钟节拍数,可以通过设置(周期ms/portTICK_PERIOD_MS)转换为需要的时间周期,单位ms。
uxAutoReload:设置定时器模式。pdTRUE 为周期定时器,pdFALSE 为单次定时器。
pvTimerID:定时器ID号,一般情况下每个定时器都有一个回调函数,FreeRTOS支持多个定时器共用一个回调函数,在回调函数中根据定时器ID号来处理不同的定时器。
pxCallbackFunction:定时器回调函数。
返回值:
NULL:创建失败
其他值:创建成功,返回定时器句柄。
实例:
TimerHandle_t xTimer_test;xTimer_test = xTimerCreate("Test timer", /* Just a text name, not used by the kernel. */(1 * 50 / portTICK_PERIOD_MS), /* The timer period in ticks. */pdFALSE, /* The timers will auto-reload themselves when they expire. */NULL, /* Assign each timer a unique id equal to its array index. */test_timer_callback /* Each timer calls the same callback when it expires. */);
2.xTimerCreateStatic()创建软件定时器(静态内存)
此函数用于创建一个软件定时器,所需要的内存需要用户自行分配。新创建的软件定时器处于休眠状态。
函数原型:
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction,StaticTimer_t *pxTimerBuffer )
参数:
pcTimerName:软件定时器名字,名字是一串字符串,用于调试使用
xTimerPeriodInTicks:软件定时器的定时器周期,单位是时钟节拍数,可以通过设置(周期ms/portTICK_PERIOD_MS)转换为需要的时间周期,单位ms。
uxAutoReload:设置定时器模式。pdTRUE 为周期定时器,pdFALSE 为单次定时器。
pvTimerID:定时器ID号,一般情况下每个定时器都有一个回调函数,FreeRTOS支持多个定时器共用一个回调函数,在回调函数中根据定时器ID号来处理不同的定时器。
pxCallbackFunction:定时器回调函数。
pxTimerBuffer :指向一个StaticTimer_t类型的变量,用来保存定时器结构体。
返回值:
NULL:创建失败
其他值:创建成功,返回定时器句柄。
实例:
static StaticTimer_t xTimerBuffer;
TimerHandle_t xTimer ;xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS.xTimerPeriod, // The period of the timer in ticks.pdTRUE, // This is an auto-reload timer.( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback functionprvTimerCallback, // The function to execute when the timer expires.&xTimerBuffer ); // The buffer that will hold the software timer structure.
3.xTimerStart() 启动软件定时器
启动软件定时器。软件定时器在创建好之后会处于等待状态,调用该函数之后会将定时器转为运行状态。如果软件定时器正在运行的话,调用函数xTimerStart()的结果和xTimerReset()是一样的。
函数原型:
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
参数:
xTimer:要开启的软件定时器的句柄
xTicksToWait :设置阻塞时间,调用该函数开启软件定时器其实就是向定时器命令队列发送一条tmrCOMMAND_START命令,既然是向队列发送消息,那肯定会涉及到入队阻塞时间的设置。
返回值:
pdPASS:启动成功
pdFALL:启动失败。
实例:
if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ){// The timer could not be set into the Active state.
}
4.xTimerStartFromISR()在中断中启动软件定时器
函数原型:
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
参数:
xTimer:要开启的软件定时器的句柄
pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换。当设置为pdTRUE时,退出中断服务函数之前一定会进行一次任务切换。
返回值:
pdPASS:启动成功
pdFALL:启动失败。
实例:
BaseType_t xHigherPriorityTaskWoken = pdFALSE;if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
{// The start command was not executed successfully. Take appropriate// action here.
}
5.xTimerStop()停止软件定时器
此函数用于停止一个软件定时器,此函数用于任务中。
函数原型:
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
参数:
xTimer:要停止的软件定时器的句柄
xTicksToWait :设置阻塞时间,调用该函数停止软件定时器其实就是向定时器命令队列发送一条tmrCOMMAND_STOP命令,既然是向队列发送消息,那肯定会涉及到入队阻塞时间的设置。
返回值:
pdPASS:停止成功
pdFALL:停止失败。
实例:
xTimerStop( pxTimer, 0 );
6.xTimerStopFromISR()中断中停止软件定时器
函数原型:
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
参数:
xTimer:要停止的软件定时器的句柄
pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换。当设置为pdTRUE时,退出中断服务函数之前一定会进行一次任务切换。
返回值:
pdPASS:停止成功
pdFALL:停止失败。
实例:
BaseType_t xHigherPriorityTaskWoken = pdFALSE;if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
{// The stop command was not executed successfully. Take appropriate// action here.
}
7.xTimerReset() 复位软件定时器
复位一个软件定时器,此函数只能用于任务中,不能用于中断中。
函数原型:
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
参数:
xTimer:要复位的软件定时器的句柄
xTicksToWait :设置阻塞时间,调用该函数停止软件定时器其实就是向定时器命令队列发送一条tmrCOMMAND_RESET命令,既然是向队列发送消息,那肯定会涉及到入队阻塞时间的设置。
返回值:
pdPASS:复位成功
pdFALL:复位失败。
实例:
if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ){// The reset command was not executed successfully. Take appropriate// action here.
}
8.xTimerResetFromISR()中断中复位软件定时器
函数原型:
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
参数:
xTimer:要复位的软件定时器的句柄
pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换。当设置为pdTRUE时,退出中断服务函数之前一定会进行一次任务切换。
返回值:
pdPASS:复位成功
pdFALL:复位失败。
实例:
BaseType_t xHigherPriorityTaskWoken = pdFALSE;if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
{// The reset command was not executed successfully. Take appropriate// action here.
}
代码验证:
创建一个任务,在任务中开启一个1秒周期的定时器,定时器定时打印。
static TimerHandle_t xTimer_test;
static const uint32_t timer_id = 2;
任务1
static void vTestTask1_H(void *pvParameters)
{
xTimer_test = xTimerCreate("Test timer", /* Just a text name, not used by the kernel. */(1000 / portTICK_PERIOD_MS), /* The timer period in ticks. */pdTRUE, /* The timers will auto-reload themselves when they expire. */(void *)timer_id, /* Assign each timer a unique id equal to its array index. */vTimerCallback /* Each timer calls the same callback when it expires. */);if(xTimer_test == NULL) {LOG_I(common,"[TASK1]:Timer create fail"); //失败}else{LOG_I(common,"[TASK1]:Timer create sucess"); //成功if( xTimerStart( xTimer_test, 0 ) != pdPASS ){LOG_I(common,"[TASK1]:Timer start fail"); //失败}
}
vTaskDelete(NULL);
}
定时器回调函数:
void vTimerCallback( TimerHandle_t pxTimer )
{configASSERT( pxTimer );static uint32_t time_cnt = 0;time_cnt++;int32_t lArrayIndex = 0;lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer );LOG_I(common,"[DEBUG]:timer name:%stimer id:%d",pcTimerGetName(pxTimer),lArrayIndex);if(lArrayIndex = timer_id){LOG_I(common,"[DEBUG]:time cnt:%d",time_cnt);}
}
结果:
在创建定时器的时候,设置了timer_id为2。在回调函数中,通过pvTimerGetTimerID()函数来获取timer_id,通过pcTimerGetName()函数来获取定时器名字,并打印出来。结果可以看到都是相互对应的。并且定时器时个周期定时器,间隔1秒钟会打印一次。
FreeRTOS学习六(软件定时器)相关推荐
- 8.FreeRTOS学习笔记-软件定时器
基本概念 软件定时器的回调函数类似硬件的中断服务函数,所以,回调函数也要快进快出,而且回调函数中不能有任何阻塞任务运行的情况,例如不可以使用vTaskDelay() FreeRTOS 提供的软件定时器 ...
- 【FreeRTOS】11 软件定时器
定时器是MCU常用的外设,我们在学习各种单片机时必然会学习它的硬件定时器.但是,MCU自带的硬件定时器资源是有限的,而且一般会用在实时性要求很强的地方. 在freeRTOS中提供了软件定时器的功能,来 ...
- 鸿蒙Hi3861学习六-Huawei LiteOS-M(软件定时器)
一.简介 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器.当经过设定的Tick时钟计数值后,会触发用户定义的回调函数.定时精度与系统Tick时钟周期有关. 硬件定时器受硬件的限制,数量上 ...
- FreeRTOS学习笔记(7)——软件定时器
一.头文件 #include "FreeRTOS.h" #include "timers.h" 二.软件定时器 2.1 基本概念 软件定时器在被创建之后,当经过 ...
- ESP32-C3入门教程 基础篇(六、TIMG 硬件定时器 与 软件定时器)
到了测试第6课,还没有玩过ESP32-C3的基本定时器,虽然FreeRTOS,可以使用软件定时器 但是软件定时器毕竟也有不适用的时候,这个在我FreeRTOS博文中有单独说明. 所以硬件定时器也得熟悉 ...
- FreeRTOS软件定时器 基于STM32
文章目录 一·.软件定时器的基本概念 二.软件定时器应用场景 三.软件定时器的精度 四.软件定时器的运作机制 五.软件定时器函数接口讲解 1.软件定时器创建函数 xTimerCreate() 2.软件 ...
- FreeRTOS软件定时器 | FreeRTOS十三
目录 说明: 一.定时器简介 1.1.定时器 1.2.软件定时器 1.3.硬件定时器 1.4.FreeRTOS软件定时器 1.5.软件定时器服务任务作用 1.6.软件定时器的命令队列 1.7.软件定时 ...
- STM32 FreeRTOS (三) 软件定时器
简介: 基本概念 ReeRTOS中加入了软件定时器这个功能组件,是一个可选的.不属于freeRTOS内核的功能,由定时器服务(其实就是一个定时器任务)来提供. 软件定时器是当设定一个定时时间,当达到设 ...
- FreeRtos软件定时器复习
一.基础概念 概念解析:定时器分为硬与软定,硬件定时器到达定时时间自动触发中断服务函数,使用软件定时器时,需要我们在创建软件定时器时指定时间到达后要调用的函数(也称超时函数/回调函数,为了统一,下文均 ...
最新文章
- 独家 | 一文读懂如何用深度学习实现网络安全
- Spring----自定义异常类
- 布朗语料库中不同部分的情态动词频率直方图绘制的代码详细解释
- 廖雪峰python教程在哪看_:廖雪峰python教程在哪
- IIS 部署asp.net Core程序注意事项
- SQLSTATE[HY000]: General error: 1030 Got error 28 from storage engine
- spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入...
- 利用可分离卷积UNet进行木薯叶病分类
- paip.提升用户体验-----用户注册设计
- Eclipse环境变量配置!
- 手写字体识别(1) 准备数据集
- java开发mdm平台_Apple iOS MDM开发流程
- 域渗透基础_域渗透实战下gpo策略利用
- 关于Flash的几点思考(Thoughts on Flash)
- Android实现snmp协议(一)
- CsvWriteramp;amp;CsvReader
- Elasticsearch实战---------相关名词介绍
- 工时表软件在项目中的作用 帮助企业管理项目成员的工时
- 架设KMS服务器流程启动加载方法
- sandisk TF卡 can not format issue 解决方法
热门文章
- javascript:用js实现tirm函数
- java for循环 写法_java中for循环的6种写法
- 柯基数据:先进的知识图谱技术,构建行业知识图谱,助企业打通内部信息孤岛,链接海量数据 |百万人学AI评选
- python水果超市管理系统_项目1-水果超市管理系统-学生
- 【EMC】EMC整改方法
- SpringMVC-Spring-Mybatis
- 你不知道的javascript读书笔记
- xp系统禁止开机启动服务器,win xp开机启动项怎么设置-win xp关闭开机启动项的方法 - 河东软件园...
- java 中free,FreeJava 的使用方法(三)FreeJava的使用,freejava使用方法
- 10000个怎么用js写 创建li_给博客园加一个会动的小人-spig.js