软件定时器
FreeRTOSConfig.h 中涉及到的宏定义:
configUSE_TIMERS
一般用于处理一些周期性任务,也可以跟事件组搭配使用,如监听IO事件。
任务创建/删除:
//两种创建方法 TimerHandle_t xTimerCreate( const char *pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ); TimerHandle_t xTimerCreateStatic( const char *pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ); /* Creating a timer does not start the timer running. The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and xTimerChangePeriodFromISR() API functions can all be used to start the timer running. 宏定义: configUSE_TIMERS and configSUPPORT_DYNAMIC_ALLOCATION */ //eg: /* 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; /* 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 >= xMaxExpiryCountBeforeStopping ) { /* 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( pxTimer, 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 ); } } #define NUM_TIMERS 5 /* An array to hold handles to the created timers. */ TimerHandle_t xTimers[ NUM_TIMERS ]; 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 initialized 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( ;; ); } //static creat #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 ]; 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 initialized 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. */
}
}
定时任务开启/关闭
//开启任务接口 //开启定时器 BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); /* 如果定时器没有运行,则从xTimerStart调用开始计算 如果定时器已经运行,作用相当于xTimerReset(). 如果在调用xTimerStart时,定时器没有删除、停止、复位,则回调函数将在 N 个tick(定时周期)后调用 宏定义 configUSE_TIMERS */ //中断中开启/关闭定时器接口 BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken ); BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken ); /* 参数描述: pxHigherPriorityTaskWoken: xTimerStartFromISR/xTimerStopFromISR write a command to the timer command queue, If writing to the timer command queue causes the timer service task to leave the Blocked state, and the timer service task has a priority equal to or greater than the currently executing task (the task that was interrupted), then *pxHigherPriorityTaskWoken will be set to pdTRUE internally within the xTimerStopFromISR() function. If xTimerStopFromISR() sets this value to pdTRUE, then a context switch should be performed before the interrupt exits. */ //eg: if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) //任务删除 BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); /* Deletes a timer. The timer must first have been created using the xTimerCreate() API function. */
软件定时器任务设置:
定时器复位、更改运行周期
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); //更改运行周期 BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, TickType_t xNewPeriod, TickType_t xTicksToWait ); /* 重新运行的时间从该函数调用开始算,相当于reset后重新运行; */ //eg: /* 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 ) { 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, pdMS_TO_TICKS( 500 ), 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. */ } } } BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t *pxHigherPriorityTaskWoken ); //获取函数运行时间 xTaskGetTickCount(); //eg: void vAFunction( void ) { TickType_t xTime1, xTime2, xExecutionTime; /* Get the time the function started. */ xTime1 = xTaskGetTickCount(); /* Perform some operation. */ /* Get the time following the execution of the operation. */ xTime2 = xTaskGetTickCount(); /* Approximately how long did the operation take? */ xExecutionTime = xTime2 – xTime1; }
软件定时器查询操作:
周期查询、 定时器是否在运行查询、name查询、ID查询、获取软件定时器守护进程句柄
//周期查询 TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); /* Returns the period of a software timer. The period is specified in RTOS ticks. */ //eg: /* A callback function assigned to a software timer. */ static void prvTimerCallback( TimerHandle_t xTimer ) { TickType_t xTimerPeriod; /* Query the period of the timer that expired. */ xTimerPeriod = xTimerGetPeriod( xTimer ); } BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); /* 查询一个定时器是否在运行 定时器不会运行,如果: 1. The timer has been created, but not started. 2. The timer is a one shot timer that has not been restarted since it expired 开启定时器:The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and xTimerChangePeriodFromISR() API functions can all be used to start a timer running. */ const char * pcTimerGetName( TimerHandle_t xTimer ); //获取软件定时器ID void *pvTimerGetTimerID( TimerHandle_t xTimer ); /*usage:can be updated using thevTimerSetTimerID() ID 在定时器创建的时候初始化,倒数第二个参数 */ //获取软件定时器守护进程句柄 TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );