#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
Go to the source code of this file.
#define corINITIAL_STATE ( 0 ) |
#define prvAddCoRoutineToReadyQueue | ( | pxCRCB | ) |
Value:
{ \ if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ { \ uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ } \ vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ }
Definition at line 90 of file croutine.c.
Referenced by prvCheckDelayedList(), prvCheckPendingReadyList(), and xCoRoutineCreate().
static void prvCheckDelayedList | ( | void | ) | [static] |
Definition at line 243 of file croutine.c.
References listGET_LIST_ITEM_VALUE, listGET_OWNER_OF_HEAD_ENTRY, portDISABLE_INTERRUPTS, portENABLE_INTERRUPTS, prvAddCoRoutineToReadyQueue, xLIST_ITEM::pvContainer, vListRemove(), xCoRoutineTickCount, corCoRoutineControlBlock::xEventListItem, corCoRoutineControlBlock::xGenericListItem, xLastTickCount, xPassedTicks, and xTaskGetTickCount().
Referenced by vCoRoutineSchedule().
00244 { 00245 corCRCB *pxCRCB; 00246 00247 xPassedTicks = xTaskGetTickCount() - xLastTickCount; 00248 while( xPassedTicks ) 00249 { 00250 xCoRoutineTickCount++; 00251 xPassedTicks--; 00252 00253 /* If the tick count has overflowed we need to swap the ready lists. */ 00254 if( xCoRoutineTickCount == 0 ) 00255 { 00256 xList * pxTemp; 00257 00258 /* Tick count has overflowed so we need to swap the delay lists. If there are 00259 any items in pxDelayedCoRoutineList here then there is an error! */ 00260 pxTemp = pxDelayedCoRoutineList; 00261 pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; 00262 pxOverflowDelayedCoRoutineList = pxTemp; 00263 } 00264 00265 /* See if this tick has made a timeout expire. */ 00266 while( ( pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ) ) != NULL ) 00267 { 00268 if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) 00269 { 00270 /* Timeout not yet expired. */ 00271 break; 00272 } 00273 00274 portDISABLE_INTERRUPTS(); 00275 { 00276 /* The event could have occurred just before this critical 00277 section. If this is the case then the generic list item will 00278 have been moved to the pending ready list and the following 00279 line is still valid. Also the pvContainer parameter will have 00280 been set to NULL so the following lines are also valid. */ 00281 vListRemove( &( pxCRCB->xGenericListItem ) ); 00282 00283 /* Is the co-routine waiting on an event also? */ 00284 if( pxCRCB->xEventListItem.pvContainer ) 00285 { 00286 vListRemove( &( pxCRCB->xEventListItem ) ); 00287 } 00288 } 00289 portENABLE_INTERRUPTS(); 00290 00291 prvAddCoRoutineToReadyQueue( pxCRCB ); 00292 } 00293 } 00294 00295 xLastTickCount = xCoRoutineTickCount; 00296 }
static void prvCheckPendingReadyList | ( | void | ) | [static] |
Definition at line 220 of file croutine.c.
References listGET_OWNER_OF_HEAD_ENTRY, listLIST_IS_EMPTY, portDISABLE_INTERRUPTS, portENABLE_INTERRUPTS, prvAddCoRoutineToReadyQueue, vListRemove(), corCoRoutineControlBlock::xEventListItem, and corCoRoutineControlBlock::xGenericListItem.
Referenced by vCoRoutineSchedule().
00221 { 00222 /* Are there any co-routines waiting to get moved to the ready list? These 00223 are co-routines that have been readied by an ISR. The ISR cannot access 00224 the ready lists itself. */ 00225 while( !listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) ) 00226 { 00227 corCRCB *pxUnblockedCRCB; 00228 00229 /* The pending ready list can be accessed by an ISR. */ 00230 portDISABLE_INTERRUPTS(); 00231 { 00232 pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); 00233 vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 00234 } 00235 portENABLE_INTERRUPTS(); 00236 00237 vListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); 00238 prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); 00239 } 00240 }
static void prvInitialiseCoRoutineLists | ( | void | ) | [static] |
Definition at line 329 of file croutine.c.
References configMAX_CO_ROUTINE_PRIORITIES, portBASE_TYPE, and vListInitialise().
Referenced by xCoRoutineCreate().
00330 { 00331 unsigned portBASE_TYPE uxPriority; 00332 00333 for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) 00334 { 00335 vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); 00336 } 00337 00338 vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); 00339 vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); 00340 vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); 00341 00342 /* Start with pxDelayedCoRoutineList using list1 and the 00343 pxOverflowDelayedCoRoutineList using list2. */ 00344 pxDelayedCoRoutineList = &xDelayedCoRoutineList1; 00345 pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; 00346 }
void vCoRoutineAddToDelayedList | ( | portTickType | xTicksToDelay, | |
xList * | pxEventList | |||
) |
Definition at line 182 of file croutine.c.
References listSET_LIST_ITEM_VALUE, vListInsert(), vListRemove(), xCoRoutineTickCount, corCoRoutineControlBlock::xEventListItem, and corCoRoutineControlBlock::xGenericListItem.
00183 { 00184 portTickType xTimeToWake; 00185 00186 /* Calculate the time to wake - this may overflow but this is 00187 not a problem. */ 00188 xTimeToWake = xCoRoutineTickCount + xTicksToDelay; 00189 00190 /* We must remove ourselves from the ready list before adding 00191 ourselves to the blocked list as the same list item is used for 00192 both lists. */ 00193 vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 00194 00195 /* The list item will be inserted in wake time order. */ 00196 listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); 00197 00198 if( xTimeToWake < xCoRoutineTickCount ) 00199 { 00200 /* Wake time has overflowed. Place this item in the 00201 overflow list. */ 00202 vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 00203 } 00204 else 00205 { 00206 /* The wake time has not overflowed, so we can use the 00207 current block list. */ 00208 vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 00209 } 00210 00211 if( pxEventList ) 00212 { 00213 /* Also add the co-routine to an event list. If this is done then the 00214 function must be called with interrupts disabled. */ 00215 vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); 00216 } 00217 }
void vCoRoutineSchedule | ( | void | ) |
Definition at line 299 of file croutine.c.
References listGET_OWNER_OF_NEXT_ENTRY, listLIST_IS_EMPTY, prvCheckDelayedList(), prvCheckPendingReadyList(), corCoRoutineControlBlock::pxCoRoutineFunction, corCoRoutineControlBlock::uxIndex, and uxTopCoRoutineReadyPriority.
00300 { 00301 /* See if any co-routines readied by events need moving to the ready lists. */ 00302 prvCheckPendingReadyList(); 00303 00304 /* See if any delayed co-routines have timed out. */ 00305 prvCheckDelayedList(); 00306 00307 /* Find the highest priority queue that contains ready co-routines. */ 00308 while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) 00309 { 00310 if( uxTopCoRoutineReadyPriority == 0 ) 00311 { 00312 /* No more co-routines to check. */ 00313 return; 00314 } 00315 --uxTopCoRoutineReadyPriority; 00316 } 00317 00318 /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines 00319 of the same priority get an equal share of the processor time. */ 00320 listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); 00321 00322 /* Call the co-routine. */ 00323 ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); 00324 00325 return; 00326 }
signed portBASE_TYPE xCoRoutineCreate | ( | crCOROUTINE_CODE | pxCoRoutineCode, | |
unsigned portBASE_TYPE | uxPriority, | |||
unsigned portBASE_TYPE | uxIndex | |||
) |
Definition at line 125 of file croutine.c.
References configMAX_CO_ROUTINE_PRIORITIES, configMAX_PRIORITIES, corINITIAL_STATE, errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, listSET_LIST_ITEM_OWNER, listSET_LIST_ITEM_VALUE, pdPASS, portBASE_TYPE, prvAddCoRoutineToReadyQueue, prvInitialiseCoRoutineLists(), pvPortMalloc(), corCoRoutineControlBlock::pxCoRoutineFunction, corCoRoutineControlBlock::uxIndex, corCoRoutineControlBlock::uxPriority, corCoRoutineControlBlock::uxState, vListInitialiseItem(), corCoRoutineControlBlock::xEventListItem, and corCoRoutineControlBlock::xGenericListItem.
Referenced by vStartFlashCoRoutines(), and vStartHookCoRoutines().
00126 { 00127 signed portBASE_TYPE xReturn; 00128 corCRCB *pxCoRoutine; 00129 00130 /* Allocate the memory that will store the co-routine control block. */ 00131 pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); 00132 if( pxCoRoutine ) 00133 { 00134 /* If pxCurrentCoRoutine is NULL then this is the first co-routine to 00135 be created and the co-routine data structures need initialising. */ 00136 if( pxCurrentCoRoutine == NULL ) 00137 { 00138 pxCurrentCoRoutine = pxCoRoutine; 00139 prvInitialiseCoRoutineLists(); 00140 } 00141 00142 /* Check the priority is within limits. */ 00143 if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) 00144 { 00145 uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; 00146 } 00147 00148 /* Fill out the co-routine control block from the function parameters. */ 00149 pxCoRoutine->uxState = corINITIAL_STATE; 00150 pxCoRoutine->uxPriority = uxPriority; 00151 pxCoRoutine->uxIndex = uxIndex; 00152 pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; 00153 00154 /* Initialise all the other co-routine control block parameters. */ 00155 vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); 00156 vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); 00157 00158 /* Set the co-routine control block as a link back from the xListItem. 00159 This is so we can get back to the containing CRCB from a generic item 00160 in a list. */ 00161 listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); 00162 listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); 00163 00164 /* Event lists are always in priority order. */ 00165 listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); 00166 00167 /* Now the co-routine has been initialised it can be added to the ready 00168 list at the correct priority. */ 00169 prvAddCoRoutineToReadyQueue( pxCoRoutine ); 00170 00171 xReturn = pdPASS; 00172 } 00173 else 00174 { 00175 xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; 00176 } 00177 00178 return xReturn; 00179 }
signed portBASE_TYPE xCoRoutineRemoveFromEventList | ( | const xList * | pxEventList | ) |
Definition at line 349 of file croutine.c.
References listGET_OWNER_OF_HEAD_ENTRY, pdFALSE, pdTRUE, portBASE_TYPE, corCoRoutineControlBlock::uxPriority, vListInsertEnd(), vListRemove(), and corCoRoutineControlBlock::xEventListItem.
00350 { 00351 corCRCB *pxUnblockedCRCB; 00352 signed portBASE_TYPE xReturn; 00353 00354 /* This function is called from within an interrupt. It can only access 00355 event lists and the pending ready list. */ 00356 pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); 00357 vListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 00358 vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); 00359 00360 if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) 00361 { 00362 xReturn = pdTRUE; 00363 } 00364 else 00365 { 00366 xReturn = pdFALSE; 00367 } 00368 00369 return xReturn; 00370 }
corCRCB* pxCurrentCoRoutine = NULL |
Definition at line 76 of file croutine.c.
xList* pxDelayedCoRoutineList [static] |
Definition at line 71 of file croutine.c.
xList* pxOverflowDelayedCoRoutineList [static] |
Definition at line 72 of file croutine.c.
xList pxReadyCoRoutineLists[configMAX_CO_ROUTINE_PRIORITIES] [static] |
Definition at line 68 of file croutine.c.
unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0 [static] |
portTickType xCoRoutineTickCount = 0 [static] |
Definition at line 78 of file croutine.c.
Referenced by prvCheckDelayedList(), and vCoRoutineAddToDelayedList().
xList xDelayedCoRoutineList1 [static] |
Definition at line 69 of file croutine.c.
xList xDelayedCoRoutineList2 [static] |
Definition at line 70 of file croutine.c.
portTickType xLastTickCount = 0 [static] |
portTickType xPassedTicks = 0 [static] |
xList xPendingReadyCoRoutineList [static] |
Definition at line 73 of file croutine.c.