Microchip® Advanced Software Framework

timers.c File Reference
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"

Data Structures

struct  tmrCallbackParameters
 
struct  tmrTimerControl
 
struct  tmrTimerParameters
 
struct  tmrTimerQueueMessage
 

Macros

#define configTIMER_SERVICE_TASK_NAME   "Tmr Svc"
 
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 
#define tmrNO_DELAY   ( TickType_t ) 0U
 

Typedefs

typedef struct
tmrCallbackParameters 
CallbackParameters_t
 
typedef struct tmrTimerQueueMessage DaemonTaskMessage_t
 
typedef xTIMER Timer_t
 
typedef struct tmrTimerParameters TimerParameter_t
 
typedef struct tmrTimerControl xTIMER
 

Functions

const char * pcTimerGetName (TimerHandle_t xTimer)
 const char * const pcTimerGetName( TimerHandle_t xTimer ); More...
 
static void prvCheckForValidListAndQueue (static void prvTimerTask void)
 
static void prvCheckForValidListAndQueue (void)
 
static TickType_t prvGetNextExpireTime (BaseType_t *const pxListWasEmpty)
 
static void prvInitialiseNewTimer (const char *const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void *const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t *pxNewTimer)
 
static BaseType_t prvInsertTimerInActiveList (Timer_t *const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime)
 
static void prvProcessExpiredTimer (const TickType_t xNextExpireTime, const TickType_t xTimeNow)
 
static void prvProcessReceivedCommands (void)
 
static void prvProcessTimerOrBlockTask (const TickType_t xNextExpireTime, BaseType_t xListWasEmpty)
 
static TickType_t prvSampleTimeNow (BaseType_t *const pxTimerListsWereSwitched)
 
static void prvSwitchTimerLists (void)
 
static void prvTimerTask (void *pvParameters)
 
void * pvTimerGetTimerID (const TimerHandle_t xTimer)
 TimerHandle_t xTimerCreate( const char * const pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, void * pvTimerID, TimerCallbackFunction_t pxCallbackFunction );. More...
 
UBaseType_t uxTimerGetTimerNumber (TimerHandle_t xTimer)
 
void vTimerSetTimerID (TimerHandle_t xTimer, void *pvNewID)
 void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); More...
 
void vTimerSetTimerNumber (TimerHandle_t xTimer, UBaseType_t uxTimerNumber)
 
TimerHandle_t xTimerCreate (const char *const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void *const pvTimerID, TimerCallbackFunction_t pxCallbackFunction)
 
BaseType_t xTimerGenericCommand (TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t *const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait)
 
TickType_t xTimerGetExpiryTime (TimerHandle_t xTimer)
 TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );. More...
 
TickType_t xTimerGetPeriod (TimerHandle_t xTimer)
 TickType_t xTimerGetPeriod( TimerHandle_t xTimer );. More...
 
TaskHandle_t xTimerGetTimerDaemonTaskHandle (void)
 TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );. More...
 
BaseType_t xTimerIsTimerActive (TimerHandle_t xTimer)
 BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );. More...
 

Variables

static PRIVILEGED_DATA List_tpxCurrentTimerList
 
static PRIVILEGED_DATA List_tpxOverflowTimerList
 
static PRIVILEGED_DATA List_t xActiveTimerList1
 
static PRIVILEGED_DATA List_t xActiveTimerList2
 
static PRIVILEGED_DATA
QueueHandle_t 
xTimerQueue = NULL
 
static PRIVILEGED_DATA TaskHandle_t xTimerTaskHandle = NULL
 

#define configTIMER_SERVICE_TASK_NAME   "Tmr Svc"
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#define tmrNO_DELAY   ( TickType_t ) 0U

typedef xTIMER Timer_t
typedef struct tmrTimerControl xTIMER

const char* pcTimerGetName ( TimerHandle_t  xTimer)

const char * const pcTimerGetName( TimerHandle_t xTimer );

Returns the name that was assigned to a timer when the timer was created.

