FreeRTOS学习笔记 & 软件定时器

软件定时器简介

定时器几乎每个 MCU 都有的外设,有的 MCU 其定时器功能异常强大,比如提供 PWM、输入捕获等功能。但最常用的还是定时器基础定时功能,通过定时器来完成需要周期性处理的事务。
MCU 自带的定时器属于硬件定时器,不同的 MCU 其硬件定时器数量不同,因为要考虑成本问题。
FreeRTOS 也提供了定时器功能,不过是软件定时器,软件定时器的精度肯定是没有硬件定时器那么高,但对于普通的精度要求不高的周期性处理的任务来说够了。
当 MCU 的硬件定时器不够的时候就可以考虑使用 FreeRTOS 的软件定时器

硬件定时器

硬件定时器是芯片本身提供的定时功能。一般是由外部晶振提供给芯片输入时钟,芯片向软件模块提供一组配置寄存器,接受控制输入,到达设定时间值后芯片中断控制器产生时钟中断。硬件定时器的精度一般很高,可以达到纳秒级别,并且是中断触发方式

软件定时器

软件定时器,软件定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受硬件定时器资源限制的定时器服务,它实现的功能与硬件定时器也是类似的

硬件定时器和软件定时器的工作机制

使用硬件定时器时,每次在定时时间到达之后就会自动触发一个中断,用户在中断中处理信息;
而使用软件定时器时,需要我们在创建软件定时器时指定时间到达后要调用的函数(也称超时函数/回调函数)在回调函数中处理信息。
软件定时器在被创建之后,当经过设定的时钟计数值后会触发用户定义的回调函数。定时精度与系统时钟的周期有关。一般系统利用 SysTick 作为软件定时器的基础时钟,软件定时器的回调函数类似硬件的中断服务函数,所以,回调函数也要快进快出,而且回调函数中不能有任何阻塞任务运行的情况,比如 vTaskDelay()以及其它能阻塞任务运行的函数,两次触发回调函数的时间间隔 xTimerPeriodInTicks 叫定时器的定时周期

FreeRTOS 软件定时器功能上支持:

●裁剪:能通过宏关闭软件定时器功能。
●软件定时器创建。
●软件定时器启动。
●软件定时器停止。
●软件定时器复位。
●软件定时器删除。

FreeRTOS 提供的软件定时器支持单次模式和周期模式,单次模式和周期模式的定时时间到之后都会调用软件定时器的回调函数,用户可以在回调函数中加入要执行的工程代码。

单次模式:当用户创建了定时器并启动了定时器后,定时时间到了,只执行一次回调函数之后就将该定时器进入休眠状态,不再重新执行。

周期模式:这个定时器会按照设置的定时时间循环执行回调函数,直到用户将定时器删除,如下所示:

在这里插入图片描述
FreeRTOS 通过一个 prvTimerTask 任务(也叫守护任务 Daemon)管理软定时器,它是在启动调度器时自动创建的,为了满足用户定时需求。prvTimerTask任务会在其执行期间检查用户启动的时间周期溢出的定时器,并调用其回调函数。只有设置 FreeRTOSConfig.h 中的宏定义 configUSE_TIMERS 设置为 1 ,将相关代码编译进来,才能正常使用软件定时器相关功能

软件定时器应用场景

在很多应用中,我们需要一些定时器任务,硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,无法提供更多的定时器,那么可以采用软件定时器来完成,由软件定时器代替硬件定时器任务。
但需要注意的是软件定时器的精度是无法和硬件定时器相比的,而且在软件定时器的定时过程中是极有可能被其它中断所打断,因为软件定时器的执行上下文环境是任务。所以,软件定时器更适用于对时间精度要求不高的任务,一些辅助型的任务

软件定时器的精度

在操作系统中,通常软件定时器以系统节拍周期为计时单位。系统节拍是系统的心跳节拍,表示系统时钟的频率,就类似人的心跳,1s 能跳动多少下,系统节拍配置为 configTICK_RATE_HZ,该宏在 FreeRTOSConfig.h 中有定义,默认是 1000。那么系统的时钟节拍周期就为 1ms(1s 跳动 1000 下,每一下就为1ms)。软件定时器的所定时数值必须是这个节拍周期的整数倍,例如节拍周期是 10ms,那么上层软件定时器定时数值只能是 10ms,20ms,100ms 等,而不能取值为 15ms。由于节拍定义了系统中定时器能够分辨的精确度,系统可以根据实际系统 CPU 的处理能力和实时性需求设置合适的数值,系统节拍周期的值越小,精度越高,但是系统开销也将越大,因为这代表在 1 秒中系统进入时钟中断的次数也就越多

