timers.c
Go to the documentation of this file.
1 /*
2  * FreeRTOS Kernel V10.0.0
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software. If you wish to use our Amazon
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * http://www.FreeRTOS.org
24  * http://aws.amazon.com/freertos
25  *
26  * 1 tab == 4 spaces!
27  */
28 
29 /* Standard includes. */
30 #include <stdlib.h>
31 
32 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
33 all the API functions to use the MPU wrappers. That should only be done when
34 task.h is included from an application file. */
35 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
36 
37 #include "FreeRTOS.h"
38 #include "task.h"
39 #include "queue.h"
40 #include "timers.h"
41 
42 #if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )
43  #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
44 #endif
45 
46 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
47 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
48 header files above, but not in this file, in order to generate the correct
49 privileged Vs unprivileged linkage and placement. */
50 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
51 
52 
53 /* This entire source file will be skipped if the application is not configured
54 to include software timer functionality. This #if is closed at the very bottom
55 of this file. If you want to include software timer functionality then ensure
56 configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
57 #if ( configUSE_TIMERS == 1 )
58 
59 /* Misc definitions. */
60 #define tmrNO_DELAY ( TickType_t ) 0U
61 
62 /* The name assigned to the timer service task. This can be overridden by
63 defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
64 #ifndef configTIMER_SERVICE_TASK_NAME
65  #define configTIMER_SERVICE_TASK_NAME "Tmr Svc"
66 #endif
67 
68 /* The definition of the timers themselves. */
69 typedef struct tmrTimerControl
70 {
71  const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
72  ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
73  TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
74  UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */
75  void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
76  TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
77  #if( configUSE_TRACE_FACILITY == 1 )
78  UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */
79  #endif
80 
81  #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
82  uint8_t ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created statically so no attempt is made to free the memory again if the timer is later deleted. */
83  #endif
84 } xTIMER;
85 
86 /* The old xTIMER name is maintained above then typedefed to the new Timer_t
87 name below to enable the use of older kernel aware debuggers. */
88 typedef xTIMER Timer_t;
89 
90 /* The definition of messages that can be sent and received on the timer queue.
91 Two types of message can be queued - messages that manipulate a software timer,
92 and messages that request the execution of a non-timer related callback. The
93 two message types are defined in two separate structures, xTimerParametersType
94 and xCallbackParametersType respectively. */
95 typedef struct tmrTimerParameters
96 {
97  TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */
98  Timer_t * pxTimer; /*<< The timer to which the command will be applied. */
99 } TimerParameter_t;
100 
101 
102 typedef struct tmrCallbackParameters
103 {
104  PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */
105  void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */
106  uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */
107 } CallbackParameters_t;
108 
109 /* The structure that contains the two message types, along with an identifier
110 that is used to determine which message type is valid. */
111 typedef struct tmrTimerQueueMessage
112 {
113  BaseType_t xMessageID; /*<< The command being sent to the timer service task. */
114  union
115  {
116  TimerParameter_t xTimerParameters;
117 
118  /* Don't include xCallbackParameters if it is not going to be used as
119  it makes the structure (and therefore the timer queue) larger. */
120  #if ( INCLUDE_xTimerPendFunctionCall == 1 )
121  CallbackParameters_t xCallbackParameters;
122  #endif /* INCLUDE_xTimerPendFunctionCall */
123  } u;
124 } DaemonTaskMessage_t;
125 
126 /*lint -save -e956 A manual analysis and inspection has been used to determine
127 which static variables must be declared volatile. */
128 
129 /* The list in which active timers are stored. Timers are referenced in expire
130 time order, with the nearest expiry time at the front of the list. Only the
131 timer service task is allowed to access these lists. */
132 PRIVILEGED_DATA static List_t xActiveTimerList1;
133 PRIVILEGED_DATA static List_t xActiveTimerList2;
134 PRIVILEGED_DATA static List_t *pxCurrentTimerList;
135 PRIVILEGED_DATA static List_t *pxOverflowTimerList;
136 
137 /* A queue that is used to send commands to the timer service task. */
138 PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
139 PRIVILEGED_DATA TaskHandle_t xTimerTaskHandle = NULL;
140 
141 /*lint -restore */
142 
143 /*-----------------------------------------------------------*/
144 
145 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
146 
147  /* If static allocation is supported then the application must provide the
148  following callback function - which enables the application to optionally
149  provide the memory that will be used by the timer task as the task's stack
150  and TCB. */
151  extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
152 
153 #endif
154 
155 /*
156  * Initialise the infrastructure used by the timer service task if it has not
157  * been initialised already.
158  */
159 static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
160 
161 /*
162  * The timer service task (daemon). Timer functionality is controlled by this
163  * task. Other tasks communicate with the timer service task using the
164  * xTimerQueue queue.
165  */
166 static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
167 
168 /*
169  * Called by the timer service task to interpret and process a command it
170  * received on the timer queue.
171  */
172 static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
173 
174 /*
175  * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
176  * depending on if the expire time causes a timer counter overflow.
177  */
178 static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION;
179 
180 /*
181  * An active timer has reached its expire time. Reload the timer if it is an
182  * auto reload timer, then call its callback.
183  */
184 static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;
185 
186 /*
187  * The tick count has overflowed. Switch the timer lists after ensuring the
188  * current timer list does not still reference some timers.
189  */
190 static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION;
191 
192 /*
193  * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE
194  * if a tick count overflow occurred since prvSampleTimeNow() was last called.
195  */
196 static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;
197 
198 /*
199  * If the timer list contains any active timers then return the expire time of
200  * the timer that will expire first and set *pxListWasEmpty to false. If the
201  * timer list does not contain any timers then return 0 and set *pxListWasEmpty
202  * to pdTRUE.
203  */
204 static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION;
205 
206 /*
207  * If a timer has expired, process it. Otherwise, block the timer service task
208  * until either a timer does expire or a command is received.
209  */
210 static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;
211 
212 /*
213  * Called after a Timer_t structure has been allocated either statically or
214  * dynamically to fill in the structure's members.
215  */
216 static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
217  const TickType_t xTimerPeriodInTicks,
218  const UBaseType_t uxAutoReload,
219  void * const pvTimerID,
220  TimerCallbackFunction_t pxCallbackFunction,
221  Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION;
222 /*-----------------------------------------------------------*/
223 
225 {
226 BaseType_t xReturn = pdFAIL;
227 
228  /* This function is called when the scheduler is started if
229  configUSE_TIMERS is set to 1. Check that the infrastructure used by the
230  timer service task has been created/initialised. If timers have already
231  been created then the initialisation will already have been performed. */
232  prvCheckForValidListAndQueue();
233 
234  if( xTimerQueue != NULL )
235  {
236  #if( configSUPPORT_STATIC_ALLOCATION == 1 )
237  {
238  StaticTask_t *pxTimerTaskTCBBuffer = NULL;
239  StackType_t *pxTimerTaskStackBuffer = NULL;
240  uint32_t ulTimerTaskStackSize;
241 
242  vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
243  xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
244  configTIMER_SERVICE_TASK_NAME,
245  ulTimerTaskStackSize,
246  NULL,
248  pxTimerTaskStackBuffer,
249  pxTimerTaskTCBBuffer );
250  if( xTimerTaskHandle != NULL )
251  {
252  xReturn = pdPASS;
253  }
254  }
255  #else
256  {
257  xReturn = xTaskCreate( prvTimerTask,
258  configTIMER_SERVICE_TASK_NAME,
260  NULL,
262  &xTimerTaskHandle );
263  }
264  *timerTaskHandle = xTimerTaskHandle;
265  #endif /* configSUPPORT_STATIC_ALLOCATION */
266  }
267  else
268  {
270  }
271 
272  configASSERT( xReturn );
273  return xReturn;
274 }
275 /*-----------------------------------------------------------*/
276 
277 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
278 
279  TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
280  const TickType_t xTimerPeriodInTicks,
281  const UBaseType_t uxAutoReload,
282  void * const pvTimerID,
283  TimerCallbackFunction_t pxCallbackFunction )
284  {
285  Timer_t *pxNewTimer;
286 
287  pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
288 
289  if( pxNewTimer != NULL )
290  {
291  prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
292 
293  #if( configSUPPORT_STATIC_ALLOCATION == 1 )
294  {
295  /* Timers can be created statically or dynamically, so note this
296  timer was created dynamically in case the timer is later
297  deleted. */
298  pxNewTimer->ucStaticallyAllocated = pdFALSE;
299  }
300  #endif /* configSUPPORT_STATIC_ALLOCATION */
301  }
302 
303  return pxNewTimer;
304  }
305 
306 #endif /* configSUPPORT_STATIC_ALLOCATION */
307 /*-----------------------------------------------------------*/
308 
309 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
310 
311  TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
312  const TickType_t xTimerPeriodInTicks,
313  const UBaseType_t uxAutoReload,
314  void * const pvTimerID,
315  TimerCallbackFunction_t pxCallbackFunction,
316  StaticTimer_t *pxTimerBuffer )
317  {
318  Timer_t *pxNewTimer;
319 
320  #if( configASSERT_DEFINED == 1 )
321  {
322  /* Sanity check that the size of the structure used to declare a
323  variable of type StaticTimer_t equals the size of the real timer
324  structure. */
325  volatile size_t xSize = sizeof( StaticTimer_t );
326  configASSERT( xSize == sizeof( Timer_t ) );
327  }
328  #endif /* configASSERT_DEFINED */
329 
330  /* A pointer to a StaticTimer_t structure MUST be provided, use it. */
331  configASSERT( pxTimerBuffer );
332  pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
333 
334  if( pxNewTimer != NULL )
335  {
336  prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
337 
338  #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
339  {
340  /* Timers can be created statically or dynamically so note this
341  timer was created statically in case it is later deleted. */
342  pxNewTimer->ucStaticallyAllocated = pdTRUE;
343  }
344  #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
345  }
346 
347  return pxNewTimer;
348  }
349 
350 #endif /* configSUPPORT_STATIC_ALLOCATION */
351 /*-----------------------------------------------------------*/
352 
353 static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
354  const TickType_t xTimerPeriodInTicks,
355  const UBaseType_t uxAutoReload,
356  void * const pvTimerID,
357  TimerCallbackFunction_t pxCallbackFunction,
358  Timer_t *pxNewTimer )
359 {
360  /* 0 is not a valid value for xTimerPeriodInTicks. */
361  configASSERT( ( xTimerPeriodInTicks > 0 ) );
362 
363  if( pxNewTimer != NULL )
364  {
365  /* Ensure the infrastructure used by the timer service task has been
366  created/initialised. */
367  prvCheckForValidListAndQueue();
368 
369  /* Initialise the timer structure members using the function
370  parameters. */
371  pxNewTimer->pcTimerName = pcTimerName;
372  pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
373  pxNewTimer->uxAutoReload = uxAutoReload;
374  pxNewTimer->pvTimerID = pvTimerID;
375  pxNewTimer->pxCallbackFunction = pxCallbackFunction;
376  vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
377  traceTIMER_CREATE( pxNewTimer );
378  }
379 }
380 /*-----------------------------------------------------------*/
381 
382 BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait )
383 {
384 BaseType_t xReturn = pdFAIL;
385 DaemonTaskMessage_t xMessage;
386 
387  configASSERT( xTimer );
388 
389  /* Send a message to the timer service task to perform a particular action
390  on a particular timer definition. */
391  if( xTimerQueue != NULL )
392  {
393  /* Send a command to the timer service task to start the xTimer timer. */
394  xMessage.xMessageID = xCommandID;
395  xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
396  xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
397 
398  if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
399  {
401  {
402  xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
403  }
404  else
405  {
406  xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
407  }
408  }
409  else
410  {
411  xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
412  }
413 
414  traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
415  }
416  else
417  {
419  }
420 
421  return xReturn;
422 }
423 /*-----------------------------------------------------------*/
424 
426 {
427  /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
428  started, then xTimerTaskHandle will be NULL. */
429  configASSERT( ( xTimerTaskHandle != NULL ) );
430  return xTimerTaskHandle;
431 }
432 /*-----------------------------------------------------------*/
433 
435 {
436 Timer_t *pxTimer = ( Timer_t * ) xTimer;
437 
438  configASSERT( xTimer );
439  return pxTimer->xTimerPeriodInTicks;
440 }
441 /*-----------------------------------------------------------*/
442 
444 {
445 Timer_t * pxTimer = ( Timer_t * ) xTimer;
446 TickType_t xReturn;
447 
448  configASSERT( xTimer );
449  xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );
450  return xReturn;
451 }
452 /*-----------------------------------------------------------*/
453 
454 const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
455 {
456 Timer_t *pxTimer = ( Timer_t * ) xTimer;
457 
458  configASSERT( xTimer );
459  return pxTimer->pcTimerName;
460 }
461 /*-----------------------------------------------------------*/
462 
463 static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
464 {
465 BaseType_t xResult;
466 Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
467 
468  /* Remove the timer from the list of active timers. A check has already
469  been performed to ensure the list is not empty. */
470  ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
471  traceTIMER_EXPIRED( pxTimer );
472 
473  /* If the timer is an auto reload timer then calculate the next
474  expiry time and re-insert the timer in the list of active timers. */
475  if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
476  {
477  /* The timer is inserted into a list using a time relative to anything
478  other than the current time. It will therefore be inserted into the
479  correct list relative to the time this task thinks it is now. */
480  if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )
481  {
482  /* The timer expired before it was added to the active timer
483  list. Reload it now. */
484  xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
485  configASSERT( xResult );
486  ( void ) xResult;
487  }
488  else
489  {
491  }
492  }
493  else
494  {
496  }
497 
498  /* Call the timer callback. */
499  pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
500 }
501 /*-----------------------------------------------------------*/
502 
503 static void prvTimerTask( void *pvParameters )
504 {
505 TickType_t xNextExpireTime;
506 BaseType_t xListWasEmpty;
507 
508  /* Just to avoid compiler warnings. */
509  ( void ) pvParameters;
510 
511  #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )
512  {
513  extern void vApplicationDaemonTaskStartupHook( void );
514 
515  /* Allow the application writer to execute some code in the context of
516  this task at the point the task starts executing. This is useful if the
517  application includes initialisation code that would benefit from
518  executing after the scheduler has been started. */
519  vApplicationDaemonTaskStartupHook();
520  }
521  #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */
522 
523  for( ;; )
524  {
525  /* Query the timers list to see if it contains any timers, and if so,
526  obtain the time at which the next timer will expire. */
527  xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
528 
529  /* If a timer has expired, process it. Otherwise, block this task
530  until either a timer does expire, or a command is received. */
531  prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
532 
533  /* Empty the command queue. */
534  prvProcessReceivedCommands();
535  }
536 }
537 /*-----------------------------------------------------------*/
538 
539 static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty )
540 {
541 TickType_t xTimeNow;
542 BaseType_t xTimerListsWereSwitched;
543 
544  vTaskSuspendAll();
545  {
546  /* Obtain the time now to make an assessment as to whether the timer
547  has expired or not. If obtaining the time causes the lists to switch
548  then don't process this timer as any timers that remained in the list
549  when the lists were switched will have been processed within the
550  prvSampleTimeNow() function. */
551  xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
552  if( xTimerListsWereSwitched == pdFALSE )
553  {
554  /* The tick count has not overflowed, has the timer expired? */
555  if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
556  {
557  ( void ) xTaskResumeAll();
558  prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
559  }
560  else
561  {
562  /* The tick count has not overflowed, and the next expire
563  time has not been reached yet. This task should therefore
564  block to wait for the next expire time or a command to be
565  received - whichever comes first. The following line cannot
566  be reached unless xNextExpireTime > xTimeNow, except in the
567  case when the current timer list is empty. */
568  if( xListWasEmpty != pdFALSE )
569  {
570  /* The current timer list is empty - is the overflow list
571  also empty? */
572  xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList );
573  }
574 
575  vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty );
576 
577  if( xTaskResumeAll() == pdFALSE )
578  {
579  /* Yield to wait for either a command to arrive, or the
580  block time to expire. If a command arrived between the
581  critical section being exited and this yield then the yield
582  will not cause the task to block. */
584  }
585  else
586  {
588  }
589  }
590  }
591  else
592  {
593  ( void ) xTaskResumeAll();
594  }
595  }
596 }
597 /*-----------------------------------------------------------*/
598 
599 static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty )
600 {
601 TickType_t xNextExpireTime;
602 
603  /* Timers are listed in expiry time order, with the head of the list
604  referencing the task that will expire first. Obtain the time at which
605  the timer with the nearest expiry time will expire. If there are no
606  active timers then just set the next expire time to 0. That will cause
607  this task to unblock when the tick count overflows, at which point the
608  timer lists will be switched and the next expiry time can be
609  re-assessed. */
610  *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
611  if( *pxListWasEmpty == pdFALSE )
612  {
613  xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
614  }
615  else
616  {
617  /* Ensure the task unblocks when the tick count rolls over. */
618  xNextExpireTime = ( TickType_t ) 0U;
619  }
620 
621  return xNextExpireTime;
622 }
623 /*-----------------------------------------------------------*/
624 
625 static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched )
626 {
627 TickType_t xTimeNow;
628 PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */
629 
630  xTimeNow = xTaskGetTickCount();
631 
632  if( xTimeNow < xLastTime )
633  {
634  prvSwitchTimerLists();
635  *pxTimerListsWereSwitched = pdTRUE;
636  }
637  else
638  {
639  *pxTimerListsWereSwitched = pdFALSE;
640  }
641 
642  xLastTime = xTimeNow;
643 
644  return xTimeNow;
645 }
646 /*-----------------------------------------------------------*/
647 
648 static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime )
649 {
650 BaseType_t xProcessTimerNow = pdFALSE;
651 
652  listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );
653  listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
654 
655  if( xNextExpiryTime <= xTimeNow )
656  {
657  /* Has the expiry time elapsed between the command to start/reset a
658  timer was issued, and the time the command was processed? */
659  if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
660  {
661  /* The time between a command being issued and the command being
662  processed actually exceeds the timers period. */
663  xProcessTimerNow = pdTRUE;
664  }
665  else
666  {
667  vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );
668  }
669  }
670  else
671  {
672  if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
673  {
674  /* If, since the command was issued, the tick count has overflowed
675  but the expiry time has not, then the timer must have already passed
676  its expiry time and should be processed immediately. */
677  xProcessTimerNow = pdTRUE;
678  }
679  else
680  {
681  vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
682  }
683  }
684 
685  return xProcessTimerNow;
686 }
687 /*-----------------------------------------------------------*/
688 
689 static void prvProcessReceivedCommands( void )
690 {
691 DaemonTaskMessage_t xMessage;
692 Timer_t *pxTimer;
693 BaseType_t xTimerListsWereSwitched, xResult;
694 TickType_t xTimeNow;
695 
696  while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
697  {
698  #if ( INCLUDE_xTimerPendFunctionCall == 1 )
699  {
700  /* Negative commands are pended function calls rather than timer
701  commands. */
702  if( xMessage.xMessageID < ( BaseType_t ) 0 )
703  {
704  const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );
705 
706  /* The timer uses the xCallbackParameters member to request a
707  callback be executed. Check the callback is not NULL. */
708  configASSERT( pxCallback );
709 
710  /* Call the function. */
711  pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 );
712  }
713  else
714  {
716  }
717  }
718  #endif /* INCLUDE_xTimerPendFunctionCall */
719 
720  /* Commands that are positive are timer commands rather than pended
721  function calls. */
722  if( xMessage.xMessageID >= ( BaseType_t ) 0 )
723  {
724  /* The messages uses the xTimerParameters member to work on a
725  software timer. */
726  pxTimer = xMessage.u.xTimerParameters.pxTimer;
727 
728  if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */
729  {
730  /* The timer is in a list, remove it. */
731  ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
732  }
733  else
734  {
736  }
737 
738  traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );
739 
740  /* In this case the xTimerListsWereSwitched parameter is not used, but
741  it must be present in the function call. prvSampleTimeNow() must be
742  called after the message is received from xTimerQueue so there is no
743  possibility of a higher priority task adding a message to the message
744  queue with a time that is ahead of the timer daemon task (because it
745  pre-empted the timer daemon task after the xTimeNow value was set). */
746  xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
747 
748  switch( xMessage.xMessageID )
749  {
750  case tmrCOMMAND_START :
752  case tmrCOMMAND_RESET :
755  /* Start or restart a timer. */
756  if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE )
757  {
758  /* The timer expired before it was added to the active
759  timer list. Process it now. */
760  pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
761  traceTIMER_EXPIRED( pxTimer );
762 
763  if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
764  {
765  xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
766  configASSERT( xResult );
767  ( void ) xResult;
768  }
769  else
770  {
772  }
773  }
774  else
775  {
777  }
778  break;
779 
780  case tmrCOMMAND_STOP :
782  /* The timer has already been removed from the active list.
783  There is nothing to do here. */
784  break;
785 
788  pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
789  configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
790 
791  /* The new period does not really have a reference, and can
792  be longer or shorter than the old one. The command time is
793  therefore set to the current time, and as the period cannot
794  be zero the next expiry time can only be in the future,
795  meaning (unlike for the xTimerStart() case above) there is
796  no fail case that needs to be handled here. */
797  ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
798  break;
799 
800  case tmrCOMMAND_DELETE :
801  /* The timer has already been removed from the active list,
802  just free up the memory if the memory was dynamically
803  allocated. */
804  #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
805  {
806  /* The timer can only have been allocated dynamically -
807  free it again. */
808  vPortFree( pxTimer );
809  }
810  #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
811  {
812  /* The timer could have been allocated statically or
813  dynamically, so check before attempting to free the
814  memory. */
815  if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
816  {
817  vPortFree( pxTimer );
818  }
819  else
820  {
822  }
823  }
824  #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
825  break;
826 
827  default :
828  /* Don't expect to get here. */
829  break;
830  }
831  }
832  }
833 }
834 /*-----------------------------------------------------------*/
835 
836 static void prvSwitchTimerLists( void )
837 {
838 TickType_t xNextExpireTime, xReloadTime;
839 List_t *pxTemp;
840 Timer_t *pxTimer;
841 BaseType_t xResult;
842 
843  /* The tick count has overflowed. The timer lists must be switched.
844  If there are any timers still referenced from the current timer list
845  then they must have expired and should be processed before the lists
846  are switched. */
847  while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
848  {
849  xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
850 
851  /* Remove the timer from the list. */
852  pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
853  ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
854  traceTIMER_EXPIRED( pxTimer );
855 
856  /* Execute its callback, then send a command to restart the timer if
857  it is an auto-reload timer. It cannot be restarted here as the lists
858  have not yet been switched. */
859  pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
860 
861  if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
862  {
863  /* Calculate the reload value, and if the reload value results in
864  the timer going into the same timer list then it has already expired
865  and the timer should be re-inserted into the current list so it is
866  processed again within this loop. Otherwise a command should be sent
867  to restart the timer to ensure it is only inserted into a list after
868  the lists have been swapped. */
869  xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
870  if( xReloadTime > xNextExpireTime )
871  {
872  listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
873  listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
874  vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
875  }
876  else
877  {
878  xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
879  configASSERT( xResult );
880  ( void ) xResult;
881  }
882  }
883  else
884  {
886  }
887  }
888 
889  pxTemp = pxCurrentTimerList;
890  pxCurrentTimerList = pxOverflowTimerList;
891  pxOverflowTimerList = pxTemp;
892 }
893 /*-----------------------------------------------------------*/
894 
895 static void prvCheckForValidListAndQueue( void )
896 {
897  /* Check that the list from which active timers are referenced, and the
898  queue used to communicate with the timer service, have been
899  initialised. */
901  {
902  if( xTimerQueue == NULL )
903  {
904  vListInitialise( &xActiveTimerList1 );
905  vListInitialise( &xActiveTimerList2 );
906  pxCurrentTimerList = &xActiveTimerList1;
907  pxOverflowTimerList = &xActiveTimerList2;
908 
909  #if( configSUPPORT_STATIC_ALLOCATION == 1 )
910  {
911  /* The timer queue is allocated statically in case
912  configSUPPORT_DYNAMIC_ALLOCATION is 0. */
913  static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
914  static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */
915 
916  xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );
917  }
918  #else
919  {
920  xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
921  }
922  #endif
923 
924  #if ( configQUEUE_REGISTRY_SIZE > 0 )
925  {
926  if( xTimerQueue != NULL )
927  {
928  vQueueAddToRegistry( xTimerQueue, "TmrQ" );
929  }
930  else
931  {
933  }
934  }
935  #endif /* configQUEUE_REGISTRY_SIZE */
936  }
937  else
938  {
940  }
941  }
943 }
944 /*-----------------------------------------------------------*/
945 
947 {
948 BaseType_t xTimerIsInActiveList;
949 Timer_t *pxTimer = ( Timer_t * ) xTimer;
950 
951  configASSERT( xTimer );
952 
953  /* Is the timer in the list of active timers? */
955  {
956  /* Checking to see if it is in the NULL list in effect checks to see if
957  it is referenced from either the current or the overflow timer lists in
958  one go, but the logic has to be reversed, hence the '!'. */
959  xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); /*lint !e961. Cast is only redundant when NULL is passed into the macro. */
960  }
962 
963  return xTimerIsInActiveList;
964 } /*lint !e818 Can't be pointer to const due to the typedef. */
965 /*-----------------------------------------------------------*/
966 
967 void *pvTimerGetTimerID( const TimerHandle_t xTimer )
968 {
969 Timer_t * const pxTimer = ( Timer_t * ) xTimer;
970 void *pvReturn;
971 
972  configASSERT( xTimer );
973 
975  {
976  pvReturn = pxTimer->pvTimerID;
977  }
979 
980  return pvReturn;
981 }
982 /*-----------------------------------------------------------*/
983 
984 void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID )
985 {
986 Timer_t * const pxTimer = ( Timer_t * ) xTimer;
987 
988  configASSERT( xTimer );
989 
991  {
992  pxTimer->pvTimerID = pvNewID;
993  }
995 }
996 /*-----------------------------------------------------------*/
997 
998 #if( INCLUDE_xTimerPendFunctionCall == 1 )
999 
1000  BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )
1001  {
1002  DaemonTaskMessage_t xMessage;
1003  BaseType_t xReturn;
1004 
1005  /* Complete the message with the function parameters and post it to the
1006  daemon task. */
1007  xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
1008  xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
1009  xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
1010  xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
1011 
1012  xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
1013 
1014  tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn );
1015 
1016  return xReturn;
1017  }
1018 
1019 #endif /* INCLUDE_xTimerPendFunctionCall */
1020 /*-----------------------------------------------------------*/
1021 
1022 #if( INCLUDE_xTimerPendFunctionCall == 1 )
1023 
1024  BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )
1025  {
1026  DaemonTaskMessage_t xMessage;
1027  BaseType_t xReturn;
1028 
1029  /* This function can only be called after a timer has been created or
1030  after the scheduler has been started because, until then, the timer
1031  queue does not exist. */
1032  configASSERT( xTimerQueue );
1033 
1034  /* Complete the message with the function parameters and post it to the
1035  daemon task. */
1036  xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;
1037  xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
1038  xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
1039  xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
1040 
1041  xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
1042 
1043  tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn );
1044 
1045  return xReturn;
1046  }
1047 
1048 #endif /* INCLUDE_xTimerPendFunctionCall */
1049 /*-----------------------------------------------------------*/
1050 
1051 #if ( configUSE_TRACE_FACILITY == 1 )
1052 
1053  UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer )
1054  {
1055  return ( ( Timer_t * ) xTimer )->uxTimerNumber;
1056  }
1057 
1058 #endif /* configUSE_TRACE_FACILITY */
1059 /*-----------------------------------------------------------*/
1060 
1061 #if ( configUSE_TRACE_FACILITY == 1 )
1062 
1063  void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber )
1064  {
1065  ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber;
1066  }
1067 
1068 #endif /* configUSE_TRACE_FACILITY */
1069 /*-----------------------------------------------------------*/
1070 
1071 /* This entire source file will be skipped if the application is not configured
1072 to include software timer functionality. If you want to include software timer
1073 functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
1074 #endif /* configUSE_TIMERS == 1 */
1075 
1076 
1077 
#define pdTRUE
Definition: projdefs.h:46
#define configTIMER_TASK_PRIORITY
#define tmrCOMMAND_RESET_FROM_ISR
Definition: timers.h:66
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition: heap_4.c:311
#define listGET_LIST_ITEM_VALUE(pxListItem)
Definition: list.h:208
#define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret)
Definition: FreeRTOS.h:601
BaseType_t xTimerPendFunctionCallFromISR(PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION
TaskHandle_t xTimerGetTimerDaemonTaskHandle(void) PRIVILEGED_FUNCTION
Definition: list.h:164
#define configTIMER_QUEUE_LENGTH
#define listIS_CONTAINED_WITHIN(pxList, pxListItem)
Definition: list.h:318
UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove) PRIVILEGED_FUNCTION
Definition: list.c:171
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY(pxList)
Definition: list.h:217
#define tmrCOMMAND_STOP_FROM_ISR
Definition: timers.h:67
#define taskEXIT_CRITICAL()
Definition: task.h:194
void vTaskSuspendAll(void) PRIVILEGED_FUNCTION
Definition: tasks.c:2034
#define tmrCOMMAND_CHANGE_PERIOD
Definition: timers.h:61
#define taskSCHEDULER_RUNNING
Definition: task.h:221
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_4.c:155
#define listSET_LIST_ITEM_VALUE(pxListItem, xValue)
Definition: list.h:198
#define tmrCOMMAND_STOP
Definition: timers.h:60
#define NULL
Definition: nm_bsp.h:52
void(* PendedFunction_t)(void *, uint32_t)
Definition: timers.h:88
#define tmrCOMMAND_DELETE
Definition: timers.h:62
#define listLIST_IS_EMPTY(pxList)
Definition: list.h:250
BaseType_t xTimerCreateTimerTask(TaskHandle_t *) PRIVILEGED_FUNCTION
BaseType_t xTimerGenericCommand(TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t *const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait) PRIVILEGED_FUNCTION
unsigned long UBaseType_t
Definition: portmacro.h:58
uint32_t TickType_t
Definition: portmacro.h:64
void * pvTimerGetTimerID(const TimerHandle_t xTimer) PRIVILEGED_FUNCTION
BaseType_t xQueueReceive(QueueHandle_t xQueue, void *const pvBuffer, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
Definition: queue.c:1240
#define xQueueSendToBackFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken)
Definition: queue.h:1054
#define tmrCOMMAND_START
Definition: timers.h:58
#define traceTIMER_COMMAND_RECEIVED(pxTimer, xMessageID, xMessageValue)
Definition: FreeRTOS.h:545
#define listSET_LIST_ITEM_OWNER(pxListItem, pxOwner)
Definition: list.h:180
#define configASSERT(x)
Definition: FreeRTOS.h:235
#define vQueueAddToRegistry(xQueue, pcName)
Definition: FreeRTOS.h:283
TickType_t xTaskGetTickCount(void) PRIVILEGED_FUNCTION
Definition: tasks.c:2217
#define tmrCOMMAND_START_DONT_TRACE
Definition: timers.h:57
void vQueueWaitForMessageRestricted(QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely) PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA
Definition: mpu_wrappers.h:175
void(* TimerCallbackFunction_t)(TimerHandle_t xTimer)
Definition: timers.h:82
#define portPRIVILEGE_BIT
Definition: FreeRTOS.h:719
#define traceTIMER_COMMAND_SEND(xTimer, xMessageID, xMessageValueValue, xReturn)
Definition: FreeRTOS.h:537
#define pdFAIL
Definition: projdefs.h:49
BaseType_t xTimerPendFunctionCall(PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
long BaseType_t
Definition: portmacro.h:57
#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR
Definition: timers.h:68
#define pdPASS
Definition: projdefs.h:48
#define listGET_OWNER_OF_HEAD_ENTRY(pxList)
Definition: list.h:307
#define configTIMER_TASK_STACK_DEPTH
void * TaskHandle_t
Definition: task.h:62
void * QueueHandle_t
Definition: queue.h:47
#define tmrCOMMAND_START_FROM_ISR
Definition: timers.h:65
TickType_t xTimerGetPeriod(TimerHandle_t xTimer) PRIVILEGED_FUNCTION
struct xSTATIC_TIMER StaticTimer_t
void vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION
Definition: list.c:104
#define portYIELD_WITHIN_API
Definition: FreeRTOS.h:723
#define pdFALSE
Definition: projdefs.h:45
#define tmrCOMMAND_EXECUTE_CALLBACK
Definition: timers.h:56
#define tmrFIRST_FROM_ISR_COMMAND
Definition: timers.h:64
BaseType_t xTaskResumeAll(void) PRIVILEGED_FUNCTION
Definition: tasks.c:2107
BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION
#define taskENTER_CRITICAL()
Definition: task.h:179
#define tmrCOMMAND_RESET
Definition: timers.h:59
const char * pcTimerGetName(TimerHandle_t xTimer) PRIVILEGED_FUNCTION
#define PRIVILEGED_FUNCTION
Definition: mpu_wrappers.h:174
void vTimerSetTimerID(TimerHandle_t xTimer, void *pvNewID) PRIVILEGED_FUNCTION
#define mtCOVERAGE_TEST_MARKER()
Definition: FreeRTOS.h:787
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR
Definition: timers.h:55
TickType_t xTimerGetExpiryTime(TimerHandle_t xTimer) PRIVILEGED_FUNCTION
#define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret)
Definition: FreeRTOS.h:605
#define traceTIMER_EXPIRED(pxTimer)
Definition: FreeRTOS.h:541
BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer) PRIVILEGED_FUNCTION
void * TimerHandle_t
Definition: timers.h:77
#define traceTIMER_CREATE(pxNewTimer)
Definition: FreeRTOS.h:529
#define xQueueSendFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken)
Definition: queue.h:1215
void vListInitialise(List_t *const pxList) PRIVILEGED_FUNCTION
Definition: list.c:38
void vListInitialiseItem(ListItem_t *const pxItem) PRIVILEGED_FUNCTION
Definition: list.c:63
#define xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait)
Definition: queue.h:394
portSTACK_TYPE StackType_t
Definition: portmacro.h:56


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:05