Please see my note book http://mbed.org/users/kenjiArai/notebook/freertos-on-mbed-board-with-mbed-cloud-ide--never-/

This is too old.
Below is another FreeRTOS on mbed.
http://developer.mbed.org/users/rgrover1/code/FreeRTOS/
I don't know it works well or not.
I have not evaluated it.

Committer:
kenjiArai
Date:
Sat Jan 01 11:17:45 2011 +0000
Revision:
0:d4960fcea8ff

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:d4960fcea8ff 1 /*
kenjiArai 0:d4960fcea8ff 2 FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.
kenjiArai 0:d4960fcea8ff 3
kenjiArai 0:d4960fcea8ff 4 ***************************************************************************
kenjiArai 0:d4960fcea8ff 5 * *
kenjiArai 0:d4960fcea8ff 6 * If you are: *
kenjiArai 0:d4960fcea8ff 7 * *
kenjiArai 0:d4960fcea8ff 8 * + New to FreeRTOS, *
kenjiArai 0:d4960fcea8ff 9 * + Wanting to learn FreeRTOS or multitasking in general quickly *
kenjiArai 0:d4960fcea8ff 10 * + Looking for basic training, *
kenjiArai 0:d4960fcea8ff 11 * + Wanting to improve your FreeRTOS skills and productivity *
kenjiArai 0:d4960fcea8ff 12 * *
kenjiArai 0:d4960fcea8ff 13 * then take a look at the FreeRTOS eBook *
kenjiArai 0:d4960fcea8ff 14 * *
kenjiArai 0:d4960fcea8ff 15 * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
kenjiArai 0:d4960fcea8ff 16 * http://www.FreeRTOS.org/Documentation *
kenjiArai 0:d4960fcea8ff 17 * *
kenjiArai 0:d4960fcea8ff 18 * A pdf reference manual is also available. Both are usually delivered *
kenjiArai 0:d4960fcea8ff 19 * to your inbox within 20 minutes to two hours when purchased between 8am *
kenjiArai 0:d4960fcea8ff 20 * and 8pm GMT (although please allow up to 24 hours in case of *
kenjiArai 0:d4960fcea8ff 21 * exceptional circumstances). Thank you for your support! *
kenjiArai 0:d4960fcea8ff 22 * *
kenjiArai 0:d4960fcea8ff 23 ***************************************************************************
kenjiArai 0:d4960fcea8ff 24
kenjiArai 0:d4960fcea8ff 25 This file is part of the FreeRTOS distribution.
kenjiArai 0:d4960fcea8ff 26
kenjiArai 0:d4960fcea8ff 27 FreeRTOS is free software; you can redistribute it and/or modify it under
kenjiArai 0:d4960fcea8ff 28 the terms of the GNU General Public License (version 2) as published by the
kenjiArai 0:d4960fcea8ff 29 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
kenjiArai 0:d4960fcea8ff 30 ***NOTE*** The exception to the GPL is included to allow you to distribute
kenjiArai 0:d4960fcea8ff 31 a combined work that includes FreeRTOS without being obliged to provide the
kenjiArai 0:d4960fcea8ff 32 source code for proprietary components outside of the FreeRTOS kernel.
kenjiArai 0:d4960fcea8ff 33 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
kenjiArai 0:d4960fcea8ff 34 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kenjiArai 0:d4960fcea8ff 35 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kenjiArai 0:d4960fcea8ff 36 more details. You should have received a copy of the GNU General Public
kenjiArai 0:d4960fcea8ff 37 License and the FreeRTOS license exception along with FreeRTOS; if not it
kenjiArai 0:d4960fcea8ff 38 can be viewed here: http://www.freertos.org/a00114.html and also obtained
kenjiArai 0:d4960fcea8ff 39 by writing to Richard Barry, contact details for whom are available on the
kenjiArai 0:d4960fcea8ff 40 FreeRTOS WEB site.
kenjiArai 0:d4960fcea8ff 41
kenjiArai 0:d4960fcea8ff 42 1 tab == 4 spaces!
kenjiArai 0:d4960fcea8ff 43
kenjiArai 0:d4960fcea8ff 44 http://www.FreeRTOS.org - Documentation, latest information, license and
kenjiArai 0:d4960fcea8ff 45 contact details.
kenjiArai 0:d4960fcea8ff 46
kenjiArai 0:d4960fcea8ff 47 http://www.SafeRTOS.com - A version that is certified for use in safety
kenjiArai 0:d4960fcea8ff 48 critical systems.
kenjiArai 0:d4960fcea8ff 49
kenjiArai 0:d4960fcea8ff 50 http://www.OpenRTOS.com - Commercial support, development, porting,
kenjiArai 0:d4960fcea8ff 51 licensing and training services.
kenjiArai 0:d4960fcea8ff 52 */
kenjiArai 0:d4960fcea8ff 53
kenjiArai 0:d4960fcea8ff 54
kenjiArai 0:d4960fcea8ff 55 #include <stdio.h>
kenjiArai 0:d4960fcea8ff 56 #include <stdlib.h>
kenjiArai 0:d4960fcea8ff 57 #include <string.h>
kenjiArai 0:d4960fcea8ff 58
kenjiArai 0:d4960fcea8ff 59 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
kenjiArai 0:d4960fcea8ff 60 all the API functions to use the MPU wrappers. That should only be done when
kenjiArai 0:d4960fcea8ff 61 task.h is included from an application file. */
kenjiArai 0:d4960fcea8ff 62 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
kenjiArai 0:d4960fcea8ff 63
kenjiArai 0:d4960fcea8ff 64 #include "FreeRTOS.h"
kenjiArai 0:d4960fcea8ff 65 #include "task.h"
kenjiArai 0:d4960fcea8ff 66 #include "StackMacros.h"
kenjiArai 0:d4960fcea8ff 67
kenjiArai 0:d4960fcea8ff 68 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
kenjiArai 0:d4960fcea8ff 69
kenjiArai 0:d4960fcea8ff 70 #if 0
kenjiArai 0:d4960fcea8ff 71 /*
kenjiArai 0:d4960fcea8ff 72 * Macro to define the amount of stack available to the idle task.
kenjiArai 0:d4960fcea8ff 73 */
kenjiArai 0:d4960fcea8ff 74 #define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
kenjiArai 0:d4960fcea8ff 75 #endif
kenjiArai 0:d4960fcea8ff 76
kenjiArai 0:d4960fcea8ff 77 /*
kenjiArai 0:d4960fcea8ff 78 * Task control block. A task control block (TCB) is allocated to each task,
kenjiArai 0:d4960fcea8ff 79 * and stores the context of the task.
kenjiArai 0:d4960fcea8ff 80 */
kenjiArai 0:d4960fcea8ff 81 typedef struct tskTaskControlBlock
kenjiArai 0:d4960fcea8ff 82 {
kenjiArai 0:d4960fcea8ff 83 volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
kenjiArai 0:d4960fcea8ff 84
kenjiArai 0:d4960fcea8ff 85 #if ( portUSING_MPU_WRAPPERS == 1 )
kenjiArai 0:d4960fcea8ff 86 xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */
kenjiArai 0:d4960fcea8ff 87 #endif
kenjiArai 0:d4960fcea8ff 88
kenjiArai 0:d4960fcea8ff 89 xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */
kenjiArai 0:d4960fcea8ff 90 xListItem xEventListItem; /*< List item used to place the TCB in event lists. */
kenjiArai 0:d4960fcea8ff 91 unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */
kenjiArai 0:d4960fcea8ff 92 portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */
kenjiArai 0:d4960fcea8ff 93 signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */
kenjiArai 0:d4960fcea8ff 94
kenjiArai 0:d4960fcea8ff 95 #if ( portSTACK_GROWTH > 0 )
kenjiArai 0:d4960fcea8ff 96 portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */
kenjiArai 0:d4960fcea8ff 97 #endif
kenjiArai 0:d4960fcea8ff 98
kenjiArai 0:d4960fcea8ff 99 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
kenjiArai 0:d4960fcea8ff 100 unsigned portBASE_TYPE uxCriticalNesting;
kenjiArai 0:d4960fcea8ff 101 #endif
kenjiArai 0:d4960fcea8ff 102
kenjiArai 0:d4960fcea8ff 103 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 104 unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */
kenjiArai 0:d4960fcea8ff 105 #endif
kenjiArai 0:d4960fcea8ff 106
kenjiArai 0:d4960fcea8ff 107 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 108 unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
kenjiArai 0:d4960fcea8ff 109 #endif
kenjiArai 0:d4960fcea8ff 110
kenjiArai 0:d4960fcea8ff 111 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
kenjiArai 0:d4960fcea8ff 112 pdTASK_HOOK_CODE pxTaskTag;
kenjiArai 0:d4960fcea8ff 113 #endif
kenjiArai 0:d4960fcea8ff 114
kenjiArai 0:d4960fcea8ff 115 #if ( configGENERATE_RUN_TIME_STATS == 1 )
kenjiArai 0:d4960fcea8ff 116 unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */
kenjiArai 0:d4960fcea8ff 117 #endif
kenjiArai 0:d4960fcea8ff 118
kenjiArai 0:d4960fcea8ff 119 } tskTCB;
kenjiArai 0:d4960fcea8ff 120
kenjiArai 0:d4960fcea8ff 121
kenjiArai 0:d4960fcea8ff 122 /*
kenjiArai 0:d4960fcea8ff 123 * Some kernel aware debuggers require data to be viewed to be global, rather
kenjiArai 0:d4960fcea8ff 124 * than file scope.
kenjiArai 0:d4960fcea8ff 125 */
kenjiArai 0:d4960fcea8ff 126 #ifdef portREMOVE_STATIC_QUALIFIER
kenjiArai 0:d4960fcea8ff 127 #define static
kenjiArai 0:d4960fcea8ff 128 #endif
kenjiArai 0:d4960fcea8ff 129
kenjiArai 0:d4960fcea8ff 130 /*lint -e956 */
kenjiArai 0:d4960fcea8ff 131 PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;
kenjiArai 0:d4960fcea8ff 132
kenjiArai 0:d4960fcea8ff 133 /* Lists for ready and blocked tasks. --------------------*/
kenjiArai 0:d4960fcea8ff 134
kenjiArai 0:d4960fcea8ff 135 PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */
kenjiArai 0:d4960fcea8ff 136 PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */
kenjiArai 0:d4960fcea8ff 137 PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
kenjiArai 0:d4960fcea8ff 138 PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */
kenjiArai 0:d4960fcea8ff 139 PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
kenjiArai 0:d4960fcea8ff 140 PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */
kenjiArai 0:d4960fcea8ff 141
kenjiArai 0:d4960fcea8ff 142 #if ( INCLUDE_vTaskDelete == 1 )
kenjiArai 0:d4960fcea8ff 143
kenjiArai 0:d4960fcea8ff 144 PRIVILEGED_DATA static volatile xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */
kenjiArai 0:d4960fcea8ff 145 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0;
kenjiArai 0:d4960fcea8ff 146
kenjiArai 0:d4960fcea8ff 147 #endif
kenjiArai 0:d4960fcea8ff 148
kenjiArai 0:d4960fcea8ff 149 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 150
kenjiArai 0:d4960fcea8ff 151 PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */
kenjiArai 0:d4960fcea8ff 152
kenjiArai 0:d4960fcea8ff 153 #endif
kenjiArai 0:d4960fcea8ff 154
kenjiArai 0:d4960fcea8ff 155 /* File private variables. --------------------------------*/
kenjiArai 0:d4960fcea8ff 156 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0;
kenjiArai 0:d4960fcea8ff 157 PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0;
kenjiArai 0:d4960fcea8ff 158 PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
kenjiArai 0:d4960fcea8ff 159 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
kenjiArai 0:d4960fcea8ff 160 PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
kenjiArai 0:d4960fcea8ff 161 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
kenjiArai 0:d4960fcea8ff 162 PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0;
kenjiArai 0:d4960fcea8ff 163 PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
kenjiArai 0:d4960fcea8ff 164 PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
kenjiArai 0:d4960fcea8ff 165 PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0;
kenjiArai 0:d4960fcea8ff 166
kenjiArai 0:d4960fcea8ff 167 #if ( configGENERATE_RUN_TIME_STATS == 1 )
kenjiArai 0:d4960fcea8ff 168
kenjiArai 0:d4960fcea8ff 169 PRIVILEGED_DATA static char pcStatsString[ 50 ] ;
kenjiArai 0:d4960fcea8ff 170 PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
kenjiArai 0:d4960fcea8ff 171 static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 172
kenjiArai 0:d4960fcea8ff 173 #endif
kenjiArai 0:d4960fcea8ff 174
kenjiArai 0:d4960fcea8ff 175 /* Debugging and trace facilities private variables and macros. ------------*/
kenjiArai 0:d4960fcea8ff 176
kenjiArai 0:d4960fcea8ff 177 /*
kenjiArai 0:d4960fcea8ff 178 * The value used to fill the stack of a task when the task is created. This
kenjiArai 0:d4960fcea8ff 179 * is used purely for checking the high water mark for tasks.
kenjiArai 0:d4960fcea8ff 180 */
kenjiArai 0:d4960fcea8ff 181 #define tskSTACK_FILL_BYTE ( 0xa5 )
kenjiArai 0:d4960fcea8ff 182
kenjiArai 0:d4960fcea8ff 183 /*
kenjiArai 0:d4960fcea8ff 184 * Macros used by vListTask to indicate which state a task is in.
kenjiArai 0:d4960fcea8ff 185 */
kenjiArai 0:d4960fcea8ff 186 #define tskBLOCKED_CHAR ( ( signed char ) 'B' )
kenjiArai 0:d4960fcea8ff 187 #define tskREADY_CHAR ( ( signed char ) 'R' )
kenjiArai 0:d4960fcea8ff 188 #define tskDELETED_CHAR ( ( signed char ) 'D' )
kenjiArai 0:d4960fcea8ff 189 #define tskSUSPENDED_CHAR ( ( signed char ) 'S' )
kenjiArai 0:d4960fcea8ff 190
kenjiArai 0:d4960fcea8ff 191 /*
kenjiArai 0:d4960fcea8ff 192 * Macros and private variables used by the trace facility.
kenjiArai 0:d4960fcea8ff 193 */
kenjiArai 0:d4960fcea8ff 194 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 195
kenjiArai 0:d4960fcea8ff 196 #define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) )
kenjiArai 0:d4960fcea8ff 197 PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer;
kenjiArai 0:d4960fcea8ff 198 PRIVILEGED_DATA static signed char *pcTraceBufferStart;
kenjiArai 0:d4960fcea8ff 199 PRIVILEGED_DATA static signed char *pcTraceBufferEnd;
kenjiArai 0:d4960fcea8ff 200 PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE;
kenjiArai 0:d4960fcea8ff 201 static unsigned portBASE_TYPE uxPreviousTask = 255;
kenjiArai 0:d4960fcea8ff 202 PRIVILEGED_DATA static char pcStatusString[ 50 ];
kenjiArai 0:d4960fcea8ff 203
kenjiArai 0:d4960fcea8ff 204 #endif
kenjiArai 0:d4960fcea8ff 205
kenjiArai 0:d4960fcea8ff 206 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 207
kenjiArai 0:d4960fcea8ff 208 /*
kenjiArai 0:d4960fcea8ff 209 * Macro that writes a trace of scheduler activity to a buffer. This trace
kenjiArai 0:d4960fcea8ff 210 * shows which task is running when and is very useful as a debugging tool.
kenjiArai 0:d4960fcea8ff 211 * As this macro is called each context switch it is a good idea to undefine
kenjiArai 0:d4960fcea8ff 212 * it if not using the facility.
kenjiArai 0:d4960fcea8ff 213 */
kenjiArai 0:d4960fcea8ff 214 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 215
kenjiArai 0:d4960fcea8ff 216 #define vWriteTraceToBuffer() \
kenjiArai 0:d4960fcea8ff 217 { \
kenjiArai 0:d4960fcea8ff 218 if( xTracing ) \
kenjiArai 0:d4960fcea8ff 219 { \
kenjiArai 0:d4960fcea8ff 220 if( uxPreviousTask != pxCurrentTCB->uxTCBNumber ) \
kenjiArai 0:d4960fcea8ff 221 { \
kenjiArai 0:d4960fcea8ff 222 if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \
kenjiArai 0:d4960fcea8ff 223 { \
kenjiArai 0:d4960fcea8ff 224 uxPreviousTask = pxCurrentTCB->uxTCBNumber; \
kenjiArai 0:d4960fcea8ff 225 *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \
kenjiArai 0:d4960fcea8ff 226 pcTraceBuffer += sizeof( unsigned long ); \
kenjiArai 0:d4960fcea8ff 227 *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \
kenjiArai 0:d4960fcea8ff 228 pcTraceBuffer += sizeof( unsigned long ); \
kenjiArai 0:d4960fcea8ff 229 } \
kenjiArai 0:d4960fcea8ff 230 else \
kenjiArai 0:d4960fcea8ff 231 { \
kenjiArai 0:d4960fcea8ff 232 xTracing = pdFALSE; \
kenjiArai 0:d4960fcea8ff 233 } \
kenjiArai 0:d4960fcea8ff 234 } \
kenjiArai 0:d4960fcea8ff 235 } \
kenjiArai 0:d4960fcea8ff 236 }
kenjiArai 0:d4960fcea8ff 237
kenjiArai 0:d4960fcea8ff 238 #else
kenjiArai 0:d4960fcea8ff 239
kenjiArai 0:d4960fcea8ff 240 #define vWriteTraceToBuffer()
kenjiArai 0:d4960fcea8ff 241
kenjiArai 0:d4960fcea8ff 242 #endif
kenjiArai 0:d4960fcea8ff 243 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 244
kenjiArai 0:d4960fcea8ff 245 /*
kenjiArai 0:d4960fcea8ff 246 * Place the task represented by pxTCB into the appropriate ready queue for
kenjiArai 0:d4960fcea8ff 247 * the task. It is inserted at the end of the list. One quirk of this is
kenjiArai 0:d4960fcea8ff 248 * that if the task being inserted is at the same priority as the currently
kenjiArai 0:d4960fcea8ff 249 * executing task, then it will only be rescheduled after the currently
kenjiArai 0:d4960fcea8ff 250 * executing task has been rescheduled.
kenjiArai 0:d4960fcea8ff 251 */
kenjiArai 0:d4960fcea8ff 252 #define prvAddTaskToReadyQueue( pxTCB ) \
kenjiArai 0:d4960fcea8ff 253 { \
kenjiArai 0:d4960fcea8ff 254 if( pxTCB->uxPriority > uxTopReadyPriority ) \
kenjiArai 0:d4960fcea8ff 255 { \
kenjiArai 0:d4960fcea8ff 256 uxTopReadyPriority = pxTCB->uxPriority; \
kenjiArai 0:d4960fcea8ff 257 } \
kenjiArai 0:d4960fcea8ff 258 vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \
kenjiArai 0:d4960fcea8ff 259 }
kenjiArai 0:d4960fcea8ff 260 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 261
kenjiArai 0:d4960fcea8ff 262 /*
kenjiArai 0:d4960fcea8ff 263 * Macro that looks at the list of tasks that are currently delayed to see if
kenjiArai 0:d4960fcea8ff 264 * any require waking.
kenjiArai 0:d4960fcea8ff 265 *
kenjiArai 0:d4960fcea8ff 266 * Tasks are stored in the queue in the order of their wake time - meaning
kenjiArai 0:d4960fcea8ff 267 * once one tasks has been found whose timer has not expired we need not look
kenjiArai 0:d4960fcea8ff 268 * any further down the list.
kenjiArai 0:d4960fcea8ff 269 */
kenjiArai 0:d4960fcea8ff 270 #define prvCheckDelayedTasks() \
kenjiArai 0:d4960fcea8ff 271 { \
kenjiArai 0:d4960fcea8ff 272 register tskTCB *pxTCB; \
kenjiArai 0:d4960fcea8ff 273 \
kenjiArai 0:d4960fcea8ff 274 while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \
kenjiArai 0:d4960fcea8ff 275 { \
kenjiArai 0:d4960fcea8ff 276 if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \
kenjiArai 0:d4960fcea8ff 277 { \
kenjiArai 0:d4960fcea8ff 278 break; \
kenjiArai 0:d4960fcea8ff 279 } \
kenjiArai 0:d4960fcea8ff 280 vListRemove( &( pxTCB->xGenericListItem ) ); \
kenjiArai 0:d4960fcea8ff 281 /* Is the task waiting on an event also? */ \
kenjiArai 0:d4960fcea8ff 282 if( pxTCB->xEventListItem.pvContainer ) \
kenjiArai 0:d4960fcea8ff 283 { \
kenjiArai 0:d4960fcea8ff 284 vListRemove( &( pxTCB->xEventListItem ) ); \
kenjiArai 0:d4960fcea8ff 285 } \
kenjiArai 0:d4960fcea8ff 286 prvAddTaskToReadyQueue( pxTCB ); \
kenjiArai 0:d4960fcea8ff 287 } \
kenjiArai 0:d4960fcea8ff 288 }
kenjiArai 0:d4960fcea8ff 289 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 290
kenjiArai 0:d4960fcea8ff 291 /*
kenjiArai 0:d4960fcea8ff 292 * Several functions take an xTaskHandle parameter that can optionally be NULL,
kenjiArai 0:d4960fcea8ff 293 * where NULL is used to indicate that the handle of the currently executing
kenjiArai 0:d4960fcea8ff 294 * task should be used in place of the parameter. This macro simply checks to
kenjiArai 0:d4960fcea8ff 295 * see if the parameter is NULL and returns a pointer to the appropriate TCB.
kenjiArai 0:d4960fcea8ff 296 */
kenjiArai 0:d4960fcea8ff 297 #define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle )
kenjiArai 0:d4960fcea8ff 298
kenjiArai 0:d4960fcea8ff 299
kenjiArai 0:d4960fcea8ff 300 /* File private functions. --------------------------------*/
kenjiArai 0:d4960fcea8ff 301
kenjiArai 0:d4960fcea8ff 302 /*
kenjiArai 0:d4960fcea8ff 303 * Utility to ready a TCB for a given task. Mainly just copies the parameters
kenjiArai 0:d4960fcea8ff 304 * into the TCB structure.
kenjiArai 0:d4960fcea8ff 305 */
kenjiArai 0:d4960fcea8ff 306 static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 307
kenjiArai 0:d4960fcea8ff 308 /*
kenjiArai 0:d4960fcea8ff 309 * Utility to ready all the lists used by the scheduler. This is called
kenjiArai 0:d4960fcea8ff 310 * automatically upon the creation of the first task.
kenjiArai 0:d4960fcea8ff 311 */
kenjiArai 0:d4960fcea8ff 312 static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 313
kenjiArai 0:d4960fcea8ff 314 /*
kenjiArai 0:d4960fcea8ff 315 * The idle task, which as all tasks is implemented as a never ending loop.
kenjiArai 0:d4960fcea8ff 316 * The idle task is automatically created and added to the ready lists upon
kenjiArai 0:d4960fcea8ff 317 * creation of the first user task.
kenjiArai 0:d4960fcea8ff 318 *
kenjiArai 0:d4960fcea8ff 319 * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
kenjiArai 0:d4960fcea8ff 320 * language extensions. The equivalent prototype for this function is:
kenjiArai 0:d4960fcea8ff 321 *
kenjiArai 0:d4960fcea8ff 322 * void prvIdleTask( void *pvParameters );
kenjiArai 0:d4960fcea8ff 323 *
kenjiArai 0:d4960fcea8ff 324 */
kenjiArai 0:d4960fcea8ff 325 //static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
kenjiArai 0:d4960fcea8ff 326 #ifdef __cplusplus
kenjiArai 0:d4960fcea8ff 327 extern "C" {
kenjiArai 0:d4960fcea8ff 328 #endif
kenjiArai 0:d4960fcea8ff 329 static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
kenjiArai 0:d4960fcea8ff 330 #ifdef __cplusplus
kenjiArai 0:d4960fcea8ff 331 }
kenjiArai 0:d4960fcea8ff 332 #endif
kenjiArai 0:d4960fcea8ff 333 /*
kenjiArai 0:d4960fcea8ff 334 * Utility to free all memory allocated by the scheduler to hold a TCB,
kenjiArai 0:d4960fcea8ff 335 * including the stack pointed to by the TCB.
kenjiArai 0:d4960fcea8ff 336 *
kenjiArai 0:d4960fcea8ff 337 * This does not free memory allocated by the task itself (i.e. memory
kenjiArai 0:d4960fcea8ff 338 * allocated by calls to pvPortMalloc from within the tasks application code).
kenjiArai 0:d4960fcea8ff 339 */
kenjiArai 0:d4960fcea8ff 340 #if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
kenjiArai 0:d4960fcea8ff 341
kenjiArai 0:d4960fcea8ff 342 static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 343
kenjiArai 0:d4960fcea8ff 344 #endif
kenjiArai 0:d4960fcea8ff 345
kenjiArai 0:d4960fcea8ff 346 /*
kenjiArai 0:d4960fcea8ff 347 * Used only by the idle task. This checks to see if anything has been placed
kenjiArai 0:d4960fcea8ff 348 * in the list of tasks waiting to be deleted. If so the task is cleaned up
kenjiArai 0:d4960fcea8ff 349 * and its TCB deleted.
kenjiArai 0:d4960fcea8ff 350 */
kenjiArai 0:d4960fcea8ff 351 static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 352
kenjiArai 0:d4960fcea8ff 353 /*
kenjiArai 0:d4960fcea8ff 354 * Allocates memory from the heap for a TCB and associated stack. Checks the
kenjiArai 0:d4960fcea8ff 355 * allocation was successful.
kenjiArai 0:d4960fcea8ff 356 */
kenjiArai 0:d4960fcea8ff 357 static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 358
kenjiArai 0:d4960fcea8ff 359 /*
kenjiArai 0:d4960fcea8ff 360 * Called from vTaskList. vListTasks details all the tasks currently under
kenjiArai 0:d4960fcea8ff 361 * control of the scheduler. The tasks may be in one of a number of lists.
kenjiArai 0:d4960fcea8ff 362 * prvListTaskWithinSingleList accepts a list and details the tasks from
kenjiArai 0:d4960fcea8ff 363 * within just that list.
kenjiArai 0:d4960fcea8ff 364 *
kenjiArai 0:d4960fcea8ff 365 * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
kenjiArai 0:d4960fcea8ff 366 * NORMAL APPLICATION CODE.
kenjiArai 0:d4960fcea8ff 367 */
kenjiArai 0:d4960fcea8ff 368 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 369
kenjiArai 0:d4960fcea8ff 370 static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 371
kenjiArai 0:d4960fcea8ff 372 #endif
kenjiArai 0:d4960fcea8ff 373
kenjiArai 0:d4960fcea8ff 374 /*
kenjiArai 0:d4960fcea8ff 375 * When a task is created, the stack of the task is filled with a known value.
kenjiArai 0:d4960fcea8ff 376 * This function determines the 'high water mark' of the task stack by
kenjiArai 0:d4960fcea8ff 377 * determining how much of the stack remains at the original preset value.
kenjiArai 0:d4960fcea8ff 378 */
kenjiArai 0:d4960fcea8ff 379 #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
kenjiArai 0:d4960fcea8ff 380
kenjiArai 0:d4960fcea8ff 381 static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 382
kenjiArai 0:d4960fcea8ff 383 #endif
kenjiArai 0:d4960fcea8ff 384
kenjiArai 0:d4960fcea8ff 385
kenjiArai 0:d4960fcea8ff 386 /*lint +e956 */
kenjiArai 0:d4960fcea8ff 387
kenjiArai 0:d4960fcea8ff 388
kenjiArai 0:d4960fcea8ff 389
kenjiArai 0:d4960fcea8ff 390 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 391 * TASK CREATION API documented in task.h
kenjiArai 0:d4960fcea8ff 392 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 393
kenjiArai 0:d4960fcea8ff 394 signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )
kenjiArai 0:d4960fcea8ff 395 {
kenjiArai 0:d4960fcea8ff 396 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 397 tskTCB * pxNewTCB;
kenjiArai 0:d4960fcea8ff 398
kenjiArai 0:d4960fcea8ff 399 /* Allocate the memory required by the TCB and stack for the new task,
kenjiArai 0:d4960fcea8ff 400 checking that the allocation was successful. */
kenjiArai 0:d4960fcea8ff 401 pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
kenjiArai 0:d4960fcea8ff 402
kenjiArai 0:d4960fcea8ff 403 if( pxNewTCB != NULL )
kenjiArai 0:d4960fcea8ff 404 {
kenjiArai 0:d4960fcea8ff 405 portSTACK_TYPE *pxTopOfStack;
kenjiArai 0:d4960fcea8ff 406
kenjiArai 0:d4960fcea8ff 407 #if( portUSING_MPU_WRAPPERS == 1 )
kenjiArai 0:d4960fcea8ff 408 /* Should the task be created in privileged mode? */
kenjiArai 0:d4960fcea8ff 409 portBASE_TYPE xRunPrivileged;
kenjiArai 0:d4960fcea8ff 410 if( ( uxPriority & portPRIVILEGE_BIT ) != 0x00 )
kenjiArai 0:d4960fcea8ff 411 {
kenjiArai 0:d4960fcea8ff 412 xRunPrivileged = pdTRUE;
kenjiArai 0:d4960fcea8ff 413 }
kenjiArai 0:d4960fcea8ff 414 else
kenjiArai 0:d4960fcea8ff 415 {
kenjiArai 0:d4960fcea8ff 416 xRunPrivileged = pdFALSE;
kenjiArai 0:d4960fcea8ff 417 }
kenjiArai 0:d4960fcea8ff 418 uxPriority &= ~portPRIVILEGE_BIT;
kenjiArai 0:d4960fcea8ff 419 #endif /* portUSING_MPU_WRAPPERS == 1 */
kenjiArai 0:d4960fcea8ff 420
kenjiArai 0:d4960fcea8ff 421 /* Calculate the top of stack address. This depends on whether the
kenjiArai 0:d4960fcea8ff 422 stack grows from high memory to low (as per the 80x86) or visa versa.
kenjiArai 0:d4960fcea8ff 423 portSTACK_GROWTH is used to make the result positive or negative as
kenjiArai 0:d4960fcea8ff 424 required by the port. */
kenjiArai 0:d4960fcea8ff 425 #if( portSTACK_GROWTH < 0 )
kenjiArai 0:d4960fcea8ff 426 {
kenjiArai 0:d4960fcea8ff 427 pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
kenjiArai 0:d4960fcea8ff 428 pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( unsigned long ) pxTopOfStack ) & ( ( unsigned long ) ~portBYTE_ALIGNMENT_MASK ) );
kenjiArai 0:d4960fcea8ff 429 }
kenjiArai 0:d4960fcea8ff 430 #else
kenjiArai 0:d4960fcea8ff 431 {
kenjiArai 0:d4960fcea8ff 432 pxTopOfStack = pxNewTCB->pxStack;
kenjiArai 0:d4960fcea8ff 433
kenjiArai 0:d4960fcea8ff 434 /* If we want to use stack checking on architectures that use
kenjiArai 0:d4960fcea8ff 435 a positive stack growth direction then we also need to store the
kenjiArai 0:d4960fcea8ff 436 other extreme of the stack space. */
kenjiArai 0:d4960fcea8ff 437 pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
kenjiArai 0:d4960fcea8ff 438 }
kenjiArai 0:d4960fcea8ff 439 #endif
kenjiArai 0:d4960fcea8ff 440
kenjiArai 0:d4960fcea8ff 441 /* Setup the newly allocated TCB with the initial state of the task. */
kenjiArai 0:d4960fcea8ff 442 prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
kenjiArai 0:d4960fcea8ff 443
kenjiArai 0:d4960fcea8ff 444 /* Initialize the TCB stack to look as if the task was already running,
kenjiArai 0:d4960fcea8ff 445 but had been interrupted by the scheduler. The return address is set
kenjiArai 0:d4960fcea8ff 446 to the start of the task function. Once the stack has been initialised
kenjiArai 0:d4960fcea8ff 447 the top of stack variable is updated. */
kenjiArai 0:d4960fcea8ff 448 #if( portUSING_MPU_WRAPPERS == 1 )
kenjiArai 0:d4960fcea8ff 449 {
kenjiArai 0:d4960fcea8ff 450 pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
kenjiArai 0:d4960fcea8ff 451 }
kenjiArai 0:d4960fcea8ff 452 #else
kenjiArai 0:d4960fcea8ff 453 {
kenjiArai 0:d4960fcea8ff 454 pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
kenjiArai 0:d4960fcea8ff 455 }
kenjiArai 0:d4960fcea8ff 456 #endif
kenjiArai 0:d4960fcea8ff 457
kenjiArai 0:d4960fcea8ff 458 /* We are going to manipulate the task queues to add this task to a
kenjiArai 0:d4960fcea8ff 459 ready list, so must make sure no interrupts occur. */
kenjiArai 0:d4960fcea8ff 460 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 461 {
kenjiArai 0:d4960fcea8ff 462 uxCurrentNumberOfTasks++;
kenjiArai 0:d4960fcea8ff 463 if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )
kenjiArai 0:d4960fcea8ff 464 {
kenjiArai 0:d4960fcea8ff 465 /* As this is the first task it must also be the current task. */
kenjiArai 0:d4960fcea8ff 466 pxCurrentTCB = pxNewTCB;
kenjiArai 0:d4960fcea8ff 467
kenjiArai 0:d4960fcea8ff 468 /* This is the first task to be created so do the preliminary
kenjiArai 0:d4960fcea8ff 469 initialisation required. We will not recover if this call
kenjiArai 0:d4960fcea8ff 470 fails, but we will report the failure. */
kenjiArai 0:d4960fcea8ff 471 prvInitialiseTaskLists();
kenjiArai 0:d4960fcea8ff 472 }
kenjiArai 0:d4960fcea8ff 473 else
kenjiArai 0:d4960fcea8ff 474 {
kenjiArai 0:d4960fcea8ff 475 /* If the scheduler is not already running, make this task the
kenjiArai 0:d4960fcea8ff 476 current task if it is the highest priority task to be created
kenjiArai 0:d4960fcea8ff 477 so far. */
kenjiArai 0:d4960fcea8ff 478 if( xSchedulerRunning == pdFALSE )
kenjiArai 0:d4960fcea8ff 479 {
kenjiArai 0:d4960fcea8ff 480 if( pxCurrentTCB->uxPriority <= uxPriority )
kenjiArai 0:d4960fcea8ff 481 {
kenjiArai 0:d4960fcea8ff 482 pxCurrentTCB = pxNewTCB;
kenjiArai 0:d4960fcea8ff 483 }
kenjiArai 0:d4960fcea8ff 484 }
kenjiArai 0:d4960fcea8ff 485 }
kenjiArai 0:d4960fcea8ff 486
kenjiArai 0:d4960fcea8ff 487 /* Remember the top priority to make context switching faster. Use
kenjiArai 0:d4960fcea8ff 488 the priority in pxNewTCB as this has been capped to a valid value. */
kenjiArai 0:d4960fcea8ff 489 if( pxNewTCB->uxPriority > uxTopUsedPriority )
kenjiArai 0:d4960fcea8ff 490 {
kenjiArai 0:d4960fcea8ff 491 uxTopUsedPriority = pxNewTCB->uxPriority;
kenjiArai 0:d4960fcea8ff 492 }
kenjiArai 0:d4960fcea8ff 493
kenjiArai 0:d4960fcea8ff 494 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 495 {
kenjiArai 0:d4960fcea8ff 496 /* Add a counter into the TCB for tracing only. */
kenjiArai 0:d4960fcea8ff 497 pxNewTCB->uxTCBNumber = uxTaskNumber;
kenjiArai 0:d4960fcea8ff 498 }
kenjiArai 0:d4960fcea8ff 499 #endif
kenjiArai 0:d4960fcea8ff 500 uxTaskNumber++;
kenjiArai 0:d4960fcea8ff 501
kenjiArai 0:d4960fcea8ff 502 prvAddTaskToReadyQueue( pxNewTCB );
kenjiArai 0:d4960fcea8ff 503
kenjiArai 0:d4960fcea8ff 504 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 505 traceTASK_CREATE( pxNewTCB );
kenjiArai 0:d4960fcea8ff 506 }
kenjiArai 0:d4960fcea8ff 507 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 508 }
kenjiArai 0:d4960fcea8ff 509 else
kenjiArai 0:d4960fcea8ff 510 {
kenjiArai 0:d4960fcea8ff 511 xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
kenjiArai 0:d4960fcea8ff 512 traceTASK_CREATE_FAILED( pxNewTCB );
kenjiArai 0:d4960fcea8ff 513 }
kenjiArai 0:d4960fcea8ff 514
kenjiArai 0:d4960fcea8ff 515 if( xReturn == pdPASS )
kenjiArai 0:d4960fcea8ff 516 {
kenjiArai 0:d4960fcea8ff 517 if( ( void * ) pxCreatedTask != NULL )
kenjiArai 0:d4960fcea8ff 518 {
kenjiArai 0:d4960fcea8ff 519 /* Pass the TCB out - in an anonymous way. The calling function/
kenjiArai 0:d4960fcea8ff 520 task can use this as a handle to delete the task later if
kenjiArai 0:d4960fcea8ff 521 required.*/
kenjiArai 0:d4960fcea8ff 522 *pxCreatedTask = ( xTaskHandle ) pxNewTCB;
kenjiArai 0:d4960fcea8ff 523 }
kenjiArai 0:d4960fcea8ff 524
kenjiArai 0:d4960fcea8ff 525 if( xSchedulerRunning != pdFALSE )
kenjiArai 0:d4960fcea8ff 526 {
kenjiArai 0:d4960fcea8ff 527 /* If the created task is of a higher priority than the current task
kenjiArai 0:d4960fcea8ff 528 then it should run now. */
kenjiArai 0:d4960fcea8ff 529 if( pxCurrentTCB->uxPriority < uxPriority )
kenjiArai 0:d4960fcea8ff 530 {
kenjiArai 0:d4960fcea8ff 531 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 532 }
kenjiArai 0:d4960fcea8ff 533 }
kenjiArai 0:d4960fcea8ff 534 }
kenjiArai 0:d4960fcea8ff 535
kenjiArai 0:d4960fcea8ff 536 return xReturn;
kenjiArai 0:d4960fcea8ff 537 }
kenjiArai 0:d4960fcea8ff 538 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 539
kenjiArai 0:d4960fcea8ff 540 #if ( INCLUDE_vTaskDelete == 1 )
kenjiArai 0:d4960fcea8ff 541
kenjiArai 0:d4960fcea8ff 542 void vTaskDelete( xTaskHandle pxTaskToDelete )
kenjiArai 0:d4960fcea8ff 543 {
kenjiArai 0:d4960fcea8ff 544 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 545
kenjiArai 0:d4960fcea8ff 546 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 547 {
kenjiArai 0:d4960fcea8ff 548 /* Ensure a yield is performed if the current task is being
kenjiArai 0:d4960fcea8ff 549 deleted. */
kenjiArai 0:d4960fcea8ff 550 if( pxTaskToDelete == pxCurrentTCB )
kenjiArai 0:d4960fcea8ff 551 {
kenjiArai 0:d4960fcea8ff 552 pxTaskToDelete = NULL;
kenjiArai 0:d4960fcea8ff 553 }
kenjiArai 0:d4960fcea8ff 554
kenjiArai 0:d4960fcea8ff 555 /* If null is passed in here then we are deleting ourselves. */
kenjiArai 0:d4960fcea8ff 556 pxTCB = prvGetTCBFromHandle( pxTaskToDelete );
kenjiArai 0:d4960fcea8ff 557
kenjiArai 0:d4960fcea8ff 558 /* Remove task from the ready list and place in the termination list.
kenjiArai 0:d4960fcea8ff 559 This will stop the task from be scheduled. The idle task will check
kenjiArai 0:d4960fcea8ff 560 the termination list and free up any memory allocated by the
kenjiArai 0:d4960fcea8ff 561 scheduler for the TCB and stack. */
kenjiArai 0:d4960fcea8ff 562 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 563
kenjiArai 0:d4960fcea8ff 564 /* Is the task waiting on an event also? */
kenjiArai 0:d4960fcea8ff 565 if( pxTCB->xEventListItem.pvContainer )
kenjiArai 0:d4960fcea8ff 566 {
kenjiArai 0:d4960fcea8ff 567 vListRemove( &( pxTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 568 }
kenjiArai 0:d4960fcea8ff 569
kenjiArai 0:d4960fcea8ff 570 vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 571
kenjiArai 0:d4960fcea8ff 572 /* Increment the ucTasksDeleted variable so the idle task knows
kenjiArai 0:d4960fcea8ff 573 there is a task that has been deleted and that it should therefore
kenjiArai 0:d4960fcea8ff 574 check the xTasksWaitingTermination list. */
kenjiArai 0:d4960fcea8ff 575 ++uxTasksDeleted;
kenjiArai 0:d4960fcea8ff 576
kenjiArai 0:d4960fcea8ff 577 /* Increment the uxTaskNumberVariable also so kernel aware debuggers
kenjiArai 0:d4960fcea8ff 578 can detect that the task lists need re-generating. */
kenjiArai 0:d4960fcea8ff 579 uxTaskNumber++;
kenjiArai 0:d4960fcea8ff 580
kenjiArai 0:d4960fcea8ff 581 traceTASK_DELETE( pxTCB );
kenjiArai 0:d4960fcea8ff 582 }
kenjiArai 0:d4960fcea8ff 583 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 584
kenjiArai 0:d4960fcea8ff 585 /* Force a reschedule if we have just deleted the current task. */
kenjiArai 0:d4960fcea8ff 586 if( xSchedulerRunning != pdFALSE )
kenjiArai 0:d4960fcea8ff 587 {
kenjiArai 0:d4960fcea8ff 588 if( ( void * ) pxTaskToDelete == NULL )
kenjiArai 0:d4960fcea8ff 589 {
kenjiArai 0:d4960fcea8ff 590 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 591 }
kenjiArai 0:d4960fcea8ff 592 }
kenjiArai 0:d4960fcea8ff 593 }
kenjiArai 0:d4960fcea8ff 594
kenjiArai 0:d4960fcea8ff 595 #endif
kenjiArai 0:d4960fcea8ff 596
kenjiArai 0:d4960fcea8ff 597
kenjiArai 0:d4960fcea8ff 598
kenjiArai 0:d4960fcea8ff 599
kenjiArai 0:d4960fcea8ff 600
kenjiArai 0:d4960fcea8ff 601
kenjiArai 0:d4960fcea8ff 602 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 603 * TASK CONTROL API documented in task.h
kenjiArai 0:d4960fcea8ff 604 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 605
kenjiArai 0:d4960fcea8ff 606 #if ( INCLUDE_vTaskDelayUntil == 1 )
kenjiArai 0:d4960fcea8ff 607
kenjiArai 0:d4960fcea8ff 608 void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )
kenjiArai 0:d4960fcea8ff 609 {
kenjiArai 0:d4960fcea8ff 610 portTickType xTimeToWake;
kenjiArai 0:d4960fcea8ff 611 portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;
kenjiArai 0:d4960fcea8ff 612
kenjiArai 0:d4960fcea8ff 613 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 614 {
kenjiArai 0:d4960fcea8ff 615 /* Generate the tick time at which the task wants to wake. */
kenjiArai 0:d4960fcea8ff 616 xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
kenjiArai 0:d4960fcea8ff 617
kenjiArai 0:d4960fcea8ff 618 if( xTickCount < *pxPreviousWakeTime )
kenjiArai 0:d4960fcea8ff 619 {
kenjiArai 0:d4960fcea8ff 620 /* The tick count has overflowed since this function was
kenjiArai 0:d4960fcea8ff 621 lasted called. In this case the only time we should ever
kenjiArai 0:d4960fcea8ff 622 actually delay is if the wake time has also overflowed,
kenjiArai 0:d4960fcea8ff 623 and the wake time is greater than the tick time. When this
kenjiArai 0:d4960fcea8ff 624 is the case it is as if neither time had overflowed. */
kenjiArai 0:d4960fcea8ff 625 if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) )
kenjiArai 0:d4960fcea8ff 626 {
kenjiArai 0:d4960fcea8ff 627 xShouldDelay = pdTRUE;
kenjiArai 0:d4960fcea8ff 628 }
kenjiArai 0:d4960fcea8ff 629 }
kenjiArai 0:d4960fcea8ff 630 else
kenjiArai 0:d4960fcea8ff 631 {
kenjiArai 0:d4960fcea8ff 632 /* The tick time has not overflowed. In this case we will
kenjiArai 0:d4960fcea8ff 633 delay if either the wake time has overflowed, and/or the
kenjiArai 0:d4960fcea8ff 634 tick time is less than the wake time. */
kenjiArai 0:d4960fcea8ff 635 if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) )
kenjiArai 0:d4960fcea8ff 636 {
kenjiArai 0:d4960fcea8ff 637 xShouldDelay = pdTRUE;
kenjiArai 0:d4960fcea8ff 638 }
kenjiArai 0:d4960fcea8ff 639 }
kenjiArai 0:d4960fcea8ff 640
kenjiArai 0:d4960fcea8ff 641 /* Update the wake time ready for the next call. */
kenjiArai 0:d4960fcea8ff 642 *pxPreviousWakeTime = xTimeToWake;
kenjiArai 0:d4960fcea8ff 643
kenjiArai 0:d4960fcea8ff 644 if( xShouldDelay )
kenjiArai 0:d4960fcea8ff 645 {
kenjiArai 0:d4960fcea8ff 646 traceTASK_DELAY_UNTIL();
kenjiArai 0:d4960fcea8ff 647
kenjiArai 0:d4960fcea8ff 648 /* We must remove ourselves from the ready list before adding
kenjiArai 0:d4960fcea8ff 649 ourselves to the blocked list as the same list item is used for
kenjiArai 0:d4960fcea8ff 650 both lists. */
kenjiArai 0:d4960fcea8ff 651 vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 652
kenjiArai 0:d4960fcea8ff 653 /* The list item will be inserted in wake time order. */
kenjiArai 0:d4960fcea8ff 654 listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
kenjiArai 0:d4960fcea8ff 655
kenjiArai 0:d4960fcea8ff 656 if( xTimeToWake < xTickCount )
kenjiArai 0:d4960fcea8ff 657 {
kenjiArai 0:d4960fcea8ff 658 /* Wake time has overflowed. Place this item in the
kenjiArai 0:d4960fcea8ff 659 overflow list. */
kenjiArai 0:d4960fcea8ff 660 vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 661 }
kenjiArai 0:d4960fcea8ff 662 else
kenjiArai 0:d4960fcea8ff 663 {
kenjiArai 0:d4960fcea8ff 664 /* The wake time has not overflowed, so we can use the
kenjiArai 0:d4960fcea8ff 665 current block list. */
kenjiArai 0:d4960fcea8ff 666 vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 667 }
kenjiArai 0:d4960fcea8ff 668 }
kenjiArai 0:d4960fcea8ff 669 }
kenjiArai 0:d4960fcea8ff 670 xAlreadyYielded = xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 671
kenjiArai 0:d4960fcea8ff 672 /* Force a reschedule if xTaskResumeAll has not already done so, we may
kenjiArai 0:d4960fcea8ff 673 have put ourselves to sleep. */
kenjiArai 0:d4960fcea8ff 674 if( !xAlreadyYielded )
kenjiArai 0:d4960fcea8ff 675 {
kenjiArai 0:d4960fcea8ff 676 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 677 }
kenjiArai 0:d4960fcea8ff 678 }
kenjiArai 0:d4960fcea8ff 679
kenjiArai 0:d4960fcea8ff 680 #endif
kenjiArai 0:d4960fcea8ff 681 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 682
kenjiArai 0:d4960fcea8ff 683 #if ( INCLUDE_vTaskDelay == 1 )
kenjiArai 0:d4960fcea8ff 684
kenjiArai 0:d4960fcea8ff 685 void vTaskDelay( portTickType xTicksToDelay )
kenjiArai 0:d4960fcea8ff 686 {
kenjiArai 0:d4960fcea8ff 687 portTickType xTimeToWake;
kenjiArai 0:d4960fcea8ff 688 signed portBASE_TYPE xAlreadyYielded = pdFALSE;
kenjiArai 0:d4960fcea8ff 689
kenjiArai 0:d4960fcea8ff 690 /* A delay time of zero just forces a reschedule. */
kenjiArai 0:d4960fcea8ff 691 if( xTicksToDelay > ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 692 {
kenjiArai 0:d4960fcea8ff 693 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 694 {
kenjiArai 0:d4960fcea8ff 695 traceTASK_DELAY();
kenjiArai 0:d4960fcea8ff 696
kenjiArai 0:d4960fcea8ff 697 /* A task that is removed from the event list while the
kenjiArai 0:d4960fcea8ff 698 scheduler is suspended will not get placed in the ready
kenjiArai 0:d4960fcea8ff 699 list or removed from the blocked list until the scheduler
kenjiArai 0:d4960fcea8ff 700 is resumed.
kenjiArai 0:d4960fcea8ff 701
kenjiArai 0:d4960fcea8ff 702 This task cannot be in an event list as it is the currently
kenjiArai 0:d4960fcea8ff 703 executing task. */
kenjiArai 0:d4960fcea8ff 704
kenjiArai 0:d4960fcea8ff 705 /* Calculate the time to wake - this may overflow but this is
kenjiArai 0:d4960fcea8ff 706 not a problem. */
kenjiArai 0:d4960fcea8ff 707 xTimeToWake = xTickCount + xTicksToDelay;
kenjiArai 0:d4960fcea8ff 708
kenjiArai 0:d4960fcea8ff 709 /* We must remove ourselves from the ready list before adding
kenjiArai 0:d4960fcea8ff 710 ourselves to the blocked list as the same list item is used for
kenjiArai 0:d4960fcea8ff 711 both lists. */
kenjiArai 0:d4960fcea8ff 712 vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 713
kenjiArai 0:d4960fcea8ff 714 /* The list item will be inserted in wake time order. */
kenjiArai 0:d4960fcea8ff 715 listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
kenjiArai 0:d4960fcea8ff 716
kenjiArai 0:d4960fcea8ff 717 if( xTimeToWake < xTickCount )
kenjiArai 0:d4960fcea8ff 718 {
kenjiArai 0:d4960fcea8ff 719 /* Wake time has overflowed. Place this item in the
kenjiArai 0:d4960fcea8ff 720 overflow list. */
kenjiArai 0:d4960fcea8ff 721 vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 722 }
kenjiArai 0:d4960fcea8ff 723 else
kenjiArai 0:d4960fcea8ff 724 {
kenjiArai 0:d4960fcea8ff 725 /* The wake time has not overflowed, so we can use the
kenjiArai 0:d4960fcea8ff 726 current block list. */
kenjiArai 0:d4960fcea8ff 727 vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 728 }
kenjiArai 0:d4960fcea8ff 729 }
kenjiArai 0:d4960fcea8ff 730 xAlreadyYielded = xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 731 }
kenjiArai 0:d4960fcea8ff 732
kenjiArai 0:d4960fcea8ff 733 /* Force a reschedule if xTaskResumeAll has not already done so, we may
kenjiArai 0:d4960fcea8ff 734 have put ourselves to sleep. */
kenjiArai 0:d4960fcea8ff 735 if( !xAlreadyYielded )
kenjiArai 0:d4960fcea8ff 736 {
kenjiArai 0:d4960fcea8ff 737 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 738 }
kenjiArai 0:d4960fcea8ff 739 }
kenjiArai 0:d4960fcea8ff 740
kenjiArai 0:d4960fcea8ff 741 #endif
kenjiArai 0:d4960fcea8ff 742 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 743
kenjiArai 0:d4960fcea8ff 744 #if ( INCLUDE_uxTaskPriorityGet == 1 )
kenjiArai 0:d4960fcea8ff 745
kenjiArai 0:d4960fcea8ff 746 unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )
kenjiArai 0:d4960fcea8ff 747 {
kenjiArai 0:d4960fcea8ff 748 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 749 unsigned portBASE_TYPE uxReturn;
kenjiArai 0:d4960fcea8ff 750
kenjiArai 0:d4960fcea8ff 751 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 752 {
kenjiArai 0:d4960fcea8ff 753 /* If null is passed in here then we are changing the
kenjiArai 0:d4960fcea8ff 754 priority of the calling function. */
kenjiArai 0:d4960fcea8ff 755 pxTCB = prvGetTCBFromHandle( pxTask );
kenjiArai 0:d4960fcea8ff 756 uxReturn = pxTCB->uxPriority;
kenjiArai 0:d4960fcea8ff 757 }
kenjiArai 0:d4960fcea8ff 758 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 759
kenjiArai 0:d4960fcea8ff 760 return uxReturn;
kenjiArai 0:d4960fcea8ff 761 }
kenjiArai 0:d4960fcea8ff 762
kenjiArai 0:d4960fcea8ff 763 #endif
kenjiArai 0:d4960fcea8ff 764 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 765
kenjiArai 0:d4960fcea8ff 766 #if ( INCLUDE_vTaskPrioritySet == 1 )
kenjiArai 0:d4960fcea8ff 767
kenjiArai 0:d4960fcea8ff 768 void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )
kenjiArai 0:d4960fcea8ff 769 {
kenjiArai 0:d4960fcea8ff 770 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 771 unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE;
kenjiArai 0:d4960fcea8ff 772
kenjiArai 0:d4960fcea8ff 773 /* Ensure the new priority is valid. */
kenjiArai 0:d4960fcea8ff 774 if( uxNewPriority >= configMAX_PRIORITIES )
kenjiArai 0:d4960fcea8ff 775 {
kenjiArai 0:d4960fcea8ff 776 uxNewPriority = configMAX_PRIORITIES - 1;
kenjiArai 0:d4960fcea8ff 777 }
kenjiArai 0:d4960fcea8ff 778
kenjiArai 0:d4960fcea8ff 779 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 780 {
kenjiArai 0:d4960fcea8ff 781 if( pxTask == pxCurrentTCB )
kenjiArai 0:d4960fcea8ff 782 {
kenjiArai 0:d4960fcea8ff 783 pxTask = NULL;
kenjiArai 0:d4960fcea8ff 784 }
kenjiArai 0:d4960fcea8ff 785
kenjiArai 0:d4960fcea8ff 786 /* If null is passed in here then we are changing the
kenjiArai 0:d4960fcea8ff 787 priority of the calling function. */
kenjiArai 0:d4960fcea8ff 788 pxTCB = prvGetTCBFromHandle( pxTask );
kenjiArai 0:d4960fcea8ff 789
kenjiArai 0:d4960fcea8ff 790 traceTASK_PRIORITY_SET( pxTask, uxNewPriority );
kenjiArai 0:d4960fcea8ff 791
kenjiArai 0:d4960fcea8ff 792 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 793 {
kenjiArai 0:d4960fcea8ff 794 uxCurrentPriority = pxTCB->uxBasePriority;
kenjiArai 0:d4960fcea8ff 795 }
kenjiArai 0:d4960fcea8ff 796 #else
kenjiArai 0:d4960fcea8ff 797 {
kenjiArai 0:d4960fcea8ff 798 uxCurrentPriority = pxTCB->uxPriority;
kenjiArai 0:d4960fcea8ff 799 }
kenjiArai 0:d4960fcea8ff 800 #endif
kenjiArai 0:d4960fcea8ff 801
kenjiArai 0:d4960fcea8ff 802 if( uxCurrentPriority != uxNewPriority )
kenjiArai 0:d4960fcea8ff 803 {
kenjiArai 0:d4960fcea8ff 804 /* The priority change may have readied a task of higher
kenjiArai 0:d4960fcea8ff 805 priority than the calling task. */
kenjiArai 0:d4960fcea8ff 806 if( uxNewPriority > uxCurrentPriority )
kenjiArai 0:d4960fcea8ff 807 {
kenjiArai 0:d4960fcea8ff 808 if( pxTask != NULL )
kenjiArai 0:d4960fcea8ff 809 {
kenjiArai 0:d4960fcea8ff 810 /* The priority of another task is being raised. If we
kenjiArai 0:d4960fcea8ff 811 were raising the priority of the currently running task
kenjiArai 0:d4960fcea8ff 812 there would be no need to switch as it must have already
kenjiArai 0:d4960fcea8ff 813 been the highest priority task. */
kenjiArai 0:d4960fcea8ff 814 xYieldRequired = pdTRUE;
kenjiArai 0:d4960fcea8ff 815 }
kenjiArai 0:d4960fcea8ff 816 }
kenjiArai 0:d4960fcea8ff 817 else if( pxTask == NULL )
kenjiArai 0:d4960fcea8ff 818 {
kenjiArai 0:d4960fcea8ff 819 /* Setting our own priority down means there may now be another
kenjiArai 0:d4960fcea8ff 820 task of higher priority that is ready to execute. */
kenjiArai 0:d4960fcea8ff 821 xYieldRequired = pdTRUE;
kenjiArai 0:d4960fcea8ff 822 }
kenjiArai 0:d4960fcea8ff 823
kenjiArai 0:d4960fcea8ff 824
kenjiArai 0:d4960fcea8ff 825
kenjiArai 0:d4960fcea8ff 826 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 827 {
kenjiArai 0:d4960fcea8ff 828 /* Only change the priority being used if the task is not
kenjiArai 0:d4960fcea8ff 829 currently using an inherited priority. */
kenjiArai 0:d4960fcea8ff 830 if( pxTCB->uxBasePriority == pxTCB->uxPriority )
kenjiArai 0:d4960fcea8ff 831 {
kenjiArai 0:d4960fcea8ff 832 pxTCB->uxPriority = uxNewPriority;
kenjiArai 0:d4960fcea8ff 833 }
kenjiArai 0:d4960fcea8ff 834
kenjiArai 0:d4960fcea8ff 835 /* The base priority gets set whatever. */
kenjiArai 0:d4960fcea8ff 836 pxTCB->uxBasePriority = uxNewPriority;
kenjiArai 0:d4960fcea8ff 837 }
kenjiArai 0:d4960fcea8ff 838 #else
kenjiArai 0:d4960fcea8ff 839 {
kenjiArai 0:d4960fcea8ff 840 pxTCB->uxPriority = uxNewPriority;
kenjiArai 0:d4960fcea8ff 841 }
kenjiArai 0:d4960fcea8ff 842 #endif
kenjiArai 0:d4960fcea8ff 843
kenjiArai 0:d4960fcea8ff 844 listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );
kenjiArai 0:d4960fcea8ff 845
kenjiArai 0:d4960fcea8ff 846 /* If the task is in the blocked or suspended list we need do
kenjiArai 0:d4960fcea8ff 847 nothing more than change it's priority variable. However, if
kenjiArai 0:d4960fcea8ff 848 the task is in a ready list it needs to be removed and placed
kenjiArai 0:d4960fcea8ff 849 in the queue appropriate to its new priority. */
kenjiArai 0:d4960fcea8ff 850 if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) )
kenjiArai 0:d4960fcea8ff 851 {
kenjiArai 0:d4960fcea8ff 852 /* The task is currently in its ready list - remove before adding
kenjiArai 0:d4960fcea8ff 853 it to it's new ready list. As we are in a critical section we
kenjiArai 0:d4960fcea8ff 854 can do this even if the scheduler is suspended. */
kenjiArai 0:d4960fcea8ff 855 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 856 prvAddTaskToReadyQueue( pxTCB );
kenjiArai 0:d4960fcea8ff 857 }
kenjiArai 0:d4960fcea8ff 858
kenjiArai 0:d4960fcea8ff 859 if( xYieldRequired == pdTRUE )
kenjiArai 0:d4960fcea8ff 860 {
kenjiArai 0:d4960fcea8ff 861 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 862 }
kenjiArai 0:d4960fcea8ff 863 }
kenjiArai 0:d4960fcea8ff 864 }
kenjiArai 0:d4960fcea8ff 865 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 866 }
kenjiArai 0:d4960fcea8ff 867
kenjiArai 0:d4960fcea8ff 868 #endif
kenjiArai 0:d4960fcea8ff 869 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 870
kenjiArai 0:d4960fcea8ff 871 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 872
kenjiArai 0:d4960fcea8ff 873 void vTaskSuspend( xTaskHandle pxTaskToSuspend )
kenjiArai 0:d4960fcea8ff 874 {
kenjiArai 0:d4960fcea8ff 875 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 876
kenjiArai 0:d4960fcea8ff 877 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 878 {
kenjiArai 0:d4960fcea8ff 879 /* Ensure a yield is performed if the current task is being
kenjiArai 0:d4960fcea8ff 880 suspended. */
kenjiArai 0:d4960fcea8ff 881 if( pxTaskToSuspend == pxCurrentTCB )
kenjiArai 0:d4960fcea8ff 882 {
kenjiArai 0:d4960fcea8ff 883 pxTaskToSuspend = NULL;
kenjiArai 0:d4960fcea8ff 884 }
kenjiArai 0:d4960fcea8ff 885
kenjiArai 0:d4960fcea8ff 886 /* If null is passed in here then we are suspending ourselves. */
kenjiArai 0:d4960fcea8ff 887 pxTCB = prvGetTCBFromHandle( pxTaskToSuspend );
kenjiArai 0:d4960fcea8ff 888
kenjiArai 0:d4960fcea8ff 889 traceTASK_SUSPEND( pxTCB );
kenjiArai 0:d4960fcea8ff 890
kenjiArai 0:d4960fcea8ff 891 /* Remove task from the ready/delayed list and place in the suspended list. */
kenjiArai 0:d4960fcea8ff 892 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 893
kenjiArai 0:d4960fcea8ff 894 /* Is the task waiting on an event also? */
kenjiArai 0:d4960fcea8ff 895 if( pxTCB->xEventListItem.pvContainer )
kenjiArai 0:d4960fcea8ff 896 {
kenjiArai 0:d4960fcea8ff 897 vListRemove( &( pxTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 898 }
kenjiArai 0:d4960fcea8ff 899
kenjiArai 0:d4960fcea8ff 900 vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 901 }
kenjiArai 0:d4960fcea8ff 902 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 903
kenjiArai 0:d4960fcea8ff 904 /* We may have just suspended the current task. */
kenjiArai 0:d4960fcea8ff 905 if( ( void * ) pxTaskToSuspend == NULL )
kenjiArai 0:d4960fcea8ff 906 {
kenjiArai 0:d4960fcea8ff 907 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 908 }
kenjiArai 0:d4960fcea8ff 909 }
kenjiArai 0:d4960fcea8ff 910
kenjiArai 0:d4960fcea8ff 911 #endif
kenjiArai 0:d4960fcea8ff 912 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 913
kenjiArai 0:d4960fcea8ff 914 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 915
kenjiArai 0:d4960fcea8ff 916 signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask )
kenjiArai 0:d4960fcea8ff 917 {
kenjiArai 0:d4960fcea8ff 918 portBASE_TYPE xReturn = pdFALSE;
kenjiArai 0:d4960fcea8ff 919 const tskTCB * const pxTCB = ( tskTCB * ) xTask;
kenjiArai 0:d4960fcea8ff 920
kenjiArai 0:d4960fcea8ff 921 /* Is the task we are attempting to resume actually in the
kenjiArai 0:d4960fcea8ff 922 suspended list? */
kenjiArai 0:d4960fcea8ff 923 if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 924 {
kenjiArai 0:d4960fcea8ff 925 /* Has the task already been resumed from within an ISR? */
kenjiArai 0:d4960fcea8ff 926 if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )
kenjiArai 0:d4960fcea8ff 927 {
kenjiArai 0:d4960fcea8ff 928 /* Is it in the suspended list because it is in the
kenjiArai 0:d4960fcea8ff 929 Suspended state? It is possible to be in the suspended
kenjiArai 0:d4960fcea8ff 930 list because it is blocked on a task with no timeout
kenjiArai 0:d4960fcea8ff 931 specified. */
kenjiArai 0:d4960fcea8ff 932 if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 933 {
kenjiArai 0:d4960fcea8ff 934 xReturn = pdTRUE;
kenjiArai 0:d4960fcea8ff 935 }
kenjiArai 0:d4960fcea8ff 936 }
kenjiArai 0:d4960fcea8ff 937 }
kenjiArai 0:d4960fcea8ff 938
kenjiArai 0:d4960fcea8ff 939 return xReturn;
kenjiArai 0:d4960fcea8ff 940 }
kenjiArai 0:d4960fcea8ff 941
kenjiArai 0:d4960fcea8ff 942 #endif
kenjiArai 0:d4960fcea8ff 943 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 944
kenjiArai 0:d4960fcea8ff 945 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 946
kenjiArai 0:d4960fcea8ff 947 void vTaskResume( xTaskHandle pxTaskToResume )
kenjiArai 0:d4960fcea8ff 948 {
kenjiArai 0:d4960fcea8ff 949 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 950
kenjiArai 0:d4960fcea8ff 951 /* Remove the task from whichever list it is currently in, and place
kenjiArai 0:d4960fcea8ff 952 it in the ready list. */
kenjiArai 0:d4960fcea8ff 953 pxTCB = ( tskTCB * ) pxTaskToResume;
kenjiArai 0:d4960fcea8ff 954
kenjiArai 0:d4960fcea8ff 955 /* The parameter cannot be NULL as it is impossible to resume the
kenjiArai 0:d4960fcea8ff 956 currently executing task. */
kenjiArai 0:d4960fcea8ff 957 if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
kenjiArai 0:d4960fcea8ff 958 {
kenjiArai 0:d4960fcea8ff 959 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 960 {
kenjiArai 0:d4960fcea8ff 961 if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 962 {
kenjiArai 0:d4960fcea8ff 963 traceTASK_RESUME( pxTCB );
kenjiArai 0:d4960fcea8ff 964
kenjiArai 0:d4960fcea8ff 965 /* As we are in a critical section we can access the ready
kenjiArai 0:d4960fcea8ff 966 lists even if the scheduler is suspended. */
kenjiArai 0:d4960fcea8ff 967 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 968 prvAddTaskToReadyQueue( pxTCB );
kenjiArai 0:d4960fcea8ff 969
kenjiArai 0:d4960fcea8ff 970 /* We may have just resumed a higher priority task. */
kenjiArai 0:d4960fcea8ff 971 if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
kenjiArai 0:d4960fcea8ff 972 {
kenjiArai 0:d4960fcea8ff 973 /* This yield may not cause the task just resumed to run, but
kenjiArai 0:d4960fcea8ff 974 will leave the lists in the correct state for the next yield. */
kenjiArai 0:d4960fcea8ff 975 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 976 }
kenjiArai 0:d4960fcea8ff 977 }
kenjiArai 0:d4960fcea8ff 978 }
kenjiArai 0:d4960fcea8ff 979 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 980 }
kenjiArai 0:d4960fcea8ff 981 }
kenjiArai 0:d4960fcea8ff 982
kenjiArai 0:d4960fcea8ff 983 #endif
kenjiArai 0:d4960fcea8ff 984
kenjiArai 0:d4960fcea8ff 985 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 986
kenjiArai 0:d4960fcea8ff 987 #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
kenjiArai 0:d4960fcea8ff 988
kenjiArai 0:d4960fcea8ff 989 portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )
kenjiArai 0:d4960fcea8ff 990 {
kenjiArai 0:d4960fcea8ff 991 portBASE_TYPE xYieldRequired = pdFALSE;
kenjiArai 0:d4960fcea8ff 992 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 993
kenjiArai 0:d4960fcea8ff 994 pxTCB = ( tskTCB * ) pxTaskToResume;
kenjiArai 0:d4960fcea8ff 995
kenjiArai 0:d4960fcea8ff 996 if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 997 {
kenjiArai 0:d4960fcea8ff 998 traceTASK_RESUME_FROM_ISR( pxTCB );
kenjiArai 0:d4960fcea8ff 999
kenjiArai 0:d4960fcea8ff 1000 if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
kenjiArai 0:d4960fcea8ff 1001 {
kenjiArai 0:d4960fcea8ff 1002 xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );
kenjiArai 0:d4960fcea8ff 1003 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1004 prvAddTaskToReadyQueue( pxTCB );
kenjiArai 0:d4960fcea8ff 1005 }
kenjiArai 0:d4960fcea8ff 1006 else
kenjiArai 0:d4960fcea8ff 1007 {
kenjiArai 0:d4960fcea8ff 1008 /* We cannot access the delayed or ready lists, so will hold this
kenjiArai 0:d4960fcea8ff 1009 task pending until the scheduler is resumed, at which point a
kenjiArai 0:d4960fcea8ff 1010 yield will be performed if necessary. */
kenjiArai 0:d4960fcea8ff 1011 vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 1012 }
kenjiArai 0:d4960fcea8ff 1013 }
kenjiArai 0:d4960fcea8ff 1014
kenjiArai 0:d4960fcea8ff 1015 return xYieldRequired;
kenjiArai 0:d4960fcea8ff 1016 }
kenjiArai 0:d4960fcea8ff 1017
kenjiArai 0:d4960fcea8ff 1018 #endif
kenjiArai 0:d4960fcea8ff 1019
kenjiArai 0:d4960fcea8ff 1020
kenjiArai 0:d4960fcea8ff 1021
kenjiArai 0:d4960fcea8ff 1022
kenjiArai 0:d4960fcea8ff 1023 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 1024 * PUBLIC SCHEDULER CONTROL documented in task.h
kenjiArai 0:d4960fcea8ff 1025 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1026
kenjiArai 0:d4960fcea8ff 1027 // Modified by Kenji Arai / JH1PJL, October 30th,2010
kenjiArai 0:d4960fcea8ff 1028 // move to port_asm.c
kenjiArai 0:d4960fcea8ff 1029 #if 0
kenjiArai 0:d4960fcea8ff 1030 void vTaskStartScheduler( void )
kenjiArai 0:d4960fcea8ff 1031 {
kenjiArai 0:d4960fcea8ff 1032 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1033
kenjiArai 0:d4960fcea8ff 1034 /* Add the idle task at the lowest priority. */
kenjiArai 0:d4960fcea8ff 1035 xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL );
kenjiArai 0:d4960fcea8ff 1036
kenjiArai 0:d4960fcea8ff 1037 if( xReturn == pdPASS )
kenjiArai 0:d4960fcea8ff 1038 {
kenjiArai 0:d4960fcea8ff 1039 /* Interrupts are turned off here, to ensure a tick does not occur
kenjiArai 0:d4960fcea8ff 1040 before or during the call to xPortStartScheduler(). The stacks of
kenjiArai 0:d4960fcea8ff 1041 the created tasks contain a status word with interrupts switched on
kenjiArai 0:d4960fcea8ff 1042 so interrupts will automatically get re-enabled when the first task
kenjiArai 0:d4960fcea8ff 1043 starts to run.
kenjiArai 0:d4960fcea8ff 1044
kenjiArai 0:d4960fcea8ff 1045 STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE
kenjiArai 0:d4960fcea8ff 1046 DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */
kenjiArai 0:d4960fcea8ff 1047 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1048
kenjiArai 0:d4960fcea8ff 1049 xSchedulerRunning = pdTRUE;
kenjiArai 0:d4960fcea8ff 1050 xTickCount = ( portTickType ) 0;
kenjiArai 0:d4960fcea8ff 1051
kenjiArai 0:d4960fcea8ff 1052 /* If configGENERATE_RUN_TIME_STATS is defined then the following
kenjiArai 0:d4960fcea8ff 1053 macro must be defined to configure the timer/counter used to generate
kenjiArai 0:d4960fcea8ff 1054 the run time counter time base. */
kenjiArai 0:d4960fcea8ff 1055 portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
kenjiArai 0:d4960fcea8ff 1056
kenjiArai 0:d4960fcea8ff 1057 /* Setting up the timer tick is hardware specific and thus in the
kenjiArai 0:d4960fcea8ff 1058 portable interface. */
kenjiArai 0:d4960fcea8ff 1059 if( xPortStartScheduler() )
kenjiArai 0:d4960fcea8ff 1060 {
kenjiArai 0:d4960fcea8ff 1061 /* Should not reach here as if the scheduler is running the
kenjiArai 0:d4960fcea8ff 1062 function will not return. */
kenjiArai 0:d4960fcea8ff 1063 }
kenjiArai 0:d4960fcea8ff 1064 else
kenjiArai 0:d4960fcea8ff 1065 {
kenjiArai 0:d4960fcea8ff 1066 /* Should only reach here if a task calls xTaskEndScheduler(). */
kenjiArai 0:d4960fcea8ff 1067 }
kenjiArai 0:d4960fcea8ff 1068 }
kenjiArai 0:d4960fcea8ff 1069 }
kenjiArai 0:d4960fcea8ff 1070 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1071
kenjiArai 0:d4960fcea8ff 1072 void vTaskEndScheduler( void )
kenjiArai 0:d4960fcea8ff 1073 {
kenjiArai 0:d4960fcea8ff 1074 /* Stop the scheduler interrupts and call the portable scheduler end
kenjiArai 0:d4960fcea8ff 1075 routine so the original ISRs can be restored if necessary. The port
kenjiArai 0:d4960fcea8ff 1076 layer must ensure interrupts enable bit is left in the correct state. */
kenjiArai 0:d4960fcea8ff 1077 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1078 xSchedulerRunning = pdFALSE;
kenjiArai 0:d4960fcea8ff 1079 vPortEndScheduler();
kenjiArai 0:d4960fcea8ff 1080 }
kenjiArai 0:d4960fcea8ff 1081 /*----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1082 #endif
kenjiArai 0:d4960fcea8ff 1083
kenjiArai 0:d4960fcea8ff 1084 void vTaskSuspendAll( void )
kenjiArai 0:d4960fcea8ff 1085 {
kenjiArai 0:d4960fcea8ff 1086 /* A critical section is not required as the variable is of type
kenjiArai 0:d4960fcea8ff 1087 portBASE_TYPE. */
kenjiArai 0:d4960fcea8ff 1088 ++uxSchedulerSuspended;
kenjiArai 0:d4960fcea8ff 1089 }
kenjiArai 0:d4960fcea8ff 1090 /*----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1091
kenjiArai 0:d4960fcea8ff 1092 signed portBASE_TYPE xTaskResumeAll( void )
kenjiArai 0:d4960fcea8ff 1093 {
kenjiArai 0:d4960fcea8ff 1094 register tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 1095 signed portBASE_TYPE xAlreadyYielded = pdFALSE;
kenjiArai 0:d4960fcea8ff 1096
kenjiArai 0:d4960fcea8ff 1097 /* It is possible that an ISR caused a task to be removed from an event
kenjiArai 0:d4960fcea8ff 1098 list while the scheduler was suspended. If this was the case then the
kenjiArai 0:d4960fcea8ff 1099 removed task will have been added to the xPendingReadyList. Once the
kenjiArai 0:d4960fcea8ff 1100 scheduler has been resumed it is safe to move all the pending ready
kenjiArai 0:d4960fcea8ff 1101 tasks from this list into their appropriate ready list. */
kenjiArai 0:d4960fcea8ff 1102 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1103 {
kenjiArai 0:d4960fcea8ff 1104 --uxSchedulerSuspended;
kenjiArai 0:d4960fcea8ff 1105
kenjiArai 0:d4960fcea8ff 1106 if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
kenjiArai 0:d4960fcea8ff 1107 {
kenjiArai 0:d4960fcea8ff 1108 if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1109 {
kenjiArai 0:d4960fcea8ff 1110 portBASE_TYPE xYieldRequired = pdFALSE;
kenjiArai 0:d4960fcea8ff 1111
kenjiArai 0:d4960fcea8ff 1112 /* Move any readied tasks from the pending list into the
kenjiArai 0:d4960fcea8ff 1113 appropriate ready list. */
kenjiArai 0:d4960fcea8ff 1114 while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL )
kenjiArai 0:d4960fcea8ff 1115 {
kenjiArai 0:d4960fcea8ff 1116 vListRemove( &( pxTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 1117 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1118 prvAddTaskToReadyQueue( pxTCB );
kenjiArai 0:d4960fcea8ff 1119
kenjiArai 0:d4960fcea8ff 1120 /* If we have moved a task that has a priority higher than
kenjiArai 0:d4960fcea8ff 1121 the current task then we should yield. */
kenjiArai 0:d4960fcea8ff 1122 if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
kenjiArai 0:d4960fcea8ff 1123 {
kenjiArai 0:d4960fcea8ff 1124 xYieldRequired = pdTRUE;
kenjiArai 0:d4960fcea8ff 1125 }
kenjiArai 0:d4960fcea8ff 1126 }
kenjiArai 0:d4960fcea8ff 1127
kenjiArai 0:d4960fcea8ff 1128 /* If any ticks occurred while the scheduler was suspended then
kenjiArai 0:d4960fcea8ff 1129 they should be processed now. This ensures the tick count does not
kenjiArai 0:d4960fcea8ff 1130 slip, and that any delayed tasks are resumed at the correct time. */
kenjiArai 0:d4960fcea8ff 1131 if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1132 {
kenjiArai 0:d4960fcea8ff 1133 while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1134 {
kenjiArai 0:d4960fcea8ff 1135 vTaskIncrementTick();
kenjiArai 0:d4960fcea8ff 1136 --uxMissedTicks;
kenjiArai 0:d4960fcea8ff 1137 }
kenjiArai 0:d4960fcea8ff 1138
kenjiArai 0:d4960fcea8ff 1139 /* As we have processed some ticks it is appropriate to yield
kenjiArai 0:d4960fcea8ff 1140 to ensure the highest priority task that is ready to run is
kenjiArai 0:d4960fcea8ff 1141 the task actually running. */
kenjiArai 0:d4960fcea8ff 1142 #if configUSE_PREEMPTION == 1
kenjiArai 0:d4960fcea8ff 1143 {
kenjiArai 0:d4960fcea8ff 1144 xYieldRequired = pdTRUE;
kenjiArai 0:d4960fcea8ff 1145 }
kenjiArai 0:d4960fcea8ff 1146 #endif
kenjiArai 0:d4960fcea8ff 1147 }
kenjiArai 0:d4960fcea8ff 1148
kenjiArai 0:d4960fcea8ff 1149 if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )
kenjiArai 0:d4960fcea8ff 1150 {
kenjiArai 0:d4960fcea8ff 1151 xAlreadyYielded = pdTRUE;
kenjiArai 0:d4960fcea8ff 1152 xMissedYield = pdFALSE;
kenjiArai 0:d4960fcea8ff 1153 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 1154 }
kenjiArai 0:d4960fcea8ff 1155 }
kenjiArai 0:d4960fcea8ff 1156 }
kenjiArai 0:d4960fcea8ff 1157 }
kenjiArai 0:d4960fcea8ff 1158 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1159
kenjiArai 0:d4960fcea8ff 1160 return xAlreadyYielded;
kenjiArai 0:d4960fcea8ff 1161 }
kenjiArai 0:d4960fcea8ff 1162
kenjiArai 0:d4960fcea8ff 1163
kenjiArai 0:d4960fcea8ff 1164
kenjiArai 0:d4960fcea8ff 1165
kenjiArai 0:d4960fcea8ff 1166
kenjiArai 0:d4960fcea8ff 1167
kenjiArai 0:d4960fcea8ff 1168 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 1169 * PUBLIC TASK UTILITIES documented in task.h
kenjiArai 0:d4960fcea8ff 1170 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1171
kenjiArai 0:d4960fcea8ff 1172
kenjiArai 0:d4960fcea8ff 1173
kenjiArai 0:d4960fcea8ff 1174 portTickType xTaskGetTickCount( void )
kenjiArai 0:d4960fcea8ff 1175 {
kenjiArai 0:d4960fcea8ff 1176 portTickType xTicks;
kenjiArai 0:d4960fcea8ff 1177
kenjiArai 0:d4960fcea8ff 1178 /* Critical section required if running on a 16 bit processor. */
kenjiArai 0:d4960fcea8ff 1179 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1180 {
kenjiArai 0:d4960fcea8ff 1181 xTicks = xTickCount;
kenjiArai 0:d4960fcea8ff 1182 }
kenjiArai 0:d4960fcea8ff 1183 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1184
kenjiArai 0:d4960fcea8ff 1185 return xTicks;
kenjiArai 0:d4960fcea8ff 1186 }
kenjiArai 0:d4960fcea8ff 1187 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1188
kenjiArai 0:d4960fcea8ff 1189 unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
kenjiArai 0:d4960fcea8ff 1190 {
kenjiArai 0:d4960fcea8ff 1191 /* A critical section is not required because the variables are of type
kenjiArai 0:d4960fcea8ff 1192 portBASE_TYPE. */
kenjiArai 0:d4960fcea8ff 1193 return uxCurrentNumberOfTasks;
kenjiArai 0:d4960fcea8ff 1194 }
kenjiArai 0:d4960fcea8ff 1195 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1196
kenjiArai 0:d4960fcea8ff 1197 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 1198
kenjiArai 0:d4960fcea8ff 1199 void vTaskList( signed char *pcWriteBuffer )
kenjiArai 0:d4960fcea8ff 1200 {
kenjiArai 0:d4960fcea8ff 1201 unsigned portBASE_TYPE uxQueue;
kenjiArai 0:d4960fcea8ff 1202
kenjiArai 0:d4960fcea8ff 1203 /* This is a VERY costly function that should be used for debug only.
kenjiArai 0:d4960fcea8ff 1204 It leaves interrupts disabled for a LONG time. */
kenjiArai 0:d4960fcea8ff 1205
kenjiArai 0:d4960fcea8ff 1206 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 1207 {
kenjiArai 0:d4960fcea8ff 1208 /* Run through all the lists that could potentially contain a TCB and
kenjiArai 0:d4960fcea8ff 1209 report the task name, state and stack high water mark. */
kenjiArai 0:d4960fcea8ff 1210
kenjiArai 0:d4960fcea8ff 1211 pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
kenjiArai 0:d4960fcea8ff 1212 strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
kenjiArai 0:d4960fcea8ff 1213
kenjiArai 0:d4960fcea8ff 1214 uxQueue = uxTopUsedPriority + 1;
kenjiArai 0:d4960fcea8ff 1215
kenjiArai 0:d4960fcea8ff 1216 do
kenjiArai 0:d4960fcea8ff 1217 {
kenjiArai 0:d4960fcea8ff 1218 uxQueue--;
kenjiArai 0:d4960fcea8ff 1219
kenjiArai 0:d4960fcea8ff 1220 if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
kenjiArai 0:d4960fcea8ff 1221 {
kenjiArai 0:d4960fcea8ff 1222 prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );
kenjiArai 0:d4960fcea8ff 1223 }
kenjiArai 0:d4960fcea8ff 1224 }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
kenjiArai 0:d4960fcea8ff 1225
kenjiArai 0:d4960fcea8ff 1226 if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
kenjiArai 0:d4960fcea8ff 1227 {
kenjiArai 0:d4960fcea8ff 1228 prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );
kenjiArai 0:d4960fcea8ff 1229 }
kenjiArai 0:d4960fcea8ff 1230
kenjiArai 0:d4960fcea8ff 1231 if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
kenjiArai 0:d4960fcea8ff 1232 {
kenjiArai 0:d4960fcea8ff 1233 prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );
kenjiArai 0:d4960fcea8ff 1234 }
kenjiArai 0:d4960fcea8ff 1235
kenjiArai 0:d4960fcea8ff 1236 #if( INCLUDE_vTaskDelete == 1 )
kenjiArai 0:d4960fcea8ff 1237 {
kenjiArai 0:d4960fcea8ff 1238 if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
kenjiArai 0:d4960fcea8ff 1239 {
kenjiArai 0:d4960fcea8ff 1240 prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR );
kenjiArai 0:d4960fcea8ff 1241 }
kenjiArai 0:d4960fcea8ff 1242 }
kenjiArai 0:d4960fcea8ff 1243 #endif
kenjiArai 0:d4960fcea8ff 1244
kenjiArai 0:d4960fcea8ff 1245 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 1246 {
kenjiArai 0:d4960fcea8ff 1247 if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
kenjiArai 0:d4960fcea8ff 1248 {
kenjiArai 0:d4960fcea8ff 1249 prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR );
kenjiArai 0:d4960fcea8ff 1250 }
kenjiArai 0:d4960fcea8ff 1251 }
kenjiArai 0:d4960fcea8ff 1252 #endif
kenjiArai 0:d4960fcea8ff 1253 }
kenjiArai 0:d4960fcea8ff 1254 xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 1255 }
kenjiArai 0:d4960fcea8ff 1256
kenjiArai 0:d4960fcea8ff 1257 #endif
kenjiArai 0:d4960fcea8ff 1258 /*----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1259
kenjiArai 0:d4960fcea8ff 1260 #if ( configGENERATE_RUN_TIME_STATS == 1 )
kenjiArai 0:d4960fcea8ff 1261
kenjiArai 0:d4960fcea8ff 1262 void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
kenjiArai 0:d4960fcea8ff 1263 {
kenjiArai 0:d4960fcea8ff 1264 unsigned portBASE_TYPE uxQueue;
kenjiArai 0:d4960fcea8ff 1265 unsigned long ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
kenjiArai 0:d4960fcea8ff 1266
kenjiArai 0:d4960fcea8ff 1267 /* This is a VERY costly function that should be used for debug only.
kenjiArai 0:d4960fcea8ff 1268 It leaves interrupts disabled for a LONG time. */
kenjiArai 0:d4960fcea8ff 1269
kenjiArai 0:d4960fcea8ff 1270 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 1271 {
kenjiArai 0:d4960fcea8ff 1272 /* Run through all the lists that could potentially contain a TCB,
kenjiArai 0:d4960fcea8ff 1273 generating a table of run timer percentages in the provided
kenjiArai 0:d4960fcea8ff 1274 buffer. */
kenjiArai 0:d4960fcea8ff 1275
kenjiArai 0:d4960fcea8ff 1276 pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
kenjiArai 0:d4960fcea8ff 1277 strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );
kenjiArai 0:d4960fcea8ff 1278
kenjiArai 0:d4960fcea8ff 1279 uxQueue = uxTopUsedPriority + 1;
kenjiArai 0:d4960fcea8ff 1280
kenjiArai 0:d4960fcea8ff 1281 do
kenjiArai 0:d4960fcea8ff 1282 {
kenjiArai 0:d4960fcea8ff 1283 uxQueue--;
kenjiArai 0:d4960fcea8ff 1284
kenjiArai 0:d4960fcea8ff 1285 if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
kenjiArai 0:d4960fcea8ff 1286 {
kenjiArai 0:d4960fcea8ff 1287 prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime );
kenjiArai 0:d4960fcea8ff 1288 }
kenjiArai 0:d4960fcea8ff 1289 }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
kenjiArai 0:d4960fcea8ff 1290
kenjiArai 0:d4960fcea8ff 1291 if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
kenjiArai 0:d4960fcea8ff 1292 {
kenjiArai 0:d4960fcea8ff 1293 prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime );
kenjiArai 0:d4960fcea8ff 1294 }
kenjiArai 0:d4960fcea8ff 1295
kenjiArai 0:d4960fcea8ff 1296 if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
kenjiArai 0:d4960fcea8ff 1297 {
kenjiArai 0:d4960fcea8ff 1298 prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime );
kenjiArai 0:d4960fcea8ff 1299 }
kenjiArai 0:d4960fcea8ff 1300
kenjiArai 0:d4960fcea8ff 1301 #if ( INCLUDE_vTaskDelete == 1 )
kenjiArai 0:d4960fcea8ff 1302 {
kenjiArai 0:d4960fcea8ff 1303 if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
kenjiArai 0:d4960fcea8ff 1304 {
kenjiArai 0:d4960fcea8ff 1305 prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, ulTotalRunTime );
kenjiArai 0:d4960fcea8ff 1306 }
kenjiArai 0:d4960fcea8ff 1307 }
kenjiArai 0:d4960fcea8ff 1308 #endif
kenjiArai 0:d4960fcea8ff 1309
kenjiArai 0:d4960fcea8ff 1310 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 1311 {
kenjiArai 0:d4960fcea8ff 1312 if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
kenjiArai 0:d4960fcea8ff 1313 {
kenjiArai 0:d4960fcea8ff 1314 prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, ulTotalRunTime );
kenjiArai 0:d4960fcea8ff 1315 }
kenjiArai 0:d4960fcea8ff 1316 }
kenjiArai 0:d4960fcea8ff 1317 #endif
kenjiArai 0:d4960fcea8ff 1318 }
kenjiArai 0:d4960fcea8ff 1319 xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 1320 }
kenjiArai 0:d4960fcea8ff 1321
kenjiArai 0:d4960fcea8ff 1322 #endif
kenjiArai 0:d4960fcea8ff 1323 /*----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1324
kenjiArai 0:d4960fcea8ff 1325 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 1326
kenjiArai 0:d4960fcea8ff 1327 void vTaskStartTrace( signed char * pcBuffer, unsigned long ulBufferSize )
kenjiArai 0:d4960fcea8ff 1328 {
kenjiArai 0:d4960fcea8ff 1329 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1330 {
kenjiArai 0:d4960fcea8ff 1331 pcTraceBuffer = ( signed char * )pcBuffer;
kenjiArai 0:d4960fcea8ff 1332 pcTraceBufferStart = pcBuffer;
kenjiArai 0:d4960fcea8ff 1333 pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE );
kenjiArai 0:d4960fcea8ff 1334 xTracing = pdTRUE;
kenjiArai 0:d4960fcea8ff 1335 }
kenjiArai 0:d4960fcea8ff 1336 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1337 }
kenjiArai 0:d4960fcea8ff 1338
kenjiArai 0:d4960fcea8ff 1339 #endif
kenjiArai 0:d4960fcea8ff 1340 /*----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1341
kenjiArai 0:d4960fcea8ff 1342 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 1343
kenjiArai 0:d4960fcea8ff 1344 unsigned long ulTaskEndTrace( void )
kenjiArai 0:d4960fcea8ff 1345 {
kenjiArai 0:d4960fcea8ff 1346 unsigned long ulBufferLength;
kenjiArai 0:d4960fcea8ff 1347
kenjiArai 0:d4960fcea8ff 1348 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1349 xTracing = pdFALSE;
kenjiArai 0:d4960fcea8ff 1350 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1351
kenjiArai 0:d4960fcea8ff 1352 ulBufferLength = ( unsigned long ) ( pcTraceBuffer - pcTraceBufferStart );
kenjiArai 0:d4960fcea8ff 1353
kenjiArai 0:d4960fcea8ff 1354 return ulBufferLength;
kenjiArai 0:d4960fcea8ff 1355 }
kenjiArai 0:d4960fcea8ff 1356
kenjiArai 0:d4960fcea8ff 1357 #endif
kenjiArai 0:d4960fcea8ff 1358
kenjiArai 0:d4960fcea8ff 1359
kenjiArai 0:d4960fcea8ff 1360
kenjiArai 0:d4960fcea8ff 1361 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 1362 * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
kenjiArai 0:d4960fcea8ff 1363 * documented in task.h
kenjiArai 0:d4960fcea8ff 1364 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1365
kenjiArai 0:d4960fcea8ff 1366
kenjiArai 0:d4960fcea8ff 1367 void vTaskIncrementTick( void )
kenjiArai 0:d4960fcea8ff 1368 {
kenjiArai 0:d4960fcea8ff 1369 /* Called by the portable layer each time a tick interrupt occurs.
kenjiArai 0:d4960fcea8ff 1370 Increments the tick then checks to see if the new tick value will cause any
kenjiArai 0:d4960fcea8ff 1371 tasks to be unblocked. */
kenjiArai 0:d4960fcea8ff 1372 if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
kenjiArai 0:d4960fcea8ff 1373 {
kenjiArai 0:d4960fcea8ff 1374 ++xTickCount;
kenjiArai 0:d4960fcea8ff 1375 if( xTickCount == ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 1376 {
kenjiArai 0:d4960fcea8ff 1377 xList *pxTemp;
kenjiArai 0:d4960fcea8ff 1378
kenjiArai 0:d4960fcea8ff 1379 /* Tick count has overflowed so we need to swap the delay lists.
kenjiArai 0:d4960fcea8ff 1380 If there are any items in pxDelayedTaskList here then there is
kenjiArai 0:d4960fcea8ff 1381 an error! */
kenjiArai 0:d4960fcea8ff 1382 pxTemp = pxDelayedTaskList;
kenjiArai 0:d4960fcea8ff 1383 pxDelayedTaskList = pxOverflowDelayedTaskList;
kenjiArai 0:d4960fcea8ff 1384 pxOverflowDelayedTaskList = pxTemp;
kenjiArai 0:d4960fcea8ff 1385 xNumOfOverflows++;
kenjiArai 0:d4960fcea8ff 1386 }
kenjiArai 0:d4960fcea8ff 1387
kenjiArai 0:d4960fcea8ff 1388 /* See if this tick has made a timeout expire. */
kenjiArai 0:d4960fcea8ff 1389 prvCheckDelayedTasks();
kenjiArai 0:d4960fcea8ff 1390 }
kenjiArai 0:d4960fcea8ff 1391 else
kenjiArai 0:d4960fcea8ff 1392 {
kenjiArai 0:d4960fcea8ff 1393 ++uxMissedTicks;
kenjiArai 0:d4960fcea8ff 1394
kenjiArai 0:d4960fcea8ff 1395 /* The tick hook gets called at regular intervals, even if the
kenjiArai 0:d4960fcea8ff 1396 scheduler is locked. */
kenjiArai 0:d4960fcea8ff 1397 #if ( configUSE_TICK_HOOK == 1 )
kenjiArai 0:d4960fcea8ff 1398 {
kenjiArai 0:d4960fcea8ff 1399 extern void vApplicationTickHook( void );
kenjiArai 0:d4960fcea8ff 1400
kenjiArai 0:d4960fcea8ff 1401 vApplicationTickHook();
kenjiArai 0:d4960fcea8ff 1402 }
kenjiArai 0:d4960fcea8ff 1403 #endif
kenjiArai 0:d4960fcea8ff 1404 }
kenjiArai 0:d4960fcea8ff 1405
kenjiArai 0:d4960fcea8ff 1406 #if ( configUSE_TICK_HOOK == 1 )
kenjiArai 0:d4960fcea8ff 1407 {
kenjiArai 0:d4960fcea8ff 1408 extern void vApplicationTickHook( void );
kenjiArai 0:d4960fcea8ff 1409
kenjiArai 0:d4960fcea8ff 1410 /* Guard against the tick hook being called when the missed tick
kenjiArai 0:d4960fcea8ff 1411 count is being unwound (when the scheduler is being unlocked. */
kenjiArai 0:d4960fcea8ff 1412 if( uxMissedTicks == 0 )
kenjiArai 0:d4960fcea8ff 1413 {
kenjiArai 0:d4960fcea8ff 1414 vApplicationTickHook();
kenjiArai 0:d4960fcea8ff 1415 }
kenjiArai 0:d4960fcea8ff 1416 }
kenjiArai 0:d4960fcea8ff 1417 #endif
kenjiArai 0:d4960fcea8ff 1418
kenjiArai 0:d4960fcea8ff 1419 traceTASK_INCREMENT_TICK( xTickCount );
kenjiArai 0:d4960fcea8ff 1420 }
kenjiArai 0:d4960fcea8ff 1421 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1422
kenjiArai 0:d4960fcea8ff 1423 #if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
kenjiArai 0:d4960fcea8ff 1424
kenjiArai 0:d4960fcea8ff 1425 void vTaskCleanUpResources( void )
kenjiArai 0:d4960fcea8ff 1426 {
kenjiArai 0:d4960fcea8ff 1427 unsigned short usQueue;
kenjiArai 0:d4960fcea8ff 1428 volatile tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 1429
kenjiArai 0:d4960fcea8ff 1430 usQueue = ( unsigned short ) uxTopUsedPriority + ( unsigned short ) 1;
kenjiArai 0:d4960fcea8ff 1431
kenjiArai 0:d4960fcea8ff 1432 /* Remove any TCB's from the ready queues. */
kenjiArai 0:d4960fcea8ff 1433 do
kenjiArai 0:d4960fcea8ff 1434 {
kenjiArai 0:d4960fcea8ff 1435 usQueue--;
kenjiArai 0:d4960fcea8ff 1436
kenjiArai 0:d4960fcea8ff 1437 while( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) )
kenjiArai 0:d4960fcea8ff 1438 {
kenjiArai 0:d4960fcea8ff 1439 listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ usQueue ] ) );
kenjiArai 0:d4960fcea8ff 1440 vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1441
kenjiArai 0:d4960fcea8ff 1442 prvDeleteTCB( ( tskTCB * ) pxTCB );
kenjiArai 0:d4960fcea8ff 1443 }
kenjiArai 0:d4960fcea8ff 1444 }while( usQueue > ( unsigned short ) tskIDLE_PRIORITY );
kenjiArai 0:d4960fcea8ff 1445
kenjiArai 0:d4960fcea8ff 1446 /* Remove any TCB's from the delayed queue. */
kenjiArai 0:d4960fcea8ff 1447 while( !listLIST_IS_EMPTY( &xDelayedTaskList1 ) )
kenjiArai 0:d4960fcea8ff 1448 {
kenjiArai 0:d4960fcea8ff 1449 listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList1 );
kenjiArai 0:d4960fcea8ff 1450 vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1451
kenjiArai 0:d4960fcea8ff 1452 prvDeleteTCB( ( tskTCB * ) pxTCB );
kenjiArai 0:d4960fcea8ff 1453 }
kenjiArai 0:d4960fcea8ff 1454
kenjiArai 0:d4960fcea8ff 1455 /* Remove any TCB's from the overflow delayed queue. */
kenjiArai 0:d4960fcea8ff 1456 while( !listLIST_IS_EMPTY( &xDelayedTaskList2 ) )
kenjiArai 0:d4960fcea8ff 1457 {
kenjiArai 0:d4960fcea8ff 1458 listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 );
kenjiArai 0:d4960fcea8ff 1459 vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1460
kenjiArai 0:d4960fcea8ff 1461 prvDeleteTCB( ( tskTCB * ) pxTCB );
kenjiArai 0:d4960fcea8ff 1462 }
kenjiArai 0:d4960fcea8ff 1463
kenjiArai 0:d4960fcea8ff 1464 while( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
kenjiArai 0:d4960fcea8ff 1465 {
kenjiArai 0:d4960fcea8ff 1466 listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xSuspendedTaskList );
kenjiArai 0:d4960fcea8ff 1467 vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1468
kenjiArai 0:d4960fcea8ff 1469 prvDeleteTCB( ( tskTCB * ) pxTCB );
kenjiArai 0:d4960fcea8ff 1470 }
kenjiArai 0:d4960fcea8ff 1471 }
kenjiArai 0:d4960fcea8ff 1472
kenjiArai 0:d4960fcea8ff 1473 #endif
kenjiArai 0:d4960fcea8ff 1474 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1475
kenjiArai 0:d4960fcea8ff 1476 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
kenjiArai 0:d4960fcea8ff 1477
kenjiArai 0:d4960fcea8ff 1478 void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue )
kenjiArai 0:d4960fcea8ff 1479 {
kenjiArai 0:d4960fcea8ff 1480 tskTCB *xTCB;
kenjiArai 0:d4960fcea8ff 1481
kenjiArai 0:d4960fcea8ff 1482 /* If xTask is NULL then we are setting our own task hook. */
kenjiArai 0:d4960fcea8ff 1483 if( xTask == NULL )
kenjiArai 0:d4960fcea8ff 1484 {
kenjiArai 0:d4960fcea8ff 1485 xTCB = ( tskTCB * ) pxCurrentTCB;
kenjiArai 0:d4960fcea8ff 1486 }
kenjiArai 0:d4960fcea8ff 1487 else
kenjiArai 0:d4960fcea8ff 1488 {
kenjiArai 0:d4960fcea8ff 1489 xTCB = ( tskTCB * ) xTask;
kenjiArai 0:d4960fcea8ff 1490 }
kenjiArai 0:d4960fcea8ff 1491
kenjiArai 0:d4960fcea8ff 1492 /* Save the hook function in the TCB. A critical section is required as
kenjiArai 0:d4960fcea8ff 1493 the value can be accessed from an interrupt. */
kenjiArai 0:d4960fcea8ff 1494 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1495 xTCB->pxTaskTag = pxTagValue;
kenjiArai 0:d4960fcea8ff 1496 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1497 }
kenjiArai 0:d4960fcea8ff 1498
kenjiArai 0:d4960fcea8ff 1499 #endif
kenjiArai 0:d4960fcea8ff 1500 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1501
kenjiArai 0:d4960fcea8ff 1502 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
kenjiArai 0:d4960fcea8ff 1503
kenjiArai 0:d4960fcea8ff 1504 pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask )
kenjiArai 0:d4960fcea8ff 1505 {
kenjiArai 0:d4960fcea8ff 1506 tskTCB *xTCB;
kenjiArai 0:d4960fcea8ff 1507 pdTASK_HOOK_CODE xReturn;
kenjiArai 0:d4960fcea8ff 1508
kenjiArai 0:d4960fcea8ff 1509 /* If xTask is NULL then we are setting our own task hook. */
kenjiArai 0:d4960fcea8ff 1510 if( xTask == NULL )
kenjiArai 0:d4960fcea8ff 1511 {
kenjiArai 0:d4960fcea8ff 1512 xTCB = ( tskTCB * ) pxCurrentTCB;
kenjiArai 0:d4960fcea8ff 1513 }
kenjiArai 0:d4960fcea8ff 1514 else
kenjiArai 0:d4960fcea8ff 1515 {
kenjiArai 0:d4960fcea8ff 1516 xTCB = ( tskTCB * ) xTask;
kenjiArai 0:d4960fcea8ff 1517 }
kenjiArai 0:d4960fcea8ff 1518
kenjiArai 0:d4960fcea8ff 1519 /* Save the hook function in the TCB. A critical section is required as
kenjiArai 0:d4960fcea8ff 1520 the value can be accessed from an interrupt. */
kenjiArai 0:d4960fcea8ff 1521 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1522 xReturn = xTCB->pxTaskTag;
kenjiArai 0:d4960fcea8ff 1523 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1524
kenjiArai 0:d4960fcea8ff 1525 return xReturn;
kenjiArai 0:d4960fcea8ff 1526 }
kenjiArai 0:d4960fcea8ff 1527
kenjiArai 0:d4960fcea8ff 1528 #endif
kenjiArai 0:d4960fcea8ff 1529 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1530
kenjiArai 0:d4960fcea8ff 1531 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
kenjiArai 0:d4960fcea8ff 1532
kenjiArai 0:d4960fcea8ff 1533 portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )
kenjiArai 0:d4960fcea8ff 1534 {
kenjiArai 0:d4960fcea8ff 1535 tskTCB *xTCB;
kenjiArai 0:d4960fcea8ff 1536 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1537
kenjiArai 0:d4960fcea8ff 1538 /* If xTask is NULL then we are calling our own task hook. */
kenjiArai 0:d4960fcea8ff 1539 if( xTask == NULL )
kenjiArai 0:d4960fcea8ff 1540 {
kenjiArai 0:d4960fcea8ff 1541 xTCB = ( tskTCB * ) pxCurrentTCB;
kenjiArai 0:d4960fcea8ff 1542 }
kenjiArai 0:d4960fcea8ff 1543 else
kenjiArai 0:d4960fcea8ff 1544 {
kenjiArai 0:d4960fcea8ff 1545 xTCB = ( tskTCB * ) xTask;
kenjiArai 0:d4960fcea8ff 1546 }
kenjiArai 0:d4960fcea8ff 1547
kenjiArai 0:d4960fcea8ff 1548 if( xTCB->pxTaskTag != NULL )
kenjiArai 0:d4960fcea8ff 1549 {
kenjiArai 0:d4960fcea8ff 1550 xReturn = xTCB->pxTaskTag( pvParameter );
kenjiArai 0:d4960fcea8ff 1551 }
kenjiArai 0:d4960fcea8ff 1552 else
kenjiArai 0:d4960fcea8ff 1553 {
kenjiArai 0:d4960fcea8ff 1554 xReturn = pdFAIL;
kenjiArai 0:d4960fcea8ff 1555 }
kenjiArai 0:d4960fcea8ff 1556
kenjiArai 0:d4960fcea8ff 1557 return xReturn;
kenjiArai 0:d4960fcea8ff 1558 }
kenjiArai 0:d4960fcea8ff 1559
kenjiArai 0:d4960fcea8ff 1560 #endif
kenjiArai 0:d4960fcea8ff 1561 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1562
kenjiArai 0:d4960fcea8ff 1563 void vTaskSwitchContext( void )
kenjiArai 0:d4960fcea8ff 1564 {
kenjiArai 0:d4960fcea8ff 1565 if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )
kenjiArai 0:d4960fcea8ff 1566 {
kenjiArai 0:d4960fcea8ff 1567 /* The scheduler is currently suspended - do not allow a context
kenjiArai 0:d4960fcea8ff 1568 switch. */
kenjiArai 0:d4960fcea8ff 1569 xMissedYield = pdTRUE;
kenjiArai 0:d4960fcea8ff 1570 return;
kenjiArai 0:d4960fcea8ff 1571 }
kenjiArai 0:d4960fcea8ff 1572
kenjiArai 0:d4960fcea8ff 1573 traceTASK_SWITCHED_OUT();
kenjiArai 0:d4960fcea8ff 1574
kenjiArai 0:d4960fcea8ff 1575 #if ( configGENERATE_RUN_TIME_STATS == 1 )
kenjiArai 0:d4960fcea8ff 1576 {
kenjiArai 0:d4960fcea8ff 1577 unsigned long ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();
kenjiArai 0:d4960fcea8ff 1578
kenjiArai 0:d4960fcea8ff 1579 /* Add the amount of time the task has been running to the accumulated
kenjiArai 0:d4960fcea8ff 1580 time so far. The time the task started running was stored in
kenjiArai 0:d4960fcea8ff 1581 ulTaskSwitchedInTime. Note that there is no overflow protection here
kenjiArai 0:d4960fcea8ff 1582 so count values are only valid until the timer overflows. Generally
kenjiArai 0:d4960fcea8ff 1583 this will be about 1 hour assuming a 1uS timer increment. */
kenjiArai 0:d4960fcea8ff 1584 pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime );
kenjiArai 0:d4960fcea8ff 1585 ulTaskSwitchedInTime = ulTempCounter;
kenjiArai 0:d4960fcea8ff 1586 }
kenjiArai 0:d4960fcea8ff 1587 #endif
kenjiArai 0:d4960fcea8ff 1588
kenjiArai 0:d4960fcea8ff 1589 taskFIRST_CHECK_FOR_STACK_OVERFLOW();
kenjiArai 0:d4960fcea8ff 1590 taskSECOND_CHECK_FOR_STACK_OVERFLOW();
kenjiArai 0:d4960fcea8ff 1591
kenjiArai 0:d4960fcea8ff 1592 /* Find the highest priority queue that contains ready tasks. */
kenjiArai 0:d4960fcea8ff 1593 while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
kenjiArai 0:d4960fcea8ff 1594 {
kenjiArai 0:d4960fcea8ff 1595 --uxTopReadyPriority;
kenjiArai 0:d4960fcea8ff 1596 }
kenjiArai 0:d4960fcea8ff 1597
kenjiArai 0:d4960fcea8ff 1598 /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
kenjiArai 0:d4960fcea8ff 1599 same priority get an equal share of the processor time. */
kenjiArai 0:d4960fcea8ff 1600 listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );
kenjiArai 0:d4960fcea8ff 1601 #if 0
kenjiArai 0:d4960fcea8ff 1602 //#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
kenjiArai 0:d4960fcea8ff 1603 {
kenjiArai 0:d4960fcea8ff 1604 xList * const pxConstList = &( pxReadyTasksLists[ uxTopReadyPriority ] );
kenjiArai 0:d4960fcea8ff 1605 /* Increment the index to the next item and return the item, ensuring */
kenjiArai 0:d4960fcea8ff 1606 /* we don't return the marker used at the end of the list. */
kenjiArai 0:d4960fcea8ff 1607 ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
kenjiArai 0:d4960fcea8ff 1608 if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) )
kenjiArai 0:d4960fcea8ff 1609 {
kenjiArai 0:d4960fcea8ff 1610 ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
kenjiArai 0:d4960fcea8ff 1611 }
kenjiArai 0:d4960fcea8ff 1612 pxCurrentTCB = (tskTCB *) (( pxConstList )->pxIndex->pvOwner); // Error then added (tskTCB *)()
kenjiArai 0:d4960fcea8ff 1613 }
kenjiArai 0:d4960fcea8ff 1614 #endif
kenjiArai 0:d4960fcea8ff 1615
kenjiArai 0:d4960fcea8ff 1616 traceTASK_SWITCHED_IN();
kenjiArai 0:d4960fcea8ff 1617 vWriteTraceToBuffer();
kenjiArai 0:d4960fcea8ff 1618 }
kenjiArai 0:d4960fcea8ff 1619 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1620
kenjiArai 0:d4960fcea8ff 1621 void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )
kenjiArai 0:d4960fcea8ff 1622 {
kenjiArai 0:d4960fcea8ff 1623 portTickType xTimeToWake;
kenjiArai 0:d4960fcea8ff 1624
kenjiArai 0:d4960fcea8ff 1625 /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
kenjiArai 0:d4960fcea8ff 1626 SCHEDULER SUSPENDED. */
kenjiArai 0:d4960fcea8ff 1627
kenjiArai 0:d4960fcea8ff 1628 /* Place the event list item of the TCB in the appropriate event list.
kenjiArai 0:d4960fcea8ff 1629 This is placed in the list in priority order so the highest priority task
kenjiArai 0:d4960fcea8ff 1630 is the first to be woken by the event. */
kenjiArai 0:d4960fcea8ff 1631 vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 1632
kenjiArai 0:d4960fcea8ff 1633 /* We must remove ourselves from the ready list before adding ourselves
kenjiArai 0:d4960fcea8ff 1634 to the blocked list as the same list item is used for both lists. We have
kenjiArai 0:d4960fcea8ff 1635 exclusive access to the ready lists as the scheduler is locked. */
kenjiArai 0:d4960fcea8ff 1636 vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1637
kenjiArai 0:d4960fcea8ff 1638
kenjiArai 0:d4960fcea8ff 1639 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 1640 {
kenjiArai 0:d4960fcea8ff 1641 if( xTicksToWait == portMAX_DELAY )
kenjiArai 0:d4960fcea8ff 1642 {
kenjiArai 0:d4960fcea8ff 1643 /* Add ourselves to the suspended task list instead of a delayed task
kenjiArai 0:d4960fcea8ff 1644 list to ensure we are not woken by a timing event. We will block
kenjiArai 0:d4960fcea8ff 1645 indefinitely. */
kenjiArai 0:d4960fcea8ff 1646 vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1647 }
kenjiArai 0:d4960fcea8ff 1648 else
kenjiArai 0:d4960fcea8ff 1649 {
kenjiArai 0:d4960fcea8ff 1650 /* Calculate the time at which the task should be woken if the event does
kenjiArai 0:d4960fcea8ff 1651 not occur. This may overflow but this doesn't matter. */
kenjiArai 0:d4960fcea8ff 1652 xTimeToWake = xTickCount + xTicksToWait;
kenjiArai 0:d4960fcea8ff 1653
kenjiArai 0:d4960fcea8ff 1654 listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
kenjiArai 0:d4960fcea8ff 1655
kenjiArai 0:d4960fcea8ff 1656 if( xTimeToWake < xTickCount )
kenjiArai 0:d4960fcea8ff 1657 {
kenjiArai 0:d4960fcea8ff 1658 /* Wake time has overflowed. Place this item in the overflow list. */
kenjiArai 0:d4960fcea8ff 1659 vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1660 }
kenjiArai 0:d4960fcea8ff 1661 else
kenjiArai 0:d4960fcea8ff 1662 {
kenjiArai 0:d4960fcea8ff 1663 /* The wake time has not overflowed, so we can use the current block list. */
kenjiArai 0:d4960fcea8ff 1664 vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1665 }
kenjiArai 0:d4960fcea8ff 1666 }
kenjiArai 0:d4960fcea8ff 1667 }
kenjiArai 0:d4960fcea8ff 1668 #else
kenjiArai 0:d4960fcea8ff 1669 {
kenjiArai 0:d4960fcea8ff 1670 /* Calculate the time at which the task should be woken if the event does
kenjiArai 0:d4960fcea8ff 1671 not occur. This may overflow but this doesn't matter. */
kenjiArai 0:d4960fcea8ff 1672 xTimeToWake = xTickCount + xTicksToWait;
kenjiArai 0:d4960fcea8ff 1673
kenjiArai 0:d4960fcea8ff 1674 listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
kenjiArai 0:d4960fcea8ff 1675
kenjiArai 0:d4960fcea8ff 1676 if( xTimeToWake < xTickCount )
kenjiArai 0:d4960fcea8ff 1677 {
kenjiArai 0:d4960fcea8ff 1678 /* Wake time has overflowed. Place this item in the overflow list. */
kenjiArai 0:d4960fcea8ff 1679 vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1680 }
kenjiArai 0:d4960fcea8ff 1681 else
kenjiArai 0:d4960fcea8ff 1682 {
kenjiArai 0:d4960fcea8ff 1683 /* The wake time has not overflowed, so we can use the current block list. */
kenjiArai 0:d4960fcea8ff 1684 vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1685 }
kenjiArai 0:d4960fcea8ff 1686 }
kenjiArai 0:d4960fcea8ff 1687 #endif
kenjiArai 0:d4960fcea8ff 1688 }
kenjiArai 0:d4960fcea8ff 1689 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1690
kenjiArai 0:d4960fcea8ff 1691 signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )
kenjiArai 0:d4960fcea8ff 1692 {
kenjiArai 0:d4960fcea8ff 1693 tskTCB *pxUnblockedTCB;
kenjiArai 0:d4960fcea8ff 1694 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1695
kenjiArai 0:d4960fcea8ff 1696 /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
kenjiArai 0:d4960fcea8ff 1697 SCHEDULER SUSPENDED. It can also be called from within an ISR. */
kenjiArai 0:d4960fcea8ff 1698
kenjiArai 0:d4960fcea8ff 1699 /* The event list is sorted in priority order, so we can remove the
kenjiArai 0:d4960fcea8ff 1700 first in the list, remove the TCB from the delayed list, and add
kenjiArai 0:d4960fcea8ff 1701 it to the ready list.
kenjiArai 0:d4960fcea8ff 1702
kenjiArai 0:d4960fcea8ff 1703 If an event is for a queue that is locked then this function will never
kenjiArai 0:d4960fcea8ff 1704 get called - the lock count on the queue will get modified instead. This
kenjiArai 0:d4960fcea8ff 1705 means we can always expect exclusive access to the event list here. */
kenjiArai 0:d4960fcea8ff 1706 pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
kenjiArai 0:d4960fcea8ff 1707 vListRemove( &( pxUnblockedTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 1708
kenjiArai 0:d4960fcea8ff 1709 if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
kenjiArai 0:d4960fcea8ff 1710 {
kenjiArai 0:d4960fcea8ff 1711 vListRemove( &( pxUnblockedTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1712 prvAddTaskToReadyQueue( pxUnblockedTCB );
kenjiArai 0:d4960fcea8ff 1713 }
kenjiArai 0:d4960fcea8ff 1714 else
kenjiArai 0:d4960fcea8ff 1715 {
kenjiArai 0:d4960fcea8ff 1716 /* We cannot access the delayed or ready lists, so will hold this
kenjiArai 0:d4960fcea8ff 1717 task pending until the scheduler is resumed. */
kenjiArai 0:d4960fcea8ff 1718 vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 1719 }
kenjiArai 0:d4960fcea8ff 1720
kenjiArai 0:d4960fcea8ff 1721 if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )
kenjiArai 0:d4960fcea8ff 1722 {
kenjiArai 0:d4960fcea8ff 1723 /* Return true if the task removed from the event list has
kenjiArai 0:d4960fcea8ff 1724 a higher priority than the calling task. This allows
kenjiArai 0:d4960fcea8ff 1725 the calling task to know if it should force a context
kenjiArai 0:d4960fcea8ff 1726 switch now. */
kenjiArai 0:d4960fcea8ff 1727 xReturn = pdTRUE;
kenjiArai 0:d4960fcea8ff 1728 }
kenjiArai 0:d4960fcea8ff 1729 else
kenjiArai 0:d4960fcea8ff 1730 {
kenjiArai 0:d4960fcea8ff 1731 xReturn = pdFALSE;
kenjiArai 0:d4960fcea8ff 1732 }
kenjiArai 0:d4960fcea8ff 1733
kenjiArai 0:d4960fcea8ff 1734 return xReturn;
kenjiArai 0:d4960fcea8ff 1735 }
kenjiArai 0:d4960fcea8ff 1736 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1737
kenjiArai 0:d4960fcea8ff 1738 void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )
kenjiArai 0:d4960fcea8ff 1739 {
kenjiArai 0:d4960fcea8ff 1740 pxTimeOut->xOverflowCount = xNumOfOverflows;
kenjiArai 0:d4960fcea8ff 1741 pxTimeOut->xTimeOnEntering = xTickCount;
kenjiArai 0:d4960fcea8ff 1742 }
kenjiArai 0:d4960fcea8ff 1743 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1744
kenjiArai 0:d4960fcea8ff 1745 portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )
kenjiArai 0:d4960fcea8ff 1746 {
kenjiArai 0:d4960fcea8ff 1747 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1748
kenjiArai 0:d4960fcea8ff 1749 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1750 {
kenjiArai 0:d4960fcea8ff 1751 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 1752 /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
kenjiArai 0:d4960fcea8ff 1753 the maximum block time then the task should block indefinitely, and
kenjiArai 0:d4960fcea8ff 1754 therefore never time out. */
kenjiArai 0:d4960fcea8ff 1755 if( *pxTicksToWait == portMAX_DELAY )
kenjiArai 0:d4960fcea8ff 1756 {
kenjiArai 0:d4960fcea8ff 1757 xReturn = pdFALSE;
kenjiArai 0:d4960fcea8ff 1758 }
kenjiArai 0:d4960fcea8ff 1759 else /* We are not blocking indefinitely, perform the checks below. */
kenjiArai 0:d4960fcea8ff 1760 #endif
kenjiArai 0:d4960fcea8ff 1761
kenjiArai 0:d4960fcea8ff 1762 if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) )
kenjiArai 0:d4960fcea8ff 1763 {
kenjiArai 0:d4960fcea8ff 1764 /* The tick count is greater than the time at which vTaskSetTimeout()
kenjiArai 0:d4960fcea8ff 1765 was called, but has also overflowed since vTaskSetTimeOut() was called.
kenjiArai 0:d4960fcea8ff 1766 It must have wrapped all the way around and gone past us again. This
kenjiArai 0:d4960fcea8ff 1767 passed since vTaskSetTimeout() was called. */
kenjiArai 0:d4960fcea8ff 1768 xReturn = pdTRUE;
kenjiArai 0:d4960fcea8ff 1769 }
kenjiArai 0:d4960fcea8ff 1770 else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait )
kenjiArai 0:d4960fcea8ff 1771 {
kenjiArai 0:d4960fcea8ff 1772 /* Not a genuine timeout. Adjust parameters for time remaining. */
kenjiArai 0:d4960fcea8ff 1773 *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering );
kenjiArai 0:d4960fcea8ff 1774 vTaskSetTimeOutState( pxTimeOut );
kenjiArai 0:d4960fcea8ff 1775 xReturn = pdFALSE;
kenjiArai 0:d4960fcea8ff 1776 }
kenjiArai 0:d4960fcea8ff 1777 else
kenjiArai 0:d4960fcea8ff 1778 {
kenjiArai 0:d4960fcea8ff 1779 xReturn = pdTRUE;
kenjiArai 0:d4960fcea8ff 1780 }
kenjiArai 0:d4960fcea8ff 1781 }
kenjiArai 0:d4960fcea8ff 1782 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1783
kenjiArai 0:d4960fcea8ff 1784 return xReturn;
kenjiArai 0:d4960fcea8ff 1785 }
kenjiArai 0:d4960fcea8ff 1786 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1787
kenjiArai 0:d4960fcea8ff 1788 void vTaskMissedYield( void )
kenjiArai 0:d4960fcea8ff 1789 {
kenjiArai 0:d4960fcea8ff 1790 xMissedYield = pdTRUE;
kenjiArai 0:d4960fcea8ff 1791 }
kenjiArai 0:d4960fcea8ff 1792
kenjiArai 0:d4960fcea8ff 1793 /*
kenjiArai 0:d4960fcea8ff 1794 * -----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 1795 * The Idle task.
kenjiArai 0:d4960fcea8ff 1796 * ----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 1797 *
kenjiArai 0:d4960fcea8ff 1798 * The portTASK_FUNCTION() macro is used to allow port/compiler specific
kenjiArai 0:d4960fcea8ff 1799 * language extensions. The equivalent prototype for this function is:
kenjiArai 0:d4960fcea8ff 1800 *
kenjiArai 0:d4960fcea8ff 1801 * void prvIdleTask( void *pvParameters );
kenjiArai 0:d4960fcea8ff 1802 *
kenjiArai 0:d4960fcea8ff 1803 */
kenjiArai 0:d4960fcea8ff 1804 static portTASK_FUNCTION( prvIdleTask, pvParameters )
kenjiArai 0:d4960fcea8ff 1805 {
kenjiArai 0:d4960fcea8ff 1806 /* Stop warnings. */
kenjiArai 0:d4960fcea8ff 1807 ( void ) pvParameters;
kenjiArai 0:d4960fcea8ff 1808
kenjiArai 0:d4960fcea8ff 1809 for( ;; )
kenjiArai 0:d4960fcea8ff 1810 {
kenjiArai 0:d4960fcea8ff 1811 /* See if any tasks have been deleted. */
kenjiArai 0:d4960fcea8ff 1812 prvCheckTasksWaitingTermination();
kenjiArai 0:d4960fcea8ff 1813
kenjiArai 0:d4960fcea8ff 1814 #if ( configUSE_PREEMPTION == 0 )
kenjiArai 0:d4960fcea8ff 1815 {
kenjiArai 0:d4960fcea8ff 1816 /* If we are not using preemption we keep forcing a task switch to
kenjiArai 0:d4960fcea8ff 1817 see if any other task has become available. If we are using
kenjiArai 0:d4960fcea8ff 1818 preemption we don't need to do this as any task becoming available
kenjiArai 0:d4960fcea8ff 1819 will automatically get the processor anyway. */
kenjiArai 0:d4960fcea8ff 1820 taskYIELD();
kenjiArai 0:d4960fcea8ff 1821 }
kenjiArai 0:d4960fcea8ff 1822 #endif
kenjiArai 0:d4960fcea8ff 1823
kenjiArai 0:d4960fcea8ff 1824 #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
kenjiArai 0:d4960fcea8ff 1825 {
kenjiArai 0:d4960fcea8ff 1826 /* When using preemption tasks of equal priority will be
kenjiArai 0:d4960fcea8ff 1827 timesliced. If a task that is sharing the idle priority is ready
kenjiArai 0:d4960fcea8ff 1828 to run then the idle task should yield before the end of the
kenjiArai 0:d4960fcea8ff 1829 timeslice.
kenjiArai 0:d4960fcea8ff 1830
kenjiArai 0:d4960fcea8ff 1831 A critical region is not required here as we are just reading from
kenjiArai 0:d4960fcea8ff 1832 the list, and an occasional incorrect value will not matter. If
kenjiArai 0:d4960fcea8ff 1833 the ready list at the idle priority contains more than one task
kenjiArai 0:d4960fcea8ff 1834 then a task other than the idle task is ready to execute. */
kenjiArai 0:d4960fcea8ff 1835 if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 )
kenjiArai 0:d4960fcea8ff 1836 {
kenjiArai 0:d4960fcea8ff 1837 taskYIELD();
kenjiArai 0:d4960fcea8ff 1838 }
kenjiArai 0:d4960fcea8ff 1839 }
kenjiArai 0:d4960fcea8ff 1840 #endif
kenjiArai 0:d4960fcea8ff 1841
kenjiArai 0:d4960fcea8ff 1842 #if ( configUSE_IDLE_HOOK == 1 )
kenjiArai 0:d4960fcea8ff 1843 {
kenjiArai 0:d4960fcea8ff 1844 extern void vApplicationIdleHook( void );
kenjiArai 0:d4960fcea8ff 1845
kenjiArai 0:d4960fcea8ff 1846 /* Call the user defined function from within the idle task. This
kenjiArai 0:d4960fcea8ff 1847 allows the application designer to add background functionality
kenjiArai 0:d4960fcea8ff 1848 without the overhead of a separate task.
kenjiArai 0:d4960fcea8ff 1849 NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
kenjiArai 0:d4960fcea8ff 1850 CALL A FUNCTION THAT MIGHT BLOCK. */
kenjiArai 0:d4960fcea8ff 1851 vApplicationIdleHook();
kenjiArai 0:d4960fcea8ff 1852 }
kenjiArai 0:d4960fcea8ff 1853 #endif
kenjiArai 0:d4960fcea8ff 1854 }
kenjiArai 0:d4960fcea8ff 1855 } /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
kenjiArai 0:d4960fcea8ff 1856
kenjiArai 0:d4960fcea8ff 1857
kenjiArai 0:d4960fcea8ff 1858
kenjiArai 0:d4960fcea8ff 1859
kenjiArai 0:d4960fcea8ff 1860
kenjiArai 0:d4960fcea8ff 1861
kenjiArai 0:d4960fcea8ff 1862
kenjiArai 0:d4960fcea8ff 1863 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 1864 * File private functions documented at the top of the file.
kenjiArai 0:d4960fcea8ff 1865 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1866
kenjiArai 0:d4960fcea8ff 1867
kenjiArai 0:d4960fcea8ff 1868
kenjiArai 0:d4960fcea8ff 1869 static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )
kenjiArai 0:d4960fcea8ff 1870 {
kenjiArai 0:d4960fcea8ff 1871 /* Store the function name in the TCB. */
kenjiArai 0:d4960fcea8ff 1872 #if configMAX_TASK_NAME_LEN > 1
kenjiArai 0:d4960fcea8ff 1873 {
kenjiArai 0:d4960fcea8ff 1874 /* Don't bring strncpy into the build unnecessarily. */
kenjiArai 0:d4960fcea8ff 1875 strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );
kenjiArai 0:d4960fcea8ff 1876 }
kenjiArai 0:d4960fcea8ff 1877 #endif
kenjiArai 0:d4960fcea8ff 1878 pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = '\0';
kenjiArai 0:d4960fcea8ff 1879
kenjiArai 0:d4960fcea8ff 1880 /* This is used as an array index so must ensure it's not too large. First
kenjiArai 0:d4960fcea8ff 1881 remove the privilege bit if one is present. */
kenjiArai 0:d4960fcea8ff 1882 if( uxPriority >= configMAX_PRIORITIES )
kenjiArai 0:d4960fcea8ff 1883 {
kenjiArai 0:d4960fcea8ff 1884 uxPriority = configMAX_PRIORITIES - 1;
kenjiArai 0:d4960fcea8ff 1885 }
kenjiArai 0:d4960fcea8ff 1886
kenjiArai 0:d4960fcea8ff 1887 pxTCB->uxPriority = uxPriority;
kenjiArai 0:d4960fcea8ff 1888 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 1889 {
kenjiArai 0:d4960fcea8ff 1890 pxTCB->uxBasePriority = uxPriority;
kenjiArai 0:d4960fcea8ff 1891 }
kenjiArai 0:d4960fcea8ff 1892 #endif
kenjiArai 0:d4960fcea8ff 1893
kenjiArai 0:d4960fcea8ff 1894 vListInitialiseItem( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 1895 vListInitialiseItem( &( pxTCB->xEventListItem ) );
kenjiArai 0:d4960fcea8ff 1896
kenjiArai 0:d4960fcea8ff 1897 /* Set the pxTCB as a link back from the xListItem. This is so we can get
kenjiArai 0:d4960fcea8ff 1898 back to the containing TCB from a generic item in a list. */
kenjiArai 0:d4960fcea8ff 1899 listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );
kenjiArai 0:d4960fcea8ff 1900
kenjiArai 0:d4960fcea8ff 1901 /* Event lists are always in priority order. */
kenjiArai 0:d4960fcea8ff 1902 listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
kenjiArai 0:d4960fcea8ff 1903 listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );
kenjiArai 0:d4960fcea8ff 1904
kenjiArai 0:d4960fcea8ff 1905 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
kenjiArai 0:d4960fcea8ff 1906 {
kenjiArai 0:d4960fcea8ff 1907 pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0;
kenjiArai 0:d4960fcea8ff 1908 }
kenjiArai 0:d4960fcea8ff 1909 #endif
kenjiArai 0:d4960fcea8ff 1910
kenjiArai 0:d4960fcea8ff 1911 #if ( configUSE_APPLICATION_TASK_TAG == 1 )
kenjiArai 0:d4960fcea8ff 1912 {
kenjiArai 0:d4960fcea8ff 1913 pxTCB->pxTaskTag = NULL;
kenjiArai 0:d4960fcea8ff 1914 }
kenjiArai 0:d4960fcea8ff 1915 #endif
kenjiArai 0:d4960fcea8ff 1916
kenjiArai 0:d4960fcea8ff 1917 #if ( configGENERATE_RUN_TIME_STATS == 1 )
kenjiArai 0:d4960fcea8ff 1918 {
kenjiArai 0:d4960fcea8ff 1919 pxTCB->ulRunTimeCounter = 0UL;
kenjiArai 0:d4960fcea8ff 1920 }
kenjiArai 0:d4960fcea8ff 1921 #endif
kenjiArai 0:d4960fcea8ff 1922
kenjiArai 0:d4960fcea8ff 1923 #if ( portUSING_MPU_WRAPPERS == 1 )
kenjiArai 0:d4960fcea8ff 1924 {
kenjiArai 0:d4960fcea8ff 1925 vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );
kenjiArai 0:d4960fcea8ff 1926 }
kenjiArai 0:d4960fcea8ff 1927 #else
kenjiArai 0:d4960fcea8ff 1928 {
kenjiArai 0:d4960fcea8ff 1929 ( void ) xRegions;
kenjiArai 0:d4960fcea8ff 1930 ( void ) usStackDepth;
kenjiArai 0:d4960fcea8ff 1931 }
kenjiArai 0:d4960fcea8ff 1932 #endif
kenjiArai 0:d4960fcea8ff 1933 }
kenjiArai 0:d4960fcea8ff 1934 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1935
kenjiArai 0:d4960fcea8ff 1936 #if ( portUSING_MPU_WRAPPERS == 1 )
kenjiArai 0:d4960fcea8ff 1937
kenjiArai 0:d4960fcea8ff 1938 void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions )
kenjiArai 0:d4960fcea8ff 1939 {
kenjiArai 0:d4960fcea8ff 1940 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 1941
kenjiArai 0:d4960fcea8ff 1942 if( xTaskToModify == pxCurrentTCB )
kenjiArai 0:d4960fcea8ff 1943 {
kenjiArai 0:d4960fcea8ff 1944 xTaskToModify = NULL;
kenjiArai 0:d4960fcea8ff 1945 }
kenjiArai 0:d4960fcea8ff 1946
kenjiArai 0:d4960fcea8ff 1947 /* If null is passed in here then we are deleting ourselves. */
kenjiArai 0:d4960fcea8ff 1948 pxTCB = prvGetTCBFromHandle( xTaskToModify );
kenjiArai 0:d4960fcea8ff 1949
kenjiArai 0:d4960fcea8ff 1950 vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
kenjiArai 0:d4960fcea8ff 1951 }
kenjiArai 0:d4960fcea8ff 1952 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1953 #endif
kenjiArai 0:d4960fcea8ff 1954
kenjiArai 0:d4960fcea8ff 1955 static void prvInitialiseTaskLists( void )
kenjiArai 0:d4960fcea8ff 1956 {
kenjiArai 0:d4960fcea8ff 1957 unsigned portBASE_TYPE uxPriority;
kenjiArai 0:d4960fcea8ff 1958
kenjiArai 0:d4960fcea8ff 1959 for( uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++ )
kenjiArai 0:d4960fcea8ff 1960 {
kenjiArai 0:d4960fcea8ff 1961 vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) );
kenjiArai 0:d4960fcea8ff 1962 }
kenjiArai 0:d4960fcea8ff 1963
kenjiArai 0:d4960fcea8ff 1964 vListInitialise( ( xList * ) &xDelayedTaskList1 );
kenjiArai 0:d4960fcea8ff 1965 vListInitialise( ( xList * ) &xDelayedTaskList2 );
kenjiArai 0:d4960fcea8ff 1966 vListInitialise( ( xList * ) &xPendingReadyList );
kenjiArai 0:d4960fcea8ff 1967
kenjiArai 0:d4960fcea8ff 1968 #if ( INCLUDE_vTaskDelete == 1 )
kenjiArai 0:d4960fcea8ff 1969 {
kenjiArai 0:d4960fcea8ff 1970 vListInitialise( ( xList * ) &xTasksWaitingTermination );
kenjiArai 0:d4960fcea8ff 1971 }
kenjiArai 0:d4960fcea8ff 1972 #endif
kenjiArai 0:d4960fcea8ff 1973
kenjiArai 0:d4960fcea8ff 1974 #if ( INCLUDE_vTaskSuspend == 1 )
kenjiArai 0:d4960fcea8ff 1975 {
kenjiArai 0:d4960fcea8ff 1976 vListInitialise( ( xList * ) &xSuspendedTaskList );
kenjiArai 0:d4960fcea8ff 1977 }
kenjiArai 0:d4960fcea8ff 1978 #endif
kenjiArai 0:d4960fcea8ff 1979
kenjiArai 0:d4960fcea8ff 1980 /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
kenjiArai 0:d4960fcea8ff 1981 using list2. */
kenjiArai 0:d4960fcea8ff 1982 pxDelayedTaskList = &xDelayedTaskList1;
kenjiArai 0:d4960fcea8ff 1983 pxOverflowDelayedTaskList = &xDelayedTaskList2;
kenjiArai 0:d4960fcea8ff 1984 }
kenjiArai 0:d4960fcea8ff 1985 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1986
kenjiArai 0:d4960fcea8ff 1987 static void prvCheckTasksWaitingTermination( void )
kenjiArai 0:d4960fcea8ff 1988 {
kenjiArai 0:d4960fcea8ff 1989 #if ( INCLUDE_vTaskDelete == 1 )
kenjiArai 0:d4960fcea8ff 1990 {
kenjiArai 0:d4960fcea8ff 1991 portBASE_TYPE xListIsEmpty;
kenjiArai 0:d4960fcea8ff 1992
kenjiArai 0:d4960fcea8ff 1993 /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
kenjiArai 0:d4960fcea8ff 1994 too often in the idle task. */
kenjiArai 0:d4960fcea8ff 1995 if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1996 {
kenjiArai 0:d4960fcea8ff 1997 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 1998 xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
kenjiArai 0:d4960fcea8ff 1999 xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 2000
kenjiArai 0:d4960fcea8ff 2001 if( !xListIsEmpty )
kenjiArai 0:d4960fcea8ff 2002 {
kenjiArai 0:d4960fcea8ff 2003 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 2004
kenjiArai 0:d4960fcea8ff 2005 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 2006 {
kenjiArai 0:d4960fcea8ff 2007 pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );
kenjiArai 0:d4960fcea8ff 2008 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 2009 --uxCurrentNumberOfTasks;
kenjiArai 0:d4960fcea8ff 2010 --uxTasksDeleted;
kenjiArai 0:d4960fcea8ff 2011 }
kenjiArai 0:d4960fcea8ff 2012 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 2013
kenjiArai 0:d4960fcea8ff 2014 prvDeleteTCB( pxTCB );
kenjiArai 0:d4960fcea8ff 2015 }
kenjiArai 0:d4960fcea8ff 2016 }
kenjiArai 0:d4960fcea8ff 2017 }
kenjiArai 0:d4960fcea8ff 2018 #endif
kenjiArai 0:d4960fcea8ff 2019 }
kenjiArai 0:d4960fcea8ff 2020 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2021
kenjiArai 0:d4960fcea8ff 2022 static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )
kenjiArai 0:d4960fcea8ff 2023 {
kenjiArai 0:d4960fcea8ff 2024 tskTCB *pxNewTCB;
kenjiArai 0:d4960fcea8ff 2025
kenjiArai 0:d4960fcea8ff 2026 /* Allocate space for the TCB. Where the memory comes from depends on
kenjiArai 0:d4960fcea8ff 2027 the implementation of the port malloc function. */
kenjiArai 0:d4960fcea8ff 2028 pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) );
kenjiArai 0:d4960fcea8ff 2029
kenjiArai 0:d4960fcea8ff 2030 if( pxNewTCB != NULL )
kenjiArai 0:d4960fcea8ff 2031 {
kenjiArai 0:d4960fcea8ff 2032 /* Allocate space for the stack used by the task being created.
kenjiArai 0:d4960fcea8ff 2033 The base of the stack memory stored in the TCB so the task can
kenjiArai 0:d4960fcea8ff 2034 be deleted later if required. */
kenjiArai 0:d4960fcea8ff 2035 pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer );
kenjiArai 0:d4960fcea8ff 2036
kenjiArai 0:d4960fcea8ff 2037 if( pxNewTCB->pxStack == NULL )
kenjiArai 0:d4960fcea8ff 2038 {
kenjiArai 0:d4960fcea8ff 2039 /* Could not allocate the stack. Delete the allocated TCB. */
kenjiArai 0:d4960fcea8ff 2040 vPortFree( pxNewTCB );
kenjiArai 0:d4960fcea8ff 2041 pxNewTCB = NULL;
kenjiArai 0:d4960fcea8ff 2042 }
kenjiArai 0:d4960fcea8ff 2043 else
kenjiArai 0:d4960fcea8ff 2044 {
kenjiArai 0:d4960fcea8ff 2045 /* Just to help debugging. */
kenjiArai 0:d4960fcea8ff 2046 memset( pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof( portSTACK_TYPE ) );
kenjiArai 0:d4960fcea8ff 2047 }
kenjiArai 0:d4960fcea8ff 2048 }
kenjiArai 0:d4960fcea8ff 2049
kenjiArai 0:d4960fcea8ff 2050 return pxNewTCB;
kenjiArai 0:d4960fcea8ff 2051 }
kenjiArai 0:d4960fcea8ff 2052 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2053
kenjiArai 0:d4960fcea8ff 2054 #if ( configUSE_TRACE_FACILITY == 1 )
kenjiArai 0:d4960fcea8ff 2055
kenjiArai 0:d4960fcea8ff 2056 static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus )
kenjiArai 0:d4960fcea8ff 2057 {
kenjiArai 0:d4960fcea8ff 2058 volatile tskTCB *pxNextTCB, *pxFirstTCB;
kenjiArai 0:d4960fcea8ff 2059 unsigned short usStackRemaining;
kenjiArai 0:d4960fcea8ff 2060
kenjiArai 0:d4960fcea8ff 2061 /* Write the details of all the TCB's in pxList into the buffer. */
kenjiArai 0:d4960fcea8ff 2062 listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
kenjiArai 0:d4960fcea8ff 2063 do
kenjiArai 0:d4960fcea8ff 2064 {
kenjiArai 0:d4960fcea8ff 2065 listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
kenjiArai 0:d4960fcea8ff 2066 #if ( portSTACK_GROWTH > 0 )
kenjiArai 0:d4960fcea8ff 2067 {
kenjiArai 0:d4960fcea8ff 2068 usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack );
kenjiArai 0:d4960fcea8ff 2069 }
kenjiArai 0:d4960fcea8ff 2070 #else
kenjiArai 0:d4960fcea8ff 2071 {
kenjiArai 0:d4960fcea8ff 2072 usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );
kenjiArai 0:d4960fcea8ff 2073 }
kenjiArai 0:d4960fcea8ff 2074 #endif
kenjiArai 0:d4960fcea8ff 2075
kenjiArai 0:d4960fcea8ff 2076 sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber );
kenjiArai 0:d4960fcea8ff 2077 strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString );
kenjiArai 0:d4960fcea8ff 2078
kenjiArai 0:d4960fcea8ff 2079 } while( pxNextTCB != pxFirstTCB );
kenjiArai 0:d4960fcea8ff 2080 }
kenjiArai 0:d4960fcea8ff 2081
kenjiArai 0:d4960fcea8ff 2082 #endif
kenjiArai 0:d4960fcea8ff 2083 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2084
kenjiArai 0:d4960fcea8ff 2085 #if ( configGENERATE_RUN_TIME_STATS == 1 )
kenjiArai 0:d4960fcea8ff 2086
kenjiArai 0:d4960fcea8ff 2087 static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime )
kenjiArai 0:d4960fcea8ff 2088 {
kenjiArai 0:d4960fcea8ff 2089 volatile tskTCB *pxNextTCB, *pxFirstTCB;
kenjiArai 0:d4960fcea8ff 2090 unsigned long ulStatsAsPercentage;
kenjiArai 0:d4960fcea8ff 2091
kenjiArai 0:d4960fcea8ff 2092 /* Write the run time stats of all the TCB's in pxList into the buffer. */
kenjiArai 0:d4960fcea8ff 2093 listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
kenjiArai 0:d4960fcea8ff 2094 do
kenjiArai 0:d4960fcea8ff 2095 {
kenjiArai 0:d4960fcea8ff 2096 /* Get next TCB in from the list. */
kenjiArai 0:d4960fcea8ff 2097 listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
kenjiArai 0:d4960fcea8ff 2098
kenjiArai 0:d4960fcea8ff 2099 /* Divide by zero check. */
kenjiArai 0:d4960fcea8ff 2100 if( ulTotalRunTime > 0UL )
kenjiArai 0:d4960fcea8ff 2101 {
kenjiArai 0:d4960fcea8ff 2102 /* Has the task run at all? */
kenjiArai 0:d4960fcea8ff 2103 if( pxNextTCB->ulRunTimeCounter == 0 )
kenjiArai 0:d4960fcea8ff 2104 {
kenjiArai 0:d4960fcea8ff 2105 /* The task has used no CPU time at all. */
kenjiArai 0:d4960fcea8ff 2106 sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName );
kenjiArai 0:d4960fcea8ff 2107 }
kenjiArai 0:d4960fcea8ff 2108 else
kenjiArai 0:d4960fcea8ff 2109 {
kenjiArai 0:d4960fcea8ff 2110 /* What percentage of the total run time as the task used?
kenjiArai 0:d4960fcea8ff 2111 This will always be rounded down to the nearest integer. */
kenjiArai 0:d4960fcea8ff 2112 ulStatsAsPercentage = ( 100UL * pxNextTCB->ulRunTimeCounter ) / ulTotalRunTime;
kenjiArai 0:d4960fcea8ff 2113
kenjiArai 0:d4960fcea8ff 2114 if( ulStatsAsPercentage > 0UL )
kenjiArai 0:d4960fcea8ff 2115 {
kenjiArai 0:d4960fcea8ff 2116 sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
kenjiArai 0:d4960fcea8ff 2117 }
kenjiArai 0:d4960fcea8ff 2118 else
kenjiArai 0:d4960fcea8ff 2119 {
kenjiArai 0:d4960fcea8ff 2120 /* If the percentage is zero here then the task has
kenjiArai 0:d4960fcea8ff 2121 consumed less than 1% of the total run time. */
kenjiArai 0:d4960fcea8ff 2122 sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter );
kenjiArai 0:d4960fcea8ff 2123 }
kenjiArai 0:d4960fcea8ff 2124 }
kenjiArai 0:d4960fcea8ff 2125
kenjiArai 0:d4960fcea8ff 2126 strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );
kenjiArai 0:d4960fcea8ff 2127 }
kenjiArai 0:d4960fcea8ff 2128
kenjiArai 0:d4960fcea8ff 2129 } while( pxNextTCB != pxFirstTCB );
kenjiArai 0:d4960fcea8ff 2130 }
kenjiArai 0:d4960fcea8ff 2131
kenjiArai 0:d4960fcea8ff 2132 #endif
kenjiArai 0:d4960fcea8ff 2133 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2134
kenjiArai 0:d4960fcea8ff 2135 #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
kenjiArai 0:d4960fcea8ff 2136
kenjiArai 0:d4960fcea8ff 2137 static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte )
kenjiArai 0:d4960fcea8ff 2138 {
kenjiArai 0:d4960fcea8ff 2139 register unsigned short usCount = 0;
kenjiArai 0:d4960fcea8ff 2140
kenjiArai 0:d4960fcea8ff 2141 while( *pucStackByte == tskSTACK_FILL_BYTE )
kenjiArai 0:d4960fcea8ff 2142 {
kenjiArai 0:d4960fcea8ff 2143 pucStackByte -= portSTACK_GROWTH;
kenjiArai 0:d4960fcea8ff 2144 usCount++;
kenjiArai 0:d4960fcea8ff 2145 }
kenjiArai 0:d4960fcea8ff 2146
kenjiArai 0:d4960fcea8ff 2147 usCount /= sizeof( portSTACK_TYPE );
kenjiArai 0:d4960fcea8ff 2148
kenjiArai 0:d4960fcea8ff 2149 return usCount;
kenjiArai 0:d4960fcea8ff 2150 }
kenjiArai 0:d4960fcea8ff 2151
kenjiArai 0:d4960fcea8ff 2152 #endif
kenjiArai 0:d4960fcea8ff 2153 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2154
kenjiArai 0:d4960fcea8ff 2155 #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
kenjiArai 0:d4960fcea8ff 2156
kenjiArai 0:d4960fcea8ff 2157 unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )
kenjiArai 0:d4960fcea8ff 2158 {
kenjiArai 0:d4960fcea8ff 2159 tskTCB *pxTCB;
kenjiArai 0:d4960fcea8ff 2160 unsigned char *pcEndOfStack;
kenjiArai 0:d4960fcea8ff 2161 unsigned portBASE_TYPE uxReturn;
kenjiArai 0:d4960fcea8ff 2162
kenjiArai 0:d4960fcea8ff 2163 pxTCB = prvGetTCBFromHandle( xTask );
kenjiArai 0:d4960fcea8ff 2164
kenjiArai 0:d4960fcea8ff 2165 #if portSTACK_GROWTH < 0
kenjiArai 0:d4960fcea8ff 2166 {
kenjiArai 0:d4960fcea8ff 2167 pcEndOfStack = ( unsigned char * ) pxTCB->pxStack;
kenjiArai 0:d4960fcea8ff 2168 }
kenjiArai 0:d4960fcea8ff 2169 #else
kenjiArai 0:d4960fcea8ff 2170 {
kenjiArai 0:d4960fcea8ff 2171 pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack;
kenjiArai 0:d4960fcea8ff 2172 }
kenjiArai 0:d4960fcea8ff 2173 #endif
kenjiArai 0:d4960fcea8ff 2174
kenjiArai 0:d4960fcea8ff 2175 uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack );
kenjiArai 0:d4960fcea8ff 2176
kenjiArai 0:d4960fcea8ff 2177 return uxReturn;
kenjiArai 0:d4960fcea8ff 2178 }
kenjiArai 0:d4960fcea8ff 2179
kenjiArai 0:d4960fcea8ff 2180 #endif
kenjiArai 0:d4960fcea8ff 2181 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2182
kenjiArai 0:d4960fcea8ff 2183 #if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
kenjiArai 0:d4960fcea8ff 2184
kenjiArai 0:d4960fcea8ff 2185 static void prvDeleteTCB( tskTCB *pxTCB )
kenjiArai 0:d4960fcea8ff 2186 {
kenjiArai 0:d4960fcea8ff 2187 /* Free up the memory allocated by the scheduler for the task. It is up to
kenjiArai 0:d4960fcea8ff 2188 the task to free any memory allocated at the application level. */
kenjiArai 0:d4960fcea8ff 2189 vPortFreeAligned( pxTCB->pxStack );
kenjiArai 0:d4960fcea8ff 2190 vPortFree( pxTCB );
kenjiArai 0:d4960fcea8ff 2191 }
kenjiArai 0:d4960fcea8ff 2192
kenjiArai 0:d4960fcea8ff 2193 #endif
kenjiArai 0:d4960fcea8ff 2194
kenjiArai 0:d4960fcea8ff 2195
kenjiArai 0:d4960fcea8ff 2196 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2197
kenjiArai 0:d4960fcea8ff 2198 #if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )
kenjiArai 0:d4960fcea8ff 2199
kenjiArai 0:d4960fcea8ff 2200 xTaskHandle xTaskGetCurrentTaskHandle( void )
kenjiArai 0:d4960fcea8ff 2201 {
kenjiArai 0:d4960fcea8ff 2202 xTaskHandle xReturn;
kenjiArai 0:d4960fcea8ff 2203
kenjiArai 0:d4960fcea8ff 2204 /* A critical section is not required as this is not called from
kenjiArai 0:d4960fcea8ff 2205 an interrupt and the current TCB will always be the same for any
kenjiArai 0:d4960fcea8ff 2206 individual execution thread. */
kenjiArai 0:d4960fcea8ff 2207 xReturn = pxCurrentTCB;
kenjiArai 0:d4960fcea8ff 2208
kenjiArai 0:d4960fcea8ff 2209 return xReturn;
kenjiArai 0:d4960fcea8ff 2210 }
kenjiArai 0:d4960fcea8ff 2211
kenjiArai 0:d4960fcea8ff 2212 #endif
kenjiArai 0:d4960fcea8ff 2213
kenjiArai 0:d4960fcea8ff 2214 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2215
kenjiArai 0:d4960fcea8ff 2216 #if ( INCLUDE_xTaskGetSchedulerState == 1 )
kenjiArai 0:d4960fcea8ff 2217
kenjiArai 0:d4960fcea8ff 2218 portBASE_TYPE xTaskGetSchedulerState( void )
kenjiArai 0:d4960fcea8ff 2219 {
kenjiArai 0:d4960fcea8ff 2220 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 2221
kenjiArai 0:d4960fcea8ff 2222 if( xSchedulerRunning == pdFALSE )
kenjiArai 0:d4960fcea8ff 2223 {
kenjiArai 0:d4960fcea8ff 2224 xReturn = taskSCHEDULER_NOT_STARTED;
kenjiArai 0:d4960fcea8ff 2225 }
kenjiArai 0:d4960fcea8ff 2226 else
kenjiArai 0:d4960fcea8ff 2227 {
kenjiArai 0:d4960fcea8ff 2228 if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
kenjiArai 0:d4960fcea8ff 2229 {
kenjiArai 0:d4960fcea8ff 2230 xReturn = taskSCHEDULER_RUNNING;
kenjiArai 0:d4960fcea8ff 2231 }
kenjiArai 0:d4960fcea8ff 2232 else
kenjiArai 0:d4960fcea8ff 2233 {
kenjiArai 0:d4960fcea8ff 2234 xReturn = taskSCHEDULER_SUSPENDED;
kenjiArai 0:d4960fcea8ff 2235 }
kenjiArai 0:d4960fcea8ff 2236 }
kenjiArai 0:d4960fcea8ff 2237
kenjiArai 0:d4960fcea8ff 2238 return xReturn;
kenjiArai 0:d4960fcea8ff 2239 }
kenjiArai 0:d4960fcea8ff 2240
kenjiArai 0:d4960fcea8ff 2241 #endif
kenjiArai 0:d4960fcea8ff 2242 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2243
kenjiArai 0:d4960fcea8ff 2244 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 2245
kenjiArai 0:d4960fcea8ff 2246 void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )
kenjiArai 0:d4960fcea8ff 2247 {
kenjiArai 0:d4960fcea8ff 2248 tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
kenjiArai 0:d4960fcea8ff 2249
kenjiArai 0:d4960fcea8ff 2250 if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
kenjiArai 0:d4960fcea8ff 2251 {
kenjiArai 0:d4960fcea8ff 2252 /* Adjust the mutex holder state to account for its new priority. */
kenjiArai 0:d4960fcea8ff 2253 listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );
kenjiArai 0:d4960fcea8ff 2254
kenjiArai 0:d4960fcea8ff 2255 /* If the task being modified is in the ready state it will need to
kenjiArai 0:d4960fcea8ff 2256 be moved in to a new list. */
kenjiArai 0:d4960fcea8ff 2257 if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) )
kenjiArai 0:d4960fcea8ff 2258 {
kenjiArai 0:d4960fcea8ff 2259 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 2260
kenjiArai 0:d4960fcea8ff 2261 /* Inherit the priority before being moved into the new list. */
kenjiArai 0:d4960fcea8ff 2262 pxTCB->uxPriority = pxCurrentTCB->uxPriority;
kenjiArai 0:d4960fcea8ff 2263 prvAddTaskToReadyQueue( pxTCB );
kenjiArai 0:d4960fcea8ff 2264 }
kenjiArai 0:d4960fcea8ff 2265 else
kenjiArai 0:d4960fcea8ff 2266 {
kenjiArai 0:d4960fcea8ff 2267 /* Just inherit the priority. */
kenjiArai 0:d4960fcea8ff 2268 pxTCB->uxPriority = pxCurrentTCB->uxPriority;
kenjiArai 0:d4960fcea8ff 2269 }
kenjiArai 0:d4960fcea8ff 2270 }
kenjiArai 0:d4960fcea8ff 2271 }
kenjiArai 0:d4960fcea8ff 2272
kenjiArai 0:d4960fcea8ff 2273 #endif
kenjiArai 0:d4960fcea8ff 2274 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2275
kenjiArai 0:d4960fcea8ff 2276 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 2277
kenjiArai 0:d4960fcea8ff 2278 void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )
kenjiArai 0:d4960fcea8ff 2279 {
kenjiArai 0:d4960fcea8ff 2280 tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;
kenjiArai 0:d4960fcea8ff 2281
kenjiArai 0:d4960fcea8ff 2282 if( pxMutexHolder != NULL )
kenjiArai 0:d4960fcea8ff 2283 {
kenjiArai 0:d4960fcea8ff 2284 if( pxTCB->uxPriority != pxTCB->uxBasePriority )
kenjiArai 0:d4960fcea8ff 2285 {
kenjiArai 0:d4960fcea8ff 2286 /* We must be the running task to be able to give the mutex back.
kenjiArai 0:d4960fcea8ff 2287 Remove ourselves from the ready list we currently appear in. */
kenjiArai 0:d4960fcea8ff 2288 vListRemove( &( pxTCB->xGenericListItem ) );
kenjiArai 0:d4960fcea8ff 2289
kenjiArai 0:d4960fcea8ff 2290 /* Disinherit the priority before adding ourselves into the new
kenjiArai 0:d4960fcea8ff 2291 ready list. */
kenjiArai 0:d4960fcea8ff 2292 pxTCB->uxPriority = pxTCB->uxBasePriority;
kenjiArai 0:d4960fcea8ff 2293 listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );
kenjiArai 0:d4960fcea8ff 2294 prvAddTaskToReadyQueue( pxTCB );
kenjiArai 0:d4960fcea8ff 2295 }
kenjiArai 0:d4960fcea8ff 2296 }
kenjiArai 0:d4960fcea8ff 2297 }
kenjiArai 0:d4960fcea8ff 2298
kenjiArai 0:d4960fcea8ff 2299 #endif
kenjiArai 0:d4960fcea8ff 2300 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2301
kenjiArai 0:d4960fcea8ff 2302 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
kenjiArai 0:d4960fcea8ff 2303
kenjiArai 0:d4960fcea8ff 2304 void vTaskEnterCritical( void )
kenjiArai 0:d4960fcea8ff 2305 {
kenjiArai 0:d4960fcea8ff 2306 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 2307
kenjiArai 0:d4960fcea8ff 2308 if( xSchedulerRunning != pdFALSE )
kenjiArai 0:d4960fcea8ff 2309 {
kenjiArai 0:d4960fcea8ff 2310 pxCurrentTCB->uxCriticalNesting++;
kenjiArai 0:d4960fcea8ff 2311 }
kenjiArai 0:d4960fcea8ff 2312 }
kenjiArai 0:d4960fcea8ff 2313
kenjiArai 0:d4960fcea8ff 2314 #endif
kenjiArai 0:d4960fcea8ff 2315 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2316
kenjiArai 0:d4960fcea8ff 2317 #if ( portCRITICAL_NESTING_IN_TCB == 1 )
kenjiArai 0:d4960fcea8ff 2318
kenjiArai 0:d4960fcea8ff 2319 void vTaskExitCritical( void )
kenjiArai 0:d4960fcea8ff 2320 {
kenjiArai 0:d4960fcea8ff 2321 if( xSchedulerRunning != pdFALSE )
kenjiArai 0:d4960fcea8ff 2322 {
kenjiArai 0:d4960fcea8ff 2323 if( pxCurrentTCB->uxCriticalNesting > 0 )
kenjiArai 0:d4960fcea8ff 2324 {
kenjiArai 0:d4960fcea8ff 2325 pxCurrentTCB->uxCriticalNesting--;
kenjiArai 0:d4960fcea8ff 2326
kenjiArai 0:d4960fcea8ff 2327 if( pxCurrentTCB->uxCriticalNesting == 0 )
kenjiArai 0:d4960fcea8ff 2328 {
kenjiArai 0:d4960fcea8ff 2329 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 2330 }
kenjiArai 0:d4960fcea8ff 2331 }
kenjiArai 0:d4960fcea8ff 2332 }
kenjiArai 0:d4960fcea8ff 2333 }
kenjiArai 0:d4960fcea8ff 2334
kenjiArai 0:d4960fcea8ff 2335 #endif
kenjiArai 0:d4960fcea8ff 2336 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 2337
kenjiArai 0:d4960fcea8ff 2338
kenjiArai 0:d4960fcea8ff 2339
kenjiArai 0:d4960fcea8ff 2340