Parameters
xTimerThe handle of the timer being queried.
Returns
The name assigned to the timer specified by the xTimer parameter.

References configASSERT, and tmrTimerControl::pcTimerName.

static TickType_t prvGetNextExpireTime ( BaseType_t *const  pxListWasEmpty)
static
static void prvInitialiseNewTimer ( const char *const  pcTimerName,
const TickType_t  xTimerPeriodInTicks,
const UBaseType_t  uxAutoReload,
void *const  pvTimerID,
TimerCallbackFunction_t  pxCallbackFunction,
Timer_t pxNewTimer 
)
static
static BaseType_t prvInsertTimerInActiveList ( Timer_t *const  pxTimer,
const TickType_t  xNextExpiryTime,
const TickType_t  xTimeNow,
const TickType_t  xCommandTime 
)
static
static void prvProcessTimerOrBlockTask ( const TickType_t  xNextExpireTime,
BaseType_t  xListWasEmpty 
)
static
static TickType_t prvSampleTimeNow ( BaseType_t *const  pxTimerListsWereSwitched)
static
static void prvTimerTask ( void *  pvParameters)
static
void* pvTimerGetTimerID ( const TimerHandle_t  xTimer)

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

Creates a new software timer instance, and returns a handle by which the created software timer can be referenced.

Internally, within the FreeRTOS implementation, software timers use a block of memory, in which the timer data structure is stored. If a software timer is created using xTimerCreate() then the required memory is automatically dynamically allocated inside the xTimerCreate() function. (see http://www.freertos.org/a00111.html). If a software timer is created using xTimerCreateStatic() then the application writer must provide the memory that will get used by the software timer. xTimerCreateStatic() therefore allows a software timer to be created without using any dynamic memory allocation.

Timers are created in the dormant state. The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the active state.

Parameters
pcTimerNameA text name that is assigned to the timer. This is done purely to assist debugging. The kernel itself only ever references a timer by its handle, and never by its name.
xTimerPeriodInTicksThe timer period. The time is defined in tick periods so the constant portTICK_PERIOD_MS can be used to convert a time that has been specified in milliseconds. For example, if the timer must expire after 100 ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or equal to 1000.
uxAutoReloadIf uxAutoReload is set to pdTRUE then the timer will expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and enter the dormant state after it expires.
pvTimerIDAn identifier that is assigned to the timer being created. Typically this would be used in the timer callback function to identify which timer expired when the same callback function is assigned to more than one timer.
pxCallbackFunctionThe function to call when the timer expires. Callback functions must have the prototype defined by TimerCallbackFunction_t, which is "void vCallbackFunction( TimerHandle_t xTimer );".
Returns
If the timer is successfully created then a handle to the newly created timer is returned. If the timer cannot be created (because either there is insufficient FreeRTOS heap remaining to allocate the timer structures, or the timer period was set to 0) then NULL is returned.

Example usage:

* #define NUM_TIMERS 5
*
* // An array to hold handles to the created timers.
* TimerHandle_t xTimers[ NUM_TIMERS ];
*
* // An array to hold a count of the number of times each timer expires.
* int32_t lExpireCounters[ NUM_TIMERS ] = { 0 };
*
* // 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.
* void vTimerCallback( TimerHandle_t pxTimer )
* {
* int32_t lArrayIndex;
* const int32_t xMaxExpiryCountBeforeStopping = 10;
*
*      // Optionally do something if the pxTimer parameter is NULL.
*      configASSERT( pxTimer );
*
*     // Which timer expired?
*     lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer );
*
*     // Increment the number of times that pxTimer has expired.
*     lExpireCounters[ lArrayIndex ] += 1;
*
*     // If the timer has expired 10 times then stop it from running.
*     if( lExpireCounters[ lArrayIndex ] == 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 );
*     }
* }
*
* void main( void )
* {
* int32_t x;
*
*     // Create then start some timers.  Starting the timers before the scheduler
*     // has been started means the timers will start running immediately that
*     // the scheduler starts.
*     for( x = 0; x < NUM_TIMERS; x++ )
*     {
*         xTimers[ x ] = xTimerCreate(    "Timer",       // Just a text name, not used by the kernel.
*                                         ( 100 * x ),   // The timer period in ticks.
*                                         pdTRUE,        // The timers will auto-reload themselves when they expire.
*                                         ( void * ) x,  // Assign each timer a unique id equal to its array index.
*                                         vTimerCallback // Each timer calls the same callback when it expires.
*                                     );
*
*         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 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 scheduler will start the timers running as they have already
*     // been set into the active state.
*     vTaskStartScheduler();
*
*     // Should not reach here.
*     for( ;; );
* }
* 

TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, void * pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer );

