123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- #include "FreeRTOS.h"
- #include "task.h"
- #include "croutine.h"
- #if( configUSE_CO_ROUTINES != 0 )
- #ifdef portREMOVE_STATIC_QUALIFIER
- #define static
- #endif
- static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ];
- static List_t xDelayedCoRoutineList1;
- static List_t xDelayedCoRoutineList2;
- static List_t * pxDelayedCoRoutineList;
- static List_t * pxOverflowDelayedCoRoutineList;
- static List_t xPendingReadyCoRoutineList;
- CRCB_t * pxCurrentCoRoutine = NULL;
- static UBaseType_t uxTopCoRoutineReadyPriority = 0;
- static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
- #define corINITIAL_STATE ( 0 )
- #define prvAddCoRoutineToReadyQueue( pxCRCB ) \
- { \
- if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
- { \
- uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
- } \
- vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
- }
- static void prvInitialiseCoRoutineLists( void );
- static void prvCheckPendingReadyList( void );
- static void prvCheckDelayedList( void );
- BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
- {
- BaseType_t xReturn;
- CRCB_t *pxCoRoutine;
-
- pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
- if( pxCoRoutine )
- {
-
- if( pxCurrentCoRoutine == NULL )
- {
- pxCurrentCoRoutine = pxCoRoutine;
- prvInitialiseCoRoutineLists();
- }
-
- if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
- {
- uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
- }
-
- pxCoRoutine->uxState = corINITIAL_STATE;
- pxCoRoutine->uxPriority = uxPriority;
- pxCoRoutine->uxIndex = uxIndex;
- pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
-
- vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
- vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
-
- listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
- listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
-
- listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
-
- prvAddCoRoutineToReadyQueue( pxCoRoutine );
- xReturn = pdPASS;
- }
- else
- {
- xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
- }
- return xReturn;
- }
- void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
- {
- TickType_t xTimeToWake;
-
- xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
-
- ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
-
- listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
- if( xTimeToWake < xCoRoutineTickCount )
- {
-
- vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
- }
- else
- {
-
- vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
- }
- if( pxEventList )
- {
-
- vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
- }
- }
- static void prvCheckPendingReadyList( void )
- {
-
- while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
- {
- CRCB_t *pxUnblockedCRCB;
-
- portDISABLE_INTERRUPTS();
- {
- pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
- ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
- }
- portENABLE_INTERRUPTS();
- ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
- prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
- }
- }
- static void prvCheckDelayedList( void )
- {
- CRCB_t *pxCRCB;
- xPassedTicks = xTaskGetTickCount() - xLastTickCount;
- while( xPassedTicks )
- {
- xCoRoutineTickCount++;
- xPassedTicks--;
-
- if( xCoRoutineTickCount == 0 )
- {
- List_t * pxTemp;
-
- pxTemp = pxDelayedCoRoutineList;
- pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
- pxOverflowDelayedCoRoutineList = pxTemp;
- }
-
- while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
- {
- pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
- if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
- {
-
- break;
- }
- portDISABLE_INTERRUPTS();
- {
-
- ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
-
- if( pxCRCB->xEventListItem.pxContainer )
- {
- ( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
- }
- }
- portENABLE_INTERRUPTS();
- prvAddCoRoutineToReadyQueue( pxCRCB );
- }
- }
- xLastTickCount = xCoRoutineTickCount;
- }
- void vCoRoutineSchedule( void )
- {
-
- prvCheckPendingReadyList();
-
- prvCheckDelayedList();
-
- while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
- {
- if( uxTopCoRoutineReadyPriority == 0 )
- {
-
- return;
- }
- --uxTopCoRoutineReadyPriority;
- }
-
- listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
-
- ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
- return;
- }
- static void prvInitialiseCoRoutineLists( void )
- {
- UBaseType_t uxPriority;
- for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
- {
- vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
- }
- vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
- vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
- vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
-
- pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
- pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
- }
- BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
- {
- CRCB_t *pxUnblockedCRCB;
- BaseType_t xReturn;
-
- pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
- ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
- vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
- if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
- return xReturn;
- }
- #endif
|