软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数,被定时器调用的这个功能函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期,简而言之,当定时器的定时周期到了以后就会执行回调函数。

软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何会阻塞任务的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学习六(软件定时器)相关推荐

  1. 8.FreeRTOS学习笔记-软件定时器

    基本概念 软件定时器的回调函数类似硬件的中断服务函数,所以,回调函数也要快进快出,而且回调函数中不能有任何阻塞任务运行的情况,例如不可以使用vTaskDelay() FreeRTOS 提供的软件定时器 ...

  2. 【FreeRTOS】11 软件定时器

    定时器是MCU常用的外设,我们在学习各种单片机时必然会学习它的硬件定时器.但是,MCU自带的硬件定时器资源是有限的,而且一般会用在实时性要求很强的地方. 在freeRTOS中提供了软件定时器的功能,来 ...

  3. 鸿蒙Hi3861学习六-Huawei LiteOS-M(软件定时器)

    一.简介 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器.当经过设定的Tick时钟计数值后,会触发用户定义的回调函数.定时精度与系统Tick时钟周期有关. 硬件定时器受硬件的限制,数量上 ...

  4. FreeRTOS学习笔记(7)——软件定时器

    一.头文件 #include "FreeRTOS.h" #include "timers.h" 二.软件定时器 2.1 基本概念 软件定时器在被创建之后,当经过 ...

  5. ESP32-C3入门教程 基础篇(六、TIMG 硬件定时器 与 软件定时器)

    到了测试第6课,还没有玩过ESP32-C3的基本定时器,虽然FreeRTOS,可以使用软件定时器 但是软件定时器毕竟也有不适用的时候,这个在我FreeRTOS博文中有单独说明. 所以硬件定时器也得熟悉 ...

  6. FreeRTOS软件定时器 基于STM32

    文章目录 一·.软件定时器的基本概念 二.软件定时器应用场景 三.软件定时器的精度 四.软件定时器的运作机制 五.软件定时器函数接口讲解 1.软件定时器创建函数 xTimerCreate() 2.软件 ...

  7. FreeRTOS软件定时器 | FreeRTOS十三

    目录 说明: 一.定时器简介 1.1.定时器 1.2.软件定时器 1.3.硬件定时器 1.4.FreeRTOS软件定时器 1.5.软件定时器服务任务作用 1.6.软件定时器的命令队列 1.7.软件定时 ...

  8. STM32 FreeRTOS (三) 软件定时器

    简介: 基本概念 ReeRTOS中加入了软件定时器这个功能组件,是一个可选的.不属于freeRTOS内核的功能,由定时器服务(其实就是一个定时器任务)来提供. 软件定时器是当设定一个定时时间,当达到设 ...

  9. FreeRtos软件定时器复习

    一.基础概念 概念解析:定时器分为硬与软定,硬件定时器到达定时时间自动触发中断服务函数,使用软件定时器时,需要我们在创建软件定时器时指定时间到达后要调用的函数(也称超时函数/回调函数,为了统一,下文均 ...

最新文章

  1. 独家 | 一文读懂如何用深度学习实现网络安全
  2. Spring----自定义异常类
  3. 布朗语料库中不同部分的情态动词频率直方图绘制的代码详细解释
  4. 廖雪峰python教程在哪看_:廖雪峰python教程在哪
  5. IIS 部署asp.net Core程序注意事项
  6. SQLSTATE[HY000]: General error: 1030 Got error 28 from storage engine
  7. spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入...
  8. 利用可分离卷积UNet进行木薯叶病分类
  9. paip.提升用户体验-----用户注册设计
  10. Eclipse环境变量配置!
  11. 手写字体识别(1) 准备数据集
  12. java开发mdm平台_Apple iOS MDM开发流程
  13. 域渗透基础_域渗透实战下gpo策略利用
  14. 关于Flash的几点思考(Thoughts on Flash)
  15. Android实现snmp协议(一)
  16. CsvWriteramp;amp;CsvReader
  17. Elasticsearch实战---------相关名词介绍
  18. 工时表软件在项目中的作用 帮助企业管理项目成员的工时
  19. 架设KMS服务器流程启动加载方法
  20. sandisk TF卡 can not format issue 解决方法

热门文章

  1. javascript:用js实现tirm函数
  2. java for循环 写法_java中for循环的6种写法
  3. 柯基数据:先进的知识图谱技术,构建行业知识图谱,助企业打通内部信息孤岛,链接海量数据 |百万人学AI评选
  4. python水果超市管理系统_项目1-水果超市管理系统-学生
  5. 【EMC】EMC整改方法
  6. SpringMVC-Spring-Mybatis
  7. 你不知道的javascript读书笔记
  8. xp系统禁止开机启动服务器,win xp开机启动项怎么设置-win xp关闭开机启动项的方法 - 河东软件园...
  9. java 中free,FreeJava 的使用方法(三)FreeJava的使用,freejava使用方法
  10. 10000个怎么用js写 创建li_给博客园加一个会动的小人-spig.js