软件定时器 API 函数

xTimerCreate 创建一个软件定时器

创建一个新的软件定时器, 并返回定时器的句柄
创建的定时器默认处于休眠状态,不会开始工作,需通过其他API激活定时器开始计时
xTimerStart()、
xTimerReset()、
xTimerStartFromISR()、
xTimerResetFromISR()、
xTimerChangePeriod() 以及 xTimerChangePeriodFromISR() API 函数都可以用于将定时器转换为活动状态

configUSE_TIMERS 和 configSUPPORT_DYNAMIC_ALLOCATION 必须在 FreeRTOSConfig.h 中同时设置为 1

#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_TIMERS 1

TimerHandle_t xTimerCreate ( const char * const pcTimerName,
		                   const TickType_t xTimerPeriod,
		                   const UBaseType_t uxAutoReload,
		                   void * const pvTimerID,
		                   TimerCallbackFunction_t pxCallbackFunction );

参数:
pcTimerName  	分配给定时器的可读文本名称
xTimerPeriod  	定时器的周期。 以 tick 为单位指定此周期,宏 pdMS_TO_TICKS() 可用于将以毫秒为单位指定的时间转换为以 tick 为单位指定的时间。 例如, 如果定时器必须要在 100 次 tick 后到期,那么只需将 xTimerPeriod 设置为 100。 或者,如果定时器 必须在 500 毫秒后到期,则需要将 xTimerPeriod 设置为 pdMS_TO_TICKS( 500 )。 使用 pdMS_TO_TICKS() 的唯一前提条件是 configTICK_RATE_HZ 小于或等于 1000。 定时器周期必须大于 0。
uxAutoReload  	如果 uxAutoReload 设置为 pdTRUE ,则定时器将按 xTimerPeriod 参数设置的频率重复到期。 如果 uxAutoReload 设置为 pdFALSE,则此定时器为一次性定时器, 它会在到期后进入休眠状态。
pvTimerID  	分配给正在创建的定时器的标识符。 通常,此标识符用于定时器回调函数: 当同一个回调函数分配给了多个定时器时,此标识符可以识别哪个定时器已到期。 或者此标识符可与 vTimerSetTimerID()pvTimerGetTimerID() API 函数一起使用, 以便保存调用 定时器回调函数之间的值。
pxCallbackFunction  	定时器到期时调用的函数。 回调函数必须有 TimerCallbackFunction_t 定义的原型,即:
void vCallbackFunction( TimerHandle_t xTimer );

Returns:
如果定时器创建成功, 则返回新创建的定时器的句柄。 如果由于剩余的 FreeRTOS 堆不足以分配定时器结构体而无法创建定时器, 则返回 NULL。

用法示例:

 #define NUM_TIMERS 5

 /* An array to hold handles to the created timers. */
 TimerHandle_t xTimers[ NUM_TIMERS ];

 /* 定义一个将被多个计时器实例使用的回调函数。
 	回调函数什么也不做,只是计算相关定时器超时的次数,并在定时器超时10次时停止定时器。计数保存为计时器的ID. */
 void vTimerCallback( TimerHandle_t xTimer )
 {
	 const uint32_t ulMaxExpiryCountBeforeStopping = 10;
	 uint32_t ulCount;

    /* 查询触发回调函数的定时器ID. */
    ulCount = ( uint32_t ) pvTimerGetTimerID( xTimer );

    /* ID自增. */
    ulCount++;

    /* 判断ID是否到达10. */
    if( ulCount >= ulMaxExpiryCountBeforeStopping )
    {
        /* ID 到达10 停止此定时器 */
        xTimerStop( xTimer, 0 );
    }
    else
    {
       /* 将递增的计数存储回定时器的ID字段. */
       vTimerSetTimerID( xTimer, ( void * ) ulCount );
    }
 }

 void main( void )
 {
 long x;

     /* Create then start some timers.  Starting the timers before
     the RTOS scheduler has been started means the timers will start
     running immediately that the RTOS scheduler starts. */
     for( x = 0; x < NUM_TIMERS; x++ )
     {
         xTimers[ x ] = xTimerCreate
                   ( /* Just a text name, not used by the RTOS
                     kernel. */
                     "Timer",
                     /* The timer period in ticks, must be
                     greater than 0. */
                     ( 100 * x ) + 100,
                     /* The timers will auto-reload themselves
                     when they expire. */
                     pdTRUE,
                     /* The ID is used to store a count of the
                     number of times the timer has expired, which
                     is initialised to 0. */
                     ( void * ) 0,
                     /* Each timer calls the same callback when
                     it expires. */
                     vTimerCallback
                   );

         if( xTimers[ x ] == NULL )
         {
             /* The timer was not created. */
         }
         else
         {
             /* Start the timer.  No block time is specified, and
             even if one was it would be ignored because the RTOS
             scheduler has not yet been started. */
             if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )
             {
                 /* The timer could not be set into the Active
                 state. */
             }
         }
     }

     /* ...
     Create tasks here.
     ... */

     /* Starting the RTOS scheduler will start the timers running
     as they have already been set into the active state. */
     vTaskStartScheduler();

     /* Should not reach here. */
     for( ;; );
 }

xTimerStart 开始一个软件定时器计时 (任务中使用)

如果定时器已经启动且已处于活动状态, 那么 xTimerStart() 具有与 xTimerReset() API 函数等效的功能

configUSE_TIMERS 配置常量必须设置为 1xTimerStart() 才可用

#define configUSE_TIMERS 1

BaseType_t xTimerStart( TimerHandle_t xTimer,TickType_t xBlockTime );

参数:
xTimer  		正在启动/重新启动的定时器的句柄。
xBlockTime  	在调用 xTimerStart() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待启动命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果在 启动 RTOS 调度器之前调用 xTimerStop(),则会忽略 xBlockTime。

Return:
如果即便经过了 xBlockTime(以 tick 为单位)后启动命令仍无法发送到定时器命令队列,则返回 pdFAIL。 如果该命令成功发送到定时器命令队列, 则返回 pdPASS。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间与实际调用 xTimerStart() 的时间有关。 定时器 服务/守护进程任务的优先级由 configTIMER_TASK_PRIORITY 配置常量设置

xTimerStartFromISR 开始一个软件定时器计时(中断中使用)

BaseType_t xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken);

参数:
xTimer  	正在启动/重新启动的定时器的句柄。
pxHigherPriorityTaskWoken  	定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerStartFromISR() 会将消息写入定时器 命令队列,从而让定时器服务/守护进程 任务有可能脱离阻塞状态。 如果调用 xTimerStartFromISR() 导致 定时器服务/守护进程任务脱离阻塞状态,且定时器服务/ 守护进程任务的优先级等于或大于当前执行的 任务(被中断的任务),那 *pxHigherPriorityTaskWoken 将在 xTimerStartFromISR() 函数内部被设置为 pdTRUE。 如果 xTimerStartFromISR() 将此值设置为 pdTRUE, 那应在中断退出前执行上下文切换。

返回:
如果启动命令无法发送至定时器命令队列, 则返回 pdFAIL。 如果命令成功发送至定时器命令队列, 则返回 pdPASS。 实际处理命令的时间 取决于定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间 是相对于实际调用 xTimerStartFromISR() 的时间而言。 定时器服务/守护进程 任务优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
用法示例:

/* The key press interrupt service routine. */
void vKeyPressEventInterruptHandler( void )
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    /* xTimerStartFromISR() or xTimerResetFromISR() could be called here
    as both cause the timer to re-calculate its expiry time.
    xHigherPriorityTaskWoken was initialised to pdFALSE when it was
    declared (in this function). */
    if( xTimerStartFromISR( xBacklightTimer,&xHigherPriorityTaskWoken ) != pdPASS )
    {
        /* The start command was not executed successfully.  Take appropriate
        action here. */
    }


    if( xHigherPriorityTaskWoken != pdFALSE )
    {
       portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }
}

