www.freertos.org test on stm32f0

Fork of FreeRTOS by Rohit Grover

Committer:
rgrover1
Date:
Fri Jan 24 14:56:04 2014 +0000
Revision:
0:8e57f3e9cc89
Making FreeRTOS available as a library

Who changed what in which revision?

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