Creates a new software timer instance, and returns a handle by which the created software timer can be referenced.

Internally, within the FreeRTOS implementation, software timers use a block of memory, in which the timer data structure is stored. If a software timer is created using xTimerCreate() then the required memory is automatically dynamically allocated inside the xTimerCreate() function. (see http://www.freertos.org/a00111.html). If a software timer is created using xTimerCreateStatic() then the application writer must provide the memory that will get used by the software timer. xTimerCreateStatic() therefore allows a software timer to be created without using any dynamic memory allocation.

Timers are created in the dormant state. The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the active state.

Parameters
pcTimerNameA text name that is assigned to the timer. This is done purely to assist debugging. The kernel itself only ever references a timer by its handle, and never by its name.
xTimerPeriodInTicksThe timer period. The time is defined in tick periods so the constant portTICK_PERIOD_MS can be used to convert a time that has been specified in milliseconds. For example, if the timer must expire after 100 ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or equal to 1000.
uxAutoReloadIf uxAutoReload is set to pdTRUE then the timer will expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and enter the dormant state after it expires.
pvTimerIDAn identifier that is assigned to the timer being created. Typically this would be used in the timer callback function to identify which timer expired when the same callback function is assigned to more than one timer.
pxCallbackFunctionThe function to call when the timer expires. Callback functions must have the prototype defined by TimerCallbackFunction_t, which is "void vCallbackFunction( TimerHandle_t xTimer );".
pxTimerBufferMust point to a variable of type StaticTimer_t, which will be then be used to hold the software timer's data structures, removing the need for the memory to be allocated dynamically.
Returns
If the timer is created then a handle to the created timer is returned. If pxTimerBuffer was NULL then NULL is returned.

Example usage:

*
* // The buffer used to hold the software timer's data structure.
* static StaticTimer_t xTimerBuffer;
*
* // A variable that will be incremented by the software timer's callback
* // function.
* UBaseType_t uxVariableToIncrement = 0;
*
* // A software timer callback function that increments a variable passed to
* // it when the software timer was created.  After the 5th increment the
* // callback function stops the software timer.
* static void prvTimerCallback( TimerHandle_t xExpiredTimer )
* {
* UBaseType_t *puxVariableToIncrement;
* BaseType_t xReturned;
*
*     // Obtain the address of the variable to increment from the timer ID.
*     puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );
*
*     // Increment the variable to show the timer callback has executed.
*     ( *puxVariableToIncrement )++;
*
*     // If this callback has executed the required number of times, stop the
*     // timer.
*     if( *puxVariableToIncrement == 5 )
*     {
*         // This is called from a timer callback so must not block.
*         xTimerStop( xExpiredTimer, staticDONT_BLOCK );
*     }
* }
*
*
* void main( void )
* {
*     // Create the software time.  xTimerCreateStatic() has an extra parameter
*     // than the normal xTimerCreate() API function.  The parameter is a pointer
*     // to the StaticTimer_t structure that will hold the software timer
*     // structure.  If the parameter is passed as NULL then the structure will be
*     // allocated dynamically, just as if xTimerCreate() had been called.
*     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 function
*                                  prvTimerCallback, // The function to execute when the timer expires.
*                                  &xTimerBuffer );  // The buffer that will hold the software timer structure.
*
*     // The scheduler has not started yet so a block time is not used.
*     xReturned = xTimerStart( xTimer, 0 );
*
*     // ...
*     // Create tasks here.
*     // ...
*
*     // Starting the scheduler will start the timers running as they have already
*     // been set into the active state.
*     vTaskStartScheduler();
*
*     // Should not reach here.
*     for( ;; );
* }
* 