xTimerStop 停止一个软件定时器计时(任务中使用)

configUSE_TIMERS 配置常量必须设置为 1xTimerStop() 才可用

#define configUSE_TIMERS 1

BaseType_t xTimerStop( TimerHandle_t xTimer,TickType_t xBlockTime );

参数:
xTimer  		正在停止的定时器的句柄。
xBlockTime  	在调用 xTimerStop() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待停止命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果在 启动 RTOS 调度器之前调用 xTimerStop(),则会忽略 xBlockTime。

Returns:
如果即使经过了 xBlockTime(以 tick 为单位)之后, 停止命令仍无法发送到定时器命令队列,则返回 pdFAIL。 如果该命令成功发送到定时器命令队列, 则返回 pdPASS。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的优先级。 定时器服务/守护进程任务的优先级由 服务/守护进程任务的优先级由 configTIMER_TASK_PRIORITY 配置常量设置

xTimerStopFromISR 停止一个软件定时器计时(中断中使用)

BaseType_t xTimerStopFromISR
             (
                 TimerHandle_t xTimer,
                 BaseType_t *pxHigherPriorityTaskWoken
             );
参数:
xTimer  	正在停止的定时器的句柄。
pxHigherPriorityTaskWoken  	定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerStopFromISR() 会将消息写入 定时器命令队列,因此有可能将定时器服务/ 守护进程任务转换为非阻塞状态。 如果调用 xTimerStopFromISR(), 会导致定时器服务/守护进程任务退出阻塞状态,并且 守护进程任务的优先级等于或大于当前执行的 当前正在执行的任务(中断的任务),则会在 xTimerStopFromISR() 函数内部 将 *pxHigherPriorityTaskWoken 设置为 pdTRUE。 如果 xTimerStopFromISR() 将此值设置为 pdTRUE,则应在中断退出之前 那应在中断退出前执行上下文切换。

返回:
如果即使经过了 xBlockTime(以 tick 为单位)之后, 则返回 pdFAIL。 如果命令成功发送至定时器命令队列, 则返回 pdPASS。 实际处理命令的时间 取决于定时器服务/守护进程任务相对于系统中其他任务的 优先级。 定时器服务/守护进程 任务优先级由 configTIMER_TASK_PRIORITY 配置常量设置

xTimerChangePeriod 改变一个软件定时器计时周期(任务中使用)

BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
                                TickType_t xNewPeriod,
                                TickType_t xBlockTime );

参数:
xTimer  	其周期将改变的定时器的句柄。
xNewPeriod  	xTimer 的新周期。定时器周期 在 tick 周期中指定,因此常量 portTICK_PERIOD_MS 可用于转换 已指定的时间(以毫秒为单位)。 例如,如果定时器必须 在100个 tick 后过期,则 xNewPeriod 应设置为100。 或者, 如果定时器必须在500 毫秒后过期,则 xNewPeriod 可以设置为 (500/portTICK_PERIOD_MS) ,前提是 configTICK_RATE_HZ 小于 或等于 1000。定时器周期必须大于 0。
xBlockTime  	在调用 xTimerDelete() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待变更周期命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果在 启动 RTOS 调度器之前调用 xTimerChangePeriod(),则会忽略 xBlockTime。

返回:
如果即使经过 xBlockTime(以 tick 为单位) 之后仍无法将更改周期命令发送到定时器命令队列,则将返回 pdFAIL。 如果能将此命令成功发送到定时器命令队列,则返回 pdPASS 则返回 pdPASS。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的 优先级。 定时器服务/守护进程任务的优先级 由 configTIMER_TASK_PRIORITY 配置常量设置

用法示例:

/* This function assumes xTimer has already been created.  If the timer
referenced by xTimer is already active when it is called, then the timer
is deleted.  If the timer referenced by xTimer is not active when it is
called, then the period of the timer is set to 500ms and the timer is
started. */
void vAFunction( TimerHandle_t xTimer )
{
    /* or more simply and equivalently
    "if( xTimerIsTimerActive( xTimer ) )" */
    if( xTimerIsTimerActive( xTimer ) != pdFALSE )
    {
        /* xTimer is already active - delete it. */
        xTimerDelete( xTimer );
    }
    else
    {
        /* xTimer is not active, change its period to 500ms.  This will also
        cause the timer to start.  Block for a maximum of 100 ticks if the
        change period command cannot immediately be sent to the timer
        command queue. */
        if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 )
                                                            == pdPASS )
        {
            /* The command was successfully sent. */
        }
        else
        {
            /* The command could not be sent, even after waiting for 100 ticks
            to pass.  Take appropriate action here. */
        }
    }
}

