SAM4S-EK_FreeRTOS+FAT-SL  1.0
An example project to test the functionality of FreeRTOS+FAT-SL using SD card as data storage medium
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
tasks.c
Go to the documentation of this file.
1 /*
2  FreeRTOS V8.0.1 - Copyright (C) 2014 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  ***************************************************************************
8  * *
9  * FreeRTOS provides completely free yet professionally developed, *
10  * robust, strictly quality controlled, supported, and cross *
11  * platform software that has become a de facto standard. *
12  * *
13  * Help yourself get started quickly and support the FreeRTOS *
14  * project by purchasing a FreeRTOS tutorial book, reference *
15  * manual, or both from: http://www.FreeRTOS.org/Documentation *
16  * *
17  * Thank you! *
18  * *
19  ***************************************************************************
20 
21  This file is part of the FreeRTOS distribution.
22 
23  FreeRTOS is free software; you can redistribute it and/or modify it under
24  the terms of the GNU General Public License (version 2) as published by the
25  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
26 
27  >>! NOTE: The modification to the GPL is included to allow you to !<<
28  >>! distribute a combined work that includes FreeRTOS without being !<<
29  >>! obliged to provide the source code for proprietary components !<<
30  >>! outside of the FreeRTOS kernel. !<<
31 
32  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
33  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34  FOR A PARTICULAR PURPOSE. Full license text is available from the following
35  link: http://www.freertos.org/a00114.html
36 
37  1 tab == 4 spaces!
38 
39  ***************************************************************************
40  * *
41  * Having a problem? Start by reading the FAQ "My application does *
42  * not run, what could be wrong?" *
43  * *
44  * http://www.FreeRTOS.org/FAQHelp.html *
45  * *
46  ***************************************************************************
47 
48  http://www.FreeRTOS.org - Documentation, books, training, latest versions,
49  license and Real Time Engineers Ltd. contact details.
50 
51  http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
52  including FreeRTOS+Trace - an indispensable productivity tool, a DOS
53  compatible FAT file system, and our tiny thread aware UDP/IP stack.
54 
55  http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
56  Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
57  licenses offer ticketed support, indemnification and middleware.
58 
59  http://www.SafeRTOS.com - High Integrity Systems also provide a safety
60  engineered and independently SIL3 certified version for use in safety and
61  mission critical applications that require provable dependability.
62 
63  1 tab == 4 spaces!
64 */
65 
66 /* Standard includes. */
67 #include <stdlib.h>
68 #include <string.h>
69 
70 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
71 all the API functions to use the MPU wrappers. That should only be done when
72 task.h is included from an application file. */
73 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
74 
75 /* FreeRTOS includes. */
76 #include "FreeRTOS.h"
77 #include "task.h"
78 #include "timers.h"
79 #include "StackMacros.h"
80 
81 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
82 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
83 header files above, but not in this file, in order to generate the correct
84 privileged Vs unprivileged linkage and placement. */
85 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
86 
87 #if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 )
88  /* At the bottom of this file are two optional functions that can be used
89  to generate human readable text from the raw data generated by the
90  uxTaskGetSystemState() function. Note the formatting functions are provided
91  for convenience only, and are NOT considered part of the kernel. */
92  #include <stdio.h>
93 #endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */
94 
95 /* Sanity check the configuration. */
96 #if configUSE_TICKLESS_IDLE != 0
97  #if INCLUDE_vTaskSuspend != 1
98  #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0
99  #endif /* INCLUDE_vTaskSuspend */
100 #endif /* configUSE_TICKLESS_IDLE */
101 
102 /*
103  * Defines the size, in words, of the stack allocated to the idle task.
104  */
105 #define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
106 
107 #if( configUSE_PREEMPTION == 0 )
108  /* If the cooperative scheduler is being used then a yield should not be
109  performed just because a higher priority task has been woken. */
110  #define taskYIELD_IF_USING_PREEMPTION()
111 #else
112  #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
113 #endif
114 
115 /*
116  * Task control block. A task control block (TCB) is allocated for each task,
117  * and stores task state information, including a pointer to the task's context
118  * (the task's run time environment, including register values)
119  */
120 typedef struct tskTaskControlBlock
121 {
122  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. */
123 
124  #if ( portUSING_MPU_WRAPPERS == 1 )
125  xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
126  #endif
127 
128  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 ). */
129  ListItem_t xEventListItem; /*< Used to reference a task from an event list. */
130  UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */
131  StackType_t *pxStack; /*< Points to the start of the stack. */
132  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. */
133 
134  #if ( portSTACK_GROWTH > 0 )
135  StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */
136  #endif
137 
138  #if ( portCRITICAL_NESTING_IN_TCB == 1 )
139  UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
140  #endif
141 
142  #if ( configUSE_TRACE_FACILITY == 1 )
143  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. */
144  UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
145  #endif
146 
147  #if ( configUSE_MUTEXES == 1 )
148  UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
149  #endif
150 
151  #if ( configUSE_APPLICATION_TASK_TAG == 1 )
152  TaskHookFunction_t pxTaskTag;
153  #endif
154 
155  #if ( configGENERATE_RUN_TIME_STATS == 1 )
156  uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
157  #endif
158 
159  #if ( configUSE_NEWLIB_REENTRANT == 1 )
160  /* Allocate a Newlib reent structure that is specific to this task.
161  Note Newlib support has been included by popular demand, but is not
162  used by the FreeRTOS maintainers themselves. FreeRTOS is not
163  responsible for resulting newlib operation. User must be familiar with
164  newlib and must provide system-wide implementations of the necessary
165  stubs. Be warned that (at the time of writing) the current newlib design
166  implements a system-wide malloc() that must be provided with locks. */
167  struct _reent xNewLib_reent;
168  #endif
169 
170 } tskTCB;
171 
172 /* The old tskTCB name is maintained above then typedefed to the new TCB_t name
173 below to enable the use of older kernel aware debuggers. */
174 typedef tskTCB TCB_t;
175 
176 /*
177  * Some kernel aware debuggers require the data the debugger needs access to to
178  * be global, rather than file scope.
179  */
180 #ifdef portREMOVE_STATIC_QUALIFIER
181  #define static
182 #endif
183 
184 /*lint -e956 A manual analysis and inspection has been used to determine which
185 static variables must be declared volatile. */
186 
188 
189 /* Lists for ready and blocked tasks. --------------------*/
190 PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */
191 PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */
192 PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
193 PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */
194 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. */
195 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. */
196 
197 #if ( INCLUDE_vTaskDelete == 1 )
198 
199  PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */
200  PRIVILEGED_DATA static volatile UBaseType_t uxTasksDeleted = ( UBaseType_t ) 0U;
201 
202 #endif
203 
204 #if ( INCLUDE_vTaskSuspend == 1 )
205 
206  PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */
207 
208 #endif
209 
210 #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
211 
212  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. */
213 
214 #endif
215 
216 /* Other file private variables. --------------------------------*/
217 PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
218 PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U;
219 PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY;
220 PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE;
221 PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U;
222 PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE;
223 PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0;
224 PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;
225 PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = portMAX_DELAY;
226 
227 /* Context switches are held pending while the scheduler is suspended. Also,
228 interrupts must not manipulate the xStateListItem of a TCB, or any of the
229 lists the xStateListItem can be referenced from, if the scheduler is suspended.
230 If an interrupt needs to unblock a task while the scheduler is suspended then it
231 moves the task's event list item into the xPendingReadyList, ready for the
232 kernel to move the task from the pending ready list into the real ready list
233 when the scheduler is unsuspended. The pending ready list itself can only be
234 accessed from a critical section. */
235 PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE;
236 
237 #if ( configGENERATE_RUN_TIME_STATS == 1 )
238 
239  PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
240  PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
241 
242 #endif
243 
244 /*lint +e956 */
245 
246 /* Debugging and trace facilities private variables and macros. ------------*/
247 
248 /*
249  * The value used to fill the stack of a task when the task is created. This
250  * is used purely for checking the high water mark for tasks.
251  */
252 #define tskSTACK_FILL_BYTE ( 0xa5U )
253 
254 /*
255  * Macros used by vListTask to indicate which state a task is in.
256  */
257 #define tskBLOCKED_CHAR ( 'B' )
258 #define tskREADY_CHAR ( 'R' )
259 #define tskDELETED_CHAR ( 'D' )
260 #define tskSUSPENDED_CHAR ( 'S' )
261 
262 /*-----------------------------------------------------------*/
263 
264 #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
265 
266  /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
267  performed in a generic way that is not optimised to any particular
268  microcontroller architecture. */
269 
270  /* uxTopReadyPriority holds the priority of the highest priority ready
271  state task. */
272  #define taskRECORD_READY_PRIORITY( uxPriority ) \
273  { \
274  if( ( uxPriority ) > uxTopReadyPriority ) \
275  { \
276  uxTopReadyPriority = ( uxPriority ); \
277  } \
278  } /* taskRECORD_READY_PRIORITY */
279 
280  /*-----------------------------------------------------------*/
281 
282  #define taskSELECT_HIGHEST_PRIORITY_TASK() \
283  { \
284  /* Find the highest priority queue that contains ready tasks. */ \
285  while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \
286  { \
287  configASSERT( uxTopReadyPriority ); \
288  --uxTopReadyPriority; \
289  } \
290  \
291  /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \
292  the same priority get an equal share of the processor time. */ \
293  listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \
294  } /* taskSELECT_HIGHEST_PRIORITY_TASK */
295 
296  /*-----------------------------------------------------------*/
297 
298  /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as
299  they are only required when a port optimised method of task selection is
300  being used. */
301  #define taskRESET_READY_PRIORITY( uxPriority )
302  #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority )
303 
304 #else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
305 
306  /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is
307  performed in a way that is tailored to the particular microcontroller
308  architecture being used. */
309 
310  /* A port optimised version is provided. Call the port defined macros. */
311  #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )
312 
313  /*-----------------------------------------------------------*/
314 
315  #define taskSELECT_HIGHEST_PRIORITY_TASK() \
316  { \
317  UBaseType_t uxTopPriority; \
318  \
319  /* Find the highest priority queue that contains ready tasks. */ \
320  portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \
321  configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \
322  listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \
323  } /* taskSELECT_HIGHEST_PRIORITY_TASK() */
324 
325  /*-----------------------------------------------------------*/
326 
327  /* A port optimised version is provided, call it only if the TCB being reset
328  is being referenced from a ready list. If it is referenced from a delayed
329  or suspended list then it won't be in a ready list. */
330  #define taskRESET_READY_PRIORITY( uxPriority ) \
331  { \
332  if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == 0 ) \
333  { \
334  portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \
335  } \
336  }
337 
338 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
339 
340 /*-----------------------------------------------------------*/
341 
342 /* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick
343 count overflows. */
344 #define taskSWITCH_DELAYED_LISTS() \
345 { \
346  List_t *pxTemp; \
347  \
348  /* The delayed tasks list should be empty when the lists are switched. */ \
349  configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \
350  \
351  pxTemp = pxDelayedTaskList; \
352  pxDelayedTaskList = pxOverflowDelayedTaskList; \
353  pxOverflowDelayedTaskList = pxTemp; \
354  xNumOfOverflows++; \
355  prvResetNextTaskUnblockTime(); \
356 }
357 
358 /*-----------------------------------------------------------*/
359 
360 /*
361  * Place the task represented by pxTCB into the appropriate ready list for
362  * the task. It is inserted at the end of the list.
363  */
364 #define prvAddTaskToReadyList( pxTCB ) \
365  traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
366  taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \
367  vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
368 /*-----------------------------------------------------------*/
369 
370 /*
371  * Several functions take an TaskHandle_t parameter that can optionally be NULL,
372  * where NULL is used to indicate that the handle of the currently executing
373  * task should be used in place of the parameter. This macro simply checks to
374  * see if the parameter is NULL and returns a pointer to the appropriate TCB.
375  */
376 #define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( TCB_t * ) pxCurrentTCB : ( TCB_t * ) ( pxHandle ) )
377 
378 /* The item value of the event list item is normally used to hold the priority
379 of the task to which it belongs (coded to allow it to be held in reverse
380 priority order). However, it is occasionally borrowed for other purposes. It
381 is important its value is not updated due to a task priority change while it is
382 being used for another purpose. The following bit definition is used to inform
383 the scheduler that the value should not be changed - in which case it is the
384 responsibility of whichever module is using the value to ensure it gets set back
385 to its original value when it is released. */
386 #if configUSE_16_BIT_TICKS == 1
387  #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U
388 #else
389  #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL
390 #endif
391 
392 /* Callback function prototypes. --------------------------*/
393 #if configCHECK_FOR_STACK_OVERFLOW > 0
394  extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
395 #endif
396 
397 #if configUSE_TICK_HOOK > 0
398  extern void vApplicationTickHook( void );
399 #endif
400 
401 /* File private functions. --------------------------------*/
402 
403 /*
404  * Utility to ready a TCB for a given task. Mainly just copies the parameters
405  * into the TCB structure.
406  */
407 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. */
408 
414 static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
415 
416 /*
417  * Utility to ready all the lists used by the scheduler. This is called
418  * automatically upon the creation of the first task.
419  */
420 static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
421 
422 /*
423  * The idle task, which as all tasks is implemented as a never ending loop.
424  * The idle task is automatically created and added to the ready lists upon
425  * creation of the first user task.
426  *
427  * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
428  * language extensions. The equivalent prototype for this function is:
429  *
430  * void prvIdleTask( void *pvParameters );
431  *
432  */
433 static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
434 
435 /*
436  * Utility to free all memory allocated by the scheduler to hold a TCB,
437  * including the stack pointed to by the TCB.
438  *
439  * This does not free memory allocated by the task itself (i.e. memory
440  * allocated by calls to pvPortMalloc from within the tasks application code).
441  */
442 #if ( INCLUDE_vTaskDelete == 1 )
443 
444  static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION;
445 
446 #endif
447 
448 /*
449  * Used only by the idle task. This checks to see if anything has been placed
450  * in the list of tasks waiting to be deleted. If so the task is cleaned up
451  * and its TCB deleted.
452  */
453 static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
454 
455 /*
456  * The currently executing task is entering the Blocked state. Add the task to
457  * either the current or the overflow delayed task list.
458  */
459 static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) PRIVILEGED_FUNCTION;
460 
461 /*
462  * Allocates memory from the heap for a TCB and associated stack. Checks the
463  * allocation was successful.
464  */
465 static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) PRIVILEGED_FUNCTION;
466 
467 /*
468  * Fills an TaskStatus_t structure with information on each task that is
469  * referenced from the pxList list (which may be a ready list, a delayed list,
470  * a suspended list, etc.).
471  *
472  * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
473  * NORMAL APPLICATION CODE.
474  */
475 #if ( configUSE_TRACE_FACILITY == 1 )
476 
477  static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION;
478 
479 #endif
480 
481 /*
482  * When a task is created, the stack of the task is filled with a known value.
483  * This function determines the 'high water mark' of the task stack by
484  * determining how much of the stack remains at the original preset value.
485  */
486 #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
487 
488  static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;
489 
490 #endif
491 
492 /*
493  * Return the amount of time, in ticks, that will pass before the kernel will
494  * next move a task from the Blocked state to the Running state.
495  *
496  * This conditional compilation should use inequality to 0, not equality to 1.
497  * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user
498  * defined low power mode implementations require configUSE_TICKLESS_IDLE to be
499  * set to a value other than 1.
500  */
501 #if ( configUSE_TICKLESS_IDLE != 0 )
502 
503  static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION;
504 
505 #endif
506 
507 /*
508  * Set xNextTaskUnblockTime to the time at which the next Blocked state task
509  * will exit the Blocked state.
510  */
511 static void prvResetNextTaskUnblockTime( void );
512 
513 /*-----------------------------------------------------------*/
514 
515 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. */
516 {
517 BaseType_t xReturn;
518 TCB_t * pxNewTCB;
519 
520  configASSERT( pxTaskCode );
521  configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) );
522 
523  /* Allocate the memory required by the TCB and stack for the new task,
524  checking that the allocation was successful. */
525  pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
526 
527  if( pxNewTCB != NULL )
528  {
529  StackType_t *pxTopOfStack;
530 
531  #if( portUSING_MPU_WRAPPERS == 1 )
532  /* Should the task be created in privileged mode? */
533  BaseType_t xRunPrivileged;
534  if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )
535  {
536  xRunPrivileged = pdTRUE;
537  }
538  else
539  {
540  xRunPrivileged = pdFALSE;
541  }
542  uxPriority &= ~portPRIVILEGE_BIT;
543  #endif /* portUSING_MPU_WRAPPERS == 1 */
544 
545  /* Calculate the top of stack address. This depends on whether the
546  stack grows from high memory to low (as per the 80x86) or vice versa.
547  portSTACK_GROWTH is used to make the result positive or negative as
548  required by the port. */
549  #if( portSTACK_GROWTH < 0 )
550  {
551  pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );
552  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. */
553 
554  /* Check the alignment of the calculated top of stack is correct. */
555  configASSERT( ( ( ( uint32_t ) pxTopOfStack & ( uint32_t ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
556  }
557  #else /* portSTACK_GROWTH */
558  {
559  pxTopOfStack = pxNewTCB->pxStack;
560 
561  /* Check the alignment of the stack buffer is correct. */
562  configASSERT( ( ( ( uint32_t ) pxNewTCB->pxStack & ( uint32_t ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
563 
564  /* If we want to use stack checking on architectures that use
565  a positive stack growth direction then we also need to store the
566  other extreme of the stack space. */
567  pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
568  }
569  #endif /* portSTACK_GROWTH */
570 
571  /* Setup the newly allocated TCB with the initial state of the task. */
572  prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
573 
574  /* Initialize the TCB stack to look as if the task was already running,
575  but had been interrupted by the scheduler. The return address is set
576  to the start of the task function. Once the stack has been initialised
577  the top of stack variable is updated. */
578  #if( portUSING_MPU_WRAPPERS == 1 )
579  {
580  pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
581  }
582  #else /* portUSING_MPU_WRAPPERS */
583  {
584  pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
585  }
586  #endif /* portUSING_MPU_WRAPPERS */
587 
588  if( ( void * ) pxCreatedTask != NULL )
589  {
590  /* Pass the TCB out - in an anonymous way. The calling function/
591  task can use this as a handle to delete the task later if
592  required.*/
593  *pxCreatedTask = ( TaskHandle_t ) pxNewTCB;
594  }
595  else
596  {
598  }
599 
600  /* Ensure interrupts don't access the task lists while they are being
601  updated. */
603  {
604  uxCurrentNumberOfTasks++;
605  if( pxCurrentTCB == NULL )
606  {
607  /* There are no other tasks, or all the other tasks are in
608  the suspended state - make this the current task. */
609  pxCurrentTCB = pxNewTCB;
610 
611  if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
612  {
613  /* This is the first task to be created so do the preliminary
614  initialisation required. We will not recover if this call
615  fails, but we will report the failure. */
616  prvInitialiseTaskLists();
617  }
618  else
619  {
621  }
622  }
623  else
624  {
625  /* If the scheduler is not already running, make this task the
626  current task if it is the highest priority task to be created
627  so far. */
628  if( xSchedulerRunning == pdFALSE )
629  {
630  if( pxCurrentTCB->uxPriority <= uxPriority )
631  {
632  pxCurrentTCB = pxNewTCB;
633  }
634  else
635  {
637  }
638  }
639  else
640  {
642  }
643  }
644 
645  uxTaskNumber++;
646 
647  #if ( configUSE_TRACE_FACILITY == 1 )
648  {
649  /* Add a counter into the TCB for tracing only. */
650  pxNewTCB->uxTCBNumber = uxTaskNumber;
651  }
652  #endif /* configUSE_TRACE_FACILITY */
653  traceTASK_CREATE( pxNewTCB );
654 
655  prvAddTaskToReadyList( pxNewTCB );
656 
657  xReturn = pdPASS;
658  portSETUP_TCB( pxNewTCB );
659  }
661  }
662  else
663  {
666  }
667 
668  if( xReturn == pdPASS )
669  {
670  if( xSchedulerRunning != pdFALSE )
671  {
672  /* If the created task is of a higher priority than the current task
673  then it should run now. */
674  if( pxCurrentTCB->uxPriority < uxPriority )
675  {
677  }
678  else
679  {
681  }
682  }
683  else
684  {
686  }
687  }
688 
689  return xReturn;
690 }
691 /*-----------------------------------------------------------*/
692 
693 #if ( INCLUDE_vTaskDelete == 1 )
694 
695  void vTaskDelete( TaskHandle_t xTaskToDelete )
696  {
697  TCB_t *pxTCB;
698 
700  {
701  /* If null is passed in here then it is the calling task that is
702  being deleted. */
703  pxTCB = prvGetTCBFromHandle( xTaskToDelete );
704 
705  /* Remove task from the ready list and place in the termination list.
706  This will stop the task from be scheduled. The idle task will check
707  the termination list and free up any memory allocated by the
708  scheduler for the TCB and stack. */
709  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
710  {
712  }
713  else
714  {
716  }
717 
718  /* Is the task waiting on an event also? */
719  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
720  {
721  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
722  }
723  else
724  {
726  }
727 
728  vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );
729 
730  /* Increment the ucTasksDeleted variable so the idle task knows
731  there is a task that has been deleted and that it should therefore
732  check the xTasksWaitingTermination list. */
733  ++uxTasksDeleted;
734 
735  /* Increment the uxTaskNumberVariable also so kernel aware debuggers
736  can detect that the task lists need re-generating. */
737  uxTaskNumber++;
738 
739  traceTASK_DELETE( pxTCB );
740  }
742 
743  /* Force a reschedule if it is the currently running task that has just
744  been deleted. */
745  if( xSchedulerRunning != pdFALSE )
746  {
747  if( pxTCB == pxCurrentTCB )
748  {
749  configASSERT( uxSchedulerSuspended == 0 );
750 
751  /* The pre-delete hook is primarily for the Windows simulator,
752  in which Windows specific clean up operations are performed,
753  after which it is not possible to yield away from this task -
754  hence xYieldPending is used to latch that a context switch is
755  required. */
756  portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
758  }
759  else
760  {
761  /* Reset the next expected unblock time in case it referred to
762  the task that has just been deleted. */
764  {
765  prvResetNextTaskUnblockTime();
766  }
768  }
769  }
770  }
771 
772 #endif /* INCLUDE_vTaskDelete */
773 /*-----------------------------------------------------------*/
774 
775 #if ( INCLUDE_vTaskDelayUntil == 1 )
776 
777  void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
778  {
779  TickType_t xTimeToWake;
780  BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
781 
782  configASSERT( pxPreviousWakeTime );
783  configASSERT( ( xTimeIncrement > 0U ) );
784  configASSERT( uxSchedulerSuspended == 0 );
785 
786  vTaskSuspendAll();
787  {
788  /* Minor optimisation. The tick count cannot change in this
789  block. */
790  const TickType_t xConstTickCount = xTickCount;
791 
792  /* Generate the tick time at which the task wants to wake. */
793  xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
794 
795  if( xConstTickCount < *pxPreviousWakeTime )
796  {
797  /* The tick count has overflowed since this function was
798  lasted called. In this case the only time we should ever
799  actually delay is if the wake time has also overflowed,
800  and the wake time is greater than the tick time. When this
801  is the case it is as if neither time had overflowed. */
802  if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
803  {
804  xShouldDelay = pdTRUE;
805  }
806  else
807  {
809  }
810  }
811  else
812  {
813  /* The tick time has not overflowed. In this case we will
814  delay if either the wake time has overflowed, and/or the
815  tick time is less than the wake time. */
816  if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
817  {
818  xShouldDelay = pdTRUE;
819  }
820  else
821  {
823  }
824  }
825 
826  /* Update the wake time ready for the next call. */
827  *pxPreviousWakeTime = xTimeToWake;
828 
829  if( xShouldDelay != pdFALSE )
830  {
832 
833  /* Remove the task from the ready list before adding it to the
834  blocked list as the same list item is used for both lists. */
835  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
836  {
837  /* The current task must be in a ready list, so there is
838  no need to check, and the port reset macro can be called
839  directly. */
840  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
841  }
842  else
843  {
845  }
846 
847  prvAddCurrentTaskToDelayedList( xTimeToWake );
848  }
849  else
850  {
852  }
853  }
854  xAlreadyYielded = xTaskResumeAll();
855 
856  /* Force a reschedule if xTaskResumeAll has not already done so, we may
857  have put ourselves to sleep. */
858  if( xAlreadyYielded == pdFALSE )
859  {
861  }
862  else
863  {
865  }
866  }
867 
868 #endif /* INCLUDE_vTaskDelayUntil */
869 /*-----------------------------------------------------------*/
870 
871 #if ( INCLUDE_vTaskDelay == 1 )
872 
873  void vTaskDelay( const TickType_t xTicksToDelay )
874  {
875  TickType_t xTimeToWake;
876  BaseType_t xAlreadyYielded = pdFALSE;
877 
878 
879  /* A delay time of zero just forces a reschedule. */
880  if( xTicksToDelay > ( TickType_t ) 0U )
881  {
882  configASSERT( uxSchedulerSuspended == 0 );
883  vTaskSuspendAll();
884  {
885  traceTASK_DELAY();
886 
887  /* A task that is removed from the event list while the
888  scheduler is suspended will not get placed in the ready
889  list or removed from the blocked list until the scheduler
890  is resumed.
891 
892  This task cannot be in an event list as it is the currently
893  executing task. */
894 
895  /* Calculate the time to wake - this may overflow but this is
896  not a problem. */
897  xTimeToWake = xTickCount + xTicksToDelay;
898 
899  /* We must remove ourselves from the ready list before adding
900  ourselves to the blocked list as the same list item is used for
901  both lists. */
902  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
903  {
904  /* The current task must be in a ready list, so there is
905  no need to check, and the port reset macro can be called
906  directly. */
907  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
908  }
909  else
910  {
912  }
913  prvAddCurrentTaskToDelayedList( xTimeToWake );
914  }
915  xAlreadyYielded = xTaskResumeAll();
916  }
917  else
918  {
920  }
921 
922  /* Force a reschedule if xTaskResumeAll has not already done so, we may
923  have put ourselves to sleep. */
924  if( xAlreadyYielded == pdFALSE )
925  {
927  }
928  else
929  {
931  }
932  }
933 
934 #endif /* INCLUDE_vTaskDelay */
935 /*-----------------------------------------------------------*/
936 
937 #if ( INCLUDE_eTaskGetState == 1 )
938 
940  {
941  eTaskState eReturn;
942  List_t *pxStateList;
943  const TCB_t * const pxTCB = ( TCB_t * ) xTask;
944 
945  configASSERT( pxTCB );
946 
947  if( pxTCB == pxCurrentTCB )
948  {
949  /* The task calling this function is querying its own state. */
950  eReturn = eRunning;
951  }
952  else
953  {
955  {
956  pxStateList = ( List_t * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) );
957  }
959 
960  if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) )
961  {
962  /* The task being queried is referenced from one of the Blocked
963  lists. */
964  eReturn = eBlocked;
965  }
966 
967  #if ( INCLUDE_vTaskSuspend == 1 )
968  else if( pxStateList == &xSuspendedTaskList )
969  {
970  /* The task being queried is referenced from the suspended
971  list. Is it genuinely suspended or is it block
972  indefinitely? */
973  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
974  {
975  eReturn = eSuspended;
976  }
977  else
978  {
979  eReturn = eBlocked;
980  }
981  }
982  #endif
983 
984  #if ( INCLUDE_vTaskDelete == 1 )
985  else if( pxStateList == &xTasksWaitingTermination )
986  {
987  /* The task being queried is referenced from the deleted
988  tasks list. */
989  eReturn = eDeleted;
990  }
991  #endif
992 
993  else
994  {
995  /* If the task is not in any other state, it must be in the
996  Ready (including pending ready) state. */
997  eReturn = eReady;
998  }
999  }
1000 
1001  return eReturn;
1002  }
1003 
1004 #endif /* INCLUDE_eTaskGetState */
1005 /*-----------------------------------------------------------*/
1006 
1007 #if ( INCLUDE_uxTaskPriorityGet == 1 )
1008 
1010  {
1011  TCB_t *pxTCB;
1012  UBaseType_t uxReturn;
1013 
1015  {
1016  /* If null is passed in here then we are changing the
1017  priority of the calling function. */
1018  pxTCB = prvGetTCBFromHandle( xTask );
1019  uxReturn = pxTCB->uxPriority;
1020  }
1022 
1023  return uxReturn;
1024  }
1025 
1026 #endif /* INCLUDE_uxTaskPriorityGet */
1027 /*-----------------------------------------------------------*/
1028 
1029 #if ( INCLUDE_vTaskPrioritySet == 1 )
1030 
1031  void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
1032  {
1033  TCB_t *pxTCB;
1034  UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry;
1035  BaseType_t xYieldRequired = pdFALSE;
1036 
1037  configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
1038 
1039  /* Ensure the new priority is valid. */
1040  if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
1041  {
1042  uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
1043  }
1044  else
1045  {
1047  }
1048 
1050  {
1051  /* If null is passed in here then it is the priority of the calling
1052  task that is being changed. */
1053  pxTCB = prvGetTCBFromHandle( xTask );
1054 
1055  traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );
1056 
1057  #if ( configUSE_MUTEXES == 1 )
1058  {
1059  uxCurrentBasePriority = pxTCB->uxBasePriority;
1060  }
1061  #else
1062  {
1063  uxCurrentBasePriority = pxTCB->uxPriority;
1064  }
1065  #endif
1066 
1067  if( uxCurrentBasePriority != uxNewPriority )
1068  {
1069  /* The priority change may have readied a task of higher
1070  priority than the calling task. */
1071  if( uxNewPriority > uxCurrentBasePriority )
1072  {
1073  if( pxTCB != pxCurrentTCB )
1074  {
1075  /* The priority of a task other than the currently
1076  running task is being raised. Is the priority being
1077  raised above that of the running task? */
1078  if( uxNewPriority >= pxCurrentTCB->uxPriority )
1079  {
1080  xYieldRequired = pdTRUE;
1081  }
1082  else
1083  {
1085  }
1086  }
1087  else
1088  {
1089  /* The priority of the running task is being raised,
1090  but the running task must already be the highest
1091  priority task able to run so no yield is required. */
1092  }
1093  }
1094  else if( pxTCB == pxCurrentTCB )
1095  {
1096  /* Setting the priority of the running task down means
1097  there may now be another task of higher priority that
1098  is ready to execute. */
1099  xYieldRequired = pdTRUE;
1100  }
1101  else
1102  {
1103  /* Setting the priority of any other task down does not
1104  require a yield as the running task must be above the
1105  new priority of the task being modified. */
1106  }
1107 
1108  /* Remember the ready list the task might be referenced from
1109  before its uxPriority member is changed so the
1110  taskRESET_READY_PRIORITY() macro can function correctly. */
1111  uxPriorityUsedOnEntry = pxTCB->uxPriority;
1112 
1113  #if ( configUSE_MUTEXES == 1 )
1114  {
1115  /* Only change the priority being used if the task is not
1116  currently using an inherited priority. */
1117  if( pxTCB->uxBasePriority == pxTCB->uxPriority )
1118  {
1119  pxTCB->uxPriority = uxNewPriority;
1120  }
1121  else
1122  {
1124  }
1125 
1126  /* The base priority gets set whatever. */
1127  pxTCB->uxBasePriority = uxNewPriority;
1128  }
1129  #else
1130  {
1131  pxTCB->uxPriority = uxNewPriority;
1132  }
1133  #endif
1134 
1135  /* Only reset the event list item value if the value is not
1136  being used for anything else. */
1138  {
1139  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. */
1140  }
1141  else
1142  {
1144  }
1145 
1146  /* If the task is in the blocked or suspended list we need do
1147  nothing more than change it's priority variable. However, if
1148  the task is in a ready list it needs to be removed and placed
1149  in the list appropriate to its new priority. */
1150  if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
1151  {
1152  /* The task is currently in its ready list - remove before adding
1153  it to it's new ready list. As we are in a critical section we
1154  can do this even if the scheduler is suspended. */
1155  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
1156  {
1157  /* It is known that the task is in its ready list so
1158  there is no need to check again and the port level
1159  reset macro can be called directly. */
1160  portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority );
1161  }
1162  else
1163  {
1165  }
1166  prvAddTaskToReadyList( pxTCB );
1167  }
1168  else
1169  {
1171  }
1172 
1173  if( xYieldRequired == pdTRUE )
1174  {
1176  }
1177  else
1178  {
1180  }
1181 
1182  /* Remove compiler warning about unused variables when the port
1183  optimised task selection is not being used. */
1184  ( void ) uxPriorityUsedOnEntry;
1185  }
1186  }
1188  }
1189 
1190 #endif /* INCLUDE_vTaskPrioritySet */
1191 /*-----------------------------------------------------------*/
1192 
1193 #if ( INCLUDE_vTaskSuspend == 1 )
1194 
1195  void vTaskSuspend( TaskHandle_t xTaskToSuspend )
1196  {
1197  TCB_t *pxTCB;
1198 
1200  {
1201  /* If null is passed in here then it is the running task that is
1202  being suspended. */
1203  pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
1204 
1205  traceTASK_SUSPEND( pxTCB );
1206 
1207  /* Remove task from the ready/delayed list and place in the
1208  suspended list. */
1209  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
1210  {
1212  }
1213  else
1214  {
1216  }
1217 
1218  /* Is the task waiting on an event also? */
1219  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
1220  {
1221  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
1222  }
1223  else
1224  {
1226  }
1227 
1228  vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
1229  }
1231 
1232  if( pxTCB == pxCurrentTCB )
1233  {
1234  if( xSchedulerRunning != pdFALSE )
1235  {
1236  /* The current task has just been suspended. */
1237  configASSERT( uxSchedulerSuspended == 0 );
1239  }
1240  else
1241  {
1242  /* The scheduler is not running, but the task that was pointed
1243  to by pxCurrentTCB has just been suspended and pxCurrentTCB
1244  must be adjusted to point to a different task. */
1245  if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
1246  {
1247  /* No other tasks are ready, so set pxCurrentTCB back to
1248  NULL so when the next task is created pxCurrentTCB will
1249  be set to point to it no matter what its relative priority
1250  is. */
1251  pxCurrentTCB = NULL;
1252  }
1253  else
1254  {
1256  }
1257  }
1258  }
1259  else
1260  {
1261  if( xSchedulerRunning != pdFALSE )
1262  {
1263  /* A task other than the currently running task was suspended,
1264  reset the next expected unblock time in case it referred to the
1265  task that is now in the Suspended state. */
1267  {
1268  prvResetNextTaskUnblockTime();
1269  }
1271  }
1272  else
1273  {
1275  }
1276  }
1277  }
1278 
1279 #endif /* INCLUDE_vTaskSuspend */
1280 /*-----------------------------------------------------------*/
1281 
1282 #if ( INCLUDE_vTaskSuspend == 1 )
1283 
1284  static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask )
1285  {
1286  BaseType_t xReturn = pdFALSE;
1287  const TCB_t * const pxTCB = ( TCB_t * ) xTask;
1288 
1289  /* Accesses xPendingReadyList so must be called from a critical
1290  section. */
1291 
1292  /* It does not make sense to check if the calling task is suspended. */
1293  configASSERT( xTask );
1294 
1295  /* Is the task being resumed actually in the suspended list? */
1296  if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
1297  {
1298  /* Has the task already been resumed from within an ISR? */
1299  if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE )
1300  {
1301  /* Is it in the suspended list because it is in the Suspended
1302  state, or because is is blocked with no timeout? */
1303  if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE )
1304  {
1305  xReturn = pdTRUE;
1306  }
1307  else
1308  {
1310  }
1311  }
1312  else
1313  {
1315  }
1316  }
1317  else
1318  {
1320  }
1321 
1322  return xReturn;
1323  } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */
1324 
1325 #endif /* INCLUDE_vTaskSuspend */
1326 /*-----------------------------------------------------------*/
1327 
1328 #if ( INCLUDE_vTaskSuspend == 1 )
1329 
1330  void vTaskResume( TaskHandle_t xTaskToResume )
1331  {
1332  TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
1333 
1334  /* It does not make sense to resume the calling task. */
1335  configASSERT( xTaskToResume );
1336 
1337  /* The parameter cannot be NULL as it is impossible to resume the
1338  currently executing task. */
1339  if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
1340  {
1342  {
1343  if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )
1344  {
1345  traceTASK_RESUME( pxTCB );
1346 
1347  /* As we are in a critical section we can access the ready
1348  lists even if the scheduler is suspended. */
1349  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1350  prvAddTaskToReadyList( pxTCB );
1351 
1352  /* We may have just resumed a higher priority task. */
1353  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1354  {
1355  /* This yield may not cause the task just resumed to run,
1356  but will leave the lists in the correct state for the
1357  next yield. */
1359  }
1360  else
1361  {
1363  }
1364  }
1365  else
1366  {
1368  }
1369  }
1371  }
1372  else
1373  {
1375  }
1376  }
1377 
1378 #endif /* INCLUDE_vTaskSuspend */
1379 
1380 /*-----------------------------------------------------------*/
1381 
1382 #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
1383 
1384  BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
1385  {
1386  BaseType_t xYieldRequired = pdFALSE;
1387  TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
1388  UBaseType_t uxSavedInterruptStatus;
1389 
1390  configASSERT( xTaskToResume );
1391 
1392  /* RTOS ports that support interrupt nesting have the concept of a
1393  maximum system call (or maximum API call) interrupt priority.
1394  Interrupts that are above the maximum system call priority are keep
1395  permanently enabled, even when the RTOS kernel is in a critical section,
1396  but cannot make any calls to FreeRTOS API functions. If configASSERT()
1397  is defined in FreeRTOSConfig.h then
1398  portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
1399  failure if a FreeRTOS API function is called from an interrupt that has
1400  been assigned a priority above the configured maximum system call
1401  priority. Only FreeRTOS functions that end in FromISR can be called
1402  from interrupts that have been assigned a priority at or (logically)
1403  below the maximum system call interrupt priority. FreeRTOS maintains a
1404  separate interrupt safe API to ensure interrupt entry is as fast and as
1405  simple as possible. More information (albeit Cortex-M specific) is
1406  provided on the following link:
1407  http://www.freertos.org/RTOS-Cortex-M3-M4.html */
1409 
1410  uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
1411  {
1412  if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )
1413  {
1414  traceTASK_RESUME_FROM_ISR( pxTCB );
1415 
1416  /* Check the ready lists can be accessed. */
1417  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
1418  {
1419  /* Ready lists can be accessed so move the task from the
1420  suspended list to the ready list directly. */
1421  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1422  {
1423  xYieldRequired = pdTRUE;
1424  }
1425  else
1426  {
1428  }
1429 
1430  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1431  prvAddTaskToReadyList( pxTCB );
1432  }
1433  else
1434  {
1435  /* The delayed or ready lists cannot be accessed so the task
1436  is held in the pending ready list until the scheduler is
1437  unsuspended. */
1438  vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
1439  }
1440  }
1441  else
1442  {
1444  }
1445  }
1446  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
1447 
1448  return xYieldRequired;
1449  }
1450 
1451 #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */
1452 /*-----------------------------------------------------------*/
1453 
1455 {
1456 BaseType_t xReturn;
1457 
1458  /* Add the idle task at the lowest priority. */
1459  #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
1460  {
1461  /* Create the idle task, storing its handle in xIdleTaskHandle so it can
1462  be returned by the xTaskGetIdleTaskHandle() function. */
1463  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. */
1464  }
1465  #else
1466  {
1467  /* Create the idle task without storing its handle. */
1468  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. */
1469  }
1470  #endif /* INCLUDE_xTaskGetIdleTaskHandle */
1471 
1472  #if ( configUSE_TIMERS == 1 )
1473  {
1474  if( xReturn == pdPASS )
1475  {
1476  xReturn = xTimerCreateTimerTask();
1477  }
1478  else
1479  {
1481  }
1482  }
1483  #endif /* configUSE_TIMERS */
1484 
1485  if( xReturn == pdPASS )
1486  {
1487  /* Interrupts are turned off here, to ensure a tick does not occur
1488  before or during the call to xPortStartScheduler(). The stacks of
1489  the created tasks contain a status word with interrupts switched on
1490  so interrupts will automatically get re-enabled when the first task
1491  starts to run. */
1493 
1494  #if ( configUSE_NEWLIB_REENTRANT == 1 )
1495  {
1496  /* Switch Newlib's _impure_ptr variable to point to the _reent
1497  structure specific to the task that will run first. */
1498  _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
1499  }
1500  #endif /* configUSE_NEWLIB_REENTRANT */
1501 
1502  xSchedulerRunning = pdTRUE;
1503  xTickCount = ( TickType_t ) 0U;
1504 
1505  /* If configGENERATE_RUN_TIME_STATS is defined then the following
1506  macro must be defined to configure the timer/counter used to generate
1507  the run time counter time base. */
1509 
1510  /* Setting up the timer tick is hardware specific and thus in the
1511  portable interface. */
1512  if( xPortStartScheduler() != pdFALSE )
1513  {
1514  /* Should not reach here as if the scheduler is running the
1515  function will not return. */
1516  }
1517  else
1518  {
1519  /* Should only reach here if a task calls xTaskEndScheduler(). */
1520  }
1521  }
1522  else
1523  {
1524  /* This line will only be reached if the kernel could not be started,
1525  because there was not enough FreeRTOS heap to create the idle task
1526  or the timer task. */
1527  configASSERT( xReturn );
1528  }
1529 }
1530 /*-----------------------------------------------------------*/
1531 
1532 void vTaskEndScheduler( void )
1533 {
1534  /* Stop the scheduler interrupts and call the portable scheduler end
1535  routine so the original ISRs can be restored if necessary. The port
1536  layer must ensure interrupts enable bit is left in the correct state. */
1538  xSchedulerRunning = pdFALSE;
1540 }
1541 /*----------------------------------------------------------*/
1542 
1543 void vTaskSuspendAll( void )
1544 {
1545  /* A critical section is not required as the variable is of type
1546  BaseType_t. Please read Richard Barry's reply in the following link to a
1547  post in the FreeRTOS support forum before reporting this as a bug! -
1548  http://goo.gl/wu4acr */
1549  ++uxSchedulerSuspended;
1550 }
1551 /*----------------------------------------------------------*/
1552 
1553 #if ( configUSE_TICKLESS_IDLE != 0 )
1554 
1555  static TickType_t prvGetExpectedIdleTime( void )
1556  {
1557  TickType_t xReturn;
1558 
1560  {
1561  xReturn = 0;
1562  }
1563  else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 )
1564  {
1565  /* There are other idle priority tasks in the ready state. If
1566  time slicing is used then the very next tick interrupt must be
1567  processed. */
1568  xReturn = 0;
1569  }
1570  else
1571  {
1572  xReturn = xNextTaskUnblockTime - xTickCount;
1573  }
1574 
1575  return xReturn;
1576  }
1577 
1578 #endif /* configUSE_TICKLESS_IDLE */
1579 /*----------------------------------------------------------*/
1580 
1582 {
1583 TCB_t *pxTCB;
1584 BaseType_t xAlreadyYielded = pdFALSE;
1585 
1586  /* If uxSchedulerSuspended is zero then this function does not match a
1587  previous call to vTaskSuspendAll(). */
1588  configASSERT( uxSchedulerSuspended );
1589 
1590  /* It is possible that an ISR caused a task to be removed from an event
1591  list while the scheduler was suspended. If this was the case then the
1592  removed task will have been added to the xPendingReadyList. Once the
1593  scheduler has been resumed it is safe to move all the pending ready
1594  tasks from this list into their appropriate ready list. */
1596  {
1597  --uxSchedulerSuspended;
1598 
1599  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
1600  {
1601  if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U )
1602  {
1603  /* Move any readied tasks from the pending list into the
1604  appropriate ready list. */
1605  while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
1606  {
1607  pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
1608  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
1609  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1610  prvAddTaskToReadyList( pxTCB );
1611 
1612  /* If we have moved a task that has a priority higher than
1613  the current task then we should yield. */
1614  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1615  {
1616  xYieldPending = pdTRUE;
1617  }
1618  else
1619  {
1621  }
1622  }
1623 
1624  /* If any ticks occurred while the scheduler was suspended then
1625  they should be processed now. This ensures the tick count does
1626  not slip, and that any delayed tasks are resumed at the correct
1627  time. */
1628  if( uxPendedTicks > ( UBaseType_t ) 0U )
1629  {
1630  while( uxPendedTicks > ( UBaseType_t ) 0U )
1631  {
1632  if( xTaskIncrementTick() != pdFALSE )
1633  {
1634  xYieldPending = pdTRUE;
1635  }
1636  else
1637  {
1639  }
1640  --uxPendedTicks;
1641  }
1642  }
1643  else
1644  {
1646  }
1647 
1648  if( xYieldPending == pdTRUE )
1649  {
1650  #if( configUSE_PREEMPTION != 0 )
1651  {
1652  xAlreadyYielded = pdTRUE;
1653  }
1654  #endif
1656  }
1657  else
1658  {
1660  }
1661  }
1662  }
1663  else
1664  {
1666  }
1667  }
1669 
1670  return xAlreadyYielded;
1671 }
1672 /*-----------------------------------------------------------*/
1673 
1675 {
1676 TickType_t xTicks;
1677 
1678  /* Critical section required if running on a 16 bit processor. */
1680  {
1681  xTicks = xTickCount;
1682  }
1684 
1685  return xTicks;
1686 }
1687 /*-----------------------------------------------------------*/
1688 
1690 {
1691 TickType_t xReturn;
1692 UBaseType_t uxSavedInterruptStatus;
1693 
1694  /* RTOS ports that support interrupt nesting have the concept of a maximum
1695  system call (or maximum API call) interrupt priority. Interrupts that are
1696  above the maximum system call priority are kept permanently enabled, even
1697  when the RTOS kernel is in a critical section, but cannot make any calls to
1698  FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
1699  then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
1700  failure if a FreeRTOS API function is called from an interrupt that has been
1701  assigned a priority above the configured maximum system call priority.
1702  Only FreeRTOS functions that end in FromISR can be called from interrupts
1703  that have been assigned a priority at or (logically) below the maximum
1704  system call interrupt priority. FreeRTOS maintains a separate interrupt
1705  safe API to ensure interrupt entry is as fast and as simple as possible.
1706  More information (albeit Cortex-M specific) is provided on the following
1707  link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
1709 
1710  uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
1711  {
1712  xReturn = xTickCount;
1713  }
1714  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
1715 
1716  return xReturn;
1717 }
1718 /*-----------------------------------------------------------*/
1719 
1721 {
1722  /* A critical section is not required because the variables are of type
1723  BaseType_t. */
1724  return uxCurrentNumberOfTasks;
1725 }
1726 /*-----------------------------------------------------------*/
1727 
1728 #if ( INCLUDE_pcTaskGetTaskName == 1 )
1729 
1730  char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery )
1731  {
1732  TCB_t *pxTCB;
1733 
1734  /* If null is passed in here then the name of the calling task is being queried. */
1735  pxTCB = prvGetTCBFromHandle( xTaskToQuery );
1736  configASSERT( pxTCB );
1737  return &( pxTCB->pcTaskName[ 0 ] );
1738  }
1739 
1740 #endif /* INCLUDE_pcTaskGetTaskName */
1741 /*-----------------------------------------------------------*/
1742 
1743 #if ( configUSE_TRACE_FACILITY == 1 )
1744 
1745  UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime )
1746  {
1747  UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
1748 
1749  vTaskSuspendAll();
1750  {
1751  /* Is there a space in the array for each task in the system? */
1752  if( uxArraySize >= uxCurrentNumberOfTasks )
1753  {
1754  /* Fill in an TaskStatus_t structure with information on each
1755  task in the Ready state. */
1756  do
1757  {
1758  uxQueue--;
1759  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady );
1760 
1761  } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
1762 
1763  /* Fill in an TaskStatus_t structure with information on each
1764  task in the Blocked state. */
1765  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked );
1766  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked );
1767 
1768  #if( INCLUDE_vTaskDelete == 1 )
1769  {
1770  /* Fill in an TaskStatus_t structure with information on
1771  each task that has been deleted but not yet cleaned up. */
1772  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted );
1773  }
1774  #endif
1775 
1776  #if ( INCLUDE_vTaskSuspend == 1 )
1777  {
1778  /* Fill in an TaskStatus_t structure with information on
1779  each task in the Suspended state. */
1780  uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended );
1781  }
1782  #endif
1783 
1784  #if ( configGENERATE_RUN_TIME_STATS == 1)
1785  {
1786  if( pulTotalRunTime != NULL )
1787  {
1788  #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
1789  portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) );
1790  #else
1791  *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
1792  #endif
1793  }
1794  }
1795  #else
1796  {
1797  if( pulTotalRunTime != NULL )
1798  {
1799  *pulTotalRunTime = 0;
1800  }
1801  }
1802  #endif
1803  }
1804  else
1805  {
1807  }
1808  }
1809  ( void ) xTaskResumeAll();
1810 
1811  return uxTask;
1812  }
1813 
1814 #endif /* configUSE_TRACE_FACILITY */
1815 /*----------------------------------------------------------*/
1816 
1817 #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
1818 
1820  {
1821  /* If xTaskGetIdleTaskHandle() is called before the scheduler has been
1822  started, then xIdleTaskHandle will be NULL. */
1823  configASSERT( ( xIdleTaskHandle != NULL ) );
1824  return xIdleTaskHandle;
1825  }
1826 
1827 #endif /* INCLUDE_xTaskGetIdleTaskHandle */
1828 /*----------------------------------------------------------*/
1829 
1830 /* This conditional compilation should use inequality to 0, not equality to 1.
1831 This is to ensure vTaskStepTick() is available when user defined low power mode
1832 implementations require configUSE_TICKLESS_IDLE to be set to a value other than
1833 1. */
1834 #if ( configUSE_TICKLESS_IDLE != 0 )
1835 
1836  void vTaskStepTick( const TickType_t xTicksToJump )
1837  {
1838  /* Correct the tick count value after a period during which the tick
1839  was suppressed. Note this does *not* call the tick hook function for
1840  each stepped tick. */
1841  configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime );
1842  xTickCount += xTicksToJump;
1843  traceINCREASE_TICK_COUNT( xTicksToJump );
1844  }
1845 
1846 #endif /* configUSE_TICKLESS_IDLE */
1847 /*----------------------------------------------------------*/
1848 
1850 {
1851 TCB_t * pxTCB;
1852 TickType_t xItemValue;
1853 BaseType_t xSwitchRequired = pdFALSE;
1854 
1855  /* Called by the portable layer each time a tick interrupt occurs.
1856  Increments the tick then checks to see if the new tick value will cause any
1857  tasks to be unblocked. */
1858  traceTASK_INCREMENT_TICK( xTickCount );
1859  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
1860  {
1861  /* Increment the RTOS tick, switching the delayed and overflowed
1862  delayed lists if it wraps to 0. */
1863  ++xTickCount;
1864 
1865  {
1866  /* Minor optimisation. The tick count cannot change in this
1867  block. */
1868  const TickType_t xConstTickCount = xTickCount;
1869 
1870  if( xConstTickCount == ( TickType_t ) 0U )
1871  {
1873  }
1874  else
1875  {
1877  }
1878 
1879  /* See if this tick has made a timeout expire. Tasks are stored in
1880  the queue in the order of their wake time - meaning once one task
1881  has been found whose block time has not expired there is no need to
1882  look any further down the list. */
1883  if( xConstTickCount >= xNextTaskUnblockTime )
1884  {
1885  for( ;; )
1886  {
1887  if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
1888  {
1889  /* The delayed list is empty. Set xNextTaskUnblockTime
1890  to the maximum possible value so it is extremely
1891  unlikely that the
1892  if( xTickCount >= xNextTaskUnblockTime ) test will pass
1893  next time through. */
1894  xNextTaskUnblockTime = portMAX_DELAY;
1895  break;
1896  }
1897  else
1898  {
1899  /* The delayed list is not empty, get the value of the
1900  item at the head of the delayed list. This is the time
1901  at which the task at the head of the delayed list must
1902  be removed from the Blocked state. */
1903  pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
1904  xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
1905 
1906  if( xConstTickCount < xItemValue )
1907  {
1908  /* It is not time to unblock this item yet, but the
1909  item value is the time at which the task at the head
1910  of the blocked list must be removed from the Blocked
1911  state - so record the item value in
1912  xNextTaskUnblockTime. */
1913  xNextTaskUnblockTime = xItemValue;
1914  break;
1915  }
1916  else
1917  {
1919  }
1920 
1921  /* It is time to remove the item from the Blocked state. */
1922  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
1923 
1924  /* Is the task waiting on an event also? If so remove
1925  it from the event list. */
1926  if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
1927  {
1928  ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
1929  }
1930  else
1931  {
1933  }
1934 
1935  /* Place the unblocked task into the appropriate ready
1936  list. */
1937  prvAddTaskToReadyList( pxTCB );
1938 
1939  /* A task being unblocked cannot cause an immediate
1940  context switch if preemption is turned off. */
1941  #if ( configUSE_PREEMPTION == 1 )
1942  {
1943  /* Preemption is on, but a context switch should
1944  only be performed if the unblocked task has a
1945  priority that is equal to or higher than the
1946  currently executing task. */
1947  if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
1948  {
1949  xSwitchRequired = pdTRUE;
1950  }
1951  else
1952  {
1954  }
1955  }
1956  #endif /* configUSE_PREEMPTION */
1957  }
1958  }
1959  }
1960  }
1961 
1962  /* Tasks of equal priority to the currently running task will share
1963  processing time (time slice) if preemption is on, and the application
1964  writer has not explicitly turned time slicing off. */
1965  #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
1966  {
1967  if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 )
1968  {
1969  xSwitchRequired = pdTRUE;
1970  }
1971  else
1972  {
1974  }
1975  }
1976  #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
1977 
1978  #if ( configUSE_TICK_HOOK == 1 )
1979  {
1980  /* Guard against the tick hook being called when the pended tick
1981  count is being unwound (when the scheduler is being unlocked). */
1982  if( uxPendedTicks == ( UBaseType_t ) 0U )
1983  {
1985  }
1986  else
1987  {
1989  }
1990  }
1991  #endif /* configUSE_TICK_HOOK */
1992  }
1993  else
1994  {
1995  ++uxPendedTicks;
1996 
1997  /* The tick hook gets called at regular intervals, even if the
1998  scheduler is locked. */
1999  #if ( configUSE_TICK_HOOK == 1 )
2000  {
2002  }
2003  #endif
2004  }
2005 
2006  #if ( configUSE_PREEMPTION == 1 )
2007  {
2008  if( xYieldPending != pdFALSE )
2009  {
2010  xSwitchRequired = pdTRUE;
2011  }
2012  else
2013  {
2015  }
2016  }
2017  #endif /* configUSE_PREEMPTION */
2018 
2019  return xSwitchRequired;
2020 }
2021 /*-----------------------------------------------------------*/
2022 
2023 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2024 
2025  void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction )
2026  {
2027  TCB_t *xTCB;
2028 
2029  /* If xTask is NULL then it is the task hook of the calling task that is
2030  getting set. */
2031  if( xTask == NULL )
2032  {
2033  xTCB = ( TCB_t * ) pxCurrentTCB;
2034  }
2035  else
2036  {
2037  xTCB = ( TCB_t * ) xTask;
2038  }
2039 
2040  /* Save the hook function in the TCB. A critical section is required as
2041  the value can be accessed from an interrupt. */
2043  xTCB->pxTaskTag = pxHookFunction;
2045  }
2046 
2047 #endif /* configUSE_APPLICATION_TASK_TAG */
2048 /*-----------------------------------------------------------*/
2049 
2050 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2051 
2052  TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )
2053  {
2054  TCB_t *xTCB;
2055  TaskHookFunction_t xReturn;
2056 
2057  /* If xTask is NULL then we are setting our own task hook. */
2058  if( xTask == NULL )
2059  {
2060  xTCB = ( TCB_t * ) pxCurrentTCB;
2061  }
2062  else
2063  {
2064  xTCB = ( TCB_t * ) xTask;
2065  }
2066 
2067  /* Save the hook function in the TCB. A critical section is required as
2068  the value can be accessed from an interrupt. */
2070  {
2071  xReturn = xTCB->pxTaskTag;
2072  }
2074 
2075  return xReturn;
2076  }
2077 
2078 #endif /* configUSE_APPLICATION_TASK_TAG */
2079 /*-----------------------------------------------------------*/
2080 
2081 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2082 
2083  BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter )
2084  {
2085  TCB_t *xTCB;
2086  BaseType_t xReturn;
2087 
2088  /* If xTask is NULL then we are calling our own task hook. */
2089  if( xTask == NULL )
2090  {
2091  xTCB = ( TCB_t * ) pxCurrentTCB;
2092  }
2093  else
2094  {
2095  xTCB = ( TCB_t * ) xTask;
2096  }
2097 
2098  if( xTCB->pxTaskTag != NULL )
2099  {
2100  xReturn = xTCB->pxTaskTag( pvParameter );
2101  }
2102  else
2103  {
2104  xReturn = pdFAIL;
2105  }
2106 
2107  return xReturn;
2108  }
2109 
2110 #endif /* configUSE_APPLICATION_TASK_TAG */
2111 /*-----------------------------------------------------------*/
2112 
2114 {
2115  if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
2116  {
2117  /* The scheduler is currently suspended - do not allow a context
2118  switch. */
2119  xYieldPending = pdTRUE;
2120  }
2121  else
2122  {
2123  xYieldPending = pdFALSE;
2125 
2126  #if ( configGENERATE_RUN_TIME_STATS == 1 )
2127  {
2128  #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
2129  portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );
2130  #else
2131  ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
2132  #endif
2133 
2134  /* Add the amount of time the task has been running to the
2135  accumulated time so far. The time the task started running was
2136  stored in ulTaskSwitchedInTime. Note that there is no overflow
2137  protection here so count values are only valid until the timer
2138  overflows. The guard against negative values is to protect
2139  against suspect run time stat counter implementations - which
2140  are provided by the application, not the kernel. */
2141  if( ulTotalRunTime > ulTaskSwitchedInTime )
2142  {
2143  pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
2144  }
2145  else
2146  {
2148  }
2149  ulTaskSwitchedInTime = ulTotalRunTime;
2150  }
2151  #endif /* configGENERATE_RUN_TIME_STATS */
2152 
2155 
2157 
2159 
2160  #if ( configUSE_NEWLIB_REENTRANT == 1 )
2161  {
2162  /* Switch Newlib's _impure_ptr variable to point to the _reent
2163  structure specific to this task. */
2164  _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
2165  }
2166  #endif /* configUSE_NEWLIB_REENTRANT */
2167  }
2168 }
2169 /*-----------------------------------------------------------*/
2170 
2171 void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait )
2172 {
2173 TickType_t xTimeToWake;
2174 
2175  configASSERT( pxEventList );
2176 
2177  /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE
2178  SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */
2179 
2180  /* Place the event list item of the TCB in the appropriate event list.
2181  This is placed in the list in priority order so the highest priority task
2182  is the first to be woken by the event. The queue that contains the event
2183  list is locked, preventing simultaneous access from interrupts. */
2184  vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
2185 
2186  /* The task must be removed from from the ready list before it is added to
2187  the blocked list as the same list item is used for both lists. Exclusive
2188  access to the ready lists guaranteed because the scheduler is locked. */
2189  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
2190  {
2191  /* The current task must be in a ready list, so there is no need to
2192  check, and the port reset macro can be called directly. */
2193  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
2194  }
2195  else
2196  {
2198  }
2199 
2200  #if ( INCLUDE_vTaskSuspend == 1 )
2201  {
2202  if( xTicksToWait == portMAX_DELAY )
2203  {
2204  /* Add the task to the suspended task list instead of a delayed task
2205  list to ensure the task is not woken by a timing event. It will
2206  block indefinitely. */
2207  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2208  }
2209  else
2210  {
2211  /* Calculate the time at which the task should be woken if the event
2212  does not occur. This may overflow but this doesn't matter, the
2213  scheduler will handle it. */
2214  xTimeToWake = xTickCount + xTicksToWait;
2215  prvAddCurrentTaskToDelayedList( xTimeToWake );
2216  }
2217  }
2218  #else /* INCLUDE_vTaskSuspend */
2219  {
2220  /* Calculate the time at which the task should be woken if the event does
2221  not occur. This may overflow but this doesn't matter, the scheduler
2222  will handle it. */
2223  xTimeToWake = xTickCount + xTicksToWait;
2224  prvAddCurrentTaskToDelayedList( xTimeToWake );
2225  }
2226  #endif /* INCLUDE_vTaskSuspend */
2227 }
2228 /*-----------------------------------------------------------*/
2229 
2230 void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait )
2231 {
2232 TickType_t xTimeToWake;
2233 
2234  configASSERT( pxEventList );
2235 
2236  /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
2237  the event groups implementation. */
2238  configASSERT( uxSchedulerSuspended != 0 );
2239 
2240  /* Store the item value in the event list item. It is safe to access the
2241  event list item here as interrupts won't access the event list item of a
2242  task that is not in the Blocked state. */
2244 
2245  /* Place the event list item of the TCB at the end of the appropriate event
2246  list. It is safe to access the event list here because it is part of an
2247  event group implementation - and interrupts don't access event groups
2248  directly (instead they access them indirectly by pending function calls to
2249  the task level). */
2250  vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
2251 
2252  /* The task must be removed from the ready list before it is added to the
2253  blocked list. Exclusive access can be assured to the ready list as the
2254  scheduler is locked. */
2255  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
2256  {
2257  /* The current task must be in a ready list, so there is no need to
2258  check, and the port reset macro can be called directly. */
2259  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
2260  }
2261  else
2262  {
2264  }
2265 
2266  #if ( INCLUDE_vTaskSuspend == 1 )
2267  {
2268  if( xTicksToWait == portMAX_DELAY )
2269  {
2270  /* Add the task to the suspended task list instead of a delayed task
2271  list to ensure it is not woken by a timing event. It will block
2272  indefinitely. */
2273  vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2274  }
2275  else
2276  {
2277  /* Calculate the time at which the task should be woken if the event
2278  does not occur. This may overflow but this doesn't matter, the
2279  kernel will manage it correctly. */
2280  xTimeToWake = xTickCount + xTicksToWait;
2281  prvAddCurrentTaskToDelayedList( xTimeToWake );
2282  }
2283  }
2284  #else /* INCLUDE_vTaskSuspend */
2285  {
2286  /* Calculate the time at which the task should be woken if the event does
2287  not occur. This may overflow but this doesn't matter, the kernel
2288  will manage it correctly. */
2289  xTimeToWake = xTickCount + xTicksToWait;
2290  prvAddCurrentTaskToDelayedList( xTimeToWake );
2291  }
2292  #endif /* INCLUDE_vTaskSuspend */
2293 }
2294 /*-----------------------------------------------------------*/
2295 
2296 #if configUSE_TIMERS == 1
2297 
2298  void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait )
2299  {
2300  TickType_t xTimeToWake;
2301 
2302  configASSERT( pxEventList );
2303 
2304  /* This function should not be called by application code hence the
2305  'Restricted' in its name. It is not part of the public API. It is
2306  designed for use by kernel code, and has special calling requirements -
2307  it should be called from a critical section. */
2308 
2309 
2310  /* Place the event list item of the TCB in the appropriate event list.
2311  In this case it is assume that this is the only task that is going to
2312  be waiting on this event list, so the faster vListInsertEnd() function
2313  can be used in place of vListInsert. */
2314  vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
2315 
2316  /* We must remove this task from the ready list before adding it to the
2317  blocked list as the same list item is used for both lists. This
2318  function is called form a critical section. */
2319  if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
2320  {
2321  /* The current task must be in a ready list, so there is no need to
2322  check, and the port reset macro can be called directly. */
2323  portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
2324  }
2325  else
2326  {
2328  }
2329 
2330  /* Calculate the time at which the task should be woken if the event does
2331  not occur. This may overflow but this doesn't matter. */
2332  xTimeToWake = xTickCount + xTicksToWait;
2333 
2335  prvAddCurrentTaskToDelayedList( xTimeToWake );
2336  }
2337 
2338 #endif /* configUSE_TIMERS */
2339 /*-----------------------------------------------------------*/
2340 
2341 BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
2342 {
2343 TCB_t *pxUnblockedTCB;
2344 BaseType_t xReturn;
2345 
2346  /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
2347  called from a critical section within an ISR. */
2348 
2349  /* The event list is sorted in priority order, so the first in the list can
2350  be removed as it is known to be the highest priority. Remove the TCB from
2351  the delayed list, and add it to the ready list.
2352 
2353  If an event is for a queue that is locked then this function will never
2354  get called - the lock count on the queue will get modified instead. This
2355  means exclusive access to the event list is guaranteed here.
2356 
2357  This function assumes that a check has already been made to ensure that
2358  pxEventList is not empty. */
2359  pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
2360  configASSERT( pxUnblockedTCB );
2361  ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
2362 
2363  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
2364  {
2365  ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
2366  prvAddTaskToReadyList( pxUnblockedTCB );
2367  }
2368  else
2369  {
2370  /* The delayed and ready lists cannot be accessed, so hold this task
2371  pending until the scheduler is resumed. */
2372  vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
2373  }
2374 
2375  if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
2376  {
2377  /* Return true if the task removed from the event list has a higher
2378  priority than the calling task. This allows the calling task to know if
2379  it should force a context switch now. */
2380  xReturn = pdTRUE;
2381 
2382  /* Mark that a yield is pending in case the user is not using the
2383  "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
2384  xYieldPending = pdTRUE;
2385  }
2386  else
2387  {
2388  xReturn = pdFALSE;
2389  }
2390 
2391  return xReturn;
2392 }
2393 /*-----------------------------------------------------------*/
2394 
2396 {
2397 TCB_t *pxUnblockedTCB;
2398 BaseType_t xReturn;
2399 
2400  /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
2401  the event flags implementation. */
2402  configASSERT( uxSchedulerSuspended != pdFALSE );
2403 
2404  /* Store the new item value in the event list. */
2405  listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE );
2406 
2407  /* Remove the event list form the event flag. Interrupts do not access
2408  event flags. */
2409  pxUnblockedTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxEventListItem );
2410  configASSERT( pxUnblockedTCB );
2411  ( void ) uxListRemove( pxEventListItem );
2412 
2413  /* Remove the task from the delayed list and add it to the ready list. The
2414  scheduler is suspended so interrupts will not be accessing the ready
2415  lists. */
2416  ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
2417  prvAddTaskToReadyList( pxUnblockedTCB );
2418 
2419  if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
2420  {
2421  /* Return true if the task removed from the event list has
2422  a higher priority than the calling task. This allows
2423  the calling task to know if it should force a context
2424  switch now. */
2425  xReturn = pdTRUE;
2426 
2427  /* Mark that a yield is pending in case the user is not using the
2428  "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
2429  xYieldPending = pdTRUE;
2430  }
2431  else
2432  {
2433  xReturn = pdFALSE;
2434  }
2435 
2436  return xReturn;
2437 }
2438 /*-----------------------------------------------------------*/
2439 
2440 void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )
2441 {
2442  configASSERT( pxTimeOut );
2443  pxTimeOut->xOverflowCount = xNumOfOverflows;
2444  pxTimeOut->xTimeOnEntering = xTickCount;
2445 }
2446 /*-----------------------------------------------------------*/
2447 
2448 BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait )
2449 {
2450 BaseType_t xReturn;
2451 
2452  configASSERT( pxTimeOut );
2453  configASSERT( pxTicksToWait );
2454 
2456  {
2457  /* Minor optimisation. The tick count cannot change in this block. */
2458  const TickType_t xConstTickCount = xTickCount;
2459 
2460  #if ( INCLUDE_vTaskSuspend == 1 )
2461  /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
2462  the maximum block time then the task should block indefinitely, and
2463  therefore never time out. */
2464  if( *pxTicksToWait == portMAX_DELAY )
2465  {
2466  xReturn = pdFALSE;
2467  }
2468  else /* We are not blocking indefinitely, perform the checks below. */
2469  #endif
2470 
2471  if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */
2472  {
2473  /* The tick count is greater than the time at which vTaskSetTimeout()
2474  was called, but has also overflowed since vTaskSetTimeOut() was called.
2475  It must have wrapped all the way around and gone past us again. This
2476  passed since vTaskSetTimeout() was called. */
2477  xReturn = pdTRUE;
2478  }
2479  else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )
2480  {
2481  /* Not a genuine timeout. Adjust parameters for time remaining. */
2482  *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering );
2483  vTaskSetTimeOutState( pxTimeOut );
2484  xReturn = pdFALSE;
2485  }
2486  else
2487  {
2488  xReturn = pdTRUE;
2489  }
2490  }
2492 
2493  return xReturn;
2494 }
2495 /*-----------------------------------------------------------*/
2496 
2497 void vTaskMissedYield( void )
2498 {
2499  xYieldPending = pdTRUE;
2500 }
2501 /*-----------------------------------------------------------*/
2502 
2503 #if ( configUSE_TRACE_FACILITY == 1 )
2504 
2506  {
2507  UBaseType_t uxReturn;
2508  TCB_t *pxTCB;
2509 
2510  if( xTask != NULL )
2511  {
2512  pxTCB = ( TCB_t * ) xTask;
2513  uxReturn = pxTCB->uxTaskNumber;
2514  }
2515  else
2516  {
2517  uxReturn = 0U;
2518  }
2519 
2520  return uxReturn;
2521  }
2522 
2523 #endif /* configUSE_TRACE_FACILITY */
2524 /*-----------------------------------------------------------*/
2525 
2526 #if ( configUSE_TRACE_FACILITY == 1 )
2527 
2528  void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle )
2529  {
2530  TCB_t *pxTCB;
2531 
2532  if( xTask != NULL )
2533  {
2534  pxTCB = ( TCB_t * ) xTask;
2535  pxTCB->uxTaskNumber = uxHandle;
2536  }
2537  }
2538 
2539 #endif /* configUSE_TRACE_FACILITY */
2540 
2541 /*
2542  * -----------------------------------------------------------
2543  * The Idle task.
2544  * ----------------------------------------------------------
2545  *
2546  * The portTASK_FUNCTION() macro is used to allow port/compiler specific
2547  * language extensions. The equivalent prototype for this function is:
2548  *
2549  * void prvIdleTask( void *pvParameters );
2550  *
2551  */
2552 static portTASK_FUNCTION( prvIdleTask, pvParameters )
2553 {
2554  /* Stop warnings. */
2555  ( void ) pvParameters;
2556 
2557  for( ;; )
2558  {
2559  /* See if any tasks have been deleted. */
2560  prvCheckTasksWaitingTermination();
2561 
2562  #if ( configUSE_PREEMPTION == 0 )
2563  {
2564  /* If we are not using preemption we keep forcing a task switch to
2565  see if any other task has become available. If we are using
2566  preemption we don't need to do this as any task becoming available
2567  will automatically get the processor anyway. */
2568  taskYIELD();
2569  }
2570  #endif /* configUSE_PREEMPTION */
2571 
2572  #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
2573  {
2574  /* When using preemption tasks of equal priority will be
2575  timesliced. If a task that is sharing the idle priority is ready
2576  to run then the idle task should yield before the end of the
2577  timeslice.
2578 
2579  A critical region is not required here as we are just reading from
2580  the list, and an occasional incorrect value will not matter. If
2581  the ready list at the idle priority contains more than one task
2582  then a task other than the idle task is ready to execute. */
2583  if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
2584  {
2585  taskYIELD();
2586  }
2587  else
2588  {
2590  }
2591  }
2592  #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
2593 
2594  #if ( configUSE_IDLE_HOOK == 1 )
2595  {
2596  extern void vApplicationIdleHook( void );
2597 
2598  /* Call the user defined function from within the idle task. This
2599  allows the application designer to add background functionality
2600  without the overhead of a separate task.
2601  NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
2602  CALL A FUNCTION THAT MIGHT BLOCK. */
2604  }
2605  #endif /* configUSE_IDLE_HOOK */
2606 
2607  /* This conditional compilation should use inequality to 0, not equality
2608  to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
2609  user defined low power mode implementations require
2610  configUSE_TICKLESS_IDLE to be set to a value other than 1. */
2611  #if ( configUSE_TICKLESS_IDLE != 0 )
2612  {
2613  TickType_t xExpectedIdleTime;
2614 
2615  /* It is not desirable to suspend then resume the scheduler on
2616  each iteration of the idle task. Therefore, a preliminary
2617  test of the expected idle time is performed without the
2618  scheduler suspended. The result here is not necessarily
2619  valid. */
2620  xExpectedIdleTime = prvGetExpectedIdleTime();
2621 
2622  if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
2623  {
2624  vTaskSuspendAll();
2625  {
2626  /* Now the scheduler is suspended, the expected idle
2627  time can be sampled again, and this time its value can
2628  be used. */
2629  configASSERT( xNextTaskUnblockTime >= xTickCount );
2630  xExpectedIdleTime = prvGetExpectedIdleTime();
2631 
2632  if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
2633  {
2635  portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
2637  }
2638  else
2639  {
2641  }
2642  }
2643  ( void ) xTaskResumeAll();
2644  }
2645  else
2646  {
2648  }
2649  }
2650  #endif /* configUSE_TICKLESS_IDLE */
2651  }
2652 }
2653 /*-----------------------------------------------------------*/
2654 
2655 #if configUSE_TICKLESS_IDLE != 0
2656 
2658  {
2659  eSleepModeStatus eReturn = eStandardSleep;
2660 
2661  if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 )
2662  {
2663  /* A task was made ready while the scheduler was suspended. */
2664  eReturn = eAbortSleep;
2665  }
2666  else if( xYieldPending != pdFALSE )
2667  {
2668  /* A yield was pended while the scheduler was suspended. */
2669  eReturn = eAbortSleep;
2670  }
2671  else
2672  {
2673  #if configUSE_TIMERS == 0
2674  {
2675  /* The idle task exists in addition to the application tasks. */
2676  const UBaseType_t uxNonApplicationTasks = 1;
2677 
2678  /* If timers are not being used and all the tasks are in the
2679  suspended list (which might mean they have an infinite block
2680  time rather than actually being suspended) then it is safe to
2681  turn all clocks off and just wait for external interrupts. */
2682  if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) )
2683  {
2684  eReturn = eNoTasksWaitingTimeout;
2685  }
2686  else
2687  {
2689  }
2690  }
2691  #endif /* configUSE_TIMERS */
2692  }
2693 
2694  return eReturn;
2695  }
2696 #endif /* configUSE_TICKLESS_IDLE */
2697 /*-----------------------------------------------------------*/
2698 
2699 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. */
2700 {
2701 UBaseType_t x;
2702 
2703  /* Store the task name in the TCB. */
2704  for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
2705  {
2706  pxTCB->pcTaskName[ x ] = pcName[ x ];
2707 
2708  /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
2709  configMAX_TASK_NAME_LEN characters just in case the memory after the
2710  string is not accessible (extremely unlikely). */
2711  if( pcName[ x ] == 0x00 )
2712  {
2713  break;
2714  }
2715  else
2716  {
2718  }
2719  }
2720 
2721  /* Ensure the name string is terminated in the case that the string length
2722  was greater or equal to configMAX_TASK_NAME_LEN. */
2723  pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';
2724 
2725  /* This is used as an array index so must ensure it's not too large. First
2726  remove the privilege bit if one is present. */
2727  if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
2728  {
2729  uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
2730  }
2731  else
2732  {
2734  }
2735 
2736  pxTCB->uxPriority = uxPriority;
2737  #if ( configUSE_MUTEXES == 1 )
2738  {
2739  pxTCB->uxBasePriority = uxPriority;
2740  }
2741  #endif /* configUSE_MUTEXES */
2742 
2743  vListInitialiseItem( &( pxTCB->xGenericListItem ) );
2744  vListInitialiseItem( &( pxTCB->xEventListItem ) );
2745 
2746  /* Set the pxTCB as a link back from the ListItem_t. This is so we can get
2747  back to the containing TCB from a generic item in a list. */
2748  listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );
2749 
2750  /* Event lists are always in priority order. */
2751  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. */
2752  listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );
2753 
2754  #if ( portCRITICAL_NESTING_IN_TCB == 1 )
2755  {
2756  pxTCB->uxCriticalNesting = ( UBaseType_t ) 0U;
2757  }
2758  #endif /* portCRITICAL_NESTING_IN_TCB */
2759 
2760  #if ( configUSE_APPLICATION_TASK_TAG == 1 )
2761  {
2762  pxTCB->pxTaskTag = NULL;
2763  }
2764  #endif /* configUSE_APPLICATION_TASK_TAG */
2765 
2766  #if ( configGENERATE_RUN_TIME_STATS == 1 )
2767  {
2768  pxTCB->ulRunTimeCounter = 0UL;
2769  }
2770  #endif /* configGENERATE_RUN_TIME_STATS */
2771 
2772  #if ( portUSING_MPU_WRAPPERS == 1 )
2773  {
2774  vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );
2775  }
2776  #else /* portUSING_MPU_WRAPPERS */
2777  {
2778  ( void ) xRegions;
2779  ( void ) usStackDepth;
2780  }
2781  #endif /* portUSING_MPU_WRAPPERS */
2782 
2783  #if ( configUSE_NEWLIB_REENTRANT == 1 )
2784  {
2785  /* Initialise this task's Newlib reent structure. */
2786  _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );
2787  }
2788  #endif /* configUSE_NEWLIB_REENTRANT */
2789 }
2790 /*-----------------------------------------------------------*/
2791 
2792 #if ( portUSING_MPU_WRAPPERS == 1 )
2793 
2794  void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions )
2795  {
2796  TCB_t *pxTCB;
2797 
2798  /* If null is passed in here then we are deleting ourselves. */
2799  pxTCB = prvGetTCBFromHandle( xTaskToModify );
2800 
2801  vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
2802  }
2803 
2804 #endif /* portUSING_MPU_WRAPPERS */
2805 /*-----------------------------------------------------------*/
2806 
2807 static void prvInitialiseTaskLists( void )
2808 {
2809 UBaseType_t uxPriority;
2810 
2811  for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
2812  {
2813  vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
2814  }
2815 
2816  vListInitialise( &xDelayedTaskList1 );
2817  vListInitialise( &xDelayedTaskList2 );
2818  vListInitialise( &xPendingReadyList );
2819 
2820  #if ( INCLUDE_vTaskDelete == 1 )
2821  {
2822  vListInitialise( &xTasksWaitingTermination );
2823  }
2824  #endif /* INCLUDE_vTaskDelete */
2825 
2826  #if ( INCLUDE_vTaskSuspend == 1 )
2827  {
2828  vListInitialise( &xSuspendedTaskList );
2829  }
2830  #endif /* INCLUDE_vTaskSuspend */
2831 
2832  /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
2833  using list2. */
2834  pxDelayedTaskList = &xDelayedTaskList1;
2835  pxOverflowDelayedTaskList = &xDelayedTaskList2;
2836 }
2837 /*-----------------------------------------------------------*/
2838 
2839 static void prvCheckTasksWaitingTermination( void )
2840 {
2841  #if ( INCLUDE_vTaskDelete == 1 )
2842  {
2843  BaseType_t xListIsEmpty;
2844 
2845  /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
2846  too often in the idle task. */
2847  while( uxTasksDeleted > ( UBaseType_t ) 0U )
2848  {
2849  vTaskSuspendAll();
2850  {
2851  xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
2852  }
2853  ( void ) xTaskResumeAll();
2854 
2855  if( xListIsEmpty == pdFALSE )
2856  {
2857  TCB_t *pxTCB;
2858 
2860  {
2861  pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
2862  ( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
2863  --uxCurrentNumberOfTasks;
2864  --uxTasksDeleted;
2865  }
2867 
2868  prvDeleteTCB( pxTCB );
2869  }
2870  else
2871  {
2873  }
2874  }
2875  }
2876  #endif /* vTaskDelete */
2877 }
2878 /*-----------------------------------------------------------*/
2879 
2880 static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
2881 {
2882  /* The list item will be inserted in wake time order. */
2884 
2885  if( xTimeToWake < xTickCount )
2886  {
2887  /* Wake time has overflowed. Place this item in the overflow list. */
2888  vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2889  }
2890  else
2891  {
2892  /* The wake time has not overflowed, so the current block list is used. */
2893  vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
2894 
2895  /* If the task entering the blocked state was placed at the head of the
2896  list of blocked tasks then xNextTaskUnblockTime needs to be updated
2897  too. */
2898  if( xTimeToWake < xNextTaskUnblockTime )
2899  {
2900  xNextTaskUnblockTime = xTimeToWake;
2901  }
2902  else
2903  {
2905  }
2906  }
2907 }
2908 /*-----------------------------------------------------------*/
2909 
2910 static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
2911 {
2912 TCB_t *pxNewTCB;
2913 
2914  /* Allocate space for the TCB. Where the memory comes from depends on
2915  the implementation of the port malloc function. */
2916  pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
2917 
2918  if( pxNewTCB != NULL )
2919  {
2920  /* Allocate space for the stack used by the task being created.
2921  The base of the stack memory stored in the TCB so the task can
2922  be deleted later if required. */
2923  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. */
2924 
2925  if( pxNewTCB->pxStack == NULL )
2926  {
2927  /* Could not allocate the stack. Delete the allocated TCB. */
2928  vPortFree( pxNewTCB );
2929  pxNewTCB = NULL;
2930  }
2931  else
2932  {
2933  /* Avoid dependency on memset() if it is not required. */
2934  #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
2935  {
2936  /* Just to help debugging. */
2937  ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) );
2938  }
2939  #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */
2940  }
2941  }
2942 
2943  return pxNewTCB;
2944 }
2945 /*-----------------------------------------------------------*/
2946 
2947 #if ( configUSE_TRACE_FACILITY == 1 )
2948 
2949  static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )
2950  {
2951  volatile TCB_t *pxNextTCB, *pxFirstTCB;
2952  UBaseType_t uxTask = 0;
2953 
2954  if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
2955  {
2956  listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
2957 
2958  /* Populate an TaskStatus_t structure within the
2959  pxTaskStatusArray array for each task that is referenced from
2960  pxList. See the definition of TaskStatus_t in task.h for the
2961  meaning of each TaskStatus_t structure member. */
2962  do
2963  {
2964  listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
2965 
2966  pxTaskStatusArray[ uxTask ].xHandle = ( TaskHandle_t ) pxNextTCB;
2967  pxTaskStatusArray[ uxTask ].pcTaskName = ( const char * ) &( pxNextTCB->pcTaskName [ 0 ] );
2968  pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber;
2969  pxTaskStatusArray[ uxTask ].eCurrentState = eState;
2970  pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority;
2971 
2972  #if ( INCLUDE_vTaskSuspend == 1 )
2973  {
2974  /* If the task is in the suspended list then there is a chance
2975  it is actually just blocked indefinitely - so really it should
2976  be reported as being in the Blocked state. */
2977  if( eState == eSuspended )
2978  {
2979  if( listLIST_ITEM_CONTAINER( &( pxNextTCB->xEventListItem ) ) != NULL )
2980  {
2981  pxTaskStatusArray[ uxTask ].eCurrentState = eBlocked;
2982  }
2983  }
2984  }
2985  #endif /* INCLUDE_vTaskSuspend */
2986 
2987  #if ( configUSE_MUTEXES == 1 )
2988  {
2989  pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority;
2990  }
2991  #else
2992  {
2993  pxTaskStatusArray[ uxTask ].uxBasePriority = 0;
2994  }
2995  #endif
2996 
2997  #if ( configGENERATE_RUN_TIME_STATS == 1 )
2998  {
2999  pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter;
3000  }
3001  #else
3002  {
3003  pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0;
3004  }
3005  #endif
3006 
3007  #if ( portSTACK_GROWTH > 0 )
3008  {
3009  pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxEndOfStack );
3010  }
3011  #else
3012  {
3013  pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxStack );
3014  }
3015  #endif
3016 
3017  uxTask++;
3018 
3019  } while( pxNextTCB != pxFirstTCB );
3020  }
3021  else
3022  {
3024  }
3025 
3026  return uxTask;
3027  }
3028 
3029 #endif /* configUSE_TRACE_FACILITY */
3030 /*-----------------------------------------------------------*/
3031 
3032 #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
3033 
3034  static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
3035  {
3036  uint32_t ulCount = 0U;
3037 
3038  while( *pucStackByte == tskSTACK_FILL_BYTE )
3039  {
3040  pucStackByte -= portSTACK_GROWTH;
3041  ulCount++;
3042  }
3043 
3044  ulCount /= ( uint32_t ) sizeof( StackType_t );
3045 
3046  return ( uint16_t ) ulCount;
3047  }
3048 
3049 #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
3050 /*-----------------------------------------------------------*/
3051 
3052 #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
3053 
3055  {
3056  TCB_t *pxTCB;
3057  uint8_t *pucEndOfStack;
3058  UBaseType_t uxReturn;
3059 
3060  pxTCB = prvGetTCBFromHandle( xTask );
3061 
3062  #if portSTACK_GROWTH < 0
3063  {
3064  pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;
3065  }
3066  #else
3067  {
3068  pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;
3069  }
3070  #endif
3071 
3072  uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack );
3073 
3074  return uxReturn;
3075  }
3076 
3077 #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
3078 /*-----------------------------------------------------------*/
3079 
3080 #if ( INCLUDE_vTaskDelete == 1 )
3081 
3082  static void prvDeleteTCB( TCB_t *pxTCB )
3083  {
3084  /* This call is required specifically for the TriCore port. It must be
3085  above the vPortFree() calls. The call is also used by ports/demos that
3086  want to allocate and clean RAM statically. */
3087  portCLEAN_UP_TCB( pxTCB );
3088 
3089  /* Free up the memory allocated by the scheduler for the task. It is up
3090  to the task to free any memory allocated at the application level. */
3091  #if ( configUSE_NEWLIB_REENTRANT == 1 )
3092  {
3093  _reclaim_reent( &( pxTCB->xNewLib_reent ) );
3094  }
3095  #endif /* configUSE_NEWLIB_REENTRANT */
3096  vPortFreeAligned( pxTCB->pxStack );
3097  vPortFree( pxTCB );
3098  }
3099 
3100 #endif /* INCLUDE_vTaskDelete */
3101 /*-----------------------------------------------------------*/
3102 
3103 static void prvResetNextTaskUnblockTime( void )
3104 {
3105 TCB_t *pxTCB;
3106 
3107  if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
3108  {
3109  /* The new current delayed list is empty. Set
3110  xNextTaskUnblockTime to the maximum possible value so it is
3111  extremely unlikely that the
3112  if( xTickCount >= xNextTaskUnblockTime ) test will pass until
3113  there is an item in the delayed list. */
3114  xNextTaskUnblockTime = portMAX_DELAY;
3115  }
3116  else
3117  {
3118  /* The new current delayed list is not empty, get the value of
3119  the item at the head of the delayed list. This is the time at
3120  which the task at the head of the delayed list should be removed
3121  from the Blocked state. */
3122  ( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
3123  xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xGenericListItem ) );
3124  }
3125 }
3126 /*-----------------------------------------------------------*/
3127 
3128 #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
3129 
3131  {
3132  TaskHandle_t xReturn;
3133 
3134  /* A critical section is not required as this is not called from
3135  an interrupt and the current TCB will always be the same for any
3136  individual execution thread. */
3137  xReturn = pxCurrentTCB;
3138 
3139  return xReturn;
3140  }
3141 
3142 #endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
3143 /*-----------------------------------------------------------*/
3144 
3145 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
3146 
3148  {
3149  BaseType_t xReturn;
3150 
3151  if( xSchedulerRunning == pdFALSE )
3152  {
3153  xReturn = taskSCHEDULER_NOT_STARTED;
3154  }
3155  else
3156  {
3157  if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
3158  {
3159  xReturn = taskSCHEDULER_RUNNING;
3160  }
3161  else
3162  {
3163  xReturn = taskSCHEDULER_SUSPENDED;
3164  }
3165  }
3166 
3167  return xReturn;
3168  }
3169 
3170 #endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */
3171 /*-----------------------------------------------------------*/
3172 
3173 #if ( configUSE_MUTEXES == 1 )
3174 
3176  {
3177  TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
3178 
3179  /* If the mutex was given back by an interrupt while the queue was
3180  locked then the mutex holder might now be NULL. */
3181  if( pxMutexHolder != NULL )
3182  {
3183  if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
3184  {
3185  /* Adjust the mutex holder state to account for its new
3186  priority. Only reset the event list item value if the value is
3187  not being used for anything else. */
3189  {
3190  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. */
3191  }
3192  else
3193  {
3195  }
3196 
3197  /* If the task being modified is in the ready state it will need to
3198  be moved into a new list. */
3199  if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
3200  {
3201  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
3202  {
3204  }
3205  else
3206  {
3208  }
3209 
3210  /* Inherit the priority before being moved into the new list. */
3212  prvAddTaskToReadyList( pxTCB );
3213  }
3214  else
3215  {
3216  /* Just inherit the priority. */
3218  }
3219 
3221  }
3222  else
3223  {
3225  }
3226  }
3227  else
3228  {
3230  }
3231  }
3232 
3233 #endif /* configUSE_MUTEXES */
3234 /*-----------------------------------------------------------*/
3235 
3236 #if ( configUSE_MUTEXES == 1 )
3237 
3238  void vTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder )
3239  {
3240  TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
3241 
3242  if( pxMutexHolder != NULL )
3243  {
3244  if( pxTCB->uxPriority != pxTCB->uxBasePriority )
3245  {
3246  /* We must be the running task to be able to give the mutex back.
3247  Remove ourselves from the ready list we currently appear in. */
3248  if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
3249  {
3251  }
3252  else
3253  {
3255  }
3256 
3257  /* Disinherit the priority before adding the task into the new
3258  ready list. */
3259  traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );
3260  pxTCB->uxPriority = pxTCB->uxBasePriority;
3261 
3262  /* Only reset the event list item value if the value is not
3263  being used for anything else. */
3265  {
3266  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. */
3267  }
3268  else
3269  {
3271  }
3272  prvAddTaskToReadyList( pxTCB );
3273  }
3274  else
3275  {
3277  }
3278  }
3279  else
3280  {
3282  }
3283  }
3284 
3285 #endif /* configUSE_MUTEXES */
3286 /*-----------------------------------------------------------*/
3287 
3288 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
3289 
3290  void vTaskEnterCritical( void )
3291  {
3293 
3294  if( xSchedulerRunning != pdFALSE )
3295  {
3296  ( pxCurrentTCB->uxCriticalNesting )++;
3297  }
3298  else
3299  {
3301  }
3302  }
3303 
3304 #endif /* portCRITICAL_NESTING_IN_TCB */
3305 /*-----------------------------------------------------------*/
3306 
3307 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
3308 
3309  void vTaskExitCritical( void )
3310  {
3311  if( xSchedulerRunning != pdFALSE )
3312  {
3313  if( pxCurrentTCB->uxCriticalNesting > 0U )
3314  {
3315  ( pxCurrentTCB->uxCriticalNesting )--;
3316 
3317  if( pxCurrentTCB->uxCriticalNesting == 0U )
3318  {
3320  }
3321  else
3322  {
3324  }
3325  }
3326  else
3327  {
3329  }
3330  }
3331  else
3332  {
3334  }
3335  }
3336 
3337 #endif /* portCRITICAL_NESTING_IN_TCB */
3338 /*-----------------------------------------------------------*/
3339 
3340 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )
3341 
3342  void vTaskList( char * pcWriteBuffer )
3343  {
3344  TaskStatus_t *pxTaskStatusArray;
3345  volatile UBaseType_t uxArraySize, x;
3346  char cStatus;
3347 
3348  /*
3349  * PLEASE NOTE:
3350  *
3351  * This function is provided for convenience only, and is used by many
3352  * of the demo applications. Do not consider it to be part of the
3353  * scheduler.
3354  *
3355  * vTaskList() calls uxTaskGetSystemState(), then formats part of the
3356  * uxTaskGetSystemState() output into a human readable table that
3357  * displays task names, states and stack usage.
3358  *
3359  * vTaskList() has a dependency on the sprintf() C library function that
3360  * might bloat the code size, use a lot of stack, and provide different
3361  * results on different platforms. An alternative, tiny, third party,
3362  * and limited functionality implementation of sprintf() is provided in
3363  * many of the FreeRTOS/Demo sub-directories in a file called
3364  * printf-stdarg.c (note printf-stdarg.c does not provide a full
3365  * snprintf() implementation!).
3366  *
3367  * It is recommended that production systems call uxTaskGetSystemState()
3368  * directly to get access to raw stats data, rather than indirectly
3369  * through a call to vTaskList().
3370  */
3371 
3372 
3373  /* Make sure the write buffer does not contain a string. */
3374  *pcWriteBuffer = 0x00;
3375 
3376  /* Take a snapshot of the number of tasks in case it changes while this
3377  function is executing. */
3378  uxArraySize = uxCurrentNumberOfTasks;
3379 
3380  /* Allocate an array index for each task. */
3381  pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );
3382 
3383  if( pxTaskStatusArray != NULL )
3384  {
3385  /* Generate the (binary) data. */
3386  uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );
3387 
3388  /* Create a human readable table from the binary data. */
3389  for( x = 0; x < uxArraySize; x++ )
3390  {
3391  switch( pxTaskStatusArray[ x ].eCurrentState )
3392  {
3393  case eReady: cStatus = tskREADY_CHAR;
3394  break;
3395 
3396  case eBlocked: cStatus = tskBLOCKED_CHAR;
3397  break;
3398 
3399  case eSuspended: cStatus = tskSUSPENDED_CHAR;
3400  break;
3401 
3402  case eDeleted: cStatus = tskDELETED_CHAR;
3403  break;
3404 
3405  default: /* Should not get here, but it is included
3406  to prevent static checking errors. */
3407  cStatus = 0x00;
3408  break;
3409  }
3410 
3411  sprintf( pcWriteBuffer, "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
3412  pcWriteBuffer += strlen( pcWriteBuffer );
3413  }
3414 
3415  /* Free the array again. */
3416  vPortFree( pxTaskStatusArray );
3417  }
3418  else
3419  {
3421  }
3422  }
3423 
3424 #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */
3425 /*----------------------------------------------------------*/
3426 
3427 #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )
3428 
3429  void vTaskGetRunTimeStats( char *pcWriteBuffer )
3430  {
3431  TaskStatus_t *pxTaskStatusArray;
3432  volatile UBaseType_t uxArraySize, x;
3433  uint32_t ulTotalTime, ulStatsAsPercentage;
3434 
3435  #if( configUSE_TRACE_FACILITY != 1 )
3436  {
3437  #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
3438  }
3439  #endif
3440 
3441  /*
3442  * PLEASE NOTE:
3443  *
3444  * This function is provided for convenience only, and is used by many
3445  * of the demo applications. Do not consider it to be part of the
3446  * scheduler.
3447  *
3448  * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part
3449  * of the uxTaskGetSystemState() output into a human readable table that
3450  * displays the amount of time each task has spent in the Running state
3451  * in both absolute and percentage terms.
3452  *
3453  * vTaskGetRunTimeStats() has a dependency on the sprintf() C library
3454  * function that might bloat the code size, use a lot of stack, and
3455  * provide different results on different platforms. An alternative,
3456  * tiny, third party, and limited functionality implementation of
3457  * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in
3458  * a file called printf-stdarg.c (note printf-stdarg.c does not provide
3459  * a full snprintf() implementation!).
3460  *
3461  * It is recommended that production systems call uxTaskGetSystemState()
3462  * directly to get access to raw stats data, rather than indirectly
3463  * through a call to vTaskGetRunTimeStats().
3464  */
3465 
3466  /* Make sure the write buffer does not contain a string. */
3467  *pcWriteBuffer = 0x00;
3468 
3469  /* Take a snapshot of the number of tasks in case it changes while this
3470  function is executing. */
3471  uxArraySize = uxCurrentNumberOfTasks;
3472 
3473  /* Allocate an array index for each task. */
3474  pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );
3475 
3476  if( pxTaskStatusArray != NULL )
3477  {
3478  /* Generate the (binary) data. */
3479  uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime );
3480 
3481  /* For percentage calculations. */
3482  ulTotalTime /= 100UL;
3483 
3484  /* Avoid divide by zero errors. */
3485  if( ulTotalTime > 0 )
3486  {
3487  /* Create a human readable table from the binary data. */
3488  for( x = 0; x < uxArraySize; x++ )
3489  {
3490  /* What percentage of the total run time has the task used?
3491  This will always be rounded down to the nearest integer.
3492  ulTotalRunTimeDiv100 has already been divided by 100. */
3493  ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
3494 
3495  if( ulStatsAsPercentage > 0UL )
3496  {
3497  #ifdef portLU_PRINTF_SPECIFIER_REQUIRED
3498  {
3499  sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
3500  }
3501  #else
3502  {
3503  /* sizeof( int ) == sizeof( long ) so a smaller
3504  printf() library can be used. */
3505  sprintf( pcWriteBuffer, "%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
3506  }
3507  #endif
3508  }
3509  else
3510  {
3511  /* If the percentage is zero here then the task has
3512  consumed less than 1% of the total run time. */
3513  #ifdef portLU_PRINTF_SPECIFIER_REQUIRED
3514  {
3515  sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
3516  }
3517  #else
3518  {
3519  /* sizeof( int ) == sizeof( long ) so a smaller
3520  printf() library can be used. */
3521  sprintf( pcWriteBuffer, "%s\t\t%u\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter );
3522  }
3523  #endif
3524  }
3525 
3526  pcWriteBuffer += strlen( pcWriteBuffer );
3527  }
3528  }
3529  else
3530  {
3532  }
3533 
3534  /* Free the array again. */
3535  vPortFree( pxTaskStatusArray );
3536  }
3537  else
3538  {
3540  }
3541  }
3542 
3543 #endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */
3544 /*-----------------------------------------------------------*/
3545 
3547 {
3548 TickType_t uxReturn;
3549 
3551 
3552  /* Reset the event list item to its normal value - so it can be used with
3553  queues and semaphores. */
3554  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. */
3555 
3556  return uxReturn;
3557 }
3558 /*-----------------------------------------------------------*/
3559 
3560 #ifdef FREERTOS_MODULE_TEST
3561  #include "tasks_test_access_functions.h"
3562 #endif
3563 
#define pdTRUE
Definition: projdefs.h:76
#define pxMutexHolder
Definition: queue.c:104
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
Definition: StackMacros.h:89
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition: heap_4.c:294
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime)
Definition: FreeRTOS.h:661
#define listGET_LIST_ITEM_VALUE(pxListItem)
Definition: list.h:199
BaseType_t(* TaskHookFunction_t)(void *)
Definition: task.h:105
#define listGET_OWNER_OF_NEXT_ENTRY(pxTCB, pxList)
Definition: list.h:268
void vApplicationTickHook(void)
#define portMAX_DELAY
Definition: portmacro.h:102
#define tskDELETED_CHAR
Definition: tasks.c:259
int sprintf(char *out, const char *format,...)
UBaseType_t uxBasePriority
Definition: task.h:159
void vTaskSetTaskNumber(TaskHandle_t xTask, const UBaseType_t uxHandle) PRIVILEGED_FUNCTION
#define traceLOW_POWER_IDLE_END()
Definition: FreeRTOS.h:354
BaseType_t xTaskRemoveFromUnorderedEventList(ListItem_t *pxEventListItem, const TickType_t xItemValue)
Definition: tasks.c:2395
void vTaskGetRunTimeStats(char *pcWriteBuffer) PRIVILEGED_FUNCTION
void vTaskSwitchContext(void)
Definition: tasks.c:2113
#define listIS_CONTAINED_WITHIN(pxList, pxListItem)
Definition: list.h:309
BaseType_t xTaskCheckForTimeOut(TimeOut_t *const pxTimeOut, TickType_t *const pxTicksToWait)
Definition: tasks.c:2448
TaskHandle_t xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION
#define traceTASK_SUSPEND(pxTaskToSuspend)
Definition: FreeRTOS.h:519
#define mtCOVERAGE_TEST_MARKER()
Definition: FreeRTOS.h:717
#define traceTASK_DELAY()
Definition: FreeRTOS.h:511
#define listLIST_ITEM_CONTAINER(pxListItem)
Definition: list.h:317
void vTaskSuspendAll(void)
Definition: tasks.c:1543
void vTaskEndScheduler(void)
Definition: tasks.c:1532
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP
Definition: FreeRTOS.h:665
#define taskEXIT_CRITICAL()
Definition: task.h:216
#define traceTASK_CREATE(pxNewTCB)
Definition: FreeRTOS.h:495
PRIVILEGED_DATA TCB_t *volatile pxCurrentTCB
Definition: tasks.c:187
void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority) PRIVILEGED_FUNCTION
uint32_t ulRunTimeCounter
Definition: task.h:160
UBaseType_t uxPriority
Definition: tasks.c:130
#define portENABLE_INTERRUPTS()
Definition: portmacro.h:130
Definition: task.h:110
#define configASSERT(x)
#define taskSCHEDULER_NOT_STARTED
Definition: task.h:242
#define traceTASK_DELAY_UNTIL()
Definition: FreeRTOS.h:507
void vTaskPlaceOnEventListRestricted(List_t *const pxEventList, const TickType_t xTicksToWait) PRIVILEGED_FUNCTION
#define tskSTACK_FILL_BYTE
Definition: tasks.c:252
#define taskYIELD()
Definition: task.h:188
#define portDISABLE_INTERRUPTS()
Definition: portmacro.h:129
#define traceLOW_POWER_IDLE_BEGIN()
Definition: FreeRTOS.h:349
#define prvAddTaskToReadyList(pxTCB)
Definition: tasks.c:364
Definition: task.h:114
#define tskIDLE_STACK_SIZE
Definition: tasks.c:105
#define taskSCHEDULER_RUNNING
Definition: task.h:243
BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION
void vApplicationStackOverflowHook(xTaskHandle pxTask, signed char *pcTaskName)
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_4.c:147
#define listSET_LIST_ITEM_VALUE(pxListItem, xValue)
Definition: list.h:189
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue)
Definition: FreeRTOS.h:294
#define portYIELD_WITHIN_API
Definition: FreeRTOS.h:649
#define traceTASK_PRIORITY_INHERIT(pxTCBOfMutexHolder, uxInheritedPriority)
Definition: FreeRTOS.h:369
void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem)
Definition: list.c:102
BaseType_t xTaskCallApplicationTaskHook(TaskHandle_t xTask, void *pvParameter) PRIVILEGED_FUNCTION
UBaseType_t xTaskNumber
Definition: task.h:156
BaseType_t xTaskRemoveFromEventList(const List_t *const pxEventList)
Definition: tasks.c:2341
#define listLIST_IS_EMPTY(pxList)
Definition: list.h:241
#define portSTACK_GROWTH
Definition: portmacro.h:107
void vTaskList(char *pcWriteBuffer) PRIVILEGED_FUNCTION
Definition: task.h:111
TickType_t xTimeOnEntering
Definition: task.h:123
#define traceTASK_RESUME(pxTaskToResume)
Definition: FreeRTOS.h:523
#define configMAX_PRIORITIES
void vPortEndScheduler(void) PRIVILEGED_FUNCTION
Definition: port.c:351
#define portRESET_READY_PRIORITY(uxPriority, uxTopReadyPriority)
Definition: tasks.c:302
void vApplicationIdleHook(void)
unsigned long UBaseType_t
Definition: portmacro.h:95
StackType_t * pxStack
Definition: tasks.c:131
uint32_t TickType_t
Definition: portmacro.h:101
#define traceINCREASE_TICK_COUNT(x)
Definition: FreeRTOS.h:344
#define traceTASK_SWITCHED_IN()
Definition: FreeRTOS.h:338
void vTaskStepTick(const TickType_t xTicksToJump) PRIVILEGED_FUNCTION
#define portSET_INTERRUPT_MASK_FROM_ISR()
Definition: FreeRTOS.h:290
BaseType_t xPortStartScheduler(void) PRIVILEGED_FUNCTION
Definition: port.c:276
eTaskState
Definition: task.h:108
StackType_t * pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) PRIVILEGED_FUNCTION
#define traceTASK_SWITCHED_OUT()
Definition: FreeRTOS.h:360
UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask) PRIVILEGED_FUNCTION
#define listSET_LIST_ITEM_OWNER(pxListItem, pxOwner)
Definition: list.h:171
void vTaskPriorityDisinherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION
ListItem_t xGenericListItem
Definition: tasks.c:128
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
Definition: projdefs.h:84
#define portPRIVILEGE_BIT
Definition: FreeRTOS.h:645
#define prvGetTCBFromHandle(pxHandle)
Definition: tasks.c:376
char * pcTaskGetTaskName(TaskHandle_t xTaskToQuery) PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA
Definition: mpu_wrappers.h:146
TickType_t uxTaskResetEventItemValue(void)
Definition: tasks.c:3546
void vTaskDelete(TaskHandle_t xTaskToDelete) PRIVILEGED_FUNCTION
const char * pcTaskName
Definition: task.h:155
UBaseType_t uxTaskGetTaskNumber(TaskHandle_t xTask) PRIVILEGED_FUNCTION
#define tskREADY_CHAR
Definition: tasks.c:258
#define traceTASK_PRIORITY_SET(pxTask, uxNewPriority)
Definition: FreeRTOS.h:515
#define pdFAIL
Definition: projdefs.h:79
#define taskRESET_READY_PRIORITY(uxPriority)
Definition: tasks.c:301
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:94
void vTaskSuspend(TaskHandle_t xTaskToSuspend) PRIVILEGED_FUNCTION
#define traceTASK_PRIORITY_DISINHERIT(pxTCBOfMutexHolder, uxOriginalPriority)
Definition: FreeRTOS.h:377
#define pdPASS
Definition: projdefs.h:78
#define listGET_OWNER_OF_HEAD_ENTRY(pxList)
Definition: list.h:298
UBaseType_t uxTaskGetSystemState(TaskStatus_t *const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t *const pulTotalRunTime)
void * TaskHandle_t
Definition: task.h:99
void vTaskPriorityInherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION
#define traceTASK_CREATE_FAILED()
Definition: FreeRTOS.h:499
UBaseType_t uxTaskGetNumberOfTasks(void)
Definition: tasks.c:1720
char pcTaskName[configMAX_TASK_NAME_LEN]
Definition: tasks.c:132
void vTaskStartScheduler(void)
Definition: tasks.c:1454
void vTaskSetTimeOutState(TimeOut_t *const pxTimeOut)
Definition: tasks.c:2440
ListItem_t xEventListItem
Definition: tasks.c:129
#define portPRE_TASK_DELETE_HOOK(pvTaskToDelete, pxYieldPending)
Definition: FreeRTOS.h:302
#define pvPortMallocAligned(x, puxStackBuffer)
Definition: FreeRTOS.h:653
void vTaskPlaceOnUnorderedEventList(List_t *pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait)
Definition: tasks.c:2230
#define tskSUSPENDED_CHAR
Definition: tasks.c:260
eSleepModeStatus
Definition: task.h:165
#define portSETUP_TCB(pxTCB)
Definition: FreeRTOS.h:306
void vTaskResume(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION
void vTaskAllocateMPURegions(TaskHandle_t xTask, const MemoryRegion_t *const pxRegions) PRIVILEGED_FUNCTION
eTaskState eCurrentState
Definition: task.h:157
#define pdFALSE
Definition: projdefs.h:75
void(* TaskFunction_t)(void *)
Definition: projdefs.h:73
volatile StackType_t * pxTopOfStack
Definition: tasks.c:122
TickType_t xTaskGetTickCount(void)
Definition: tasks.c:1674
BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION
#define taskYIELD_IF_USING_PREEMPTION()
Definition: tasks.c:110
#define taskENTER_CRITICAL()
Definition: task.h:202
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters)
Definition: portmacro.h:138
#define portPOINTER_SIZE_TYPE
Definition: FreeRTOS.h:319
eSleepModeStatus eTaskConfirmSleepModeStatus(void) PRIVILEGED_FUNCTION
#define listGET_LIST_ITEM_OWNER(pxListItem)
Definition: list.h:180
BaseType_t xTaskResumeAll(void)
Definition: tasks.c:1581
#define taskSELECT_HIGHEST_PRIORITY_TASK()
Definition: tasks.c:282
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:145
void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION
BaseType_t xOverflowCount
Definition: task.h:122
#define traceTASK_INCREMENT_TICK(xTickCount)
Definition: FreeRTOS.h:531
#define tskIDLE_PRIORITY
Definition: task.h:178
#define vPortFreeAligned(pvBlockToFree)
Definition: FreeRTOS.h:657
Definition: task.h:112
#define taskEVENT_LIST_ITEM_VALUE_IN_USE
Definition: tasks.c:389
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
Definition: FreeRTOS.h:637
#define traceTASK_RESUME_FROM_ISR(pxTaskToResume)
Definition: FreeRTOS.h:527
TaskHandle_t xTaskGetIdleTaskHandle(void)
#define taskSCHEDULER_SUSPENDED
Definition: task.h:241
tskTCB TCB_t
Definition: tasks.c:174
BaseType_t xTimerCreateTimerTask(void) PRIVILEGED_FUNCTION
Definition: list.h:157
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
Definition: FreeRTOS.h:709
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
Definition: StackMacros.h:88
void vListInitialise(List_t *const pxList)
Definition: list.c:75
#define listCURRENT_LIST_LENGTH(pxList)
Definition: list.h:246
#define xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask)
Definition: task.h:330
TickType_t xTaskGetTickCountFromISR(void)
Definition: tasks.c:1689
#define tskBLOCKED_CHAR
Definition: tasks.c:257
#define taskSWITCH_DELAYED_LISTS()
Definition: tasks.c:344
void vTaskPlaceOnEventList(List_t *const pxEventList, const TickType_t xTicksToWait)
Definition: tasks.c:2171
uint16_t usStackHighWaterMark
Definition: task.h:161
void vTaskMissedYield(void)
Definition: tasks.c:2497
TaskHandle_t xHandle
Definition: task.h:154
void vListInitialiseItem(ListItem_t *const pxItem)
Definition: list.c:95
#define traceTASK_DELETE(pxTaskToDelete)
Definition: FreeRTOS.h:503
eTaskState eTaskGetState(TaskHandle_t xTask) PRIVILEGED_FUNCTION
BaseType_t xTaskIncrementTick(void)
Definition: tasks.c:1849
portSTACK_TYPE StackType_t
Definition: portmacro.h:93
#define portCLEAN_UP_TCB(pxTCB)
Definition: FreeRTOS.h:298
UBaseType_t uxCurrentPriority
Definition: task.h:158
#define portTASK_FUNCTION(vFunction, pvParameters)
Definition: portmacro.h:139
#define configMAX_TASK_NAME_LEN
struct tskTaskControlBlock tskTCB
void vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem)
Definition: list.c:121
UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove)
Definition: list.c:179