Francisco Paez / freertos

Dependents:   frdm_k64f_freertos_lib

Committer:
fep
Date:
Wed May 31 02:27:10 2017 +0000
Revision:
0:62cd296ba2a7
FreeRTOS v9.0.0 for Cortex-M4F (FRDM-K64F and others...)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fep 0:62cd296ba2a7 1 /*
fep 0:62cd296ba2a7 2 FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
fep 0:62cd296ba2a7 3 All rights reserved
fep 0:62cd296ba2a7 4
fep 0:62cd296ba2a7 5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
fep 0:62cd296ba2a7 6
fep 0:62cd296ba2a7 7 This file is part of the FreeRTOS distribution.
fep 0:62cd296ba2a7 8
fep 0:62cd296ba2a7 9 FreeRTOS is free software; you can redistribute it and/or modify it under
fep 0:62cd296ba2a7 10 the terms of the GNU General Public License (version 2) as published by the
fep 0:62cd296ba2a7 11 Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
fep 0:62cd296ba2a7 12
fep 0:62cd296ba2a7 13 ***************************************************************************
fep 0:62cd296ba2a7 14 >>! NOTE: The modification to the GPL is included to allow you to !<<
fep 0:62cd296ba2a7 15 >>! distribute a combined work that includes FreeRTOS without being !<<
fep 0:62cd296ba2a7 16 >>! obliged to provide the source code for proprietary components !<<
fep 0:62cd296ba2a7 17 >>! outside of the FreeRTOS kernel. !<<
fep 0:62cd296ba2a7 18 ***************************************************************************
fep 0:62cd296ba2a7 19
fep 0:62cd296ba2a7 20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
fep 0:62cd296ba2a7 21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
fep 0:62cd296ba2a7 22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
fep 0:62cd296ba2a7 23 link: http://www.freertos.org/a00114.html
fep 0:62cd296ba2a7 24
fep 0:62cd296ba2a7 25 ***************************************************************************
fep 0:62cd296ba2a7 26 * *
fep 0:62cd296ba2a7 27 * FreeRTOS provides completely free yet professionally developed, *
fep 0:62cd296ba2a7 28 * robust, strictly quality controlled, supported, and cross *
fep 0:62cd296ba2a7 29 * platform software that is more than just the market leader, it *
fep 0:62cd296ba2a7 30 * is the industry's de facto standard. *
fep 0:62cd296ba2a7 31 * *
fep 0:62cd296ba2a7 32 * Help yourself get started quickly while simultaneously helping *
fep 0:62cd296ba2a7 33 * to support the FreeRTOS project by purchasing a FreeRTOS *
fep 0:62cd296ba2a7 34 * tutorial book, reference manual, or both: *
fep 0:62cd296ba2a7 35 * http://www.FreeRTOS.org/Documentation *
fep 0:62cd296ba2a7 36 * *
fep 0:62cd296ba2a7 37 ***************************************************************************
fep 0:62cd296ba2a7 38
fep 0:62cd296ba2a7 39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
fep 0:62cd296ba2a7 40 the FAQ page "My application does not run, what could be wrong?". Have you
fep 0:62cd296ba2a7 41 defined configASSERT()?
fep 0:62cd296ba2a7 42
fep 0:62cd296ba2a7 43 http://www.FreeRTOS.org/support - In return for receiving this top quality
fep 0:62cd296ba2a7 44 embedded software for free we request you assist our global community by
fep 0:62cd296ba2a7 45 participating in the support forum.
fep 0:62cd296ba2a7 46
fep 0:62cd296ba2a7 47 http://www.FreeRTOS.org/training - Investing in training allows your team to
fep 0:62cd296ba2a7 48 be as productive as possible as early as possible. Now you can receive
fep 0:62cd296ba2a7 49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
fep 0:62cd296ba2a7 50 Ltd, and the world's leading authority on the world's leading RTOS.
fep 0:62cd296ba2a7 51
fep 0:62cd296ba2a7 52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
fep 0:62cd296ba2a7 53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fep 0:62cd296ba2a7 54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
fep 0:62cd296ba2a7 55
fep 0:62cd296ba2a7 56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
fep 0:62cd296ba2a7 57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
fep 0:62cd296ba2a7 58
fep 0:62cd296ba2a7 59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
fep 0:62cd296ba2a7 60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
fep 0:62cd296ba2a7 61 licenses offer ticketed support, indemnification and commercial middleware.
fep 0:62cd296ba2a7 62
fep 0:62cd296ba2a7 63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
fep 0:62cd296ba2a7 64 engineered and independently SIL3 certified version for use in safety and
fep 0:62cd296ba2a7 65 mission critical applications that require provable dependability.
fep 0:62cd296ba2a7 66
fep 0:62cd296ba2a7 67 1 tab == 4 spaces!
fep 0:62cd296ba2a7 68 */
fep 0:62cd296ba2a7 69
fep 0:62cd296ba2a7 70 #include "FreeRTOS.h"
fep 0:62cd296ba2a7 71 #include "task.h"
fep 0:62cd296ba2a7 72 #include "croutine.h"
fep 0:62cd296ba2a7 73
fep 0:62cd296ba2a7 74 /* Remove the whole file is co-routines are not being used. */
fep 0:62cd296ba2a7 75 #if( configUSE_CO_ROUTINES != 0 )
fep 0:62cd296ba2a7 76
fep 0:62cd296ba2a7 77 /*
fep 0:62cd296ba2a7 78 * Some kernel aware debuggers require data to be viewed to be global, rather
fep 0:62cd296ba2a7 79 * than file scope.
fep 0:62cd296ba2a7 80 */
fep 0:62cd296ba2a7 81 #ifdef portREMOVE_STATIC_QUALIFIER
fep 0:62cd296ba2a7 82 #define static
fep 0:62cd296ba2a7 83 #endif
fep 0:62cd296ba2a7 84
fep 0:62cd296ba2a7 85
fep 0:62cd296ba2a7 86 /* Lists for ready and blocked co-routines. --------------------*/
fep 0:62cd296ba2a7 87 static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
fep 0:62cd296ba2a7 88 static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
fep 0:62cd296ba2a7 89 static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
fep 0:62cd296ba2a7 90 static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
fep 0:62cd296ba2a7 91 static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
fep 0:62cd296ba2a7 92 static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
fep 0:62cd296ba2a7 93
fep 0:62cd296ba2a7 94 /* Other file private variables. --------------------------------*/
fep 0:62cd296ba2a7 95 CRCB_t * pxCurrentCoRoutine = NULL;
fep 0:62cd296ba2a7 96 static UBaseType_t uxTopCoRoutineReadyPriority = 0;
fep 0:62cd296ba2a7 97 static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
fep 0:62cd296ba2a7 98
fep 0:62cd296ba2a7 99 /* The initial state of the co-routine when it is created. */
fep 0:62cd296ba2a7 100 #define corINITIAL_STATE ( 0 )
fep 0:62cd296ba2a7 101
fep 0:62cd296ba2a7 102 /*
fep 0:62cd296ba2a7 103 * Place the co-routine represented by pxCRCB into the appropriate ready queue
fep 0:62cd296ba2a7 104 * for the priority. It is inserted at the end of the list.
fep 0:62cd296ba2a7 105 *
fep 0:62cd296ba2a7 106 * This macro accesses the co-routine ready lists and therefore must not be
fep 0:62cd296ba2a7 107 * used from within an ISR.
fep 0:62cd296ba2a7 108 */
fep 0:62cd296ba2a7 109 #define prvAddCoRoutineToReadyQueue( pxCRCB ) \
fep 0:62cd296ba2a7 110 { \
fep 0:62cd296ba2a7 111 if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
fep 0:62cd296ba2a7 112 { \
fep 0:62cd296ba2a7 113 uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
fep 0:62cd296ba2a7 114 } \
fep 0:62cd296ba2a7 115 vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
fep 0:62cd296ba2a7 116 }
fep 0:62cd296ba2a7 117
fep 0:62cd296ba2a7 118 /*
fep 0:62cd296ba2a7 119 * Utility to ready all the lists used by the scheduler. This is called
fep 0:62cd296ba2a7 120 * automatically upon the creation of the first co-routine.
fep 0:62cd296ba2a7 121 */
fep 0:62cd296ba2a7 122 static void prvInitialiseCoRoutineLists( void );
fep 0:62cd296ba2a7 123
fep 0:62cd296ba2a7 124 /*
fep 0:62cd296ba2a7 125 * Co-routines that are readied by an interrupt cannot be placed directly into
fep 0:62cd296ba2a7 126 * the ready lists (there is no mutual exclusion). Instead they are placed in
fep 0:62cd296ba2a7 127 * in the pending ready list in order that they can later be moved to the ready
fep 0:62cd296ba2a7 128 * list by the co-routine scheduler.
fep 0:62cd296ba2a7 129 */
fep 0:62cd296ba2a7 130 static void prvCheckPendingReadyList( void );
fep 0:62cd296ba2a7 131
fep 0:62cd296ba2a7 132 /*
fep 0:62cd296ba2a7 133 * Macro that looks at the list of co-routines that are currently delayed to
fep 0:62cd296ba2a7 134 * see if any require waking.
fep 0:62cd296ba2a7 135 *
fep 0:62cd296ba2a7 136 * Co-routines are stored in the queue in the order of their wake time -
fep 0:62cd296ba2a7 137 * meaning once one co-routine has been found whose timer has not expired
fep 0:62cd296ba2a7 138 * we need not look any further down the list.
fep 0:62cd296ba2a7 139 */
fep 0:62cd296ba2a7 140 static void prvCheckDelayedList( void );
fep 0:62cd296ba2a7 141
fep 0:62cd296ba2a7 142 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 143
fep 0:62cd296ba2a7 144 BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
fep 0:62cd296ba2a7 145 {
fep 0:62cd296ba2a7 146 BaseType_t xReturn;
fep 0:62cd296ba2a7 147 CRCB_t *pxCoRoutine;
fep 0:62cd296ba2a7 148
fep 0:62cd296ba2a7 149 /* Allocate the memory that will store the co-routine control block. */
fep 0:62cd296ba2a7 150 pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
fep 0:62cd296ba2a7 151 if( pxCoRoutine )
fep 0:62cd296ba2a7 152 {
fep 0:62cd296ba2a7 153 /* If pxCurrentCoRoutine is NULL then this is the first co-routine to
fep 0:62cd296ba2a7 154 be created and the co-routine data structures need initialising. */
fep 0:62cd296ba2a7 155 if( pxCurrentCoRoutine == NULL )
fep 0:62cd296ba2a7 156 {
fep 0:62cd296ba2a7 157 pxCurrentCoRoutine = pxCoRoutine;
fep 0:62cd296ba2a7 158 prvInitialiseCoRoutineLists();
fep 0:62cd296ba2a7 159 }
fep 0:62cd296ba2a7 160
fep 0:62cd296ba2a7 161 /* Check the priority is within limits. */
fep 0:62cd296ba2a7 162 if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
fep 0:62cd296ba2a7 163 {
fep 0:62cd296ba2a7 164 uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
fep 0:62cd296ba2a7 165 }
fep 0:62cd296ba2a7 166
fep 0:62cd296ba2a7 167 /* Fill out the co-routine control block from the function parameters. */
fep 0:62cd296ba2a7 168 pxCoRoutine->uxState = corINITIAL_STATE;
fep 0:62cd296ba2a7 169 pxCoRoutine->uxPriority = uxPriority;
fep 0:62cd296ba2a7 170 pxCoRoutine->uxIndex = uxIndex;
fep 0:62cd296ba2a7 171 pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
fep 0:62cd296ba2a7 172
fep 0:62cd296ba2a7 173 /* Initialise all the other co-routine control block parameters. */
fep 0:62cd296ba2a7 174 vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
fep 0:62cd296ba2a7 175 vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
fep 0:62cd296ba2a7 176
fep 0:62cd296ba2a7 177 /* Set the co-routine control block as a link back from the ListItem_t.
fep 0:62cd296ba2a7 178 This is so we can get back to the containing CRCB from a generic item
fep 0:62cd296ba2a7 179 in a list. */
fep 0:62cd296ba2a7 180 listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
fep 0:62cd296ba2a7 181 listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
fep 0:62cd296ba2a7 182
fep 0:62cd296ba2a7 183 /* Event lists are always in priority order. */
fep 0:62cd296ba2a7 184 listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
fep 0:62cd296ba2a7 185
fep 0:62cd296ba2a7 186 /* Now the co-routine has been initialised it can be added to the ready
fep 0:62cd296ba2a7 187 list at the correct priority. */
fep 0:62cd296ba2a7 188 prvAddCoRoutineToReadyQueue( pxCoRoutine );
fep 0:62cd296ba2a7 189
fep 0:62cd296ba2a7 190 xReturn = pdPASS;
fep 0:62cd296ba2a7 191 }
fep 0:62cd296ba2a7 192 else
fep 0:62cd296ba2a7 193 {
fep 0:62cd296ba2a7 194 xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
fep 0:62cd296ba2a7 195 }
fep 0:62cd296ba2a7 196
fep 0:62cd296ba2a7 197 return xReturn;
fep 0:62cd296ba2a7 198 }
fep 0:62cd296ba2a7 199 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 200
fep 0:62cd296ba2a7 201 void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
fep 0:62cd296ba2a7 202 {
fep 0:62cd296ba2a7 203 TickType_t xTimeToWake;
fep 0:62cd296ba2a7 204
fep 0:62cd296ba2a7 205 /* Calculate the time to wake - this may overflow but this is
fep 0:62cd296ba2a7 206 not a problem. */
fep 0:62cd296ba2a7 207 xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
fep 0:62cd296ba2a7 208
fep 0:62cd296ba2a7 209 /* We must remove ourselves from the ready list before adding
fep 0:62cd296ba2a7 210 ourselves to the blocked list as the same list item is used for
fep 0:62cd296ba2a7 211 both lists. */
fep 0:62cd296ba2a7 212 ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
fep 0:62cd296ba2a7 213
fep 0:62cd296ba2a7 214 /* The list item will be inserted in wake time order. */
fep 0:62cd296ba2a7 215 listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
fep 0:62cd296ba2a7 216
fep 0:62cd296ba2a7 217 if( xTimeToWake < xCoRoutineTickCount )
fep 0:62cd296ba2a7 218 {
fep 0:62cd296ba2a7 219 /* Wake time has overflowed. Place this item in the
fep 0:62cd296ba2a7 220 overflow list. */
fep 0:62cd296ba2a7 221 vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
fep 0:62cd296ba2a7 222 }
fep 0:62cd296ba2a7 223 else
fep 0:62cd296ba2a7 224 {
fep 0:62cd296ba2a7 225 /* The wake time has not overflowed, so we can use the
fep 0:62cd296ba2a7 226 current block list. */
fep 0:62cd296ba2a7 227 vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
fep 0:62cd296ba2a7 228 }
fep 0:62cd296ba2a7 229
fep 0:62cd296ba2a7 230 if( pxEventList )
fep 0:62cd296ba2a7 231 {
fep 0:62cd296ba2a7 232 /* Also add the co-routine to an event list. If this is done then the
fep 0:62cd296ba2a7 233 function must be called with interrupts disabled. */
fep 0:62cd296ba2a7 234 vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
fep 0:62cd296ba2a7 235 }
fep 0:62cd296ba2a7 236 }
fep 0:62cd296ba2a7 237 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 238
fep 0:62cd296ba2a7 239 static void prvCheckPendingReadyList( void )
fep 0:62cd296ba2a7 240 {
fep 0:62cd296ba2a7 241 /* Are there any co-routines waiting to get moved to the ready list? These
fep 0:62cd296ba2a7 242 are co-routines that have been readied by an ISR. The ISR cannot access
fep 0:62cd296ba2a7 243 the ready lists itself. */
fep 0:62cd296ba2a7 244 while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
fep 0:62cd296ba2a7 245 {
fep 0:62cd296ba2a7 246 CRCB_t *pxUnblockedCRCB;
fep 0:62cd296ba2a7 247
fep 0:62cd296ba2a7 248 /* The pending ready list can be accessed by an ISR. */
fep 0:62cd296ba2a7 249 portDISABLE_INTERRUPTS();
fep 0:62cd296ba2a7 250 {
fep 0:62cd296ba2a7 251 pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
fep 0:62cd296ba2a7 252 ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
fep 0:62cd296ba2a7 253 }
fep 0:62cd296ba2a7 254 portENABLE_INTERRUPTS();
fep 0:62cd296ba2a7 255
fep 0:62cd296ba2a7 256 ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
fep 0:62cd296ba2a7 257 prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
fep 0:62cd296ba2a7 258 }
fep 0:62cd296ba2a7 259 }
fep 0:62cd296ba2a7 260 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 261
fep 0:62cd296ba2a7 262 static void prvCheckDelayedList( void )
fep 0:62cd296ba2a7 263 {
fep 0:62cd296ba2a7 264 CRCB_t *pxCRCB;
fep 0:62cd296ba2a7 265
fep 0:62cd296ba2a7 266 xPassedTicks = xTaskGetTickCount() - xLastTickCount;
fep 0:62cd296ba2a7 267 while( xPassedTicks )
fep 0:62cd296ba2a7 268 {
fep 0:62cd296ba2a7 269 xCoRoutineTickCount++;
fep 0:62cd296ba2a7 270 xPassedTicks--;
fep 0:62cd296ba2a7 271
fep 0:62cd296ba2a7 272 /* If the tick count has overflowed we need to swap the ready lists. */
fep 0:62cd296ba2a7 273 if( xCoRoutineTickCount == 0 )
fep 0:62cd296ba2a7 274 {
fep 0:62cd296ba2a7 275 List_t * pxTemp;
fep 0:62cd296ba2a7 276
fep 0:62cd296ba2a7 277 /* Tick count has overflowed so we need to swap the delay lists. If there are
fep 0:62cd296ba2a7 278 any items in pxDelayedCoRoutineList here then there is an error! */
fep 0:62cd296ba2a7 279 pxTemp = pxDelayedCoRoutineList;
fep 0:62cd296ba2a7 280 pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
fep 0:62cd296ba2a7 281 pxOverflowDelayedCoRoutineList = pxTemp;
fep 0:62cd296ba2a7 282 }
fep 0:62cd296ba2a7 283
fep 0:62cd296ba2a7 284 /* See if this tick has made a timeout expire. */
fep 0:62cd296ba2a7 285 while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
fep 0:62cd296ba2a7 286 {
fep 0:62cd296ba2a7 287 pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
fep 0:62cd296ba2a7 288
fep 0:62cd296ba2a7 289 if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
fep 0:62cd296ba2a7 290 {
fep 0:62cd296ba2a7 291 /* Timeout not yet expired. */
fep 0:62cd296ba2a7 292 break;
fep 0:62cd296ba2a7 293 }
fep 0:62cd296ba2a7 294
fep 0:62cd296ba2a7 295 portDISABLE_INTERRUPTS();
fep 0:62cd296ba2a7 296 {
fep 0:62cd296ba2a7 297 /* The event could have occurred just before this critical
fep 0:62cd296ba2a7 298 section. If this is the case then the generic list item will
fep 0:62cd296ba2a7 299 have been moved to the pending ready list and the following
fep 0:62cd296ba2a7 300 line is still valid. Also the pvContainer parameter will have
fep 0:62cd296ba2a7 301 been set to NULL so the following lines are also valid. */
fep 0:62cd296ba2a7 302 ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
fep 0:62cd296ba2a7 303
fep 0:62cd296ba2a7 304 /* Is the co-routine waiting on an event also? */
fep 0:62cd296ba2a7 305 if( pxCRCB->xEventListItem.pvContainer )
fep 0:62cd296ba2a7 306 {
fep 0:62cd296ba2a7 307 ( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
fep 0:62cd296ba2a7 308 }
fep 0:62cd296ba2a7 309 }
fep 0:62cd296ba2a7 310 portENABLE_INTERRUPTS();
fep 0:62cd296ba2a7 311
fep 0:62cd296ba2a7 312 prvAddCoRoutineToReadyQueue( pxCRCB );
fep 0:62cd296ba2a7 313 }
fep 0:62cd296ba2a7 314 }
fep 0:62cd296ba2a7 315
fep 0:62cd296ba2a7 316 xLastTickCount = xCoRoutineTickCount;
fep 0:62cd296ba2a7 317 }
fep 0:62cd296ba2a7 318 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 319
fep 0:62cd296ba2a7 320 void vCoRoutineSchedule( void )
fep 0:62cd296ba2a7 321 {
fep 0:62cd296ba2a7 322 /* See if any co-routines readied by events need moving to the ready lists. */
fep 0:62cd296ba2a7 323 prvCheckPendingReadyList();
fep 0:62cd296ba2a7 324
fep 0:62cd296ba2a7 325 /* See if any delayed co-routines have timed out. */
fep 0:62cd296ba2a7 326 prvCheckDelayedList();
fep 0:62cd296ba2a7 327
fep 0:62cd296ba2a7 328 /* Find the highest priority queue that contains ready co-routines. */
fep 0:62cd296ba2a7 329 while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
fep 0:62cd296ba2a7 330 {
fep 0:62cd296ba2a7 331 if( uxTopCoRoutineReadyPriority == 0 )
fep 0:62cd296ba2a7 332 {
fep 0:62cd296ba2a7 333 /* No more co-routines to check. */
fep 0:62cd296ba2a7 334 return;
fep 0:62cd296ba2a7 335 }
fep 0:62cd296ba2a7 336 --uxTopCoRoutineReadyPriority;
fep 0:62cd296ba2a7 337 }
fep 0:62cd296ba2a7 338
fep 0:62cd296ba2a7 339 /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
fep 0:62cd296ba2a7 340 of the same priority get an equal share of the processor time. */
fep 0:62cd296ba2a7 341 listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
fep 0:62cd296ba2a7 342
fep 0:62cd296ba2a7 343 /* Call the co-routine. */
fep 0:62cd296ba2a7 344 ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
fep 0:62cd296ba2a7 345
fep 0:62cd296ba2a7 346 return;
fep 0:62cd296ba2a7 347 }
fep 0:62cd296ba2a7 348 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 349
fep 0:62cd296ba2a7 350 static void prvInitialiseCoRoutineLists( void )
fep 0:62cd296ba2a7 351 {
fep 0:62cd296ba2a7 352 UBaseType_t uxPriority;
fep 0:62cd296ba2a7 353
fep 0:62cd296ba2a7 354 for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
fep 0:62cd296ba2a7 355 {
fep 0:62cd296ba2a7 356 vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
fep 0:62cd296ba2a7 357 }
fep 0:62cd296ba2a7 358
fep 0:62cd296ba2a7 359 vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
fep 0:62cd296ba2a7 360 vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
fep 0:62cd296ba2a7 361 vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
fep 0:62cd296ba2a7 362
fep 0:62cd296ba2a7 363 /* Start with pxDelayedCoRoutineList using list1 and the
fep 0:62cd296ba2a7 364 pxOverflowDelayedCoRoutineList using list2. */
fep 0:62cd296ba2a7 365 pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
fep 0:62cd296ba2a7 366 pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
fep 0:62cd296ba2a7 367 }
fep 0:62cd296ba2a7 368 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 369
fep 0:62cd296ba2a7 370 BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
fep 0:62cd296ba2a7 371 {
fep 0:62cd296ba2a7 372 CRCB_t *pxUnblockedCRCB;
fep 0:62cd296ba2a7 373 BaseType_t xReturn;
fep 0:62cd296ba2a7 374
fep 0:62cd296ba2a7 375 /* This function is called from within an interrupt. It can only access
fep 0:62cd296ba2a7 376 event lists and the pending ready list. This function assumes that a
fep 0:62cd296ba2a7 377 check has already been made to ensure pxEventList is not empty. */
fep 0:62cd296ba2a7 378 pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
fep 0:62cd296ba2a7 379 ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
fep 0:62cd296ba2a7 380 vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
fep 0:62cd296ba2a7 381
fep 0:62cd296ba2a7 382 if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
fep 0:62cd296ba2a7 383 {
fep 0:62cd296ba2a7 384 xReturn = pdTRUE;
fep 0:62cd296ba2a7 385 }
fep 0:62cd296ba2a7 386 else
fep 0:62cd296ba2a7 387 {
fep 0:62cd296ba2a7 388 xReturn = pdFALSE;
fep 0:62cd296ba2a7 389 }
fep 0:62cd296ba2a7 390
fep 0:62cd296ba2a7 391 return xReturn;
fep 0:62cd296ba2a7 392 }
fep 0:62cd296ba2a7 393
fep 0:62cd296ba2a7 394 #endif /* configUSE_CO_ROUTINES == 0 */
fep 0:62cd296ba2a7 395
fep 0:62cd296ba2a7 396