xTimerChangePeriodFromISR 改变一个软件定时器计时周期(中断中使用)

BaseType_t xTimerChangePeriodFromISR
           (
              TimerHandle_t xTimer,
              TickType_t xNewPeriod,
              BaseType_t *pxHigherPriorityTaskWoken
           );

参数:
xTimer  	正在更改其周期的软件定时器的句柄。
xNewPeriod  	xTimer 的新周期。
pxHigherPriorityTaskWoken  	定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 
调用 xTimerChangePeriodFromISR() 会将消息写入 定时器命令队列,因此有可能将定时器服务/ 守护进程任务转换为非阻塞状态。 
如果调用 xTimerChangePeriodFromISR() 导致定时器服务/守护进程任务退出阻塞状态,
并且 定时器服务/守护进程任务的优先级等于或大于 当前正在执行任务(被中断的任务) ,则 *pxHigherPriorityTaskWoken 将获得在 xTimerChangePeriodFromISR() 函数内部 设置为 pdTRUE 。 
如果 xTimerChangePeriodFromISR() 将此值设置为 pdTRUE ,则应在中断退出前执行上下文切换 。

Returns:
如果更改定时器周期的命令无法发送到定时器命令队列, 则返回 pdFAIL 。 如果命令已成功发送到定时器命令队列, 则返回 pdPASS 。 
实际处理命令的时间 将取决于定时服务/守护进程任务相对于系统中的其他任务的 优先级。 定时服务/守护进程任务 优先级由 configTIMER_TASK_PRIORITY 配置常量设置

xTimerDelete 删除一个软件定时器

必须将 configUSE_TIMERS 配置常量设置为 1xTimerDelete() 才可用

#define configUSE_TIMERS 1
BaseType_t xTimerDelete( TimerHandle_t xTimer,TickType_t xBlockTime );

参数:
xTimer  	正在删除的定时器的句柄。
xBlockTime  	在调用 xTimerDelete() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待删除命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果 在 RTOS 调度器启动之前调用 xTimerDelete(),则忽略 xBlockTime。

Returns:
如果即使经过 xBlockTime(以 tick 为单位) 之后仍无法将删除命令发送到定时器命令队列,则将返回 pdFAIL。 如果能将此命令成功发送到定时器命令队列,则返回 pdPASS 则返回 pdPASS。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的 优先级。 定时器服务/守护进程任务的优先级 由 configTIMER_TASK_PRIORITY 配置常量设置

xTimerReset 复位一个软件定时器(任务中使用)

configUSE_TIMERS 配置常量必须设置为 1xTimerReset() 才可用

#define configUSE_TIMERS 1
BaseType_t xTimerReset( TimerHandle_t xTimer,
                            TickType_t xBlockTime );

参数:
xTimer  	正在重置/启动/重新启动的定时器的句柄。
xBlockTime  	在调用 xTimerReset() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待重置命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果在 启动 RTOS 调度器之前调用 xTimerReset(),则忽略 xBlockTime。
Returns:
如果即使经过 xBlockTime(以 tick 为单位) 之后仍无法将重置命令发送到定时器命令队列,则返回 pdFAIL。 如果能将此命令成功发送到定时器命令队列,则返回 pdPASS 。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间与实际调用 xTimerReset() 的时间有关。 定时器 服务/守护进程任务的优先级由 configTIMER_TASK_PRIORITY 配置常量设置

用法示例:

/* When a key is pressed, an LCD back-light is switched on.  If 5 seconds pass
without a key being pressed, then the LCD back-light is switched off.  In
this case, the timer is a one-shot timer. */

TimerHandle_t xBacklightTimer = NULL;

