1- xTimerCreate
timers.h
TimerHandle_t xTimerCreate
( const char * const pcTimerName,
const TickType_t xTimerPeriod,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction );
创建一个新的软件定时器实例, 并返回一个可以引用定时器的句柄。
要使此 RTOS API 函数可用:
configUSE_TIMERS 和 configSUPPORT_DYNAMIC_ALLOCATION 必须在 FreeRTOSConfig.h 中同时设置为 1(configSUPPORT_DYNAMIC_ALLOCATION 也可以不定义,此时其默认值为 1)。
FreeRTOS/Source/timers.c C 源文件必须包含在 构建中。
每个软件定时器都需要少量 RAM 来保存定时器的状态。 如果使用 xTimerCreate() 创建定时器, 则此 RAM 由 FreeRTOS 堆自动分配。 如果使用 xTimerCreateStatic() 创建软件定时器, 则 RAM 由应用程序编写器提供,这需要用到一个附加参数, 但允许在编译时静态分配 RAM 。 请参阅静态分配与 动态分配页面了解更多信息。
定时器是在休眠状态下创建的。 xTimerStart()、 xTimerReset()、 xTimerStartFromISR()、 xTimerResetFromISR()、 xTimerChangePeriod() 以及 xTimerChangePeriodFromISR() API 函数都可以用于将定时器转换为活动状态。
参数:
pcTimerName 分配给定时器的可读文本名称。 这样做纯粹是为了协助 调试。 RTOS 内核本身只通过句柄引用定时器, 而从不通过名字引用。
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 ];
/* Define a callback function that will be used by multiple timer
instances. The callback function does nothing but count the number
of times the associated timer expires, and stop the timer once the
timer has expired 10 times. The count is saved as the ID of the
timer. */
void vTimerCallback( TimerHandle_t xTimer )
{
const uint32_t ulMaxExpiryCountBeforeStopping = 10;
uint32_t ulCount;
/* Optionally do something if the pxTimer parameter is NULL. */
configASSERT( xTimer );
/* The number of times this timer has expired is saved as the
timer's ID. Obtain the count. */
ulCount = ( uint32_t ) pvTimerGetTimerID( xTimer );
/* Increment the count, then test to see if the timer has expired
ulMaxExpiryCountBeforeStopping yet. */
ulCount++;
/* If the timer has expired 10 times then stop it from running. */
if( ulCount >= ulMaxExpiryCountBeforeStopping )
{
/* Do not use a block time if calling a timer API function
from a timer callback function, as doing so could cause a
deadlock! */
xTimerStop( xTimer, 0 );
}
else
{
/* Store the incremented count back into the timer's ID field
so it can be read back again the next time this software timer
expires. */
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( ;; );
}
2 - xTimerCreateStatic
timers.h
TimerHandle_t xTimerCreateStatic
( const char * const pcTimerName,
const TickType_t xTimerPeriod,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction
StaticTimer_t *pxTimerBuffer );
创建一个新的软件定时器实例, 并返回一个可以引用定时器的句柄。
要使此 RTOS API 函数可用:
configUSE_TIMERS 和 configSUPPORT_STATIC_ALLOCATION 都必须在 FreeRTOSConfig.h 中设置为 1。
FreeRTOS/Source/timer.c C 源文件必须包含在构建中。
每个软件定时器都需要少量 RAM 来保存定时器的状态。 如果定时器是使用 xTimerCreate() 创建的, 则会从 FreeRTOS 堆中自动分配所需的 RAM。 如果软件定时器是使用 xTimerCreateStatic() 创建的, 则 RAM 由应用程序编写器提供,这需要用到一个附加参数, 但允许在编译时静态分配 RAM 。
定时器是在休眠状态下创建的。 xTimerStart()、 xTimerReset()、 xTimerStartFromISR()、 xTimerResetFromISR()、 xTimerChangePeriod() 以及 xTimerChangePeriodFromISR() API 函数都可以用于将定时器转换为活动状态。
参数:
pcTimerName 分配给定时器的可读文本名称。 这样做纯粹是为了协助 调试。 RTOS 内核本身只通过句柄引用定时器, 而从不通过名字引用。
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 );
pxTimerBuffer 必须指向 StaticTimer_t 类型的变量,然后 用该变量保存定时器的状态。
返回:
如果定时器创建成功, 则返回新创建的定时器的句柄。 如果 pxTimerBuffer 为 NULL,则不会创建定时器, 同时返回 NULL。
用法示例:
pxTimerBuffer #define NUM_TIMERS 5
/* An array to hold handles to the created timers. */
TimerHandle_t xTimers[ NUM_TIMERS ];
/* An array of StaticTimer_t structures, which are used to store
the state of each created timer. */
StaticTimer_t xTimerBuffers[ NUM_TIMERS ];
/* Define a callback function that will be used by multiple timer
instances. The callback function does nothing but count the number
of times the associated timer expires, and stop the timer once the
timer has expired 10 times. The count is saved as the ID of the
timer. */
void vTimerCallback( TimerHandle_t xTimer )
{
const uint32_t ulMaxExpiryCountBeforeStopping = 10;
uint32_t ulCount;
/* Optionally do something if the pxTimer parameter is NULL. */
configASSERT( pxTimer );
/* The number of times this timer has expired is saved as the
timer's ID. Obtain the count. */
ulCount = ( uint32_t ) pvTimerGetTimerID( xTimer );
/* Increment the count, then test to see if the timer has expired
ulMaxExpiryCountBeforeStopping yet. */
ulCount++;
/* If the timer has expired 10 times then stop it from running. */
if( ulCount >= ulMaxExpiryCountBeforeStopping )
{
/* Do not use a block time if calling a timer API function
from a timer callback function, as doing so could cause a
deadlock! */
xTimerStop( xTimer, 0 );
}
else
{
/* Store the incremented count back into the timer's ID field
so it can be read back again the next time this software timer
expires. */
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 ] = xTimerCreateStatic
( /* 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,
/* Pass in the address of a StaticTimer_t
variable, which will hold the data associated with
the timer being created. */
&( xTimerBuffers[ x ] );
);
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( ;; );
}
3-xTimerIsTimerActive
timers.h
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
查询软件定时器是否处于活动或休眠状态。
如果出现以下情况,定时器将处于休眠状态:
已创建但尚未启动,或
这是一个尚未重启的过期的一次性计时器。
定时器是在休眠状态下创建的。 xTimerStart()、 xTimerReset()、 xTimerStartFromISR()、 xTimerResetFromISR()、 xTimerChangePeriod() 以及 xTimerChangePeriodFromISR() API 函数都可以用于将定时器转换为活动状态。
参数:
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. */
}
}
4- xTimerStart
timers.h
BaseType_t xTimerStart( TimerHandle_t xTimer,
TickType_t xBlockTime );
软件定时器功能由定时器服务/守护进程任务提供。 许多 公共 FreeRTOS 定时器 API 函数通过定时器命令队列 向定时器服务任务发送命令。 定时器命令队列是 RTOS 内核本身的私有队列, 应用程序代码无法直接访问该队列。 定时器命令队列的长度 由 configTIMER_QUEUE_LENGTH 配置常量设置。
xTimerStart() 启动先前使用 xTimerCreate() API 函数创建的定时器。 如果定时器已经启动且已处于活动状态, 那么 xTimerStart() 具有与 xTimerReset() API 函数等效的功能。
启动定时器可确保定时器处于活动状态。 如果定时器 在此期间没有被停用、删除或重置, 那么在调用 xTimerStart() 并经过了 “n” 个 tick 之后,将调用与定时器相关联的回调函数, 其中 “n” 表示规定的定时器周期。
在 RTOS 调度器启动之前调用 xTimerStart() 是有效的, 但是完成此操作后,直到启动 RTOS 调度器之前,定时器都不会真正启动, 并且定时器的到期时间与 RTOS 调度器的启动时间有关, 与调用 xTimerStart() 的时间无关。
configUSE_TIMERS 配置常量必须设置为 1,xTimerStart() 才可用。
参数:
xTimer 正在启动/重新启动的定时器的句柄。
xBlockTime 在调用 xTimerStart() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待启动命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果在 启动 RTOS 调度器之前调用 xTimerStop(),则会忽略 xBlockTime。
返回:
如果即便经过了 xBlockTime(以 tick 为单位)后启动命令仍无法发送到定时器命令队列,则返回 pdFAIL。 如果该命令成功发送到定时器命令队列, 则返回 pdPASS。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间与实际调用 xTimerStart() 的时间有关。 定时器 服务/守护进程任务的优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
5 - xTimerStop
timers.h
BaseType_t xTimerStop( TimerHandle_t xTimer,
TickType_t xBlockTime );
软件定时器功能由定时器服务/守护进程任务提供。 许多 公共 FreeRTOS 定时器 API 函数通过定时器命令队列 向定时器服务任务发送命令。 定时器命令队列是 RTOS 内核本身的私有队列, 应用程序代码无法直接访问该队列。 定时器命令队列的长度 由 configTIMER_QUEUE_LENGTH 配置常量设置。
xTimerStop() 停止先前使用 xTimerStart()、 xTimerReset()、 xTimerStartFromISR()、 xTimerResetFromISR()、 xTimerChangePeriod() 以及 xTimerChangePeriodFromISR() API 函数之一启动的定时器。
停用定时器可确保定时器不处于活动状态。
configUSE_TIMERS 配置常量必须设置为 1,xTimerStop() 才可用。
参数:
xTimer 正在停止的定时器的句柄。
xBlockTime 在调用 xTimerStop() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待停止命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果在 启动 RTOS 调度器之前调用 xTimerStop(),则会忽略 xBlockTime。
Returns:
如果即使经过了 xBlockTime(以 tick 为单位)之后, 停止命令仍无法发送到定时器命令队列,则返回 pdFAIL。 如果该命令成功发送到定时器命令队列, 则返回 pdPASS。 实际处理命令的时间取决于 定时器服务/守护进程任务相对于系统中其他任务的优先级。 定时器服务/守护进程任务的优先级由 服务/守护进程任务的优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
用法示例:
#define NUM_TIMERS 5
/* An array to hold handles to the created timers. */
TimerHandle_t xTimers[ NUM_TIMERS ];
/* Define a callback function that will be used by multiple timer
instances. The callback function does nothing but count the number
of times the associated timer expires, and stop the timer once the
timer has expired 10 times. The count is saved as the ID of the
timer. */
void vTimerCallback( TimerHandle_t xTimer )
{
const uint32_t ulMaxExpiryCountBeforeStopping = 10;
uint32_t ulCount;
/* Optionally do something if the pxTimer parameter is NULL. */
configASSERT( xTimer );
/* The number of times this timer has expired is saved as the
timer's ID. Obtain the count. */
ulCount = ( uint32_t ) pvTimerGetTimerID( xTimer );
/* Increment the count, then test to see if the timer has expired
ulMaxExpiryCountBeforeStopping yet. */
ulCount++;
/* If the timer has expired 10 times then stop it from running. */
if( ulCount >= ulMaxExpiryCountBeforeStopping )
{
/* Do not use a block time if calling a timer API function
from a timer callback function, as doing so could cause a
deadlock! */
xTimerStop( xTimer, 0 );
}
else
{
/* Store the incremented count back into the timer's ID field
so it can be read back again the next time this software timer
expires. */
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( ;; );
}
6-xTimerChangePeriod
timers.h
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
TickType_t xNewPeriod,
TickType_t xBlockTime );
软件定时器功能由定时器服务/守护进程任务提供。 许多 公共 FreeRTOS 定时器 API 函数通过定时器命令队列 向定时器服务任务发送命令。 定时器命令队列是 RTOS 内核本身的私有队列, 应用程序代码无法直接访问该队列。 定时器命令队列的长度 由 configTIMER_QUEUE_LENGTH 配置常量设置。
xTimerChangePeriod() 可以改变先前使用 xTimerCreate() API 函数创建的定时器的周期。
可以调用 xTimerChangePeriod() 来更改活动 或休眠状态的定时器的周期。 更改休眠定时器的周期也会启动 定时器。
必须将 configUSE_TIMERS 配置常量设置为 1, xTimerChangePeriod() 才可用。
参数:
xTimer 正在更改其周期的定时器的句柄。
xNewPeriod xTimer 的新周期。定时器周期 在 tick 周期中指定,因此常量 portTICK_PERIOD_MS 可用于转换 已指定的时间(以毫秒为单位)。 例如,如果定时器必须 在100个 tick 后过期,则 xNewPeriod 应设置为100。 或者, 如果定时器必须在500 毫秒后过期,则 xNewPeriod 可以设置为 (500/portTICK_PERIOD_MS) ,前提是 configTICK_RATE_HZ 小于 或等于 1000。
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. */
}
}
}
7 - xTimerDelete
timers.h
BaseType_t xTimerDelete( TimerHandle_t xTimer,
TickType_t xBlockTime );
软件定时器功能由定时器服务/守护进程任务提供。 许多 公共 FreeRTOS 定时器 API 函数通过定时器命令队列 向定时器服务任务发送命令。 定时器命令队列是 RTOS 内核本身的私有队列, 应用程序代码无法直接访问该队列。 定时器命令队列的长度 由 configTIMER_QUEUE_LENGTH 配置常量设置。
xTimerDelete() 可删除以前使用 xTimerCreate() API 函数创建的定时器。请注意,删除静态分配的定时器时,在 xTimerIsTimerActive() 指示该定时器处于非活动状态之前,无法重复使用其静态内存。
必须将 configUSE_TIMERS 配置常量设置为 1, xTimerDelete() 才可用。
参数:
xTimer 正在删除的定时器的句柄。
xBlockTime 在调用 xTimerDelete() 时队列已满的情况下, 指定调用任务应保持阻塞状态 以等待删除命令成功发送到定时器命令队列的时间 (以 tick 为单位)。 如果 在 RTOS 调度器启动之前调用 xTimerDelete(),则忽略 xBlockTime。
Returns:
如果即使经过 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. */
}
}
}
8- xTimerReset
timers.h
BaseType_t xTimerReset( TimerHandle_t xTimer,
TickType_t xBlockTime );
软件定时器功能由定时器服务/守护进程任务提供。 许多 公共 FreeRTOS 定时器 API 函数通过定时器命令队列 向定时器服务任务发送命令。 定时器命令队列是 RTOS 内核本身的私有队列, 应用程序代码无法直接访问该队列。 定时器命令队列的长度 由 configTIMER_QUEUE_LENGTH 配置常量设置。
xTimerReset() 重新启动先前使用 xTimerCreate() API 函数创建的定时器。 如果定时器已经启动且已处于活动状态, 那么 xTimerReset() 会使定时器 重新评估其到期时间,因此到期时间与 xTimerReset() 的调用时间有关。 如果定时器处于休眠状态,则 xTimerReset() 具有与 xTimerStart() API 函数等效的功能。
重置定时器可确保定时器处于活动状态。 如果定时器 在此期间没有被停用、删除或重置, 那么在调用 xTimerReset() 并经过了 “n” 个 tick 之后,将调用与定时器相关联的回调函数, 其中“n”表示规定的定时器周期。
在 RTOS 调度器启动之前调用 xTimerReset() 是有效的, 但是完成此操作后,直到启动 RTOS 调度器之前,定时器都不会真正启动, 并且定时器的到期时间与 RTOS 调度器的启动时间有关, 与调用 xTimerReset() 的时间无关。
configUSE_TIMERS 配置常量必须设置为 1,xTimerReset() 才可用。
参数:
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( ;; );
}
9- xTimerStartFromISR
timers.h
BaseType_t xTimerStartFromISR
(
TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken
);
可从中断服务例程调用的 xTimerStart() 的版本。
参数:
xTimer 正在启动/重新启动的定时器的句柄。
pxHigherPriorityTaskWoken 定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerStartFromISR() 会将消息写入定时器 命令队列,从而让定时器服务/守护进程 任务有可能脱离阻塞状态。 如果调用 xTimerStartFromISR() 导致 定时器服务/守护进程任务脱离阻塞状态,且定时器服务/ 守护进程任务的优先级等于或大于当前执行的 任务(被中断的任务),那 *pxHigherPriorityTaskWoken 将在 xTimerStartFromISR() 函数内部被设置为 pdTRUE。 如果 xTimerStartFromISR() 将此值设置为 pdTRUE, 那应在中断退出前执行上下文切换。
返回:
如果启动命令无法发送至定时器命令队列, 则返回 pdFAIL。 如果命令成功发送至定时器命令队列, 则返回 pdPASS。 实际处理命令的时间 取决于定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间 是相对于实际调用 xTimerStartFromISR() 的时间而言。 定时器服务/守护进程 任务优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
用法示例:
/* This scenario assumes xBacklightTimer has already been created. 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, and unlike the example given for
the xTimerReset() function, the key press event handler is an interrupt
service routine. */
/* 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 interrupt service routine. */
void vKeyPressEventInterruptHandler( void )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Ensure the LCD back-light is on, then restart the timer that is
responsible for turning the back-light off after 5 seconds of
key inactivity. This is an interrupt service routine so can only
call FreeRTOS API functions that end in "FromISR". */
vSetBacklightState( BACKLIGHT_ON );
/* 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. */
}
/* Perform the rest of the key processing here. */
/* If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
should be performed. The syntax required to perform a context switch
from inside an ISR varies from port to port, and from compiler to
compiler. Inspect the demos for the port you are using to find the
actual syntax required. */
if( xHigherPriorityTaskWoken != pdFALSE )
{
/* Call the interrupt safe yield function here (actual function
depends on the FreeRTOS port being used). */
}
}
10- xTimerStopFromISR
timers.h
BaseType_t xTimerStopFromISR
(
TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken
);
可从中断服务例程调用的 xTimerStop() 的版本。
参数:
xTimer 正在停止的定时器的句柄。
pxHigherPriorityTaskWoken 定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerStopFromISR() 会将消息写入 定时器命令队列,因此有可能将定时器服务/ 守护进程任务转换为非阻塞状态。 如果调用 xTimerStopFromISR(), 会导致定时器服务/守护进程任务退出阻塞状态,并且 守护进程任务的优先级等于或大于当前执行的 当前正在执行的任务(中断的任务),则会在 xTimerStopFromISR() 函数内部 将 *pxHigherPriorityTaskWoken 设置为 pdTRUE。 如果 xTimerStopFromISR() 将此值设置为 pdTRUE,则应在中断退出之前 那应在中断退出前执行上下文切换。
返回:
如果即使经过了 xBlockTime(以 tick 为单位)之后, 则返回 pdFAIL。 如果命令成功发送至定时器命令队列, 则返回 pdPASS。 实际处理命令的时间 取决于定时器服务/守护进程任务相对于系统中其他任务的 优先级。 定时器服务/守护进程 任务优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
用法示例:
/* This scenario assumes xTimer has already been created and started. When
an interrupt occurs, the timer should be simply stopped. */
/* The interrupt service routine that stops the timer. */
void vAnExampleInterruptServiceRoutine( void )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* The interrupt has occurred - simply stop the timer.
xHigherPriorityTaskWoken was set to pdFALSE where it was defined
(within this function). As this is an interrupt service routine, only
FreeRTOS API functions that end in "FromISR" can be used. */
if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
{
/* The stop command was not executed successfully. Take appropriate
action here. */
}
/* If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
should be performed. The syntax required to perform a context switch
from inside an ISR varies from port to port, and from compiler to
compiler. Inspect the demos for the port you are using to find the
actual syntax required. */
if( xHigherPriorityTaskWoken != pdFALSE )
{
/* Call the interrupt safe yield function here (actual function
depends on the FreeRTOS port being used). */
}
}
11- xTimerChangePeriodFromISR
timers.h
BaseType_t xTimerChangePeriodFromISR
(
TimerHandle_t xTimer,
TickType_t xNewPeriod,
BaseType_t *pxHigherPriorityTaskWoken
);
可从中断服务例程调用的 xTimerChangePeriod() 的版本。
参数:
xTimer 正在更改其周期的软件定时器的句柄。
xNewPeriod xTimer 的新周期。定时器周期 在 tick 周期中指定,因此常量 portTICK_PERIOD_MS 可用于转换 已指定的时间(以毫秒为单位)。 例如,如果定时器必须 在100个 tick 后过期,则 xNewPeriod 应设置为100。 或者, 如果定时器必须在500 毫秒后过期,则 xNewPeriod 可以设置为 (500/portTICK_PERIOD_MS) ,前提是 configTICK_RATE_HZ 小于 或等于1000。
pxHigherPriorityTaskWoken 定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerChangePeriodFromISR() 会将消息写入 定时器命令队列,因此有可能将定时器服务/ 守护进程任务转换为非阻塞状态。 如果调用 xTimerChangePeriodFromISR() 导致定时器服务/守护进程任务退出阻塞状态,并且 定时器服务/守护进程任务的优先级等于或大于 当前正在执行任务(被中断的任务) ,则 *pxHigherPriorityTaskWoken 将获得在 xTimerChangePeriodFromISR() 函数内部 设置为 pdTRUE 。 如果 xTimerChangePeriodFromISR() 将此值设置为 pdTRUE ,则应在中断退出前执行上下文切换 。
Returns:
如果更改定时器周期的命令无法发送到定时器命令队列, 则返回 pdFAIL 。 如果命令已成功发送到定时器命令队列, 则返回 pdPASS 。 实际处理命令的时间 将取决于定时服务/守护进程任务相对于系统中的其他任务的 优先级。 定时服务/守护进程任务 优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
用法示例:
/* This scenario assumes xTimer has already been created and started. When
an interrupt occurs, the period of xTimer should be changed to 500ms. */
/* The interrupt service routine that changes the period of xTimer. */
void vAnExampleInterruptServiceRoutine( void )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* The interrupt has occurred - change the period of xTimer to 500ms.
xHigherPriorityTaskWoken was set to pdFALSE where it was defined
(within this function). As this is an interrupt service routine, only
FreeRTOS API functions that end in "FromISR" can be used. */
if( xTimerChangePeriodFromISR( xTimer,
pdMS_TO_TICKS( 500 ),
&xHigherPriorityTaskWoken ) != pdPASS )
{
/* The command to change the timers period was not executed
successfully. Take appropriate action here. */
}
/* If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
should be performed. The syntax required to perform a context switch
from inside an ISR varies from port to port, and from compiler to
compiler. Inspect the demos for the port you are using to find the
actual syntax required. */
if( xHigherPriorityTaskWoken != pdFALSE )
{
/* Call the interrupt safe yield function here (actual function
depends on the FreeRTOS port being used). */
}
}
12-xTimerResetFromISR
timers.h
BaseType_t xTimerResetFromISR
(
TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken
);
可从中断服务例程调用的 xTimerReset() 的版本。
参数:
xTimer 待启动、重置或重启的定时器的句柄。
pxHigherPriorityTaskWoken 定时器服务/守护进程任务大部分时间 都处于阻塞状态,等待消息到达定时器 命令队列。 调用 xTimerResetFromISR() 将消息写入定时器 命令队列,从而让定时器服务/守护进程 任务有可能脱离阻塞状态。 如果调用 xTimerResetFromISR() 导致 定时器服务/守护进程任务脱离阻塞状态,且定时器服务/ 守护进程任务的优先级等于或大于当前执行的 任务(被中断的任务),那 *pxHigherPriorityTaskWoken 将在 xTimerResetFromISR() 函数内部被设置为 pdTRUE。 如果 xTimerResetFromISR() 将此值设置为 pdTRUE, 那应在中断退出前执行上下文切换。
返回:
如果重置命令无法发送至定时器命令队列, 则将返回 pdFAIL。 如果命令成功发送至定时器命令队列, 则返回 pdPASS。 实际处理命令的时间 取决于定时器服务/守护进程任务相对于系统中其他任务的优先级, 尽管定时器到期时间 和实际调用 xTimerResetFromISR() 的时间相关。 定时器服务/守护进程 任务优先级由 configTIMER_TASK_PRIORITY 配置常量设置。
用法示例:
/* This scenario assumes xBacklightTimer has already been created. 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, and unlike the example given for
the xTimerReset() function, the key press event handler is an interrupt
service routine. */
/* 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 interrupt service routine. */
void vKeyPressEventInterruptHandler( void )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* 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. This is an interrupt service routine so can only
call FreeRTOS API functions that end in "FromISR". */
vSetBacklightState( BACKLIGHT_ON );
/* 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( xTimerResetFromISR( xBacklightTimer,
&xHigherPriorityTaskWoken ) != pdPASS )
{
/* The reset command was not executed successfully. Take appropriate
action here. */
}
/* Perform the rest of the key processing here. */
/* If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
should be performed. The syntax required to perform a context switch
from inside an ISR varies from port to port, and from compiler to
compiler. Inspect the demos for the port you are using to find the
actual syntax required. */
if( xHigherPriorityTaskWoken != pdFALSE )
{
/* Call the interrupt safe yield function here (actual function
depends on the FreeRTOS port being used). */
}
}
13-pvTimerGetTimerID
timers.h
void *pvTimerGetTimerID( TimerHandle_t xTimer );
返回分配给软件计时器的 ID。
使用调用 xTimerCreate() 时的 pvTimerID 参数将 ID 分配给定时器, 该函数用于创建定时器。
创建定时器时,会为定时器分配一个标识符 (ID), 您随时可以使用 vTimerSetTimerID() API 函数更改此 ID。
如果将同一个回调函数分配给多个定时器, 则可以在回调函数内检查定时器标识符, 以确定哪个定时器实际已到期。
在定时器回调函数的调用之间,定时器标识符也可用于将数据存储在定时器中 。
参数:
xTimer 被查询的定时器。
Returns:
分配给被查询的定时器的 ID。
14- vTimerSetReloadMode
timers.h
void vTimerSetReloadMode( TimerHandle_t xTimer,
const UBaseType_t uxAutoReload );
将软件定时器的“模式”更新为自动重新加载定时器或一次性 定时器。
自动重新加载定时器每次过期都会自行重置,从而导致定时器 定期到期(并因此执行其回调)。
一次性定时器不会自动重置,因此除非手动重新启动, 否则只会过期一次(并因此执行其回调)。
此 API 函数仅在已构建项目中包含 FreeRTOS/Source/timers.c 源文件时 可用。
参数:
xTimer 要更新的定时器的句柄。 该句柄 将从对用于创建定时器的 xTimerCreate() 或 xTimerCreateStatic() 调用中返回。
uxAutoReload 将 uxAutoReload 设置为 pdTRUE 以将定时器设置为自动重新加载 模式,或设置为 pdFALSE 以将定时器设置为一次性模式。
15- vTimerSetTimerID
timers.h
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
创建定时器时,会为软件定时器分配一个标识符 (ID), 您可随时使用 vTimerSetTimerID() API 函数更改此标识符。
如果将同一个回调函数分配给多个定时器, 则可以在回调函数内检查定时器标识符, 以确定哪个定时器实际已到期。
在定时器回调函数的调用之间,定时器标识符也可用于将数据存储在定时器中 。
参数:
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 );
}
16- xTimerGetTimerDaemonTaskHandle
timers.h
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
Returns:
返回与软件定时器守护进程(或服务)任务 关联的任务句柄。 如果在 FreeRTOSConfig.h 中将 configUSE_TIMERS 设置为 1, 则在启动 RTOS 调度器时会自动创建定时器守护进程任务。
17 -xTimerPendFunctionCall()
timers.h
BaseType_t xTimerPendFunctionCall(
PendedFunction_t xFunctionToPend,
void *pvParameter1,
uint32_t ulParameter2,
TickType_t xTicksToWait );
用于将函数的执行挂起到 RTOS 守护进程任务(定时器 服务任务,因此此函数前缀为“Timer”)。
可延迟到 RTOS 守护进程任务的函数必须具有以下 原型:
void vPendableFunction( void * pvParameter1, uint32_t ulParameter2 );
pvParameter1 和 ulParameter2 供 应用程序代码使用。
INCLUDE_xTimerPendFunctionCall() 和 configUSE_TIMERS 必须同时设置为 1,xTimerPendFunctionCall() 才可用。
参数:
xFunctionToPend 要从定时器服务/ 守护进程任务执行的函数。 函数必须符合上面所示的 PendedFunction_t 如上所示 的 PendedFunction_t 原型。
pvParameter1 回调函数的第一个参数的值。 该参数为 void * 类型,可用于传递任何类型。 例如,整数类型可转换为 void *, 或者可使用 void * 指向结构体。
ulParameter2 回调函数的第二个参数的值。
xTicksToWait 调用此函数将导致 向队列中的定时器守护进程任务发送一条消息。 xTicksToWait 是指在队列已满的情况下,需要阻塞调用任务 (不使用任何处理时间)以等待定时器队列 释放可用空间的时间。 队列的长度由 FreeRTOSConfig.h 中的 configTIMER_QUEUE_LENGTH 值设置。
Returns:
如果消息成功发送到 RTOS 则返回 pdPASS,否则返回 pdFALSE。
18- xTimerPendFunctionCallFromISR()
timers.h
BaseType_t xTimerPendFunctionCallFromISR(
PendedFunction_t xFunctionToPend,
void *pvParameter1,
uint32_t ulParameter2,
BaseType_t *pxHigherPriorityTaskWoken );
在应用程序中断服务程序中使用此函数, 用于将函数的执行推迟到 RTOS 守护进程任务(即定时器服务任务,因此该函数 在 timers.c 中实现,并以“Timer”为前缀)。
理想情况下,中断服务程序 (ISR) 需尽可能短, 但有时 ISR 要么需要处理很多任务, 要么需要执行非确定性任务。 在这些情况下,可使用 xTimerPendFunctionCallFromISR() 将 函数的处理推迟到 RTOS 守护进程任务。
这里提供了一种允许中断直接返回到 随后将执行挂起函数任务的机制。 使用该机制, 回调函数可在中断时间内连续执行, 就像回调在中断本身中执行一样。
可延迟到 RTOS 守护进程任务的函数必须具有以下 原型:
void vPendableFunction( void * pvParameter1, uint32_t ulParameter2 );
pvParameter1 和 ulParameter2 供 应用程序代码使用。
INCLUDE_xTimerPendFunctionCall() 和 configUSE_TIMERS 必须同时 设置为 1,xTimerPendFunctionCallFromISR() 才可用。
参数:
xFunctionToPend 要从定时器服务/ 守护进程任务执行的函数。 函数必须符合上面所示的 PendedFunction_t 如上所示的 PendedFunction_t 原型。
pvParameter1 回调函数的第一个参数的值。 该参数为 void * 类型,可用于传递任何类型。 例如,整数类型可转换为 void *, 或者可使用 void * 指向结构体。
ulParameter2 回调函数的第二个参数的值。
pxHigherPriorityTaskWoken 如上所述,调用 xTimerPendFunctionCallFromSR() 将意味着向 RTOS 定时器守护进程任务发送一条消息。 如果 守护进程任务的优先级(该任务 使用 configTIMER_TASK_PRIORITY 设置, 位于 FreeRTOSConfig.h 中)高于 当前正在运行的任务(中断中断的任务), **则需在 xTimerPendFunctionCallFromISR() 中 将 *pxHigherPriorityTaskWoken 设置为 pdTRUE, 表示应在中断退出之前请求上下文切换。 因此 必须将 *pxHigherPriorityTaskWoken 初始化为 pdFALSE。 请参阅 下面的代码示例。
Returns:
如果消息成功发送到 RTOS 定时器守护进程任务, 则返回 pdPASS,否则返回 pdFALSE。
用法示例:
/*** The callback function that will execute in the context of the daemon task.
Note callback functions must all use this same prototype. */
void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 )
{
BaseType_t xInterfaceToService;
/* The interface that requires servicing is passed in the second
parameter. The first parameter is not used in this case. */
xInterfaceToService = ( BaseType_t ) ulParameter2;
/* ...Perform the processing here... */
}
/* An ISR that receives data packets from multiple interfaces */
void vAnISR( void )
{
BaseType_t xInterfaceToService, xHigherPriorityTaskWoken;
/* Query the hardware to determine which interface needs processing. */
xInterfaceToService = prvCheckInterfaces();
/* The actual processing is to be deferred to a task. Request the
vProcessInterface() callback function is executed, passing in the
number of the interface that needs processing. The interface to
service is passed in the second parameter. The first parameter is
not used in this case. */
xHigherPriorityTaskWoken = pdFALSE;
xTimerPendFunctionCallFromISR( vProcessInterface,
NULL,
( uint32_t ) xInterfaceToService,
&xHigherPriorityTaskWoken );
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
switch should be requested. The macro used is port specific and will
be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
the documentation page for the port being used. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
19- pcTimerGetName
timers.h
const char * pcTimerGetName( TimerHandle_t xTimer );
返回软件定时器的人类可读文本名称。
将文本名称分配给定时器需使用 调用 xTimerCreate() 函数的 pcTimerName 参数, 该函数用于创建定时器。
参数:
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 );
}
}
20 -xTimerGetPeriod
timers.h
TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
返回一个软件计时器的周期。 周期以滴答为单位。
初始时,一个定时器的周期由 用于创建定时器的 xTimerCreate() 函数的 xTimerPeriod 参数设置。 可以使用 xTimerChangePeriod() 和 xTimerChangePeriodFromISR() API 函数改变此周期。
参数:
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
timers.h
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
返回软件定时器到期的时间, 即执行定时器回调函数的时间。
如果 xTimerGetExpiryTime() 返回的值小于当前时间, 则定时器会在 tick 计数溢出并归 0 后到期。 计数溢出在 RTOS 实现中进行处理, 因此定时器的回调函数会在正确时间执行, 无论是在 tick 计数溢出之前还是之后。
参数:
xTimer 被查询的定时器。
Returns:
如果 xTimer 引用的定时器处于活动状态, 则返回定时器下一次到期的时间 (可能是在当前 tick 计数溢出之后, 请参阅上方注释)。
如果 xTimer 引用的定时器未处于活动状态, 则未定义返回值。
用法示例:
static void prvAFunction( TimerHandle_t xTimer )
{
TickType_t xRemainingTime;
/* Calculate the time that remains before the timer referenced by xTimer
expires. TickType_t is an unsigned type, so the subtraction will result in
the correct answer even if the timer will not expire until after the tick
count has overflowed. */
xRemainingTime = xTimerGetExpiryTime( xTimer ) - xTaskGetTickCount();
}
21- xTimerGetReloadMode/uxTimerGetReloadMode
task.h
BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer );
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
查询 xTimer 句柄引用的软件计时器的“模式”。
该模式可以是自动重载定时器(每次到期都会自动重置),或者 一次性计时器(除非手动重新启动,否则仅到期一次)。
xTimerGetReloadMode 和 uxTimerGetReloadMode 仅在其返回类型上有所不同。xTimerGetReloadMode 返回 BaseType_t 以匹配实际返回值 pdTRUE/pdFALSE 的类型。 uxTimerGetReloadMode 是为了向后兼容而提供的, 新的应用程序应该使用 xTimerGetReloadMode 来代替。
这些 API 函数仅在已构建项目中包含 FreeRTOS ‘timers.c’ 源文件, 并且在 FreeRTOSConfig.h 中将 configUSE_TIMERS 设置为 1 时才可用。
参数:
xTimer 要查询的定时器的句柄。该句柄通过调用用于创建计时器的 xTimerCreate() 或 xTimerCreateStatic() 返回。
Returns:
如果句柄为 xTimer 的定时器为自动重载定时器,则返回 pdTRUE,否则返回 pdFALSE。