Francisco Paez / freertos-cm3

Dependents:   mbed_lpc1768_freertos_lib

Committer:
fep
Date:
Wed May 31 02:36:43 2017 +0000
Revision:
0:5ff20db10a96
FreeRTOS v9.0.0 for ARM Cortex-M3 based boards.

Who changed what in which revision?

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