/* The callback function assigned to the one-shot timer.  In this case the
parameter is not used. */
void vBacklightTimerCallback( TimerHandle_t pxTimer )
{
    /* The timer expired, therefore 5 seconds must have passed since a key
    was pressed.  Switch off the LCD back-light. */
    vSetBacklightState( BACKLIGHT_OFF );
}

/* The key press event handler. */
void vKeyPressEventHandler( char cKey )
{
    /* Ensure the LCD back-light is on, then reset the timer that is
    responsible for turning the back-light off after 5 seconds of
    key inactivity.  Wait 10 ticks for the command to be successfully sent
    if it cannot be sent immediately. */
    vSetBacklightState( BACKLIGHT_ON );
    if( xTimerReset( xBacklightTimer, 10 ) != pdPASS )
    {
        /* The reset command was not executed successfully.  Take appropriate
        action here. */
    }

    /* Perform the rest of the key processing here. */
}

void main( void )
{
long x;

    /* Create then start the one-shot timer that is responsible for turning
    the back-light off if no keys are pressed within a 5 second period. */
    xBacklightTimer = xTimerCreate
             (
                  /* Just a text name, not used by the RTOS kernel. */
                  "BacklightTimer",
                  /* The timer period in ticks. */
                  ( 5000 / portTICK_PERIOD_MS),
                  /* The timer is a one-shot timer. */
                  pdFALSE,
                  /* The id is not used by the callback so can take any
                  value. */
                  0,
                  /* The callback function that switches the LCD back-light
                  off. */
                  vBacklightTimerCallback
              );

    if( xBacklightTimer == NULL )
    {
        /* The timer was not created. */
    }
    else
    {
        /* Start the timer.  No block time is specified, and even if one was
        it would be ignored because the RTOS scheduler has not yet been
        started. */
        if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )
        {
            /* The timer could not be set into the Active state. */
        }
    }

    /* ...
     Create tasks here.
    ... */

    /* Starting the RTOS scheduler will start the timer running as it has
    already been set into the active state. */
    vTaskStartScheduler();

    /* Should not reach here. */
    for( ;; );
}

xTimerResetFromISR 复位一个软件定时器(中断中使用)

 BaseType_t xTimerResetFromISR
                (
                   TimerHandle_t xTimer,
                   BaseType_t *pxHigherPriorityTaskWoken
                );
参数:
xTimer  	待启动、重置或重启的定时器的句柄。
pxHigherPriorityTaskWoken  	定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerResetFromISR() 将消息写入定时器 命令队列,从而让定时器服务/守护进程 任务有可能脱离阻塞状态。 如果调用 xTimerResetFromISR() 导致 定时器服务/守护进程任务脱离阻塞状态,且定时器服务/ 守护进程任务的优先级等于或大于当前执行的 任务(被中断的任务),那 *pxHigherPriorityTaskWoken 将在 xTimerResetFromISR() 函数内部被设置为 pdTRUE。 如果 xTimerResetFromISR() 将此值设置为 pdTRUE, 那应在中断退出前执行上下文切换。
返回:
如果重置命令无法发送至定时器命令队列, 则将返回 pdFAIL。 如果命令成功发送至定时器命令队列, 则返回 pdPASS。 实际处理命令的时间 取决于定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间 和实际调用 xTimerResetFromISR() 的时间相关。 定时器服务/守护进程 任务优先级由 configTIMER_TASK_PRIORITY 配置常量设置

vTimerSetReloadMode 设置软件定时器自动重装载模式

void vTimerSetReloadMode( TimerHandle_t xTimer,
                           const UBaseType_t uxAutoReload );
参数:
xTimer  	要更新的定时器的句柄。 该句柄 将从对用于创建定时器的 xTimerCreate()xTimerCreateStatic() 调用中返回。
uxAutoReload  	将 uxAutoReload 设置为 pdTRUE 以将定时器设置为周期模式,或设置为 pdFALSE 以将定时器设置为单次模式。

vTimerSetTimerID 设置软件定时器ID

创建定时器时,会为软件定时器分配一个标识符 (ID), 您可随时使用 vTimerSetTimerID() API 函数更改此标识符。

如果将同一个回调函数分配给多个定时器, 则可以在回调函数内检查定时器标识符, 以确定哪个定时器实际已到期。

