STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
tasks.c
Go to the documentation of this file.
1 /*
2  FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
3  All rights reserved
4 
5  VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6 
7  This file is part of the FreeRTOS distribution.
8 
9  FreeRTOS is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License (version 2) as published by the
11  Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
12 
13  ***************************************************************************
14  >>! NOTE: The modification to the GPL is included to allow you to !<<
15  >>! distribute a combined work that includes FreeRTOS without being !<<
16  >>! obliged to provide the source code for proprietary components !<<
17  >>! outside of the FreeRTOS kernel. !<<
18  ***************************************************************************
19 
20  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
21  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22  FOR A PARTICULAR PURPOSE. Full license text is available on the following
23  link: http://www.freertos.org/a00114.html
24 
25  ***************************************************************************
26  * *
27  * FreeRTOS provides completely free yet professionally developed, *
28  * robust, strictly quality controlled, supported, and cross *
29  * platform software that is more than just the market leader, it *
30  * is the industry's de facto standard. *
31  * *
32  * Help yourself get started quickly while simultaneously helping *
33  * to support the FreeRTOS project by purchasing a FreeRTOS *
34  * tutorial book, reference manual, or both: *
35  * http://www.FreeRTOS.org/Documentation *
36  * *
37  ***************************************************************************
38 
39  http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
40  the FAQ page "My application does not run, what could be wrong?". Have you
41  defined configASSERT()?
42 
43  http://www.FreeRTOS.org/support - In return for receiving this top quality
44  embedded software for free we request you assist our global community by
45  participating in the support forum.
46 
47  http://www.FreeRTOS.org/training - Investing in training allows your team to
48  be as productive as possible as early as possible. Now you can receive
49  FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
50  Ltd, and the world's leading authority on the world's leading RTOS.
51 
52  http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
53  including FreeRTOS+Trace - an indispensable productivity tool, a DOS
54  compatible FAT file system, and our tiny thread aware UDP/IP stack.
55 
56  http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
57  Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
58 
59  http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
60  Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
61  licenses offer ticketed support, indemnification and commercial middleware.
62 
63  http://www.SafeRTOS.com - High Integrity Systems also provide a safety
64  engineered and independently SIL3 certified version for use in safety and
65  mission critical applications that require provable dependability.
66 
67  1 tab == 4 spaces!
68 */
69 
70 /* Standard includes. */
71 #include <stdlib.h>
72 #include <string.h>
73 
74 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
75 all the API functions to use the MPU wrappers. That should only be done when
76 task.h is included from an application file. */
77 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
78 
79 /* FreeRTOS includes. */
80 #include "FreeRTOS.h"
81 #include "task.h"
82 #include "timers.h"
83 #include "StackMacros.h"
84 
85 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
86 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
87 header files above, but not in this file, in order to generate the correct
88 privileged Vs unprivileged linkage and placement. */
89 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
90 
91 /* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting
92 functions but without including stdio.h here. */
93 #if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 )
94  /* At the bottom of this file are two optional functions that can be used
95  to generate human readable text from the raw data generated by the
96  uxTaskGetSystemState() function. Note the formatting functions are provided
97  for convenience only, and are NOT considered part of the kernel. */
98  #include <stdio.h>
99 #endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */
100 
101 /* Sanity check the configuration. */
102 #if( configUSE_TICKLESS_IDLE != 0 )
103  #if( INCLUDE_vTaskSuspend != 1 )
104  #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0
105  #endif /* INCLUDE_vTaskSuspend */
106 #endif /* configUSE_TICKLESS_IDLE */
107 
108 /*
109  * Defines the size, in words, of the stack allocated to the idle task.
110  */
111 #define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
112 
113 #if( configUSE_PREEMPTION == 0 )
114  /* If the cooperative scheduler is being used then a yield should not be
115  performed just because a higher priority task has been woken. */
116  #define taskYIELD_IF_USING_PREEMPTION()
117 #else
118  #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
119 #endif
120 
121 /* Value that can be assigned to the eNotifyState member of the TCB. */
122 typedef enum
123 {
127 } eNotifyValue;
128 
129 /*
130  * Task control block. A task control block (TCB) is allocated for each task,
131  * and stores task state information, including a pointer to the task's context
132  * (the task's run time environment, including register values)
133  */
134 typedef struct tskTaskControlBlock
135 {
136  volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
137 
138  #if ( portUSING_MPU_WRAPPERS == 1 )
139  xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
140  BaseType_t xUsingStaticallyAllocatedStack; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */
141  #endif
142 
143  ListItem_t xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
144  ListItem_t xEventListItem; /*< Used to reference a task from an event list. */
145  UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */
146  StackType_t *pxStack; /*< Points to the start of the stack. */
147  char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
148 
149  #if ( portSTACK_GROWTH > 0 )
150  StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */
151  #endif
152 
153  #if ( portCRITICAL_NESTING_IN_TCB == 1 )
154  UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
155  #endif
156 
157  #if ( configUSE_TRACE_FACILITY == 1 )
158  UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */
159  UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
160  #endif
161 
162  #if ( configUSE_MUTEXES == 1 )
163  UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
164  UBaseType_t uxMutexesHeld;
165  #endif
166 
167  #if ( configUSE_APPLICATION_TASK_TAG == 1 )
168  TaskHookFunction_t pxTaskTag;
169  #endif
170 
171  #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
172  void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
173  #endif
174 
175  #if ( configGENERATE_RUN_TIME_STATS == 1 )
176  uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
177  #endif
178 
179  #if ( configUSE_NEWLIB_REENTRANT == 1 )
180  /* Allocate a Newlib reent structure that is specific to this task.
181  Note Newlib support has been included by popular demand, but is not
182  used by the FreeRTOS maintainers themselves. FreeRTOS is not
183  responsible for resulting newlib operation. User must be familiar with
184  newlib and must provide system-wide implementations of the necessary
185  stubs. Be warned that (at the time of writing) the current newlib design
186  implements a system-wide malloc() that must be provided with locks. */
187  struct _reent xNewLib_reent;
188  #endif
189 
190  #if ( configUSE_TASK_NOTIFICATIONS == 1 )
191  volatile uint32_t ulNotifiedValue;
192  volatile eNotifyValue eNotifyState;
193  #endif
194 
195 } tskTCB;
196 
197 /* The old tskTCB name is maintained above then typedefed to the new TCB_t name
198 below to enable the use of older kernel aware debuggers. */
199 typedef tskTCB TCB_t;
200 
201 /*
202  * Some kernel aware debuggers require the data the debugger needs access to to
203  * be global, rather than file scope.
204  */
205 #ifdef portREMOVE_STATIC_QUALIFIER
206  #define static
207 #endif
208 
209 /*lint -e956 A manual analysis and inspection has been used to determine which
210 static variables must be declared volatile. */
211 
213 
214 /* Lists for ready and blocked tasks. --------------------*/
215 PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */
216 PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */
217 PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
218 PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */
219 PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
220 PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */
221 
222 #if ( INCLUDE_vTaskDelete == 1 )
223 
224  PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */
225  PRIVILEGED_DATA static volatile UBaseType_t uxTasksDeleted = ( UBaseType_t ) 0U;
226 
227 #endif
228 
229 #if ( INCLUDE_vTaskSuspend == 1 )
230 
231  PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */
232 
233 #endif
234 
235 #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
236 
237  PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */
238 
239 #endif
240 
241 /* Other file private variables. --------------------------------*/
242 PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
243 PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U;
244 PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY;
245 PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE;
246 PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U;
247 PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE;
248 PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0;
249 PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;
250 PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */
251 
252 /* Context switches are held pending while the scheduler is suspended. Also,
253 interrupts must not manipulate the xGenericListItem of a TCB, or any of the
254 lists the xGenericListItem can be referenced from, if the scheduler is suspended.
255 If an interrupt needs to unblock a task while the scheduler is suspended then it
256 moves the task's event list item into the xPendingReadyList, ready for the
257 kernel to move the task from the pending ready list into the real ready list
258 when the scheduler is unsuspended. The pending ready list itself can only be
259 accessed from a critical section. */
260 PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE;
261 
262 #if ( configGENERATE_RUN_TIME_STATS == 1 )
263 
264  PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
265  PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
266 
267 #endif
268 
269 /*lint +e956 */
270 
271 /* Debugging and trace facilities private variables and macros. ------------*/
272 
273 /*
274  * The value used to fill the stack of a task when the task is created. This
275  * is used purely for checking the high water mark for tasks.
276  */
277 #define tskSTACK_FILL_BYTE ( 0xa5U )
278 
279 /*
280  * Macros used by vListTask to indicate which state a task is in.
281  */
282 #define tskBLOCKED_CHAR ( 'B' )
283 #define tskREADY_CHAR ( 'R' )
284 #define tskDELETED_CHAR ( 'D' )
285 #define tskSUSPENDED_CHAR ( 'S' )
286 
287 /*-----------------------------------------------------------*/
288 
289 #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
290 
291  /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
292  performed in a generic way that is not optimised to any particular
293  microcontroller architecture. */
294 
295  /* uxTopReadyPriority holds the priority of the highest priority ready
296  state task. */
297  #define taskRECORD_READY_PRIORITY( uxPriority ) \
298  { \
299  if( ( uxPriority ) > uxTopReadyPriority ) \
300  { \
301  uxTopReadyPriority = ( uxPriority ); \
302  } \
303  } /* taskRECORD_READY_PRIORITY */
304 
305  /*-----------------------------------------------------------*/
306 
307  #define taskSELECT_HIGHEST_PRIORITY_TASK() \
308  { \
309  /* Find the highest priority queue that contains ready tasks. */ \
310  while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \
311  { \
312  configASSERT( uxTopReadyPriority ); \
313  --uxTopReadyPriority; \
314  } \
315  \
316  /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \
317  the same priority get an equal share of the processor time. */ \
318  listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \
319  } /* taskSELECT_HIGHEST_PRIORITY_TASK */
320 
321  /*-----------------------------------------------------------*/
322 
323  /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as
324  they are only required when a port optimised method of task selection is
325  being used. */
326  #define taskRESET_READY_PRIORITY( uxPriority )
327  #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority )
328 
329 #else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
330 
331  /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is
332  performed in a way that is tailored to the particular microcontroller
333  architecture being used. */
334 
335  /* A port optimised version is provided. Call the port defined macros. */
336  #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )
337 
338  /*-----------------------------------------------------------*/
339 
340  #define taskSELECT_HIGHEST_PRIORITY_TASK() \
341  { \
342  UBaseType_t uxTopPriority; \
343  \
344  /* Find the highest priority queue that contains ready tasks. */ \
345  portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \
346  configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \
347  listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \
348  } /* taskSELECT_HIGHEST_PRIORITY_TASK() */
349 
350  /*-----------------------------------------------------------*/
351 
352  /* A port optimised version is provided, call it only if the TCB being reset
353  is being referenced from a ready list. If it is referenced from a delayed
354  or suspended list then it won't be in a ready list. */
355  #define taskRESET_READY_PRIORITY( uxPriority ) \
356  { \
357  if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \
358  { \
359  portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \
360  } \
361  }
362 
363 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
364 
365 /*-----------------------------------------------------------*/
366 
367 /* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick
368 count overflows. */
369 #define taskSWITCH_DELAYED_LISTS() \
370 { \
371  List_t *pxTemp; \
372  \
373  /* The delayed tasks list should be empty when the lists are switched. */ \
374  configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \
375  \
376  pxTemp = pxDelayedTaskList; \
377  pxDelayedTaskList = pxOverflowDelayedTaskList; \
378  pxOverflowDelayedTaskList = pxTemp; \
379  xNumOfOverflows++; \
380  prvResetNextTaskUnblockTime(); \
381 }
382 
383 /*-----------------------------------------------------------*/
384 
385 /*
386  * Place the task represented by pxTCB into the appropriate ready list for
387  * the task. It is inserted at the end of the list.
388  */
389 #define prvAddTaskToReadyList( pxTCB ) \
390  traceMOVED_TASK_TO_READY_STATE( pxTCB ); \
391  taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
392  vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
393 /*-----------------------------------------------------------*/
394 
395 /*
396  * Several functions take an TaskHandle_t parameter that can optionally be NULL,
397  * where NULL is used to indicate that the handle of the currently executing
398  * task should be used in place of the parameter. This macro simply checks to
399  * see if the parameter is NULL and returns a pointer to the appropriate TCB.
400  */
401 #define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( TCB_t * ) pxCurrentTCB : ( TCB_t * ) ( pxHandle ) )
402 
403 /* The item value of the event list item is normally used to hold the priority
404 of the task to which it belongs (coded to allow it to be held in reverse
405 priority order). However, it is occasionally borrowed for other purposes. It
406 is important its value is not updated due to a task priority change while it is
407 being used for another purpose. The following bit definition is used to inform
408 the scheduler that the value should not be changed - in which case it is the
409 responsibility of whichever module is using the value to ensure it gets set back
410 to its original value when it is released. */
411 #if configUSE_16_BIT_TICKS == 1
412  #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U
413 #else
414  #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL
415 #endif
416 
417 /* Callback function prototypes. --------------------------*/
418 #if configCHECK_FOR_STACK_OVERFLOW > 0
419  extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
420 #endif
421 
422 #if configUSE_TICK_HOOK > 0
423  extern void vApplicationTickHook( void );
424 #endif
425 
426 /* File private functions. --------------------------------*/
427 
428 /*
429  * Utility to ready a TCB for a given task. Mainly just copies the parameters
430  * into the TCB structure.
431  */
432 static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
433 
439 #if ( INCLUDE_vTaskSuspend == 1 )
440  static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
441 #endif /* INCLUDE_vTaskSuspend */
442 
443 /*
444  * Utility to ready all the lists used by the scheduler. This is called
445  * automatically upon the creation of the first task.
446  */
447 static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
448 
449 /*
450  * The idle task, which as all tasks is implemented as a never ending loop.
451  * The idle task is automatically created and added to the ready lists upon
452  * creation of the first user task.
453  *
454  * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
455  * language extensions. The equivalent prototype for this function is:
456  *
457  * void prvIdleTask( void *pvParameters );
458  *
459  */
460 static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
461 
462 /*
463  * Utility to free all memory allocated by the scheduler to hold a TCB,
464  * including the stack pointed to by the TCB.
465  *
466  * This does not free memory allocated by the task itself (i.e. memory
467  * allocated by calls to pvPortMalloc from within the tasks application code).
468  */
469 #if ( INCLUDE_vTaskDelete == 1 )
470 
471  static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION;
472 
473 #endif
474 
475 /*
476  * Used only by the idle task. This checks to see if anything has been placed
477  * in the list of tasks waiting to be deleted. If so the task is cleaned up
478  * and its TCB deleted.
479  */
480 static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
481 
482 /*
483  * The currently executing task is entering the Blocked state. Add the task to
484  * either the current or the overflow delayed task list.
485  */
486 static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) PRIVILEGED_FUNCTION;
487 
488 /*
489  * Allocates memory from the heap for a TCB and associated stack. Checks the
490  * allocation was successful.
491  */
492 static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) PRIVILEGED_FUNCTION;
493 
494 /*
495  * Fills an TaskStatus_t structure with information on each task that is
496  * referenced from the pxList list (which may be a ready list, a delayed list,
497  * a suspended list, etc.).
498  *
499  * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
500  * NORMAL APPLICATION CODE.
501  */
502 #if ( configUSE_TRACE_FACILITY == 1 )
503 
504  static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION;
505 
506 #endif
507 
508 /*
509  * When a task is created, the stack of the task is filled with a known value.
510  * This function determines the 'high water mark' of the task stack by
511  * determining how much of the stack remains at the original preset value.
512  */
513 #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
514 
515  static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;
516 
517 #endif
518 
519 /*
520  * Return the amount of time, in ticks, that will pass before the kernel will
521  * next move a task from the Blocked state to the Running state.
522  *
523  * This conditional compilation should use inequality to 0, not equality to 1.
524  * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user
525  * defined low power mode implementations require configUSE_TICKLESS_IDLE to be
526  * set to a value other than 1.
527  */
528 #if ( configUSE_TICKLESS_IDLE != 0 )
529 
530  static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION;
531 
532 #endif
533 
534 /*
535  * Set xNextTaskUnblockTime to the time at which the next Blocked state task
536  * will exit the Blocked state.
537  */
538 static void prvResetNextTaskUnblockTime( void );
539 
540 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
541 
542  /*
543  * Helper function used to pad task names with spaces when printing out
544  * human readable tables of task information.
545  */
546  static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName );
547 
548 #endif
549 /*-----------------------------------------------------------*/
550 
551 BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
552 {
553 BaseType_t xReturn;
554 TCB_t * pxNewTCB;
556 
557  configASSERT( pxTaskCode );
558  configASSERT( ( ( uxPriority & ( UBaseType_t ) ( ~portPRIVILEGE_BIT ) ) < ( UBaseType_t ) configMAX_PRIORITIES ) );
559 
560  /* Allocate the memory required by the TCB and stack for the new task,
561  checking that the allocation was successful. */
562  pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
563 
564  if( pxNewTCB != NULL )
565  {
566  #if( portUSING_MPU_WRAPPERS == 1 )
567  /* Should the task be created in privileged mode? */
568  BaseType_t xRunPrivileged;
569  if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )
570  {
571  xRunPrivileged = pdTRUE;
572  }
573  else
574  {
575  xRunPrivileged = pdFALSE;
576  }
577  uxPriority &= ~portPRIVILEGE_BIT;
578 
579  if( puxStackBuffer != NULL )
580  {
581  /* The application provided its own stack. Note this so no
582  attempt is made to delete the stack should that task be
583  deleted. */
584  pxNewTCB->xUsingStaticallyAllocatedStack = pdTRUE;
585  }
586  else
587  {
588  /* The stack was allocated dynamically. Note this so it can be
589  deleted again if the task is deleted. */
590  pxNewTCB->xUsingStaticallyAllocatedStack = pdFALSE;
591  }
592  #endif /* portUSING_MPU_WRAPPERS == 1 */
593 
594  /* Calculate the top of stack address. This depends on whether the
595  stack grows from high memory to low (as per the 80x86) or vice versa.
596  portSTACK_GROWTH is used to make the result positive or negative as
597  required by the port. */
598  #if( portSTACK_GROWTH < 0 )
599  {
600  pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );
601  pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */
602 
603  /* Check the alignment of the calculated top of stack is correct. */
604  configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
605  }
606  #else /* portSTACK_GROWTH */
607  {
608  pxTopOfStack = pxNewTCB->pxStack;
609 
610  /* Check the alignment of the stack buffer is correct. */
611  configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
612 
613  /* If we want to use stack checking on architectures that use
614  a positive stack growth direction then we also need to store the
615  other extreme of the stack space. */
616  pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
617  }
618  #endif /* portSTACK_GROWTH */
619 
620  /* Setup the newly allocated TCB with the initial state of the task. */
621  prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
622 
623  /* Initialize the TCB stack to look as if the task was already running,
624  but had been interrupted by the scheduler. The return address is set
625  to the start of the task function. Once the stack has been initialised
626  the top of stack variable is updated. */
627  #if( portUSING_MPU_WRAPPERS == 1 )
628  {
629  pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
630  }
631  #else /* portUSING_MPU_WRAPPERS */
632  {
633  pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
634  }
635  #endif /* portUSING_MPU_WRAPPERS */
636 
637  if( ( void * ) pxCreatedTask != NULL )
638  {
639  /* Pass the TCB out - in an anonymous way. The calling function/
640  task can use this as a handle to delete the task later if
641  required.*/
642  *pxCreatedTask = ( TaskHandle_t ) pxNewTCB;
643  }
644  else
645  {
647  }
648 
649  /* Ensure interrupts don't access the task lists while they are being
650  updated. */
652  {
653  uxCurrentNumberOfTasks++;
654  if( pxCurrentTCB == NULL )
655  {
656  /* There are no other tasks, or all the other tasks are in
657  the suspended state - make this the current task. */
658  pxCurrentTCB = pxNewTCB;
659 
660  if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
661  {
662  /* This is the first task to be created so do the preliminary
663  initialization required. We will not recover if this call
664  fails, but we will report the failure. */
665  prvInitialiseTaskLists();
666  }
667  else
668  {
670  }
671  }
672  else
673  {
674  /* If the scheduler is not already running, make this task the
675  current task if it is the highest priority task to be created
676  so far. */
677  if( xSchedulerRunning == pdFALSE )
678  {
679  if( pxCurrentTCB->uxPriority <= uxPriority )
680  {
681  pxCurrentTCB = pxNewTCB;
682  }
683  else
684  {
686  }
687  }
688  else
689  {
691  }
692  }
693 
694  uxTaskNumber++;
695 
696  #if ( configUSE_TRACE_FACILITY == 1 )
697  {
698  /* Add a counter into the TCB for tracing only. */
699  pxNewTCB->uxTCBNumber = uxTaskNumber;
700  }
701  #endif /* configUSE_TRACE_FACILITY */
702  traceTASK_CREATE( pxNewTCB );
703 
704  prvAddTaskToReadyList( pxNewTCB );
705 
706  xReturn = pdPASS;
707  portSETUP_TCB( pxNewTCB );
708  }
710  }
711  else
712  {
715  }
716 
717  if( xReturn == pdPASS )
718  {
719  if( xSchedulerRunning != pdFALSE )
720  {
721  /* If the created task is of a higher priority than the current task
722  then it should run now. */
723  if( pxCurrentTCB->uxPriority < uxPriority )
724  {
726  }
727  else
728  {
730  }
731  }
732  else
733  {
735  }
736  }
737 
738  return xReturn;
739 }
740 /*-----------------------------------------------------------*/
741 
742 #if ( INCLUDE_vTaskDelete == 1 )
743 
744  void vTaskDelete( TaskHandle_t xTaskToDelete )
745  {
746  TCB_t *pxTCB;
747 
749  {
750  /* If null is passed in here then it is the calling task that is
751  being deleted. */
752  pxTCB = prvGetTCBFromHandle( xTaskToDelete );
753 
754  /* Remove task from the ready list and place in the termination list.
755  This will stop the task from be scheduled. The idle task will check
756  the termination list and free up any memory allocated by the
757  scheduler for the TCB and stack. */
758  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
759  {
761  }
762  else
763  {
765  }
766 
767  /* Is the task waiting on an event also? */
768  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
769  {
770  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
771  }
772  else
773  {
775  }
776 
777  vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );
778 
779  /* Increment the ucTasksDeleted variable so the idle task knows
780  there is a task that has been deleted and that it should therefore
781  check the xTasksWaitingTermination list. */
782  ++uxTasksDeleted;
783 
784  /* Increment the uxTaskNumberVariable also so kernel aware debuggers
785  can detect that the task lists need re-generating. */
786  uxTaskNumber++;
787 
788  traceTASK_DELETE( pxTCB );
789  }
791 
792  /* Force a reschedule if it is the currently running task that has just
793  been deleted. */
794  if( xSchedulerRunning != pdFALSE )
795  {
796  if( pxTCB == pxCurrentTCB )
797  {
798  configASSERT( uxSchedulerSuspended == 0 );
799 
800  /* The pre-delete hook is primarily for the Windows simulator,
801  in which Windows specific clean up operations are performed,
802  after which it is not possible to yield away from this task -
803  hence xYieldPending is used to latch that a context switch is
804  required. */
805  portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
807  }
808  else
809  {
810  /* Reset the next expected unblock time in case it referred to
811  the task that has just been deleted. */
813  {
814  prvResetNextTaskUnblockTime();
815  }
817  }
818  }
819  }
820 
821 #endif /* INCLUDE_vTaskDelete */
822 /*-----------------------------------------------------------*/
823 
824 #if ( INCLUDE_vTaskDelayUntil == 1 )
825 
826  void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
827  {
828  TickType_t xTimeToWake;
829  BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
830 
831  configASSERT( pxPreviousWakeTime );
832  configASSERT( ( xTimeIncrement > 0U ) );
833  configASSERT( uxSchedulerSuspended == 0 );
834 
835  vTaskSuspendAll();
836  {
837  /* Minor optimisation. The tick count cannot change in this
838  block. */
839  const TickType_t xConstTickCount = xTickCount;
840 
841  /* Generate the tick time at which the task wants to wake. */
842  xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
843 
844  if( xConstTickCount < *pxPreviousWakeTime )
845  {
846  /* The tick count has overflowed since this function was
847  lasted called. In this case the only time we should ever
848  actually delay is if the wake time has also overflowed,
849  and the wake time is greater than the tick time. When this
850  is the case it is as if neither time had overflowed. */
851  if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
852  {
853  xShouldDelay = pdTRUE;
854  }
855  else
856  {
858  }
859  }
860  else
861  {
862  /* The tick time has not overflowed. In this case we will
863  delay if either the wake time has overflowed, and/or the
864  tick time is less than the wake time. */
865  if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
866  {
867  xShouldDelay = pdTRUE;
868  }
869  else
870  {
872  }
873  }
874 
875  /* Update the wake time ready for the next call. */
876  *pxPreviousWakeTime = xTimeToWake;
877 
878  if( xShouldDelay != pdFALSE )
879  {
881 
882  /* Remove the task from the ready list before adding it to the
883  blocked list as the same list item is used for both lists. */
884  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
885  {
886  /* The current task must be in a ready list, so there is
887  no need to check, and the port reset macro can be called
888  directly. */
889  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
890  }
891  else
892  {
894  }
895 
896  prvAddCurrentTaskToDelayedList( xTimeToWake );
897  }
898  else
899  {
901  }
902  }
903  xAlreadyYielded = xTaskResumeAll();
904 
905  /* Force a reschedule if xTaskResumeAll has not already done so, we may
906  have put ourselves to sleep. */
907  if( xAlreadyYielded == pdFALSE )
908  {
910  }
911  else
912  {
914  }
915  }
916 
917 #endif /* INCLUDE_vTaskDelayUntil */
918 /*-----------------------------------------------------------*/
919 
920 #if ( INCLUDE_vTaskDelay == 1 )
921 
922  void vTaskDelay( const TickType_t xTicksToDelay )
923  {
924  TickType_t xTimeToWake;
925  BaseType_t xAlreadyYielded = pdFALSE;
926 
927 
928  /* A delay time of zero just forces a reschedule. */
929  if( xTicksToDelay > ( TickType_t ) 0U )
930  {
931  configASSERT( uxSchedulerSuspended == 0 );
932  vTaskSuspendAll();
933  {
934  traceTASK_DELAY();
935 
936  /* A task that is removed from the event list while the
937  scheduler is suspended will not get placed in the ready
938  list or removed from the blocked list until the scheduler
939  is resumed.
940 
941  This task cannot be in an event list as it is the currently
942  executing task. */
943 
944  /* Calculate the time to wake - this may overflow but this is
945  not a problem. */
946  xTimeToWake = xTickCount + xTicksToDelay;
947 
948  /* We must remove ourselves from the ready list before adding
949  ourselves to the blocked list as the same list item is used for
950  both lists. */
951  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
952  {
953  /* The current task must be in a ready list, so there is
954  no need to check, and the port reset macro can be called
955  directly. */
956  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
957  }
958  else
959  {
961  }
962  prvAddCurrentTaskToDelayedList( xTimeToWake );
963  }
964  xAlreadyYielded = xTaskResumeAll();
965  }
966  else
967  {
969  }
970 
971  /* Force a reschedule if xTaskResumeAll has not already done so, we may
972  have put ourselves to sleep. */
973  if( xAlreadyYielded == pdFALSE )
974  {
976  }
977  else
978  {
980  }
981  }
982 
983 #endif /* INCLUDE_vTaskDelay */
984 /*-----------------------------------------------------------*/
985 
986 #if ( INCLUDE_eTaskGetState == 1 )
987 
989  {
990  eTaskState eReturn;
991  List_t *pxStateList;
992  const TCB_t * const pxTCB = ( TCB_t * ) xTask;
993 
994  configASSERT( pxTCB );
995 
996  if( pxTCB == pxCurrentTCB )
997  {
998  /* The task calling this function is querying its own state. */
999  eReturn = eRunning;
1000  }
1001  else
1002  {
1004  {
1005  pxStateList = ( List_t * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) );
1006  }
1008 
1009  if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) )
1010  {
1011  /* The task being queried is referenced from one of the Blocked
1012  lists. */
1013  eReturn = eBlocked;
1014  }
1015 
1016  #if ( INCLUDE_vTaskSuspend == 1 )
1017  else if( pxStateList == &xSuspendedTaskList )
1018  {
1019  /* The task being queried is referenced from the suspended
1020  list. Is it genuinely suspended or is it block
1021  indefinitely? */
1022  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
1023  {
1024  eReturn = eSuspended;
1025  }
1026  else
1027  {
1028  eReturn = eBlocked;
1029  }
1030  }
1031  #endif
1032 
1033  #if ( INCLUDE_vTaskDelete == 1 )
1034  else if( pxStateList == &xTasksWaitingTermination )
1035  {
1036  /* The task being queried is referenced from the deleted
1037  tasks list. */
1038  eReturn = eDeleted;
1039  }
1040  #endif
1041 
1042  else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */
1043  {
1044  /* If the task is not in any other state, it must be in the
1045  Ready (including pending ready) state. */
1046  eReturn = eReady;
1047  }
1048  }
1049 
1050  return eReturn;
1051  } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */
1052 
1053 #endif /* INCLUDE_eTaskGetState */
1054 /*-----------------------------------------------------------*/
1055 
1056 #if ( INCLUDE_uxTaskPriorityGet == 1 )
1057 
1059  {
1060  TCB_t *pxTCB;
1061  UBaseType_t uxReturn;
1062 
1064  {
1065  /* If null is passed in here then it is the priority of the that
1066  called uxTaskPriorityGet() that is being queried. */
1067  pxTCB = prvGetTCBFromHandle( xTask );
1068  uxReturn = pxTCB->uxPriority;
1069  }
1071 
1072  return uxReturn;
1073  }
1074 
1075 #endif /* INCLUDE_uxTaskPriorityGet */
1076 /*-----------------------------------------------------------*/
1077 
1078 #if ( INCLUDE_uxTaskPriorityGet == 1 )
1079 
1081  {
1082  TCB_t *pxTCB;
1083  UBaseType_t uxReturn, uxSavedInterruptState;
1084 
1085  /* RTOS ports that support interrupt nesting have the concept of a
1086  maximum system call (or maximum API call) interrupt priority.
1087  Interrupts that are above the maximum system call priority are keep
1088  permanently enabled, even when the RTOS kernel is in a critical section,
1089  but cannot make any calls to FreeRTOS API functions. If configASSERT()
1090  is defined in FreeRTOSConfig.h then
1091  portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
1092  failure if a FreeRTOS API function is called from an interrupt that has
1093  been assigned a priority above the configured maximum system call
1094  priority. Only FreeRTOS functions that end in FromISR can be called
1095  from interrupts that have been assigned a priority at or (logically)
1096  below the maximum system call interrupt priority. FreeRTOS maintains a
1097  separate interrupt safe API to ensure interrupt entry is as fast and as
1098  simple as possible. More information (albeit Cortex-M specific) is
1099  provided on the following link:
1100  http://www.freertos.org/RTOS-Cortex-M3-M4.html */
1102 
1103  uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR();
1104  {
1105  /* If null is passed in here then it is the priority of the calling
1106  task that is being queried. */
1107  pxTCB = prvGetTCBFromHandle( xTask );
1108  uxReturn = pxTCB->uxPriority;
1109  }
1110  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState );
1111 
1112  return uxReturn;
1113  }
1114 
1115 #endif /* INCLUDE_uxTaskPriorityGet */
1116 /*-----------------------------------------------------------*/
1117 
1118 #if ( INCLUDE_vTaskPrioritySet == 1 )
1119 
1120  void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
1121  {
1122  TCB_t *pxTCB;
1123  UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry;
1124  BaseType_t xYieldRequired = pdFALSE;
1125 
1126  configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
1127 
1128  /* Ensure the new priority is valid. */
1129  if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
1130  {
1131  uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
1132  }
1133  else
1134  {
1136  }
1137 
1139  {
1140  /* If null is passed in here then it is the priority of the calling
1141  task that is being changed. */
1142  pxTCB = prvGetTCBFromHandle( xTask );
1143 
1144  traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );
1145 
1146  #if ( configUSE_MUTEXES == 1 )
1147  {
1148  uxCurrentBasePriority = pxTCB->uxBasePriority;
1149  }
1150  #else
1151  {
1152  uxCurrentBasePriority = pxTCB->uxPriority;
1153  }
1154  #endif
1155 
1156  if( uxCurrentBasePriority != uxNewPriority )
1157  {
1158  /* The priority change may have readied a task of higher
1159  priority than the calling task. */
1160  if( uxNewPriority > uxCurrentBasePriority )
1161  {
1162  if( pxTCB != pxCurrentTCB )
1163  {
1164  /* The priority of a task other than the currently
1165  running task is being raised. Is the priority being
1166  raised above that of the running task? */
1167  if( uxNewPriority >= pxCurrentTCB->uxPriority )
1168  {
1169  xYieldRequired = pdTRUE;
1170  }
1171  else
1172  {
1174  }
1175  }
1176  else
1177  {
1178  /* The priority of the running task is being raised,
1179  but the running task must already be the highest
1180  priority task able to run so no yield is required. */
1181  }
1182  }
1183  else if( pxTCB == pxCurrentTCB )
1184  {
1185  /* Setting the priority of the running task down means
1186  there may now be another task of higher priority that
1187  is ready to execute. */
1188  xYieldRequired = pdTRUE;
1189  }
1190  else
1191  {
1192  /* Setting the priority of any other task down does not
1193  require a yield as the running task must be above the
1194  new priority of the task being modified. */
1195  }
1196 
1197  /* Remember the ready list the task might be referenced from
1198  before its uxPriority member is changed so the
1199  taskRESET_READY_PRIORITY() macro can function correctly. */
1200  uxPriorityUsedOnEntry = pxTCB->uxPriority;
1201 
1202  #if ( configUSE_MUTEXES == 1 )
1203  {
1204  /* Only change the priority being used if the task is not
1205  currently using an inherited priority. */
1206  if( pxTCB->uxBasePriority == pxTCB->uxPriority )
1207  {
1208  pxTCB->uxPriority = uxNewPriority;
1209  }
1210  else
1211  {
1213  }
1214 
1215  /* The base priority gets set whatever. */
1216  pxTCB->uxBasePriority = uxNewPriority;
1217  }
1218  #else
1219  {
1220  pxTCB->uxPriority = uxNewPriority;
1221  }
1222  #endif
1223 
1224  /* Only reset the event list item value if the value is not
1225  being used for anything else. */
1227  {
1228  listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
1229  }
1230  else
1231  {
1233  }
1234 
1235  /* If the task is in the blocked or suspended list we need do
1236  nothing more than change it's priority variable. However, if
1237  the task is in a ready list it needs to be removed and placed
1238  in the list appropriate to its new priority. */
1239  if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
1240  {
1241  /* The task is currently in its ready list - remove before adding
1242  it to it's new ready list. As we are in a critical section we
1243  can do this even if the scheduler is suspended. */
1244  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
1245  {
1246  /* It is known that the task is in its ready list so
1247  there is no need to check again and the port level
1248  reset macro can be called directly. */
1249  portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority );
1250  }
1251  else
1252  {
1254  }
1255  prvAddTaskToReadyList( pxTCB );
1256  }
1257  else
1258  {
1260  }
1261 
1262  if( xYieldRequired == pdTRUE )
1263  {
1265  }
1266  else
1267  {
1269  }
1270 
1271  /* Remove compiler warning about unused variables when the port
1272  optimised task selection is not being used. */
1273  ( void ) uxPriorityUsedOnEntry;
1274  }
1275  }
1277  }
1278 
1279 #endif /* INCLUDE_vTaskPrioritySet */
1280 /*-----------------------------------------------------------*/
1281 
1282 #if ( INCLUDE_vTaskSuspend == 1 )
1283 
1284  void vTaskSuspend( TaskHandle_t xTaskToSuspend )
1285  {
1286  TCB_t *pxTCB;
1287 
1289  {
1290  /* If null is passed in here then it is the running task that is
1291  being suspended. */
1292  pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
1293 
1294  traceTASK_SUSPEND( pxTCB );
1295 
1296  /* Remove task from the ready/delayed list and place in the
1297  suspended list. */
1298  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
1299  {
1301  }
1302  else
1303  {
1305  }
1306 
1307  /* Is the task waiting on an event also? */
1308  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
1309  {
1310  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
1311  }
1312  else
1313  {
1315  }
1316 
1317  vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
1318  }
1320 
1321  if( pxTCB == pxCurrentTCB )
1322  {
1323  if( xSchedulerRunning != pdFALSE )
1324  {
1325  /* The current task has just been suspended. */
1326  configASSERT( uxSchedulerSuspended == 0 );
1328  }
1329  else
1330  {
1331  /* The scheduler is not running, but the task that was pointed
1332  to by pxCurrentTCB has just been suspended and pxCurrentTCB
1333  must be adjusted to point to a different task. */
1334  if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
1335  {
1336  /* No other tasks are ready, so set pxCurrentTCB back to
1337  NULL so when the next task is created pxCurrentTCB will
1338  be set to point to it no matter what its relative priority
1339  is. */
1340  pxCurrentTCB = NULL;
1341  }
1342  else
1343  {
1345  }
1346  }
1347  }
1348  else
1349  {
1350  if( xSchedulerRunning != pdFALSE )
1351  {
1352  /* A task other than the currently running task was suspended,
1353  reset the next expected unblock time in case it referred to the
1354  task that is now in the Suspended state. */
1356  {
1357  prvResetNextTaskUnblockTime();
1358  }
1360  }
1361  else
1362  {
1364  }
1365  }
1366  }
1367 
1368 #endif /* INCLUDE_vTaskSuspend */
1369 /*-----------------------------------------------------------*/
1370 
1371 #if ( INCLUDE_vTaskSuspend == 1 )
1372 
1373  static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask )
1374  {
1375  BaseType_t xReturn = pdFALSE;
1376  const TCB_t * const pxTCB = ( TCB_t * ) xTask;
1377 
1378  /* Accesses xPendingReadyList so must be called from a critical
1379  section. */
1380 
1381  /* It does not make sense to check if the calling task is suspended. */
1382  configASSERT( xTask );
1383 
1384  /* Is the task being resumed actually in the suspended list? */
1385  if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
1386  {
1387  /* Has the task already been resumed from within an ISR? */
1388  if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE )
1389  {
1390  /* Is it in the suspended list because it is in the Suspended
1391  state, or because is is blocked with no timeout? */
1392  if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE )
1393  {
1394  xReturn = pdTRUE;
1395  }
1396  else
1397  {
1399  }
1400  }
1401  else
1402  {
1404  }
1405  }
1406  else
1407  {
1409  }
1410 
1411  return xReturn;
1412  } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */
1413 
1414 #endif /* INCLUDE_vTaskSuspend */
1415 /*-----------------------------------------------------------*/
1416 
1417 #if ( INCLUDE_vTaskSuspend == 1 )
1418 
1419  void vTaskResume( TaskHandle_t xTaskToResume )
1420  {
1421  TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
1422 
1423  /* It does not make sense to resume the calling task. */
1424  configASSERT( xTaskToResume );
1425 
1426  /* The parameter cannot be NULL as it is impossible to resume the
1427  currently executing task. */
1428  if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
1429  {
1431  {
1432  if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )
1433  {
1434  traceTASK_RESUME( pxTCB );
1435 
1436  /* As we are in a critical section we can access the ready
1437  lists even if the scheduler is suspended. */
1438  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1439  prvAddTaskToReadyList( pxTCB );
1440 
1441  /* We may have just resumed a higher priority task. */
1442  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1443  {
1444  /* This yield may not cause the task just resumed to run,
1445  but will leave the lists in the correct state for the
1446  next yield. */
1448  }
1449  else
1450  {
1452  }
1453  }
1454  else
1455  {
1457  }
1458  }
1460  }
1461  else
1462  {
1464  }
1465  }
1466 
1467 #endif /* INCLUDE_vTaskSuspend */
1468 
1469 /*-----------------------------------------------------------*/
1470 
1471 #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
1472 
1473  BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
1474  {
1475  BaseType_t xYieldRequired = pdFALSE;
1476  TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
1477  UBaseType_t uxSavedInterruptStatus;
1478 
1479  configASSERT( xTaskToResume );
1480 
1481  /* RTOS ports that support interrupt nesting have the concept of a
1482  maximum system call (or maximum API call) interrupt priority.
1483  Interrupts that are above the maximum system call priority are keep
1484  permanently enabled, even when the RTOS kernel is in a critical section,
1485  but cannot make any calls to FreeRTOS API functions. If configASSERT()
1486  is defined in FreeRTOSConfig.h then
1487  portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
1488  failure if a FreeRTOS API function is called from an interrupt that has
1489  been assigned a priority above the configured maximum system call
1490  priority. Only FreeRTOS functions that end in FromISR can be called
1491  from interrupts that have been assigned a priority at or (logically)
1492  below the maximum system call interrupt priority. FreeRTOS maintains a
1493  separate interrupt safe API to ensure interrupt entry is as fast and as
1494  simple as possible. More information (albeit Cortex-M specific) is
1495  provided on the following link:
1496  http://www.freertos.org/RTOS-Cortex-M3-M4.html */
1498 
1499  uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
1500  {
1501  if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )
1502  {
1503  traceTASK_RESUME_FROM_ISR( pxTCB );
1504 
1505  /* Check the ready lists can be accessed. */
1506  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
1507  {
1508  /* Ready lists can be accessed so move the task from the
1509  suspended list to the ready list directly. */
1510  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1511  {
1512  xYieldRequired = pdTRUE;
1513  }
1514  else
1515  {
1517  }
1518 
1519  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1520  prvAddTaskToReadyList( pxTCB );
1521  }
1522  else
1523  {
1524  /* The delayed or ready lists cannot be accessed so the task
1525  is held in the pending ready list until the scheduler is
1526  unsuspended. */
1527  vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
1528  }
1529  }
1530  else
1531  {
1533  }
1534  }
1535  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
1536 
1537  return xYieldRequired;
1538  }
1539 
1540 #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */
1541 /*-----------------------------------------------------------*/
1542 
1544 {
1545 BaseType_t xReturn;
1546 
1547  /* Add the idle task at the lowest priority. */
1548  #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
1549  {
1550  /* Create the idle task, storing its handle in xIdleTaskHandle so it can
1551  be returned by the xTaskGetIdleTaskHandle() function. */
1552  xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
1553  }
1554  #else
1555  {
1556  /* Create the idle task without storing its handle. */
1557  xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
1558  }
1559  #endif /* INCLUDE_xTaskGetIdleTaskHandle */
1560 
1561  #if ( configUSE_TIMERS == 1 )
1562  {
1563  if( xReturn == pdPASS )
1564  {
1565  xReturn = xTimerCreateTimerTask();
1566  }
1567  else
1568  {
1570  }
1571  }
1572  #endif /* configUSE_TIMERS */
1573 
1574  if( xReturn == pdPASS )
1575  {
1576  /* Interrupts are turned off here, to ensure a tick does not occur
1577  before or during the call to xPortStartScheduler(). The stacks of
1578  the created tasks contain a status word with interrupts switched on
1579  so interrupts will automatically get re-enabled when the first task
1580  starts to run. */
1582 
1583  #if ( configUSE_NEWLIB_REENTRANT == 1 )
1584  {
1585  /* Switch Newlib's _impure_ptr variable to point to the _reent
1586  structure specific to the task that will run first. */
1587  _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
1588  }
1589  #endif /* configUSE_NEWLIB_REENTRANT */
1590 
1591  xNextTaskUnblockTime = portMAX_DELAY;
1592  xSchedulerRunning = pdTRUE;
1593  xTickCount = ( TickType_t ) 0U;
1594 
1595  /* If configGENERATE_RUN_TIME_STATS is defined then the following
1596  macro must be defined to configure the timer/counter used to generate
1597  the run time counter time base. */
1599 
1600  /* Setting up the timer tick is hardware specific and thus in the
1601  portable interface. */
1602  if( xPortStartScheduler() != pdFALSE )
1603  {
1604  /* Should not reach here as if the scheduler is running the
1605  function will not return. */
1606  }
1607  else
1608  {
1609  /* Should only reach here if a task calls xTaskEndScheduler(). */
1610  }
1611  }
1612  else
1613  {
1614  /* This line will only be reached if the kernel could not be started,
1615  because there was not enough FreeRTOS heap to create the idle task
1616  or the timer task. */
1617  configASSERT( xReturn );
1618  }
1619 }
1620 /*-----------------------------------------------------------*/
1621 
1622 void vTaskEndScheduler( void )
1623 {
1624  /* Stop the scheduler interrupts and call the portable scheduler end
1625  routine so the original ISRs can be restored if necessary. The port
1626  layer must ensure interrupts enable bit is left in the correct state. */
1628  xSchedulerRunning = pdFALSE;
1630 }
1631 /*----------------------------------------------------------*/
1632 
1633 void vTaskSuspendAll( void )
1634 {
1635  /* A critical section is not required as the variable is of type
1636  BaseType_t. Please read Richard Barry's reply in the following link to a
1637  post in the FreeRTOS support forum before reporting this as a bug! -
1638  http://goo.gl/wu4acr */
1639  ++uxSchedulerSuspended;
1640 }
1641 /*----------------------------------------------------------*/
1642 
1643 #if ( configUSE_TICKLESS_IDLE != 0 )
1644 
1645  static TickType_t prvGetExpectedIdleTime( void )
1646  {
1647  TickType_t xReturn;
1648 
1650  {
1651  xReturn = 0;
1652  }
1653  else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 )
1654  {
1655  /* There are other idle priority tasks in the ready state. If
1656  time slicing is used then the very next tick interrupt must be
1657  processed. */
1658  xReturn = 0;
1659  }
1660  else
1661  {
1662  xReturn = xNextTaskUnblockTime - xTickCount;
1663  }
1664 
1665  return xReturn;
1666  }
1667 
1668 #endif /* configUSE_TICKLESS_IDLE */
1669 /*----------------------------------------------------------*/
1670 
1672 {
1673 TCB_t *pxTCB;
1674 BaseType_t xAlreadyYielded = pdFALSE;
1675 
1676  /* If uxSchedulerSuspended is zero then this function does not match a
1677  previous call to vTaskSuspendAll(). */
1678  configASSERT( uxSchedulerSuspended );
1679 
1680  /* It is possible that an ISR caused a task to be removed from an event
1681  list while the scheduler was suspended. If this was the case then the
1682  removed task will have been added to the xPendingReadyList. Once the
1683  scheduler has been resumed it is safe to move all the pending ready
1684  tasks from this list into their appropriate ready list. */
1686  {
1687  --uxSchedulerSuspended;
1688 
1689  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
1690  {
1691  if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U )
1692  {
1693  /* Move any readied tasks from the pending list into the
1694  appropriate ready list. */
1695  while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
1696  {
1697  pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
1698  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
1699  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1700  prvAddTaskToReadyList( pxTCB );
1701 
1702  /* If the moved task has a priority higher than the current
1703  task then a yield must be performed. */
1704  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1705  {
1706  xYieldPending = pdTRUE;
1707  }
1708  else
1709  {
1711  }
1712  }
1713 
1714  /* If any ticks occurred while the scheduler was suspended then
1715  they should be processed now. This ensures the tick count does
1716  not slip, and that any delayed tasks are resumed at the correct
1717  time. */
1718  if( uxPendedTicks > ( UBaseType_t ) 0U )
1719  {
1720  while( uxPendedTicks > ( UBaseType_t ) 0U )
1721  {
1722  if( xTaskIncrementTick() != pdFALSE )
1723  {
1724  xYieldPending = pdTRUE;
1725  }
1726  else
1727  {
1729  }
1730  --uxPendedTicks;
1731  }
1732  }
1733  else
1734  {
1736  }
1737 
1738  if( xYieldPending == pdTRUE )
1739  {
1740  #if( configUSE_PREEMPTION != 0 )
1741  {
1742  xAlreadyYielded = pdTRUE;
1743  }
1744  #endif
1746  }
1747  else
1748  {
1750  }
1751  }
1752  }
1753  else
1754  {
1756  }
1757  }
1759 
1760  return xAlreadyYielded;
1761 }
1762 /*-----------------------------------------------------------*/
1763 
1765 {
1766 TickType_t xTicks;
1767 
1768  /* Critical section required if running on a 16 bit processor. */
1770  {
1771  xTicks = xTickCount;
1772  }
1774 
1775  return xTicks;
1776 }
1777 /*-----------------------------------------------------------*/
1778 
1780 {
1781 TickType_t xReturn;
1782 UBaseType_t uxSavedInterruptStatus;
1783 
1784  /* RTOS ports that support interrupt nesting have the concept of a maximum
1785  system call (or maximum API call) interrupt priority. Interrupts that are
1786  above the maximum system call priority are kept permanently enabled, even
1787  when the RTOS kernel is in a critical section, but cannot make any calls to
1788  FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
1789  then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
1790  failure if a FreeRTOS API function is called from an interrupt that has been
1791  assigned a priority above the configured maximum system call priority.
1792  Only FreeRTOS functions that end in FromISR can be called from interrupts
1793  that have been assigned a priority at or (logically) below the maximum
1794  system call interrupt priority. FreeRTOS maintains a separate interrupt
1795  safe API to ensure interrupt entry is as fast and as simple as possible.
1796  More information (albeit Cortex-M specific) is provided on the following
1797  link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
1799 
1800  uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR();
1801  {
1802  xReturn = xTickCount;
1803  }
1804  portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
1805 
1806  return xReturn;
1807 }
1808 /*-----------------------------------------------------------*/
1809 
1811 {
1812  /* A critical section is not required because the variables are of type
1813  BaseType_t. */
1814  return uxCurrentNumberOfTasks;
1815 }
1816 /*-----------------------------------------------------------*/
1817 
1818 #if ( INCLUDE_pcTaskGetTaskName == 1 )
1819 
1820  char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
1821  {
1822  TCB_t *pxTCB;
1823 
1824  /* If null is passed in here then the name of the calling task is being queried. */
1825  pxTCB = prvGetTCBFromHandle( xTaskToQuery );
1826  configASSERT( pxTCB );
1827  return &( pxTCB->pcTaskName[ 0 ] );
1828  }
1829 
1830 #endif /* INCLUDE_pcTaskGetTaskName */
1831 /*-----------------------------------------------------------*/
1832 
1833 #if ( configUSE_TRACE_FACILITY == 1 )
1834 
1835  UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime )
1836  {
1837  UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
1838 
1839  vTaskSuspendAll();
1840  {
1841  /* Is there a space in the array for each task in the system? */
1842  if( uxArraySize >= uxCurrentNumberOfTasks )
1843  {
1844  /* Fill in an TaskStatus_t structure with information on each
1845  task in the Ready state. */
1846  do
1847  {
1848  uxQueue--;
1849  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady );
1850 
1851  } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
1852 
1853  /* Fill in an TaskStatus_t structure with information on each
1854  task in the Blocked state. */
1855  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked );
1856  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked );
1857 
1858  #if( INCLUDE_vTaskDelete == 1 )
1859  {
1860  /* Fill in an TaskStatus_t structure with information on
1861  each task that has been deleted but not yet cleaned up. */
1862  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted );
1863  }
1864  #endif
1865 
1866  #if ( INCLUDE_vTaskSuspend == 1 )
1867  {
1868  /* Fill in an TaskStatus_t structure with information on
1869  each task in the Suspended state. */
1870  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended );
1871  }
1872  #endif
1873 
1874  #if ( configGENERATE_RUN_TIME_STATS == 1)
1875  {
1876  if( pulTotalRunTime != NULL )
1877  {
1878  #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
1879  portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) );
1880  #else
1881  *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
1882  #endif
1883  }
1884  }
1885  #else
1886  {
1887  if( pulTotalRunTime != NULL )
1888  {
1889  *pulTotalRunTime = 0;
1890  }
1891  }
1892  #endif
1893  }
1894  else
1895  {
1897  }
1898  }
1899  ( void ) xTaskResumeAll();
1900 
1901  return uxTask;
1902  }
1903 
1904 #endif /* configUSE_TRACE_FACILITY */
1905 /*----------------------------------------------------------*/
1906 
1907 #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
1908 
1910  {
1911  /* If xTaskGetIdleTaskHandle() is called before the scheduler has been
1912  started, then xIdleTaskHandle will be NULL. */
1913  configASSERT( ( xIdleTaskHandle != NULL ) );
1914  return xIdleTaskHandle;
1915  }
1916 
1917 #endif /* INCLUDE_xTaskGetIdleTaskHandle */
1918 /*----------------------------------------------------------*/
1919 
1920 /* This conditional compilation should use inequality to 0, not equality to 1.
1921 This is to ensure vTaskStepTick() is available when user defined low power mode
1922 implementations require configUSE_TICKLESS_IDLE to be set to a value other than
1923 1. */
1924 #if ( configUSE_TICKLESS_IDLE != 0 )
1925 
1926  void vTaskStepTick( const TickType_t xTicksToJump )
1927  {
1928  /* Correct the tick count value after a period during which the tick
1929  was suppressed. Note this does *not* call the tick hook function for
1930  each stepped tick. */
1931  configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime );
1932  xTickCount += xTicksToJump;
1933  traceINCREASE_TICK_COUNT( xTicksToJump );
1934  }
1935 
1936 #endif /* configUSE_TICKLESS_IDLE */
1937 /*----------------------------------------------------------*/
1938 
1940 {
1941 TCB_t * pxTCB;
1942 TickType_t xItemValue;
1943 BaseType_t xSwitchRequired = pdFALSE;
1944 
1945  /* Called by the portable layer each time a tick interrupt occurs.
1946  Increments the tick then checks to see if the new tick value will cause any
1947  tasks to be unblocked. */
1948  traceTASK_INCREMENT_TICK( xTickCount );
1949  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
1950  {
1951  /* Increment the RTOS tick, switching the delayed and overflowed
1952  delayed lists if it wraps to 0. */
1953  ++xTickCount;
1954 
1955  {
1956  /* Minor optimisation. The tick count cannot change in this
1957  block. */
1958  const TickType_t xConstTickCount = xTickCount;
1959 
1960  if( xConstTickCount == ( TickType_t ) 0U )
1961  {
1963  }
1964  else
1965  {
1967  }
1968 
1969  /* See if this tick has made a timeout expire. Tasks are stored in
1970  the queue in the order of their wake time - meaning once one task
1971  has been found whose block time has not expired there is no need to
1972  look any further down the list. */
1973  if( xConstTickCount >= xNextTaskUnblockTime )
1974  {
1975  for( ;; )
1976  {
1977  if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
1978  {
1979  /* The delayed list is empty. Set xNextTaskUnblockTime
1980  to the maximum possible value so it is extremely
1981  unlikely that the
1982  if( xTickCount >= xNextTaskUnblockTime ) test will pass
1983  next time through. */
1984  xNextTaskUnblockTime = portMAX_DELAY;
1985  break;
1986  }
1987  else
1988  {
1989  /* The delayed list is not empty, get the value of the
1990  item at the head of the delayed list. This is the time
1991  at which the task at the head of the delayed list must
1992  be removed from the Blocked state. */
1993  pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
1994  xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
1995 
1996  if( xConstTickCount < xItemValue )
1997  {
1998  /* It is not time to unblock this item yet, but the
1999  item value is the time at which the task at the head
2000  of the blocked list must be removed from the Blocked
2001  state - so record the item value in
2002  xNextTaskUnblockTime. */
2003  xNextTaskUnblockTime = xItemValue;
2004  break;
2005  }
2006  else
2007  {
2009  }
2010 
2011  /* It is time to remove the item from the Blocked state. */
2012  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
2013 
2014  /* Is the task waiting on an event also? If so remove
2015  it from the event list. */
2016  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
2017  {
2018  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
2019  }
2020  else
2021  {
2023  }
2024 
2025  /* Place the unblocked task into the appropriate ready
2026  list. */
2027  prvAddTaskToReadyList( pxTCB );
2028 
2029  /* A task being unblocked cannot cause an immediate
2030  context switch if preemption is turned off. */
2031  #if ( configUSE_PREEMPTION == 1 )
2032  {
2033  /* Preemption is on, but a context switch should
2034  only be performed if the unblocked task has a
2035  priority that is equal to or higher than the
2036  currently executing task. */
2037  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
2038  {
2039  xSwitchRequired = pdTRUE;
2040  }
2041  else
2042  {
2044  }
2045  }
2046  #endif /* configUSE_PREEMPTION */
2047  }
2048  }
2049  }
2050  }
2051 
2052  /* Tasks of equal priority to the currently running task will share
2053  processing time (time slice) if preemption is on, and the application
2054  writer has not explicitly turned time slicing off. */
2055  #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
2056  {
2057  if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 )
2058  {
2059  xSwitchRequired = pdTRUE;
2060  }
2061  else
2062  {
2064  }
2065  }
2066  #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
2067 
2068  #if ( configUSE_TICK_HOOK == 1 )
2069  {
2070  /* Guard against the tick hook being called when the pended tick
2071  count is being unwound (when the scheduler is being unlocked). */
2072  if( uxPendedTicks == ( UBaseType_t ) 0U )
2073  {
2074  vApplicationTickHook();
2075  }
2076  else
2077  {
2079  }
2080  }
2081  #endif /* configUSE_TICK_HOOK */
2082  }
2083  else
2084  {
2085  ++uxPendedTicks;
2086 
2087  /* The tick hook gets called at regular intervals, even if the
2088  scheduler is locked. */
2089  #if ( configUSE_TICK_HOOK == 1 )
2090  {
2091  vApplicationTickHook();
2092  }
2093  #endif
2094  }
2095 
2096  #if ( configUSE_PREEMPTION == 1 )
2097  {
2098  if( xYieldPending != pdFALSE )
2099  {
2100  xSwitchRequired = pdTRUE;
2101  }
2102  else
2103  {
2105  }
2106  }
2107  #endif /* configUSE_PREEMPTION */
2108 
2109  return xSwitchRequired;
2110 }
2111 /*-----------------------------------------------------------*/
2112 
2113 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2114 
2115  void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction )
2116  {
2117  TCB_t *xTCB;
2118 
2119  /* If xTask is NULL then it is the task hook of the calling task that is
2120  getting set. */
2121  if( xTask == NULL )
2122  {
2123  xTCB = ( TCB_t * ) pxCurrentTCB;
2124  }
2125  else
2126  {
2127  xTCB = ( TCB_t * ) xTask;
2128  }
2129 
2130  /* Save the hook function in the TCB. A critical section is required as
2131  the value can be accessed from an interrupt. */
2133  xTCB->pxTaskTag = pxHookFunction;
2135  }
2136 
2137 #endif /* configUSE_APPLICATION_TASK_TAG */
2138 /*-----------------------------------------------------------*/
2139 
2140 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2141 
2142  TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )
2143  {
2144  TCB_t *xTCB;
2145  TaskHookFunction_t xReturn;
2146 
2147  /* If xTask is NULL then we are setting our own task hook. */
2148  if( xTask == NULL )
2149  {
2150  xTCB = ( TCB_t * ) pxCurrentTCB;
2151  }
2152  else
2153  {
2154  xTCB = ( TCB_t * ) xTask;
2155  }
2156 
2157  /* Save the hook function in the TCB. A critical section is required as
2158  the value can be accessed from an interrupt. */
2160  {
2161  xReturn = xTCB->pxTaskTag;
2162  }
2164 
2165  return xReturn;
2166  }
2167 
2168 #endif /* configUSE_APPLICATION_TASK_TAG */
2169 /*-----------------------------------------------------------*/
2170 
2171 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2172 
2173  BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter )
2174  {
2175  TCB_t *xTCB;
2176  BaseType_t xReturn;
2177 
2178  /* If xTask is NULL then we are calling our own task hook. */
2179  if( xTask == NULL )
2180  {
2181  xTCB = ( TCB_t * ) pxCurrentTCB;
2182  }
2183  else
2184  {
2185  xTCB = ( TCB_t * ) xTask;
2186  }
2187 
2188  if( xTCB->pxTaskTag != NULL )
2189  {
2190  xReturn = xTCB->pxTaskTag( pvParameter );
2191  }
2192  else
2193  {
2194  xReturn = pdFAIL;
2195  }
2196 
2197  return xReturn;
2198  }
2199 
2200 #endif /* configUSE_APPLICATION_TASK_TAG */
2201 /*-----------------------------------------------------------*/
2202 
2204 {
2205  if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
2206  {
2207  /* The scheduler is currently suspended - do not allow a context
2208  switch. */
2209  xYieldPending = pdTRUE;
2210  }
2211  else
2212  {
2213  xYieldPending = pdFALSE;
2215 
2216  #if ( configGENERATE_RUN_TIME_STATS == 1 )
2217  {
2218  #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
2219  portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );
2220  #else
2221  ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
2222  #endif
2223 
2224  /* Add the amount of time the task has been running to the
2225  accumulated time so far. The time the task started running was
2226  stored in ulTaskSwitchedInTime. Note that there is no overflow
2227  protection here so count values are only valid until the timer
2228  overflows. The guard against negative values is to protect
2229  against suspect run time stat counter implementations - which
2230  are provided by the application, not the kernel. */
2231  if( ulTotalRunTime > ulTaskSwitchedInTime )
2232  {
2233  pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
2234  }
2235  else
2236  {
2238  }
2239  ulTaskSwitchedInTime = ulTotalRunTime;
2240  }
2241  #endif /* configGENERATE_RUN_TIME_STATS */
2242 
2243  /* Check for stack overflow, if configured. */
2245 
2246  /* Select a new task to run using either the generic C or port
2247  optimised asm code. */
2250 
2251  #if ( configUSE_NEWLIB_REENTRANT == 1 )
2252  {
2253  /* Switch Newlib's _impure_ptr variable to point to the _reent
2254  structure specific to this task. */
2255  _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
2256  }
2257  #endif /* configUSE_NEWLIB_REENTRANT */
2258  }
2259 }
2260 /*-----------------------------------------------------------*/
2261 
2262 void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait )
2263 {
2264 TickType_t xTimeToWake;
2265 
2266  configASSERT( pxEventList );
2267 
2268  /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE
2269  SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */
2270 
2271  /* Place the event list item of the TCB in the appropriate event list.
2272  This is placed in the list in priority order so the highest priority task
2273  is the first to be woken by the event. The queue that contains the event
2274  list is locked, preventing simultaneous access from interrupts. */
2275  vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
2276 
2277  /* The task must be removed from from the ready list before it is added to
2278  the blocked list as the same list item is used for both lists. Exclusive
2279  access to the ready lists guaranteed because the scheduler is locked. */
2280  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
2281  {
2282  /* The current task must be in a ready list, so there is no need to
2283  check, and the port reset macro can be called directly. */
2284  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
2285  }
2286  else
2287  {
2289  }
2290 
2291  #if ( INCLUDE_vTaskSuspend == 1 )
2292  {
2293  if( xTicksToWait == portMAX_DELAY )
2294  {
2295  /* Add the task to the suspended task list instead of a delayed task
2296  list to ensure the task is not woken by a timing event. It will
2297  block indefinitely. */
2298  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2299  }
2300  else
2301  {
2302  /* Calculate the time at which the task should be woken if the event
2303  does not occur. This may overflow but this doesn't matter, the
2304  scheduler will handle it. */
2305  xTimeToWake = xTickCount + xTicksToWait;
2306  prvAddCurrentTaskToDelayedList( xTimeToWake );
2307  }
2308  }
2309  #else /* INCLUDE_vTaskSuspend */
2310  {
2311  /* Calculate the time at which the task should be woken if the event does
2312  not occur. This may overflow but this doesn't matter, the scheduler
2313  will handle it. */
2314  xTimeToWake = xTickCount + xTicksToWait;
2315  prvAddCurrentTaskToDelayedList( xTimeToWake );
2316  }
2317  #endif /* INCLUDE_vTaskSuspend */
2318 }
2319 /*-----------------------------------------------------------*/
2320 
2321 void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait )
2322 {
2323 TickType_t xTimeToWake;
2324 
2325  configASSERT( pxEventList );
2326 
2327  /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
2328  the event groups implementation. */
2329  configASSERT( uxSchedulerSuspended != 0 );
2330 
2331  /* Store the item value in the event list item. It is safe to access the
2332  event list item here as interrupts won't access the event list item of a
2333  task that is not in the Blocked state. */
2335 
2336  /* Place the event list item of the TCB at the end of the appropriate event
2337  list. It is safe to access the event list here because it is part of an
2338  event group implementation - and interrupts don't access event groups
2339  directly (instead they access them indirectly by pending function calls to
2340  the task level). */
2341  vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
2342 
2343  /* The task must be removed from the ready list before it is added to the
2344  blocked list. Exclusive access can be assured to the ready list as the
2345  scheduler is locked. */
2346  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
2347  {
2348  /* The current task must be in a ready list, so there is no need to
2349  check, and the port reset macro can be called directly. */
2350  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
2351  }
2352  else
2353  {
2355  }
2356 
2357  #if ( INCLUDE_vTaskSuspend == 1 )
2358  {
2359  if( xTicksToWait == portMAX_DELAY )
2360  {
2361  /* Add the task to the suspended task list instead of a delayed task
2362  list to ensure it is not woken by a timing event. It will block
2363  indefinitely. */
2364  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2365  }
2366  else
2367  {
2368  /* Calculate the time at which the task should be woken if the event
2369  does not occur. This may overflow but this doesn't matter, the
2370  kernel will manage it correctly. */
2371  xTimeToWake = xTickCount + xTicksToWait;
2372  prvAddCurrentTaskToDelayedList( xTimeToWake );
2373  }
2374  }
2375  #else /* INCLUDE_vTaskSuspend */
2376  {
2377  /* Calculate the time at which the task should be woken if the event does
2378  not occur. This may overflow but this doesn't matter, the kernel
2379  will manage it correctly. */
2380  xTimeToWake = xTickCount + xTicksToWait;
2381  prvAddCurrentTaskToDelayedList( xTimeToWake );
2382  }
2383  #endif /* INCLUDE_vTaskSuspend */
2384 }
2385 /*-----------------------------------------------------------*/
2386 
2387 #if configUSE_TIMERS == 1
2388 
2389  void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely )
2390  {
2391  TickType_t xTimeToWake;
2392 
2393  configASSERT( pxEventList );
2394 
2395  /* This function should not be called by application code hence the
2396  'Restricted' in its name. It is not part of the public API. It is
2397  designed for use by kernel code, and has special calling requirements -
2398  it should be called with the scheduler suspended. */
2399 
2400 
2401  /* Place the event list item of the TCB in the appropriate event list.
2402  In this case it is assume that this is the only task that is going to
2403  be waiting on this event list, so the faster vListInsertEnd() function
2404  can be used in place of vListInsert. */
2405  vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
2406 
2407  /* We must remove this task from the ready list before adding it to the
2408  blocked list as the same list item is used for both lists. This
2409  function is called with the scheduler locked so interrupts will not
2410  access the lists at the same time. */
2411  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
2412  {
2413  /* The current task must be in a ready list, so there is no need to
2414  check, and the port reset macro can be called directly. */
2415  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
2416  }
2417  else
2418  {
2420  }
2421 
2422  /* If vTaskSuspend() is available then the suspended task list is also
2423  available and a task that is blocking indefinitely can enter the
2424  suspended state (it is not really suspended as it will re-enter the
2425  Ready state when the event it is waiting indefinitely for occurs).
2426  Blocking indefinitely is useful when using tickless idle mode as when
2427  all tasks are blocked indefinitely all timers can be turned off. */
2428  #if( INCLUDE_vTaskSuspend == 1 )
2429  {
2430  if( xWaitIndefinitely == pdTRUE )
2431  {
2432  /* Add the task to the suspended task list instead of a delayed
2433  task list to ensure the task is not woken by a timing event. It
2434  will block indefinitely. */
2435  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2436  }
2437  else
2438  {
2439  /* Calculate the time at which the task should be woken if the
2440  event does not occur. This may overflow but this doesn't
2441  matter. */
2442  xTimeToWake = xTickCount + xTicksToWait;
2444  prvAddCurrentTaskToDelayedList( xTimeToWake );
2445  }
2446  }
2447  #else
2448  {
2449  /* Calculate the time at which the task should be woken if the event
2450  does not occur. This may overflow but this doesn't matter. */
2451  xTimeToWake = xTickCount + xTicksToWait;
2453  prvAddCurrentTaskToDelayedList( xTimeToWake );
2454 
2455  /* Remove compiler warnings when INCLUDE_vTaskSuspend() is not
2456  defined. */
2457  ( void ) xWaitIndefinitely;
2458  }
2459  #endif
2460  }
2461 
2462 #endif /* configUSE_TIMERS */
2463 /*-----------------------------------------------------------*/
2464 
2465 BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
2466 {
2467 TCB_t *pxUnblockedTCB;
2468 BaseType_t xReturn;
2469 
2470  /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
2471  called from a critical section within an ISR. */
2472 
2473  /* The event list is sorted in priority order, so the first in the list can
2474  be removed as it is known to be the highest priority. Remove the TCB from
2475  the delayed list, and add it to the ready list.
2476 
2477  If an event is for a queue that is locked then this function will never
2478  get called - the lock count on the queue will get modified instead. This
2479  means exclusive access to the event list is guaranteed here.
2480 
2481  This function assumes that a check has already been made to ensure that
2482  pxEventList is not empty. */
2483  pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
2484  configASSERT( pxUnblockedTCB );
2485  ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
2486 
2487  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
2488  {
2489  ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
2490  prvAddTaskToReadyList( pxUnblockedTCB );
2491  }
2492  else
2493  {
2494  /* The delayed and ready lists cannot be accessed, so hold this task
2495  pending until the scheduler is resumed. */
2496  vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
2497  }
2498 
2499  if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
2500  {
2501  /* Return true if the task removed from the event list has a higher
2502  priority than the calling task. This allows the calling task to know if
2503  it should force a context switch now. */
2504  xReturn = pdTRUE;
2505 
2506  /* Mark that a yield is pending in case the user is not using the
2507  "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
2508  xYieldPending = pdTRUE;
2509  }
2510  else
2511  {
2512  xReturn = pdFALSE;
2513  }
2514 
2515  #if( configUSE_TICKLESS_IDLE != 0 )
2516  {
2517  /* If a task is blocked on a kernel object then xNextTaskUnblockTime
2518  might be set to the blocked task's time out time. If the task is
2519  unblocked for a reason other than a timeout xNextTaskUnblockTime is
2520  normally left unchanged, because it is automatically reset to a new
2521  value when the tick count equals xNextTaskUnblockTime. However if
2522  tickless idling is used it might be more important to enter sleep mode
2523  at the earliest possible time - so reset xNextTaskUnblockTime here to
2524  ensure it is updated at the earliest possible time. */
2525  prvResetNextTaskUnblockTime();
2526  }
2527  #endif
2528 
2529  return xReturn;
2530 }
2531 /*-----------------------------------------------------------*/
2532 
2534 {
2535 TCB_t *pxUnblockedTCB;
2536 BaseType_t xReturn;
2537 
2538  /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
2539  the event flags implementation. */
2540  configASSERT( uxSchedulerSuspended != pdFALSE );
2541 
2542  /* Store the new item value in the event list. */
2543  listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE );
2544 
2545  /* Remove the event list form the event flag. Interrupts do not access
2546  event flags. */
2547  pxUnblockedTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxEventListItem );
2548  configASSERT( pxUnblockedTCB );
2549  ( void ) uxListRemove( pxEventListItem );
2550 
2551  /* Remove the task from the delayed list and add it to the ready list. The
2552  scheduler is suspended so interrupts will not be accessing the ready
2553  lists. */
2554  ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
2555  prvAddTaskToReadyList( pxUnblockedTCB );
2556 
2557  if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
2558  {
2559  /* Return true if the task removed from the event list has
2560  a higher priority than the calling task. This allows
2561  the calling task to know if it should force a context
2562  switch now. */
2563  xReturn = pdTRUE;
2564 
2565  /* Mark that a yield is pending in case the user is not using the
2566  "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
2567  xYieldPending = pdTRUE;
2568  }
2569  else
2570  {
2571  xReturn = pdFALSE;
2572  }
2573 
2574  return xReturn;
2575 }
2576 /*-----------------------------------------------------------*/
2577 
2578 void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )
2579 {
2580  configASSERT( pxTimeOut );
2581  pxTimeOut->xOverflowCount = xNumOfOverflows;
2582  pxTimeOut->xTimeOnEntering = xTickCount;
2583 }
2584 /*-----------------------------------------------------------*/
2585 
2586 BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait )
2587 {
2588 BaseType_t xReturn;
2589 
2590  configASSERT( pxTimeOut );
2591  configASSERT( pxTicksToWait );
2592 
2594  {
2595  /* Minor optimisation. The tick count cannot change in this block. */
2596  const TickType_t xConstTickCount = xTickCount;
2597 
2598  #if ( INCLUDE_vTaskSuspend == 1 )
2599  /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
2600  the maximum block time then the task should block indefinitely, and
2601  therefore never time out. */
2602  if( *pxTicksToWait == portMAX_DELAY )
2603  {
2604  xReturn = pdFALSE;
2605  }
2606  else /* We are not blocking indefinitely, perform the checks below. */
2607  #endif
2608 
2609  if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */
2610  {
2611  /* The tick count is greater than the time at which vTaskSetTimeout()
2612  was called, but has also overflowed since vTaskSetTimeOut() was called.
2613  It must have wrapped all the way around and gone past us again. This
2614  passed since vTaskSetTimeout() was called. */
2615  xReturn = pdTRUE;
2616  }
2617  else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )
2618  {
2619  /* Not a genuine timeout. Adjust parameters for time remaining. */
2620  *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );
2621  vTaskSetTimeOutState( pxTimeOut );
2622  xReturn = pdFALSE;
2623  }
2624  else
2625  {
2626  xReturn = pdTRUE;
2627  }
2628  }
2630 
2631  return xReturn;
2632 }
2633 /*-----------------------------------------------------------*/
2634 
2635 void vTaskMissedYield( void )
2636 {
2637  xYieldPending = pdTRUE;
2638 }
2639 /*-----------------------------------------------------------*/
2640 
2641 #if ( configUSE_TRACE_FACILITY == 1 )
2642 
2644  {
2645  UBaseType_t uxReturn;
2646  TCB_t *pxTCB;
2647 
2648  if( xTask != NULL )
2649  {
2650  pxTCB = ( TCB_t * ) xTask;
2651  uxReturn = pxTCB->uxTaskNumber;
2652  }
2653  else
2654  {
2655  uxReturn = 0U;
2656  }
2657 
2658  return uxReturn;
2659  }
2660 
2661 #endif /* configUSE_TRACE_FACILITY */
2662 /*-----------------------------------------------------------*/
2663 
2664 #if ( configUSE_TRACE_FACILITY == 1 )
2665 
2666  void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle )
2667  {
2668  TCB_t *pxTCB;
2669 
2670  if( xTask != NULL )
2671  {
2672  pxTCB = ( TCB_t * ) xTask;
2673  pxTCB->uxTaskNumber = uxHandle;
2674  }
2675  }
2676 
2677 #endif /* configUSE_TRACE_FACILITY */
2678 
2679 /*
2680  * -----------------------------------------------------------
2681  * The Idle task.
2682  * ----------------------------------------------------------
2683  *
2684  * The portTASK_FUNCTION() macro is used to allow port/compiler specific
2685  * language extensions. The equivalent prototype for this function is:
2686  *
2687  * void prvIdleTask( void *pvParameters );
2688  *
2689  */
2690 static portTASK_FUNCTION( prvIdleTask, pvParameters )
2691 {
2692  /* Stop warnings. */
2693  ( void ) pvParameters;
2694 
2695  for( ;; )
2696  {
2697  /* See if any tasks have been deleted. */
2698  prvCheckTasksWaitingTermination();
2699 
2700  #if ( configUSE_PREEMPTION == 0 )
2701  {
2702  /* If we are not using preemption we keep forcing a task switch to
2703  see if any other task has become available. If we are using
2704  preemption we don't need to do this as any task becoming available
2705  will automatically get the processor anyway. */
2706  taskYIELD();
2707  }
2708  #endif /* configUSE_PREEMPTION */
2709 
2710  #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
2711  {
2712  /* When using preemption tasks of equal priority will be
2713  timesliced. If a task that is sharing the idle priority is ready
2714  to run then the idle task should yield before the end of the
2715  timeslice.
2716 
2717  A critical region is not required here as we are just reading from
2718  the list, and an occasional incorrect value will not matter. If
2719  the ready list at the idle priority contains more than one task
2720  then a task other than the idle task is ready to execute. */
2721  if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
2722  {
2723  taskYIELD();
2724  }
2725  else
2726  {
2728  }
2729  }
2730  #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
2731 
2732  #if ( configUSE_IDLE_HOOK == 1 )
2733  {
2734  extern void vApplicationIdleHook( void );
2735 
2736  /* Call the user defined function from within the idle task. This
2737  allows the application designer to add background functionality
2738  without the overhead of a separate task.
2739  NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
2740  CALL A FUNCTION THAT MIGHT BLOCK. */
2741  vApplicationIdleHook();
2742  }
2743  #endif /* configUSE_IDLE_HOOK */
2744 
2745  /* This conditional compilation should use inequality to 0, not equality
2746  to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
2747  user defined low power mode implementations require
2748  configUSE_TICKLESS_IDLE to be set to a value other than 1. */
2749  #if ( configUSE_TICKLESS_IDLE != 0 )
2750  {
2751  TickType_t xExpectedIdleTime;
2752 
2753  /* It is not desirable to suspend then resume the scheduler on
2754  each iteration of the idle task. Therefore, a preliminary
2755  test of the expected idle time is performed without the
2756  scheduler suspended. The result here is not necessarily
2757  valid. */
2758  xExpectedIdleTime = prvGetExpectedIdleTime();
2759 
2760  if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
2761  {
2762  vTaskSuspendAll();
2763  {
2764  /* Now the scheduler is suspended, the expected idle
2765  time can be sampled again, and this time its value can
2766  be used. */
2767  configASSERT( xNextTaskUnblockTime >= xTickCount );
2768  xExpectedIdleTime = prvGetExpectedIdleTime();
2769 
2770  if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
2771  {
2773  portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
2775  }
2776  else
2777  {
2779  }
2780  }
2781  ( void ) xTaskResumeAll();
2782  }
2783  else
2784  {
2786  }
2787  }
2788  #endif /* configUSE_TICKLESS_IDLE */
2789  }
2790 }
2791 /*-----------------------------------------------------------*/
2792 
2793 #if( configUSE_TICKLESS_IDLE != 0 )
2794 
2796  {
2797  /* The idle task exists in addition to the application tasks. */
2798  const UBaseType_t uxNonApplicationTasks = 1;
2799  eSleepModeStatus eReturn = eStandardSleep;
2800 
2801  if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 )
2802  {
2803  /* A task was made ready while the scheduler was suspended. */
2804  eReturn = eAbortSleep;
2805  }
2806  else if( xYieldPending != pdFALSE )
2807  {
2808  /* A yield was pended while the scheduler was suspended. */
2809  eReturn = eAbortSleep;
2810  }
2811  else
2812  {
2813  /* If all the tasks are in the suspended list (which might mean they
2814  have an infinite block time rather than actually being suspended)
2815  then it is safe to turn all clocks off and just wait for external
2816  interrupts. */
2817  if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) )
2818  {
2819  eReturn = eNoTasksWaitingTimeout;
2820  }
2821  else
2822  {
2824  }
2825  }
2826 
2827  return eReturn;
2828  }
2829 
2830 #endif /* configUSE_TICKLESS_IDLE */
2831 /*-----------------------------------------------------------*/
2832 
2833 static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
2834 {
2835 UBaseType_t x;
2836 
2837  /* Store the task name in the TCB. */
2838  for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
2839  {
2840  pxTCB->pcTaskName[ x ] = pcName[ x ];
2841 
2842  /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
2843  configMAX_TASK_NAME_LEN characters just in case the memory after the
2844  string is not accessible (extremely unlikely). */
2845  if( pcName[ x ] == 0x00 )
2846  {
2847  break;
2848  }
2849  else
2850  {
2852  }
2853  }
2854 
2855  /* Ensure the name string is terminated in the case that the string length
2856  was greater or equal to configMAX_TASK_NAME_LEN. */
2857  pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';
2858 
2859  /* This is used as an array index so must ensure it's not too large. First
2860  remove the privilege bit if one is present. */
2861  if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
2862  {
2863  uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
2864  }
2865  else
2866  {
2868  }
2869 
2870  pxTCB->uxPriority = uxPriority;
2871  #if ( configUSE_MUTEXES == 1 )
2872  {
2873  pxTCB->uxBasePriority = uxPriority;
2874  pxTCB->uxMutexesHeld = 0;
2875  }
2876  #endif /* configUSE_MUTEXES */
2877 
2878  vListInitialiseItem( &( pxTCB->xGenericListItem ) );
2879  vListInitialiseItem( &( pxTCB->xEventListItem ) );
2880 
2881  /* Set the pxTCB as a link back from the ListItem_t. This is so we can get
2882  back to the containing TCB from a generic item in a list. */
2883  listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );
2884 
2885  /* Event lists are always in priority order. */
2886  listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
2887  listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );
2888 
2889  #if ( portCRITICAL_NESTING_IN_TCB == 1 )
2890  {
2891  pxTCB->uxCriticalNesting = ( UBaseType_t ) 0U;
2892  }
2893  #endif /* portCRITICAL_NESTING_IN_TCB */
2894 
2895  #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2896  {
2897  pxTCB->pxTaskTag = NULL;
2898  }
2899  #endif /* configUSE_APPLICATION_TASK_TAG */
2900 
2901  #if ( configGENERATE_RUN_TIME_STATS == 1 )
2902  {
2903  pxTCB->ulRunTimeCounter = 0UL;
2904  }
2905  #endif /* configGENERATE_RUN_TIME_STATS */
2906 
2907  #if ( portUSING_MPU_WRAPPERS == 1 )
2908  {
2909  vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );
2910  }
2911  #else /* portUSING_MPU_WRAPPERS */
2912  {
2913  ( void ) xRegions;
2914  ( void ) usStackDepth;
2915  }
2916  #endif /* portUSING_MPU_WRAPPERS */
2917 
2918  #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
2919  {
2920  for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ )
2921  {
2922  pxTCB->pvThreadLocalStoragePointers[ x ] = NULL;
2923  }
2924  }
2925  #endif
2926 
2927  #if ( configUSE_TASK_NOTIFICATIONS == 1 )
2928  {
2929  pxTCB->ulNotifiedValue = 0;
2930  pxTCB->eNotifyState = eNotWaitingNotification;
2931  }
2932  #endif
2933 
2934  #if ( configUSE_NEWLIB_REENTRANT == 1 )
2935  {
2936  /* Initialise this task's Newlib reent structure. */
2937  _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );
2938  }
2939  #endif /* configUSE_NEWLIB_REENTRANT */
2940 }
2941 /*-----------------------------------------------------------*/
2942 
2943 #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
2944 
2945  void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue )
2946  {
2947  TCB_t *pxTCB;
2948 
2950  {
2951  pxTCB = prvGetTCBFromHandle( xTaskToSet );
2952  pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
2953  }
2954  }
2955 
2956 #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */
2957 /*-----------------------------------------------------------*/
2958 
2959 #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
2960 
2961  void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex )
2962  {
2963  void *pvReturn = NULL;
2964  TCB_t *pxTCB;
2965 
2967  {
2968  pxTCB = prvGetTCBFromHandle( xTaskToQuery );
2969  pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ];
2970  }
2971  else
2972  {
2973  pvReturn = NULL;
2974  }
2975 
2976  return pvReturn;
2977  }
2978 
2979 #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */
2980 /*-----------------------------------------------------------*/
2981 
2982 #if ( portUSING_MPU_WRAPPERS == 1 )
2983 
2984  void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions )
2985  {
2986  TCB_t *pxTCB;
2987 
2988  /* If null is passed in here then we are modifying the MPU settings of
2989  the calling task. */
2990  pxTCB = prvGetTCBFromHandle( xTaskToModify );
2991 
2992  vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
2993  }
2994 
2995 #endif /* portUSING_MPU_WRAPPERS */
2996 /*-----------------------------------------------------------*/
2997 
2998 static void prvInitialiseTaskLists( void )
2999 {
3001 
3002  for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
3003  {
3004  vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
3005  }
3006 
3007  vListInitialise( &xDelayedTaskList1 );
3008  vListInitialise( &xDelayedTaskList2 );
3009  vListInitialise( &xPendingReadyList );
3010 
3011  #if ( INCLUDE_vTaskDelete == 1 )
3012  {
3013  vListInitialise( &xTasksWaitingTermination );
3014  }
3015  #endif /* INCLUDE_vTaskDelete */
3016 
3017  #if ( INCLUDE_vTaskSuspend == 1 )
3018  {
3019  vListInitialise( &xSuspendedTaskList );
3020  }
3021  #endif /* INCLUDE_vTaskSuspend */
3022 
3023  /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
3024  using list2. */
3025  pxDelayedTaskList = &xDelayedTaskList1;
3026  pxOverflowDelayedTaskList = &xDelayedTaskList2;
3027 }
3028 /*-----------------------------------------------------------*/
3029 
3030 static void prvCheckTasksWaitingTermination( void )
3031 {
3032  #if ( INCLUDE_vTaskDelete == 1 )
3033  {
3034  BaseType_t xListIsEmpty;
3035 
3036  /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
3037  too often in the idle task. */
3038  while( uxTasksDeleted > ( UBaseType_t ) 0U )
3039  {
3040  vTaskSuspendAll();
3041  {
3042  xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
3043  }
3044  ( void ) xTaskResumeAll();
3045 
3046  if( xListIsEmpty == pdFALSE )
3047  {
3048  TCB_t *pxTCB;
3049 
3051  {
3052  pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
3053  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
3054  --uxCurrentNumberOfTasks;
3055  --uxTasksDeleted;
3056  }
3058 
3059  prvDeleteTCB( pxTCB );
3060  }
3061  else
3062  {
3064  }
3065  }
3066  }
3067  #endif /* vTaskDelete */
3068 }
3069 /*-----------------------------------------------------------*/
3070 
3071 static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
3072 {
3073  /* The list item will be inserted in wake time order. */
3075 
3076  if( xTimeToWake < xTickCount )
3077  {
3078  /* Wake time has overflowed. Place this item in the overflow list. */
3079  vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
3080  }
3081  else
3082  {
3083  /* The wake time has not overflowed, so the current block list is used. */
3084  vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
3085 
3086  /* If the task entering the blocked state was placed at the head of the
3087  list of blocked tasks then xNextTaskUnblockTime needs to be updated
3088  too. */
3089  if( xTimeToWake < xNextTaskUnblockTime )
3090  {
3091  xNextTaskUnblockTime = xTimeToWake;
3092  }
3093  else
3094  {
3096  }
3097  }
3098 }
3099 /*-----------------------------------------------------------*/
3100 
3101 static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
3102 {
3103 TCB_t *pxNewTCB;
3104 
3105  /* If the stack grows down then allocate the stack then the TCB so the stack
3106  does not grow into the TCB. Likewise if the stack grows up then allocate
3107  the TCB then the stack. */
3108  #if( portSTACK_GROWTH > 0 )
3109  {
3110  /* Allocate space for the TCB. Where the memory comes from depends on
3111  the implementation of the port malloc function. */
3112  pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
3113 
3114  if( pxNewTCB != NULL )
3115  {
3116  /* Allocate space for the stack used by the task being created.
3117  The base of the stack memory stored in the TCB so the task can
3118  be deleted later if required. */
3119  pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
3120 
3121  if( pxNewTCB->pxStack == NULL )
3122  {
3123  /* Could not allocate the stack. Delete the allocated TCB. */
3124  vPortFree( pxNewTCB );
3125  pxNewTCB = NULL;
3126  }
3127  }
3128  }
3129  #else /* portSTACK_GROWTH */
3130  {
3132 
3133  /* Allocate space for the stack used by the task being created. */
3134  pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
3135 
3136  if( pxStack != NULL )
3137  {
3138  /* Allocate space for the TCB. Where the memory comes from depends
3139  on the implementation of the port malloc function. */
3140  pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
3141 
3142  if( pxNewTCB != NULL )
3143  {
3144  /* Store the stack location in the TCB. */
3145  pxNewTCB->pxStack = pxStack;
3146  }
3147  else
3148  {
3149  /* The stack cannot be used as the TCB was not created. Free it
3150  again. */
3151  vPortFree( pxStack );
3152  }
3153  }
3154  else
3155  {
3156  pxNewTCB = NULL;
3157  }
3158  }
3159  #endif /* portSTACK_GROWTH */
3160 
3161  if( pxNewTCB != NULL )
3162  {
3163  /* Avoid dependency on memset() if it is not required. */
3164  #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
3165  {
3166  /* Just to help debugging. */
3167  ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) );
3168  }
3169  #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */
3170  }
3171 
3172  return pxNewTCB;
3173 }
3174 /*-----------------------------------------------------------*/
3175 
3176 #if ( configUSE_TRACE_FACILITY == 1 )
3177 
3178  static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )
3179  {
3180  volatile TCB_t *pxNextTCB, *pxFirstTCB;
3181  UBaseType_t uxTask = 0;
3182 
3183  if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
3184  {
3185  listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
3186 
3187  /* Populate an TaskStatus_t structure within the
3188  pxTaskStatusArray array for each task that is referenced from
3189  pxList. See the definition of TaskStatus_t in task.h for the
3190  meaning of each TaskStatus_t structure member. */
3191  do
3192  {
3193  listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
3194 
3195  pxTaskStatusArray[ uxTask ].xHandle = ( TaskHandle_t ) pxNextTCB;
3196  pxTaskStatusArray[ uxTask ].pcTaskName = ( const char * ) &( pxNextTCB->pcTaskName [ 0 ] );
3197  pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber;
3198  pxTaskStatusArray[ uxTask ].eCurrentState = eState;
3199  pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority;
3200 
3201  #if ( INCLUDE_vTaskSuspend == 1 )
3202  {
3203  /* If the task is in the suspended list then there is a chance
3204  it is actually just blocked indefinitely - so really it should
3205  be reported as being in the Blocked state. */
3206  if( eState == eSuspended )
3207  {
3208  if( listLIST_ITEM_CONTAINER( &( pxNextTCB->xEventListItem ) ) != NULL )
3209  {
3210  pxTaskStatusArray[ uxTask ].eCurrentState = eBlocked;
3211  }
3212  }
3213  }
3214  #endif /* INCLUDE_vTaskSuspend */
3215 
3216  #if ( configUSE_MUTEXES == 1 )
3217  {
3218  pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority;
3219  }
3220  #else
3221  {
3222  pxTaskStatusArray[ uxTask ].uxBasePriority = 0;
3223  }
3224  #endif
3225 
3226  #if ( configGENERATE_RUN_TIME_STATS == 1 )
3227  {
3228  pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter;
3229  }
3230  #else
3231  {
3232  pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0;
3233  }
3234  #endif
3235 
3236  #if ( portSTACK_GROWTH > 0 )
3237  {
3238  pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxEndOfStack );
3239  }
3240  #else
3241  {
3242  pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxStack );
3243  }
3244  #endif
3245 
3246  uxTask++;
3247 
3248  } while( pxNextTCB != pxFirstTCB );
3249  }
3250  else
3251  {
3253  }
3254 
3255  return uxTask;
3256  }
3257 
3258 #endif /* configUSE_TRACE_FACILITY */
3259 /*-----------------------------------------------------------*/
3260 
3261 #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
3262 
3263  static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
3264  {
3265  uint32_t ulCount = 0U;
3266 
3267  while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE )
3268  {
3269  pucStackByte -= portSTACK_GROWTH;
3270  ulCount++;
3271  }
3272 
3273  ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
3274 
3275  return ( uint16_t ) ulCount;
3276  }
3277 
3278 #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
3279 /*-----------------------------------------------------------*/
3280 
3281 #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
3282 
3284  {
3285  TCB_t *pxTCB;
3286  uint8_t *pucEndOfStack;
3287  UBaseType_t uxReturn;
3288 
3289  pxTCB = prvGetTCBFromHandle( xTask );
3290 
3291  #if portSTACK_GROWTH < 0
3292  {
3293  pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;
3294  }
3295  #else
3296  {
3297  pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;
3298  }
3299  #endif
3300 
3301  uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack );
3302 
3303  return uxReturn;
3304  }
3305 
3306 #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
3307 /*-----------------------------------------------------------*/
3308 
3309 #if ( INCLUDE_vTaskDelete == 1 )
3310 
3311  static void prvDeleteTCB( TCB_t *pxTCB )
3312  {
3313  /* This call is required specifically for the TriCore port. It must be
3314  above the vPortFree() calls. The call is also used by ports/demos that
3315  want to allocate and clean RAM statically. */
3316  portCLEAN_UP_TCB( pxTCB );
3317 
3318  /* Free up the memory allocated by the scheduler for the task. It is up
3319  to the task to free any memory allocated at the application level. */
3320  #if ( configUSE_NEWLIB_REENTRANT == 1 )
3321  {
3322  _reclaim_reent( &( pxTCB->xNewLib_reent ) );
3323  }
3324  #endif /* configUSE_NEWLIB_REENTRANT */
3325 
3326  #if( portUSING_MPU_WRAPPERS == 1 )
3327  {
3328  /* Only free the stack if it was allocated dynamically in the first
3329  place. */
3330  if( pxTCB->xUsingStaticallyAllocatedStack == pdFALSE )
3331  {
3332  vPortFreeAligned( pxTCB->pxStack );
3333  }
3334  }
3335  #else
3336  {
3337  vPortFreeAligned( pxTCB->pxStack );
3338  }
3339  #endif
3340 
3341  vPortFree( pxTCB );
3342  }
3343 
3344 #endif /* INCLUDE_vTaskDelete */
3345 /*-----------------------------------------------------------*/
3346 
3347 static void prvResetNextTaskUnblockTime( void )
3348 {
3349 TCB_t *pxTCB;
3350 
3351  if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
3352  {
3353  /* The new current delayed list is empty. Set xNextTaskUnblockTime to
3354  the maximum possible value so it is extremely unlikely that the
3355  if( xTickCount >= xNextTaskUnblockTime ) test will pass until
3356  there is an item in the delayed list. */
3357  xNextTaskUnblockTime = portMAX_DELAY;
3358  }
3359  else
3360  {
3361  /* The new current delayed list is not empty, get the value of
3362  the item at the head of the delayed list. This is the time at
3363  which the task at the head of the delayed list should be removed
3364  from the Blocked state. */
3365  ( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
3366  xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xGenericListItem ) );
3367  }
3368 }
3369 /*-----------------------------------------------------------*/
3370 
3371 #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
3372 
3374  {
3375  TaskHandle_t xReturn;
3376 
3377  /* A critical section is not required as this is not called from
3378  an interrupt and the current TCB will always be the same for any
3379  individual execution thread. */
3380  xReturn = pxCurrentTCB;
3381 
3382  return xReturn;
3383  }
3384 
3385 #endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
3386 /*-----------------------------------------------------------*/
3387 
3388 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
3389 
3391  {
3392  BaseType_t xReturn;
3393 
3394  if( xSchedulerRunning == pdFALSE )
3395  {
3396  xReturn = taskSCHEDULER_NOT_STARTED;
3397  }
3398  else
3399  {
3400  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
3401  {
3402  xReturn = taskSCHEDULER_RUNNING;
3403  }
3404  else
3405  {
3406  xReturn = taskSCHEDULER_SUSPENDED;
3407  }
3408  }
3409 
3410  return xReturn;
3411  }
3412 
3413 #endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */
3414 /*-----------------------------------------------------------*/
3415 
3416 #if ( configUSE_MUTEXES == 1 )
3417 
3419  {
3420  TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
3421 
3422  /* If the mutex was given back by an interrupt while the queue was
3423  locked then the mutex holder might now be NULL. */
3424  if( pxMutexHolder != NULL )
3425  {
3426  /* If the holder of the mutex has a priority below the priority of
3427  the task attempting to obtain the mutex then it will temporarily
3428  inherit the priority of the task attempting to obtain the mutex. */
3429  if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
3430  {
3431  /* Adjust the mutex holder state to account for its new
3432  priority. Only reset the event list item value if the value is
3433  not being used for anything else. */
3435  {
3436  listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
3437  }
3438  else
3439  {
3441  }
3442 
3443  /* If the task being modified is in the ready state it will need
3444  to be moved into a new list. */
3445  if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
3446  {
3447  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
3448  {
3450  }
3451  else
3452  {
3454  }
3455 
3456  /* Inherit the priority before being moved into the new list. */
3458  prvAddTaskToReadyList( pxTCB );
3459  }
3460  else
3461  {
3462  /* Just inherit the priority. */
3464  }
3465 
3467  }
3468  else
3469  {
3471  }
3472  }
3473  else
3474  {
3476  }
3477  }
3478 
3479 #endif /* configUSE_MUTEXES */
3480 /*-----------------------------------------------------------*/
3481 
3482 #if ( configUSE_MUTEXES == 1 )
3483 
3484  BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder )
3485  {
3486  TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
3487  BaseType_t xReturn = pdFALSE;
3488 
3489  if( pxMutexHolder != NULL )
3490  {
3491  /* A task can only have an inherited priority if it holds the mutex.
3492  If the mutex is held by a task then it cannot be given from an
3493  interrupt, and if a mutex is given by the holding task then it must
3494  be the running state task. */
3495  configASSERT( pxTCB == pxCurrentTCB );
3496 
3497  configASSERT( pxTCB->uxMutexesHeld );
3498  ( pxTCB->uxMutexesHeld )--;
3499 
3500  /* Has the holder of the mutex inherited the priority of another
3501  task? */
3502  if( pxTCB->uxPriority != pxTCB->uxBasePriority )
3503  {
3504  /* Only disinherit if no other mutexes are held. */
3505  if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 )
3506  {
3507  /* A task can only have an inherited priority if it holds
3508  the mutex. If the mutex is held by a task then it cannot be
3509  given from an interrupt, and if a mutex is given by the
3510  holding task then it must be the running state task. Remove
3511  the holding task from the ready list. */
3512  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
3513  {
3515  }
3516  else
3517  {
3519  }
3520 
3521  /* Disinherit the priority before adding the task into the
3522  new ready list. */
3523  traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );
3524  pxTCB->uxPriority = pxTCB->uxBasePriority;
3525 
3526  /* Reset the event list item value. It cannot be in use for
3527  any other purpose if this task is running, and it must be
3528  running to give back the mutex. */
3529  listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
3530  prvAddTaskToReadyList( pxTCB );
3531 
3532  /* Return true to indicate that a context switch is required.
3533  This is only actually required in the corner case whereby
3534  multiple mutexes were held and the mutexes were given back
3535  in an order different to that in which they were taken.
3536  If a context switch did not occur when the first mutex was
3537  returned, even if a task was waiting on it, then a context
3538  switch should occur when the last mutex is returned whether
3539  a task is waiting on it or not. */
3540  xReturn = pdTRUE;
3541  }
3542  else
3543  {
3545  }
3546  }
3547  else
3548  {
3550  }
3551  }
3552  else
3553  {
3555  }
3556 
3557  return xReturn;
3558  }
3559 
3560 #endif /* configUSE_MUTEXES */
3561 /*-----------------------------------------------------------*/
3562 
3563 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
3564 
3565  void vTaskEnterCritical( void )
3566  {
3568 
3569  if( xSchedulerRunning != pdFALSE )
3570  {
3571  ( pxCurrentTCB->uxCriticalNesting )++;
3572 
3573  /* This is not the interrupt safe version of the enter critical
3574  function so assert() if it is being called from an interrupt
3575  context. Only API functions that end in "FromISR" can be used in an
3576  interrupt. Only assert if the critical nesting count is 1 to
3577  protect against recursive calls if the assert function also uses a
3578  critical section. */
3579  if( pxCurrentTCB->uxCriticalNesting == 1 )
3580  {
3582  }
3583  }
3584  else
3585  {
3587  }
3588  }
3589 
3590 #endif /* portCRITICAL_NESTING_IN_TCB */
3591 /*-----------------------------------------------------------*/
3592 
3593 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
3594 
3595  void vTaskExitCritical( void )
3596  {
3597  if( xSchedulerRunning != pdFALSE )
3598  {
3599  if( pxCurrentTCB->uxCriticalNesting > 0U )
3600  {
3601  ( pxCurrentTCB->uxCriticalNesting )--;
3602 
3603  if( pxCurrentTCB->uxCriticalNesting == 0U )
3604  {
3606  }
3607  else
3608  {
3610  }
3611  }
3612  else
3613  {
3615  }
3616  }
3617  else
3618  {
3620  }
3621  }
3622 
3623 #endif /* portCRITICAL_NESTING_IN_TCB */
3624 /*-----------------------------------------------------------*/
3625 
3626 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
3627 
3628  static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName )
3629  {
3630  size_t x;
3631 
3632  /* Start by copying the entire string. */
3633  strcpy( pcBuffer, pcTaskName );
3634 
3635  /* Pad the end of the string with spaces to ensure columns line up when
3636  printed out. */
3637  for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ )
3638  {
3639  pcBuffer[ x ] = ' ';
3640  }
3641 
3642  /* Terminate. */
3643  pcBuffer[ x ] = 0x00;
3644 
3645  /* Return the new end of string. */
3646  return &( pcBuffer[ x ] );
3647  }
3648 
3649 #endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */
3650 /*-----------------------------------------------------------*/
3651 
3652 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
3653 
3654  void vTaskList( char * pcWriteBuffer )
3655  {
3656  TaskStatus_t *pxTaskStatusArray;
3657  volatile UBaseType_t uxArraySize, x;
3658  char cStatus;
3659 
3660  /*
3661  * PLEASE NOTE:
3662  *
3663  * This function is provided for convenience only, and is used by many
3664  * of the demo applications. Do not consider it to be part of the
3665  * scheduler.
3666  *
3667  * vTaskList() calls uxTaskGetSystemState(), then formats part of the
3668  * uxTaskGetSystemState() output into a human readable table that
3669  * displays task names, states and stack usage.
3670  *
3671  * vTaskList() has a dependency on the sprintf() C library function that
3672  * might bloat the code size, use a lot of stack, and provide different
3673  * results on different platforms. An alternative, tiny, third party,
3674  * and limited functionality implementation of sprintf() is provided in
3675  * many of the FreeRTOS/Demo sub-directories in a file called
3676  * printf-stdarg.c (note printf-stdarg.c does not provide a full
3677  * snprintf() implementation!).
3678  *
3679  * It is recommended that production systems call uxTaskGetSystemState()
3680  * directly to get access to raw stats data, rather than indirectly
3681  * through a call to vTaskList().
3682  */
3683 
3684 
3685  /* Make sure the write buffer does not contain a string. */
3686  *pcWriteBuffer = 0x00;
3687 
3688  /* Take a snapshot of the number of tasks in case it changes while this
3689  function is executing. */
3690  uxArraySize = uxCurrentNumberOfTasks;
3691 
3692  /* Allocate an array index for each task. */
3693  pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );
3694 
3695  if( pxTaskStatusArray != NULL )
3696  {
3697  /* Generate the (binary) data. */
3698  uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );
3699 
3700  /* Create a human readable table from the binary data. */
3701  for( x = 0; x < uxArraySize; x++ )
3702  {
3703  switch( pxTaskStatusArray[ x ].eCurrentState )
3704  {
3705  case eReady: cStatus = tskREADY_CHAR;
3706  break;
3707 
3708  case eBlocked: cStatus = tskBLOCKED_CHAR;
3709  break;
3710 
3711  case eSuspended: cStatus = tskSUSPENDED_CHAR;
3712  break;
3713 
3714  case eDeleted: cStatus = tskDELETED_CHAR;
3715  break;
3716 
3717  default: /* Should not get here, but it is included
3718  to prevent static checking errors. */
3719  cStatus = 0x00;
3720  break;
3721  }
3722 
3723  /* Write the task name to the string, padding with spaces so it
3724  can be printed in tabular form more easily. */
3725  pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
3726 
3727  /* Write the rest of the string. */
3728  sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
3729  pcWriteBuffer += strlen( pcWriteBuffer );
3730  }
3731 
3732  /* Free the array again. */
3733  vPortFree( pxTaskStatusArray );
3734  }
3735  else
3736  {
3738  }
3739  }
3740 
3741 #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
3742 /*----------------------------------------------------------*/
3743 
3744 #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
3745 
3746  void vTaskGetRunTimeStats( char *pcWriteBuffer )
3747  {
3748  TaskStatus_t *pxTaskStatusArray;
3749  volatile UBaseType_t uxArraySize, x;
3750  uint32_t ulTotalTime, ulStatsAsPercentage;
3751 
3752  #if( configUSE_TRACE_FACILITY != 1 )
3753  {
3754  #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
3755  }
3756  #endif
3757 
3758  /*
3759  * PLEASE NOTE:
3760  *
3761  * This function is provided for convenience only, and is used by many
3762  * of the demo applications. Do not consider it to be part of the
3763  * scheduler.
3764  *
3765  * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part
3766  * of the uxTaskGetSystemState() output into a human readable table that
3767  * displays the amount of time each task has spent in the Running state
3768  * in both absolute and percentage terms.
3769  *
3770  * vTaskGetRunTimeStats() has a dependency on the sprintf() C library
3771  * function that might bloat the code size, use a lot of stack, and
3772  * provide different results on different platforms. An alternative,
3773  * tiny, third party, and limited functionality implementation of
3774  * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in
3775  * a file called printf-stdarg.c (note printf-stdarg.c does not provide
3776  * a full snprintf() implementation!).
3777  *
3778  * It is recommended that production systems call uxTaskGetSystemState()
3779  * directly to get access to raw stats data, rather than indirectly
3780  * through a call to vTaskGetRunTimeStats().
3781  */
3782 
3783  /* Make sure the write buffer does not contain a string. */
3784  *pcWriteBuffer = 0x00;
3785 
3786  /* Take a snapshot of the number of tasks in case it changes while this
3787  function is executing. */
3788  uxArraySize = uxCurrentNumberOfTasks;
3789 
3790  /* Allocate an array index for each task. */
3791  pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );
3792 
3793  if( pxTaskStatusArray != NULL )
3794  {
3795  /* Generate the (binary) data. */
3796  uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime );
3797 
3798  /* For percentage calculations. */
3799  ulTotalTime /= 100UL;
3800 
3801  /* Avoid divide by zero errors. */
3802  if( ulTotalTime > 0 )
3803  {
3804  /* Create a human readable table from the binary data. */
3805  for( x = 0; x < uxArraySize; x++ )
3806  {
3807  /* What percentage of the total run time has the task used?
3808  This will always be rounded down to the nearest integer.
3809  ulTotalRunTimeDiv100 has already been divided by 100. */
3810  ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
3811 
3812  /* Write the task name to the string, padding with
3813  spaces so it can be printed in tabular form more
3814  easily. */
3815  pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
3816 
3817  if( ulStatsAsPercentage > 0UL )
3818  {
3819  #ifdef portLU_PRINTF_SPECIFIER_REQUIRED
3820  {
3821  sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
3822  }
3823  #else
3824  {
3825  /* sizeof( int ) == sizeof( long ) so a smaller
3826  printf() library can be used. */
3827  sprintf( pcWriteBuffer, "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
3828  }
3829  #endif
3830  }
3831  else
3832  {
3833  /* If the percentage is zero here then the task has
3834  consumed less than 1% of the total run time. */
3835  #ifdef portLU_PRINTF_SPECIFIER_REQUIRED
3836  {
3837  sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter );
3838  }
3839  #else
3840  {
3841  /* sizeof( int ) == sizeof( long ) so a smaller
3842  printf() library can be used. */
3843  sprintf( pcWriteBuffer, "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter );
3844  }
3845  #endif
3846  }
3847 
3848  pcWriteBuffer += strlen( pcWriteBuffer );
3849  }
3850  }
3851  else
3852  {
3854  }
3855 
3856  /* Free the array again. */
3857  vPortFree( pxTaskStatusArray );
3858  }
3859  else
3860  {
3862  }
3863  }
3864 
3865 #endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
3866 /*-----------------------------------------------------------*/
3867 
3869 {
3870 TickType_t uxReturn;
3871 
3873 
3874  /* Reset the event list item to its normal value - so it can be used with
3875  queues and semaphores. */
3876  listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
3877 
3878  return uxReturn;
3879 }
3880 /*-----------------------------------------------------------*/
3881 
3882 #if ( configUSE_MUTEXES == 1 )
3883 
3884  void *pvTaskIncrementMutexHeldCount( void )
3885  {
3886  /* If xSemaphoreCreateMutex() is called before any tasks have been created
3887  then pxCurrentTCB will be NULL. */
3888  if( pxCurrentTCB != NULL )
3889  {
3890  ( pxCurrentTCB->uxMutexesHeld )++;
3891  }
3892 
3893  return pxCurrentTCB;
3894  }
3895 
3896 #endif /* configUSE_MUTEXES */
3897 /*-----------------------------------------------------------*/
3898 
3899 #if( configUSE_TASK_NOTIFICATIONS == 1 )
3900 
3901  uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
3902  {
3903  TickType_t xTimeToWake;
3904  uint32_t ulReturn;
3905 
3907  {
3908  /* Only block if the notification count is not already non-zero. */
3909  if( pxCurrentTCB->ulNotifiedValue == 0UL )
3910  {
3911  /* Mark this task as waiting for a notification. */
3912  pxCurrentTCB->eNotifyState = eWaitingNotification;
3913 
3914  if( xTicksToWait > ( TickType_t ) 0 )
3915  {
3916  /* The task is going to block. First it must be removed
3917  from the ready list. */
3918  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
3919  {
3920  /* The current task must be in a ready list, so there is
3921  no need to check, and the port reset macro can be called
3922  directly. */
3923  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
3924  }
3925  else
3926  {
3928  }
3929 
3930  #if ( INCLUDE_vTaskSuspend == 1 )
3931  {
3932  if( xTicksToWait == portMAX_DELAY )
3933  {
3934  /* Add the task to the suspended task list instead
3935  of a delayed task list to ensure the task is not
3936  woken by a timing event. It will block
3937  indefinitely. */
3938  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
3939  }
3940  else
3941  {
3942  /* Calculate the time at which the task should be
3943  woken if no notification events occur. This may
3944  overflow but this doesn't matter, the scheduler will
3945  handle it. */
3946  xTimeToWake = xTickCount + xTicksToWait;
3947  prvAddCurrentTaskToDelayedList( xTimeToWake );
3948  }
3949  }
3950  #else /* INCLUDE_vTaskSuspend */
3951  {
3952  /* Calculate the time at which the task should be
3953  woken if the event does not occur. This may
3954  overflow but this doesn't matter, the scheduler will
3955  handle it. */
3956  xTimeToWake = xTickCount + xTicksToWait;
3957  prvAddCurrentTaskToDelayedList( xTimeToWake );
3958  }
3959  #endif /* INCLUDE_vTaskSuspend */
3960 
3962 
3963  /* All ports are written to allow a yield in a critical
3964  section (some will yield immediately, others wait until the
3965  critical section exits) - but it is not something that
3966  application code should ever do. */
3968  }
3969  else
3970  {
3972  }
3973  }
3974  else
3975  {
3977  }
3978  }
3980 
3982  {
3984  ulReturn = pxCurrentTCB->ulNotifiedValue;
3985 
3986  if( ulReturn != 0UL )
3987  {
3988  if( xClearCountOnExit != pdFALSE )
3989  {
3990  pxCurrentTCB->ulNotifiedValue = 0UL;
3991  }
3992  else
3993  {
3994  ( pxCurrentTCB->ulNotifiedValue )--;
3995  }
3996  }
3997  else
3998  {
4000  }
4001 
4002  pxCurrentTCB->eNotifyState = eNotWaitingNotification;
4003  }
4005 
4006  return ulReturn;
4007  }
4008 
4009 #endif /* configUSE_TASK_NOTIFICATIONS */
4010 /*-----------------------------------------------------------*/
4011 
4012 #if( configUSE_TASK_NOTIFICATIONS == 1 )
4013 
4014  BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
4015  {
4016  TickType_t xTimeToWake;
4017  BaseType_t xReturn;
4018 
4020  {
4021  /* Only block if a notification is not already pending. */
4022  if( pxCurrentTCB->eNotifyState != eNotified )
4023  {
4024  /* Clear bits in the task's notification value as bits may get
4025  set by the notifying task or interrupt. This can be used to
4026  clear the value to zero. */
4027  pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;
4028 
4029  /* Mark this task as waiting for a notification. */
4030  pxCurrentTCB->eNotifyState = eWaitingNotification;
4031 
4032  if( xTicksToWait > ( TickType_t ) 0 )
4033  {
4034  /* The task is going to block. First it must be removed
4035  from the ready list. */
4036  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
4037  {
4038  /* The current task must be in a ready list, so there is
4039  no need to check, and the port reset macro can be called
4040  directly. */
4041  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
4042  }
4043  else
4044  {
4046  }
4047 
4048  #if ( INCLUDE_vTaskSuspend == 1 )
4049  {
4050  if( xTicksToWait == portMAX_DELAY )
4051  {
4052  /* Add the task to the suspended task list instead
4053  of a delayed task list to ensure the task is not
4054  woken by a timing event. It will block
4055  indefinitely. */
4056  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
4057  }
4058  else
4059  {
4060  /* Calculate the time at which the task should be
4061  woken if no notification events occur. This may
4062  overflow but this doesn't matter, the scheduler will
4063  handle it. */
4064  xTimeToWake = xTickCount + xTicksToWait;
4065  prvAddCurrentTaskToDelayedList( xTimeToWake );
4066  }
4067  }
4068  #else /* INCLUDE_vTaskSuspend */
4069  {
4070  /* Calculate the time at which the task should be
4071  woken if the event does not occur. This may
4072  overflow but this doesn't matter, the scheduler will
4073  handle it. */
4074  xTimeToWake = xTickCount + xTicksToWait;
4075  prvAddCurrentTaskToDelayedList( xTimeToWake );
4076  }
4077  #endif /* INCLUDE_vTaskSuspend */
4078 
4080 
4081  /* All ports are written to allow a yield in a critical
4082  section (some will yield immediately, others wait until the
4083  critical section exits) - but it is not something that
4084  application code should ever do. */
4086  }
4087  else
4088  {
4090  }
4091  }
4092  else
4093  {
4095  }
4096  }
4098 
4100  {
4102 
4103  if( pulNotificationValue != NULL )
4104  {
4105  /* Output the current notification value, which may or may not
4106  have changed. */
4107  *pulNotificationValue = pxCurrentTCB->ulNotifiedValue;
4108  }
4109 
4110  /* If eNotifyValue is set then either the task never entered the
4111  blocked state (because a notification was already pending) or the
4112  task unblocked because of a notification. Otherwise the task
4113  unblocked because of a timeout. */
4114  if( pxCurrentTCB->eNotifyState == eWaitingNotification )
4115  {
4116  /* A notification was not received. */
4117  xReturn = pdFALSE;
4118  }
4119  else
4120  {
4121  /* A notification was already pending or a notification was
4122  received while the task was waiting. */
4123  pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;
4124  xReturn = pdTRUE;
4125  }
4126 
4127  pxCurrentTCB->eNotifyState = eNotWaitingNotification;
4128  }
4130 
4131  return xReturn;
4132  }
4133 
4134 #endif /* configUSE_TASK_NOTIFICATIONS */
4135 /*-----------------------------------------------------------*/
4136 
4137 #if( configUSE_TASK_NOTIFICATIONS == 1 )
4138 
4139  BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue )
4140  {
4141  TCB_t * pxTCB;
4142  eNotifyValue eOriginalNotifyState;
4143  BaseType_t xReturn = pdPASS;
4144 
4145  configASSERT( xTaskToNotify );
4146  pxTCB = ( TCB_t * ) xTaskToNotify;
4147 
4149  {
4150  if( pulPreviousNotificationValue != NULL )
4151  {
4152  *pulPreviousNotificationValue = pxTCB->ulNotifiedValue;
4153  }
4154 
4155  eOriginalNotifyState = pxTCB->eNotifyState;
4156 
4157  pxTCB->eNotifyState = eNotified;
4158 
4159  switch( eAction )
4160  {
4161  case eSetBits :
4162  pxTCB->ulNotifiedValue |= ulValue;
4163  break;
4164 
4165  case eIncrement :
4166  ( pxTCB->ulNotifiedValue )++;
4167  break;
4168 
4169  case eSetValueWithOverwrite :
4170  pxTCB->ulNotifiedValue = ulValue;
4171  break;
4172 
4174  if( eOriginalNotifyState != eNotified )
4175  {
4176  pxTCB->ulNotifiedValue = ulValue;
4177  }
4178  else
4179  {
4180  /* The value could not be written to the task. */
4181  xReturn = pdFAIL;
4182  }
4183  break;
4184 
4185  case eNoAction:
4186  /* The task is being notified without its notify value being
4187  updated. */
4188  break;
4189  }
4190 
4191  traceTASK_NOTIFY();
4192 
4193  /* If the task is in the blocked state specifically to wait for a
4194  notification then unblock it now. */
4195  if( eOriginalNotifyState == eWaitingNotification )
4196  {
4197  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
4198  prvAddTaskToReadyList( pxTCB );
4199 
4200  /* The task should not have been on an event list. */
4202 
4203  #if( configUSE_TICKLESS_IDLE != 0 )
4204  {
4205  /* If a task is blocked waiting for a notification then
4206  xNextTaskUnblockTime might be set to the blocked task's time
4207  out time. If the task is unblocked for a reason other than
4208  a timeout xNextTaskUnblockTime is normally left unchanged,
4209  because it will automatically get reset to a new value when
4210  the tick count equals xNextTaskUnblockTime. However if
4211  tickless idling is used it might be more important to enter
4212  sleep mode at the earliest possible time - so reset
4213  xNextTaskUnblockTime here to ensure it is updated at the
4214  earliest possible time. */
4215  prvResetNextTaskUnblockTime();
4216  }
4217  #endif
4218 
4219  if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
4220  {
4221  /* The notified task has a priority above the currently
4222  executing task so a yield is required. */
4224  }
4225  else
4226  {
4228  }
4229  }
4230  else
4231  {
4233  }
4234  }
4236 
4237  return xReturn;
4238  }
4239 
4240 #endif /* configUSE_TASK_NOTIFICATIONS */
4241 /*-----------------------------------------------------------*/
4242 
4243 #if( configUSE_TASK_NOTIFICATIONS == 1 )
4244 
4245  BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken )
4246  {
4247  TCB_t * pxTCB;
4248  eNotifyValue eOriginalNotifyState;
4249  BaseType_t xReturn = pdPASS;
4250  UBaseType_t uxSavedInterruptStatus;
4251 
4252  configASSERT( xTaskToNotify );
4253 
4254  /* RTOS ports that support interrupt nesting have the concept of a
4255  maximum system call (or maximum API call) interrupt priority.
4256  Interrupts that are above the maximum system call priority are keep
4257  permanently enabled, even when the RTOS kernel is in a critical section,
4258  but cannot make any calls to FreeRTOS API functions. If configASSERT()
4259  is defined in FreeRTOSConfig.h then
4260  portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
4261  failure if a FreeRTOS API function is called from an interrupt that has
4262  been assigned a priority above the configured maximum system call
4263  priority. Only FreeRTOS functions that end in FromISR can be called
4264  from interrupts that have been assigned a priority at or (logically)
4265  below the maximum system call interrupt priority. FreeRTOS maintains a
4266  separate interrupt safe API to ensure interrupt entry is as fast and as
4267  simple as possible. More information (albeit Cortex-M specific) is
4268  provided on the following link:
4269  http://www.freertos.org/RTOS-Cortex-M3-M4.html */
4271 
4272  pxTCB = ( TCB_t * ) xTaskToNotify;
4273 
4274  uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
4275  {
4276  if( pulPreviousNotificationValue != NULL )
4277  {
4278  *pulPreviousNotificationValue = pxTCB->ulNotifiedValue;
4279  }
4280 
4281  eOriginalNotifyState = pxTCB->eNotifyState;
4282  pxTCB->eNotifyState = eNotified;
4283 
4284  switch( eAction )
4285  {
4286  case eSetBits :
4287  pxTCB->ulNotifiedValue |= ulValue;
4288  break;
4289 
4290  case eIncrement :
4291  ( pxTCB->ulNotifiedValue )++;
4292  break;
4293 
4294  case eSetValueWithOverwrite :
4295  pxTCB->ulNotifiedValue = ulValue;
4296  break;
4297 
4299  if( eOriginalNotifyState != eNotified )
4300  {
4301  pxTCB->ulNotifiedValue = ulValue;
4302  }
4303  else
4304  {
4305  /* The value could not be written to the task. */
4306  xReturn = pdFAIL;
4307  }
4308  break;
4309 
4310  case eNoAction :
4311  /* The task is being notified without its notify value being
4312  updated. */
4313  break;
4314  }
4315 
4317 
4318  /* If the task is in the blocked state specifically to wait for a
4319  notification then unblock it now. */
4320  if( eOriginalNotifyState == eWaitingNotification )
4321  {
4322  /* The task should not have been on an event list. */
4324 
4325  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
4326  {
4327  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
4328  prvAddTaskToReadyList( pxTCB );
4329  }
4330  else
4331  {
4332  /* The delayed and ready lists cannot be accessed, so hold
4333  this task pending until the scheduler is resumed. */
4334  vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
4335  }
4336 
4337  if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
4338  {
4339  /* The notified task has a priority above the currently
4340  executing task so a yield is required. */
4341  if( pxHigherPriorityTaskWoken != NULL )
4342  {
4343  *pxHigherPriorityTaskWoken = pdTRUE;
4344  }
4345  }
4346  else
4347  {
4349  }
4350  }
4351  }
4352  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
4353 
4354  return xReturn;
4355  }
4356 
4357 #endif /* configUSE_TASK_NOTIFICATIONS */
4358 /*-----------------------------------------------------------*/
4359 
4360 #if( configUSE_TASK_NOTIFICATIONS == 1 )
4361 
4362  void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken )
4363  {
4364  TCB_t * pxTCB;
4365  eNotifyValue eOriginalNotifyState;
4366  UBaseType_t uxSavedInterruptStatus;
4367 
4368  configASSERT( xTaskToNotify );
4369 
4370  /* RTOS ports that support interrupt nesting have the concept of a
4371  maximum system call (or maximum API call) interrupt priority.
4372  Interrupts that are above the maximum system call priority are keep
4373  permanently enabled, even when the RTOS kernel is in a critical section,
4374  but cannot make any calls to FreeRTOS API functions. If configASSERT()
4375  is defined in FreeRTOSConfig.h then
4376  portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
4377  failure if a FreeRTOS API function is called from an interrupt that has
4378  been assigned a priority above the configured maximum system call
4379  priority. Only FreeRTOS functions that end in FromISR can be called
4380  from interrupts that have been assigned a priority at or (logically)
4381  below the maximum system call interrupt priority. FreeRTOS maintains a
4382  separate interrupt safe API to ensure interrupt entry is as fast and as
4383  simple as possible. More information (albeit Cortex-M specific) is
4384  provided on the following link:
4385  http://www.freertos.org/RTOS-Cortex-M3-M4.html */
4387 
4388  pxTCB = ( TCB_t * ) xTaskToNotify;
4389 
4390  uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
4391  {
4392  eOriginalNotifyState = pxTCB->eNotifyState;
4393  pxTCB->eNotifyState = eNotified;
4394 
4395  /* 'Giving' is equivalent to incrementing a count in a counting
4396  semaphore. */
4397  ( pxTCB->ulNotifiedValue )++;
4398 
4400 
4401  /* If the task is in the blocked state specifically to wait for a
4402  notification then unblock it now. */
4403  if( eOriginalNotifyState == eWaitingNotification )
4404  {
4405  /* The task should not have been on an event list. */
4407 
4408  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
4409  {
4410  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
4411  prvAddTaskToReadyList( pxTCB );
4412  }
4413  else
4414  {
4415  /* The delayed and ready lists cannot be accessed, so hold
4416  this task pending until the scheduler is resumed. */
4417  vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
4418  }
4419 
4420  if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
4421  {
4422  /* The notified task has a priority above the currently
4423  executing task so a yield is required. */
4424  if( pxHigherPriorityTaskWoken != NULL )
4425  {
4426  *pxHigherPriorityTaskWoken = pdTRUE;
4427  }
4428  }
4429  else
4430  {
4432  }
4433  }
4434  }
4435  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
4436  }
4437 
4438 #endif /* configUSE_TASK_NOTIFICATIONS */
4439 
4440 /*-----------------------------------------------------------*/
4441 
4442 #if( configUSE_TASK_NOTIFICATIONS == 1 )
4443 
4445  {
4446  TCB_t *pxTCB;
4447  BaseType_t xReturn;
4448 
4449  pxTCB = ( TCB_t * ) xTask;
4450 
4451  /* If null is passed in here then it is the calling task that is having
4452  its notification state cleared. */
4453  pxTCB = prvGetTCBFromHandle( pxTCB );
4454 
4456  {
4457  if( pxTCB->eNotifyState == eNotified )
4458  {
4459  pxTCB->eNotifyState = eNotWaitingNotification;
4460  xReturn = pdPASS;
4461  }
4462  else
4463  {
4464  xReturn = pdFAIL;
4465  }
4466  }
4468 
4469  return xReturn;
4470  }
4471 
4472 #endif /* configUSE_TASK_NOTIFICATIONS */
4473 
4474 #ifdef FREERTOS_MODULE_TEST
4475  #include "tasks_test_access_functions.h"
4476 #endif
4477 
#define pdTRUE
Definition: projdefs.h:83
#define pxMutexHolder
Definition: queue.c:108
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition: heap_1.c:149
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime)
Definition: FreeRTOS.h:696
#define listGET_LIST_ITEM_VALUE(pxListItem)
Definition: list.h:249
#define listGET_OWNER_OF_NEXT_ENTRY(pxTCB, pxList)
Definition: list.h:318
#define portMAX_DELAY
Definition: portmacro.h:106
#define tskDELETED_CHAR
Definition: tasks.c:284
UBaseType_t uxTaskPriorityGetFromISR(TaskHandle_t xTask) PRIVILEGED_FUNCTION
void vTaskSetTaskNumber(TaskHandle_t xTask, const UBaseType_t uxHandle) PRIVILEGED_FUNCTION
#define traceLOW_POWER_IDLE_END()
Definition: FreeRTOS.h:361
BaseType_t xTaskRemoveFromUnorderedEventList(ListItem_t *pxEventListItem, const TickType_t xItemValue)
Definition: tasks.c:2533
void vTaskGetRunTimeStats(char *pcWriteBuffer) PRIVILEGED_FUNCTION
void vTaskSwitchContext(void)
Definition: tasks.c:2203
#define listIS_CONTAINED_WITHIN(pxList, pxListItem)
Definition: list.h:359
BaseType_t xTaskCheckForTimeOut(TimeOut_t *const pxTimeOut, TickType_t *const pxTicksToWait)
Definition: tasks.c:2586
TaskHandle_t xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION
#define traceTASK_SUSPEND(pxTaskToSuspend)
Definition: FreeRTOS.h:526
#define mtCOVERAGE_TEST_MARKER()
Definition: FreeRTOS.h:752
UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove) PRIVILEGED_FUNCTION
Definition: list.c:212
#define traceTASK_DELAY()
Definition: FreeRTOS.h:518
#define listLIST_ITEM_CONTAINER(pxListItem)
Definition: list.h:367
void vTaskSuspendAll(void)
Definition: tasks.c:1633
void vTaskEndScheduler(void)
Definition: tasks.c:1622
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP
Definition: FreeRTOS.h:700
#define taskEXIT_CRITICAL()
Definition: task.h:231
#define traceTASK_CREATE(pxNewTCB)
Definition: FreeRTOS.h:502
PRIVILEGED_DATA TCB_t *volatile pxCurrentTCB
Definition: tasks.c:212
void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority) PRIVILEGED_FUNCTION
#define portASSERT_IF_IN_ISR()
Definition: FreeRTOS.h:760
TickType_t xTimeOnEntering
Definition: task.h:137
#define portENABLE_INTERRUPTS()
Definition: portmacro.h:144
Definition: task.h:114
#define configASSERT(x)
#define taskSCHEDULER_NOT_STARTED
Definition: task.h:257
#define traceTASK_DELAY_UNTIL()
Definition: FreeRTOS.h:514
void vTaskPlaceOnEventListRestricted(List_t *const pxEventList, const TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely) PRIVILEGED_FUNCTION
#define tskSTACK_FILL_BYTE
Definition: tasks.c:277
#define taskYIELD()
Definition: task.h:202
#define portDISABLE_INTERRUPTS()
Definition: portmacro.h:143
eNotifyValue
Definition: tasks.c:122
#define traceLOW_POWER_IDLE_BEGIN()
Definition: FreeRTOS.h:356
#define prvAddTaskToReadyList(pxTCB)
Definition: tasks.c:389
Definition: task.h:118
#define tskIDLE_STACK_SIZE
Definition: tasks.c:111
uint32_t ulRunTimeCounter
Definition: task.h:174
void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION
Definition: list.c:116
void * pvTaskIncrementMutexHeldCount(void) PRIVILEGED_FUNCTION
#define taskSCHEDULER_RUNNING
Definition: task.h:258
eNotifyAction
Definition: task.h:122
BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION
#define portTICK_TYPE_ENTER_CRITICAL()
Definition: FreeRTOS.h:783
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_1.c:99
#define listSET_LIST_ITEM_VALUE(pxListItem, xValue)
Definition: list.h:239
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue)
Definition: FreeRTOS.h:301
#define portYIELD_WITHIN_API
Definition: FreeRTOS.h:684
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR()
Definition: FreeRTOS.h:785
#define traceTASK_PRIORITY_INHERIT(pxTCBOfMutexHolder, uxInheritedPriority)
Definition: FreeRTOS.h:376
char pcTaskName[configMAX_TASK_NAME_LEN]
Definition: tasks.c:147
BaseType_t xTaskCallApplicationTaskHook(TaskHandle_t xTask, void *pvParameter) PRIVILEGED_FUNCTION
BaseType_t xTaskRemoveFromEventList(const List_t *const pxEventList)
Definition: tasks.c:2465
#define listLIST_IS_EMPTY(pxList)
Definition: list.h:291
#define portSTACK_GROWTH
Definition: portmacro.h:115
void vTaskList(char *pcWriteBuffer) PRIVILEGED_FUNCTION
Definition: task.h:115
#define traceTASK_RESUME(pxTaskToResume)
Definition: FreeRTOS.h:530
#define configMAX_PRIORITIES
void vPortEndScheduler(void) PRIVILEGED_FUNCTION
Definition: port.c:383
#define portRESET_READY_PRIORITY(uxPriority, uxTopReadyPriority)
Definition: tasks.c:327
BaseType_t xTaskGenericNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION
unsigned long UBaseType_t
Definition: portmacro.h:99
ListItem_t xEventListItem
Definition: tasks.c:144
uint32_t TickType_t
Definition: portmacro.h:105
#define traceINCREASE_TICK_COUNT(x)
Definition: FreeRTOS.h:351
#define traceTASK_SWITCHED_IN()
Definition: FreeRTOS.h:345
void vTaskStepTick(const TickType_t xTicksToJump) PRIVILEGED_FUNCTION
#define portSET_INTERRUPT_MASK_FROM_ISR()
Definition: FreeRTOS.h:297
BaseType_t xPortStartScheduler(void) PRIVILEGED_FUNCTION
Definition: port.c:302
eTaskState
Definition: task.h:112
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR(x)
Definition: FreeRTOS.h:786
StackType_t * pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) PRIVILEGED_FUNCTION
#define portTICK_TYPE_EXIT_CRITICAL()
Definition: FreeRTOS.h:784
#define NULL
Definition: usbd_def.h:53
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
#define traceTASK_SWITCHED_OUT()
Definition: FreeRTOS.h:367
UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask) PRIVILEGED_FUNCTION
#define traceTASK_NOTIFY_WAIT()
Definition: FreeRTOS.h:638
#define listSET_LIST_ITEM_OWNER(pxListItem, pxOwner)
Definition: list.h:221
BaseType_t(* TaskHookFunction_t)(void *)
Definition: task.h:109
Definition: task.h:125
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
Definition: projdefs.h:91
#define portPRIVILEGE_BIT
Definition: FreeRTOS.h:680
#define prvGetTCBFromHandle(pxHandle)
Definition: tasks.c:401
char * pcTaskGetTaskName(TaskHandle_t xTaskToQuery) PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA
Definition: mpu_wrappers.h:170
TickType_t uxTaskResetEventItemValue(void)
Definition: tasks.c:3868
void vTaskDelete(TaskHandle_t xTaskToDelete) PRIVILEGED_FUNCTION
UBaseType_t uxTaskGetTaskNumber(TaskHandle_t xTask) PRIVILEGED_FUNCTION
#define tskREADY_CHAR
Definition: tasks.c:283
BaseType_t xTaskPriorityDisinherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION
#define traceTASK_PRIORITY_SET(pxTask, uxNewPriority)
Definition: FreeRTOS.h:522
BaseType_t xOverflowCount
Definition: task.h:136
#define pdFAIL
Definition: projdefs.h:86
#define taskRESET_READY_PRIORITY(uxPriority)
Definition: tasks.c:326
#define taskCHECK_FOR_STACK_OVERFLOW()
Definition: StackMacros.h:165
UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask) PRIVILEGED_FUNCTION
void vTaskDelayUntil(TickType_t *const pxPreviousWakeTime, const TickType_t xTimeIncrement) PRIVILEGED_FUNCTION
long BaseType_t
Definition: portmacro.h:98
void vTaskSuspend(TaskHandle_t xTaskToSuspend) PRIVILEGED_FUNCTION
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS
Definition: FreeRTOS.h:204
TaskHandle_t xTaskGetIdleTaskHandle(void) PRIVILEGED_FUNCTION
#define traceTASK_PRIORITY_DISINHERIT(pxTCBOfMutexHolder, uxOriginalPriority)
Definition: FreeRTOS.h:384
TaskHandle_t xHandle
Definition: task.h:168
#define pdPASS
Definition: projdefs.h:85
#define listGET_OWNER_OF_HEAD_ENTRY(pxList)
Definition: list.h:348
UBaseType_t uxBasePriority
Definition: task.h:173
void * TaskHandle_t
Definition: task.h:103
UBaseType_t uxPriority
Definition: tasks.c:145
UBaseType_t uxCurrentPriority
Definition: task.h:172
void vTaskPriorityInherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION
#define traceTASK_NOTIFY_TAKE_BLOCK()
Definition: FreeRTOS.h:626
#define traceTASK_CREATE_FAILED()
Definition: FreeRTOS.h:506
UBaseType_t uxTaskGetNumberOfTasks(void)
Definition: tasks.c:1810
void vTaskStartScheduler(void)
Definition: tasks.c:1543
void vTaskSetTimeOutState(TimeOut_t *const pxTimeOut)
Definition: tasks.c:2578
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION
#define portPRE_TASK_DELETE_HOOK(pvTaskToDelete, pxYieldPending)
Definition: FreeRTOS.h:309
#define pvPortMallocAligned(x, puxStackBuffer)
Definition: FreeRTOS.h:688
BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask)
void vTaskPlaceOnUnorderedEventList(List_t *pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait)
Definition: tasks.c:2321
void vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION
Definition: list.c:145
#define tskSUSPENDED_CHAR
Definition: tasks.c:285
eSleepModeStatus
Definition: task.h:179
const char * pcTaskName
Definition: task.h:169
#define portSETUP_TCB(pxTCB)
Definition: FreeRTOS.h:313
void vTaskResume(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION
void vTaskAllocateMPURegions(TaskHandle_t xTask, const MemoryRegion_t *const pxRegions) PRIVILEGED_FUNCTION
UBaseType_t xTaskNumber
Definition: task.h:170
#define pdFALSE
Definition: projdefs.h:82
TickType_t xTaskGetTickCount(void)
Definition: tasks.c:1764
BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION
#define taskYIELD_IF_USING_PREEMPTION()
Definition: tasks.c:116
#define taskENTER_CRITICAL()
Definition: task.h:216
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters)
Definition: portmacro.h:153
volatile StackType_t * pxTopOfStack
Definition: tasks.c:136
#define portPOINTER_SIZE_TYPE
Definition: FreeRTOS.h:326
eTaskState eCurrentState
Definition: task.h:171
eSleepModeStatus eTaskConfirmSleepModeStatus(void) PRIVILEGED_FUNCTION
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait) PRIVILEGED_FUNCTION
#define listGET_LIST_ITEM_OWNER(pxListItem)
Definition: list.h:230
BaseType_t xTaskResumeAll(void)
Definition: tasks.c:1671
#define taskSELECT_HIGHEST_PRIORITY_TASK()
Definition: tasks.c:307
#define traceTASK_NOTIFY_WAIT_BLOCK()
Definition: FreeRTOS.h:634
#define traceTASK_NOTIFY_TAKE()
Definition: FreeRTOS.h:630
#define traceTASK_NOTIFY()
Definition: FreeRTOS.h:642
BaseType_t xTaskGenericCreate(TaskFunction_t pxTaskCode, const char *const pcName, const uint16_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const pxCreatedTask, StackType_t *const puxStackBuffer, const MemoryRegion_t *const xRegions) PRIVILEGED_FUNCTION
#define PRIVILEGED_FUNCTION
Definition: mpu_wrappers.h:169
void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION
#define traceTASK_INCREMENT_TICK(xTickCount)
Definition: FreeRTOS.h:538
#define tskIDLE_PRIORITY
Definition: task.h:192
#define vPortFreeAligned(pvBlockToFree)
Definition: FreeRTOS.h:692
Definition: task.h:116
#define taskEVENT_LIST_ITEM_VALUE_IN_USE
Definition: tasks.c:414
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
Definition: FreeRTOS.h:672
#define traceTASK_RESUME_FROM_ISR(pxTaskToResume)
Definition: FreeRTOS.h:534
ListItem_t xGenericListItem
Definition: tasks.c:143
#define taskSCHEDULER_SUSPENDED
Definition: task.h:256
tskTCB TCB_t
Definition: tasks.c:199
BaseType_t xTimerCreateTimerTask(void) PRIVILEGED_FUNCTION
Definition: list.h:205
UBaseType_t uxTaskGetSystemState(TaskStatus_t *const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t *const pulTotalRunTime) PRIVILEGED_FUNCTION
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
Definition: FreeRTOS.h:744
#define listCURRENT_LIST_LENGTH(pxList)
Definition: list.h:296
#define traceTASK_NOTIFY_GIVE_FROM_ISR()
Definition: FreeRTOS.h:650
BaseType_t xTaskGenericNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue) PRIVILEGED_FUNCTION
#define xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask)
Definition: task.h:345
TickType_t xTaskGetTickCountFromISR(void)
Definition: tasks.c:1779
#define tskBLOCKED_CHAR
Definition: tasks.c:282
#define taskSWITCH_DELAYED_LISTS()
Definition: tasks.c:369
void vTaskPlaceOnEventList(List_t *const pxEventList, const TickType_t xTicksToWait)
Definition: tasks.c:2262
void(* TaskFunction_t)(void *)
Definition: projdefs.h:77
#define traceTASK_NOTIFY_FROM_ISR()
Definition: FreeRTOS.h:646
void vListInitialise(List_t *const pxList) PRIVILEGED_FUNCTION
Definition: list.c:79
void vListInitialiseItem(ListItem_t *const pxItem) PRIVILEGED_FUNCTION
Definition: list.c:104
void vTaskMissedYield(void)
Definition: tasks.c:2635
#define traceTASK_DELETE(pxTaskToDelete)
Definition: FreeRTOS.h:510
eTaskState eTaskGetState(TaskHandle_t xTask) PRIVILEGED_FUNCTION
BaseType_t xTaskIncrementTick(void)
Definition: tasks.c:1939
portSTACK_TYPE StackType_t
Definition: portmacro.h:97
#define portCLEAN_UP_TCB(pxTCB)
Definition: FreeRTOS.h:305
#define portTASK_FUNCTION(vFunction, pvParameters)
Definition: portmacro.h:154
#define configMAX_TASK_NAME_LEN
struct tskTaskControlBlock tskTCB
StackType_t * pxStack
Definition: tasks.c:146
uint16_t usStackHighWaterMark
Definition: task.h:175