void *pvTimerGetTimerID( TimerHandle_t xTimer );

Returns the ID assigned to the timer.

IDs are assigned to timers using the pvTimerID parameter of the call to xTimerCreated() that was used to create the timer, and by calling the vTimerSetTimerID() API function.

If the same callback function is assigned to multiple timers then the timer ID can be used as time specific (timer local) storage.

Parameters
xTimerThe timer being queried.
Returns
The ID assigned to the timer being queried.

Example usage:

See the xTimerCreate() API function example usage scenario.

References configASSERT, tmrTimerControl::pvTimerID, taskENTER_CRITICAL, and taskEXIT_CRITICAL.

UBaseType_t uxTimerGetTimerNumber ( TimerHandle_t  xTimer)
void vTimerSetTimerID ( TimerHandle_t  xTimer,
void *  pvNewID 
)

void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );

Sets the ID assigned to the timer.

IDs are assigned to timers using the pvTimerID parameter of the call to xTimerCreated() that was used to create the timer.

If the same callback function is assigned to multiple timers then the timer ID can be used as time specific (timer local) storage.

Parameters
xTimerThe timer being updated.
pvNewIDThe ID to assign to the timer.

Example usage:

See the xTimerCreate() API function example usage scenario.

References configASSERT, tmrTimerControl::pvTimerID, taskENTER_CRITICAL, and taskEXIT_CRITICAL.

void vTimerSetTimerNumber ( TimerHandle_t  xTimer,
UBaseType_t  uxTimerNumber 
)
TimerHandle_t xTimerCreate ( const char *const  pcTimerName,
const TickType_t  xTimerPeriodInTicks,
const UBaseType_t  uxAutoReload,
void *const  pvTimerID,
TimerCallbackFunction_t  pxCallbackFunction 
)
TickType_t xTimerGetExpiryTime ( TimerHandle_t  xTimer)

TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );.

Returns the time in ticks at which the timer will expire. If this is less than the current tick count then the expiry time has overflowed from the current time.

Parameters
xTimerThe handle of the timer being queried.
Returns
If the timer is running then the time in ticks at which the timer will next expire is returned. If the timer is not running then the return value is undefined.

References configASSERT, listGET_LIST_ITEM_VALUE, and tmrTimerControl::xTimerListItem.

TickType_t xTimerGetPeriod ( TimerHandle_t  xTimer)

TickType_t xTimerGetPeriod( TimerHandle_t xTimer );.

Returns the period of a timer.

Parameters
xTimerThe handle of the timer being queried.
Returns
The period of the timer in ticks.

References configASSERT, and tmrTimerControl::xTimerPeriodInTicks.

TaskHandle_t xTimerGetTimerDaemonTaskHandle ( void  )

TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );.

Simply returns the handle of the timer service/daemon task. It it not valid to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.

References configASSERT, and xTimerTaskHandle.

BaseType_t xTimerIsTimerActive ( TimerHandle_t  xTimer)

BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );.

Queries a timer to see if it is active or dormant.

A timer will be dormant if: 1) It has been created but not started, or 2) It is an expired one-shot timer that has not been restarted.

Timers are created in the dormant state. The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the active state.

Parameters
xTimerThe timer being queried.
Returns
pdFALSE will be returned if the timer is dormant. A value other than pdFALSE will be returned if the timer is active.

Example usage:

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

References configASSERT, listIS_CONTAINED_WITHIN, taskENTER_CRITICAL, taskEXIT_CRITICAL, and tmrTimerControl::xTimerListItem.

PRIVILEGED_DATA List_t xActiveTimerList1
static
PRIVILEGED_DATA List_t xActiveTimerList2
static