在定时器回调函数的调用之间,定时器标识符也可用于将数据存储在定时器中

void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );

参数:
xTimer  	更新的计时器。
pvNewID  	句柄,定时器标识符将被设置为此句柄。
用法示例:

/* A callback function assigned to a timer. */
void TimerCallbackFunction( TimerHandle_t pxExpiredTimer )
{
	uint32_t ulCallCount;

    /* A count of the number of times this timer has expired
    and executed its callback function is stored in the
    timer's ID.  Retrieve the count, increment it, then save
    it back into the timer's ID. */
    ulCallCount = ( uint32_t ) pvTimerGetTimerID( pxExpiredTimer );
    ulCallCount++;
    vTimerSetTimerID( pxExpiredTimer, ( void * ) ulCallCount );
}

查询软件定时器状态 API 函数

xTimerIsTimerActive 查询软件定时器是否处于活动或休眠状态

BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );

参数:
xTimer  	被查询的定时器。

Returns:
如果定时器处于休眠状态,将返回 pdFALSE。 如果定时器处于活动状态,将返回 pdFALSE 以外的值。

用法示例:
 /* This function assumes xTimer has already
 been created. */
 void vAFunction( TimerHandle_t xTimer )
 {
     /* or more simply and equivalently
     "if( xTimerIsTimerActive( xTimer ) )" */
     if( xTimerIsTimerActive( xTimer ) != pdFALSE )
     {
         /* xTimer is active, do something. */
     }
     else
     {
         /* xTimer is not active, do something else. */
     }
 }

pvTimerGetTimerID 查询软件定时器ID

void *pvTimerGetTimerID( TimerHandle_t xTimer );

参数:
xTimer  	被查询的定时器。
Returns:
分配给被查询的定时器的 ID。

xTimerGetTimerDaemonTaskHandle 查询软件定时器守护任务句柄

TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );

Returns:
返回与软件定时器守护进程(或服务)任务 关联的任务句柄。 如果在 FreeRTOSConfig.h 中将 configUSE_TIMERS 设置为 1, 则在启动 RTOS 调度器时会自动创建定时器守护进程任务

pcTimerGetName 查询软件定时器名

const char * pcTimerGetName( TimerHandle_t xTimer );

参数:
xTimer  	被查询的定时器。

返回:
指向定时器文本名称的指针,该指针为以 NULL 结尾的标准 C 字符串。

用法示例:
const char *pcTimerName = "ExampleTimer";

/* A function that creates a timer. */
static void prvCreateTimer( void )
{
TimerHandle_t xTimer;

    /* Create a timer. */
    xTimer = xTimerCreate( pcTimerName,           /* Text name. */
                           pdMS_TO_TICKS( 500 ),  /* Period. */
                           pdTRUE,                /* Autoreload. */
                           NULL,                  /* No ID. */
                           prvExampleCallback );  /* Callback function. */

    if( xTimer != NULL )
    {
        xTimerStart( xTimer, portMAX_DELAY );

        /* Just to demonstrate pcTimerGetName(), query the timer's name and
        assert if it does not equal pcTimerName. */
        configASSERT( strcmp( pcTimerGetName( xTimer ), pcTimerName ) == 0 );
    }
}

xTimerGetPeriod 查询软件定时器计时周期

TickType_t xTimerGetPeriod( TimerHandle_t xTimer );

参数:
xTimer  	被查询的定时器。
Returns:
计时器的周期,以滴答为单位。
用法示例:
/* A callback function assigned to a software timer. */
static void prvExampleTimerCallback( TimerHandle_t xTimer )
{
TickType_t xTimerPeriod;

    /* Query the period of the timer that expires. */
    xTimerPeriod = xTimerGetPeriod( xTimer );
}

xTimerGetExpiryTime 查询软件定时器到期时间

TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );

xTimerGetReloadMode 查询软件定时器工作模式

BaseType_t  xTimerGetReloadMode( TimerHandle_t xTimer );

参数:
xTimer	要查询的定时器的句柄。该句柄通过调用用于创建计时器的 xTimerCreate()xTimerCreateStatic() 返回。

Returns:
如果句柄为 xTimer 的定时器为自动重载定时器,则返回 pdTRUE,否则返回 pdFALSE。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值