#include "list.h"
Go to the source code of this file.
Data Structures | |
struct | corCoRoutineControlBlock |
Defines | |
#define | crDELAY(xHandle, xTicksToDelay) |
#define | crEND() } |
#define | crQUEUE_RECEIVE(xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult) |
#define | crQUEUE_RECEIVE_FROM_ISR(pxQueue, pvBuffer, pxCoRoutineWoken) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken ) |
#define | crQUEUE_SEND(xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult) |
#define | crQUEUE_SEND_FROM_ISR(pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) |
#define | crSET_STATE0(xHandle) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): |
#define | crSET_STATE1(xHandle) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): |
#define | crSTART(pxCRCB) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0: |
Typedefs | |
typedef struct corCoRoutineControlBlock | corCRCB |
typedef void(* | crCOROUTINE_CODE )(xCoRoutineHandle, unsigned portBASE_TYPE) |
typedef void * | xCoRoutineHandle |
Functions | |
void | vCoRoutineAddToDelayedList (portTickType xTicksToDelay, xList *pxEventList) |
void | vCoRoutineSchedule (void) |
signed portBASE_TYPE | xCoRoutineCreate (crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex) |
signed portBASE_TYPE | xCoRoutineRemoveFromEventList (const xList *pxEventList) |
#define crDELAY | ( | xHandle, | |||
xTicksToDelay | ) |
Value:
if( xTicksToDelay > 0 ) \ { \ vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \ } \ crSET_STATE0( xHandle );
Definition at line 319 of file croutine.h.
Referenced by prvFixedDelayCoRoutine().
#define crEND | ( | ) | } |
Definition at line 264 of file croutine.h.
Referenced by prvFixedDelayCoRoutine(), prvFlashCoRoutine(), and prvHookCoRoutine().
#define crQUEUE_RECEIVE | ( | xHandle, | |||
pxQueue, | |||||
pvBuffer, | |||||
xTicksToWait, | |||||
pxResult | ) |
Value:
{ \ *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \ if( *pxResult == errQUEUE_BLOCKED ) \ { \ crSET_STATE0( xHandle ); \ *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \ } \ if( *pxResult == errQUEUE_YIELD ) \ { \ crSET_STATE1( xHandle ); \ *pxResult = pdPASS; \ } \ }
Definition at line 501 of file croutine.h.
Referenced by prvFlashCoRoutine(), and prvHookCoRoutine().
#define crQUEUE_RECEIVE_FROM_ISR | ( | pxQueue, | |||
pvBuffer, | |||||
pxCoRoutineWoken | ) | xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken ) |
#define crQUEUE_SEND | ( | xHandle, | |||
pxQueue, | |||||
pvItemToQueue, | |||||
xTicksToWait, | |||||
pxResult | ) |
Value:
{ \ *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \ if( *pxResult == errQUEUE_BLOCKED ) \ { \ crSET_STATE0( xHandle ); \ *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \ } \ if( *pxResult == errQUEUE_YIELD ) \ { \ crSET_STATE1( xHandle ); \ *pxResult = pdPASS; \ } \ }
Definition at line 409 of file croutine.h.
Referenced by prvFixedDelayCoRoutine(), and prvHookCoRoutine().
#define crQUEUE_SEND_FROM_ISR | ( | pxQueue, | |||
pvItemToQueue, | |||||
xCoRoutinePreviouslyWoken | ) | xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) |
#define crSET_STATE0 | ( | xHandle | ) | ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): |
Definition at line 270 of file croutine.h.
#define crSET_STATE1 | ( | xHandle | ) | ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): |
Definition at line 271 of file croutine.h.
#define crSTART | ( | pxCRCB | ) | switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0: |
Definition at line 233 of file croutine.h.
Referenced by prvFixedDelayCoRoutine(), prvFlashCoRoutine(), and prvHookCoRoutine().
typedef struct corCoRoutineControlBlock corCRCB |
typedef void(* crCOROUTINE_CODE)(xCoRoutineHandle, unsigned portBASE_TYPE) |
Definition at line 76 of file croutine.h.
typedef void* xCoRoutineHandle |
Definition at line 73 of file croutine.h.
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 }