Freertos for LPC CM3 tested on LPC1768

Committer:
dflet
Date:
Sat Jun 06 13:27:43 2015 +0000
Revision:
0:91ad48ad5687
Setup for LPC CM3 but may work with LPC CM4

Who changed what in which revision?

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