void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) { portTickType xTimeToWake; /* Calculate the time to wake - this may overflow but this is not a problem. */ xTimeToWake = xCoRoutineTickCount + xTicksToDelay; /* We must remove ourselves from the ready list before adding ourselves to the blocked list as the same list item is used for both lists. */ ( void ) uxListRemove( ( xListItem * ) & ( pxCurrentCoRoutine->xGenericListItem ) ); /* The list item will be inserted in wake time order. */ listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); if ( xTimeToWake < xCoRoutineTickCount ) { /* Wake time has overflowed. Place this item in the overflow list. */ vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) & ( pxCurrentCoRoutine->xGenericListItem ) ); } else { /* The wake time has not overflowed, so we can use the current block list. */ vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) & ( pxCurrentCoRoutine->xGenericListItem ) ); } if ( pxEventList ) { /* Also add the co-routine to an event list. If this is done then the function must be called with interrupts disabled. */ vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); } }
BaseType_t xNetworkBuffersInitialise( void ) { BaseType_t xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ); configASSERT( xNetworkBufferSemaphore ); #if ( configQUEUE_REGISTRY_SIZE > 0 ) { vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" ); } #endif /* configQUEUE_REGISTRY_SIZE */ /* If the trace recorder code is included name the semaphore for viewing in FreeRTOS+Trace. */ #if( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 ) { extern QueueHandle_t xNetworkEventQueue; vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" ); vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" ); } #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */ if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. No storage is allocated to the buffers yet. */ for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ ) { /* Initialise and set the owner of the buffer list items. */ xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL; vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) ); } uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
static void prvSwitchTimerLists( void ) { TickType_t xNextExpireTime, xReloadTime; List_t *pxTemp; Timer_t *pxTimer; BaseType_t xResult; /* The tick count has overflowed. The timer lists must be switched. If there are any timers still referenced from the current timer list then they must have expired and should be processed before the lists are switched. */ while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) { xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); /* Remove the timer from the list. */ pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); traceTIMER_EXPIRED( pxTimer ); /* Execute its callback, then send a command to restart the timer if it is an auto-reload timer. It cannot be restarted here as the lists have not yet been switched. */ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) { /* Calculate the reload value, and if the reload value results in the timer going into the same timer list then it has already expired and the timer should be re-inserted into the current list so it is processed again within this loop. Otherwise a command should be sent to restart the timer to ensure it is only inserted into a list after the lists have been swapped. */ xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); if( xReloadTime > xNextExpireTime ) { listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); } else { xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); configASSERT( xResult ); ( void ) xResult; } } else { mtCOVERAGE_TEST_MARKER(); } } pxTemp = pxCurrentTimerList; pxCurrentTimerList = pxOverflowTimerList; pxOverflowTimerList = pxTemp; }
static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) { BaseType_t xProcessTimerNow = pdFALSE; listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); if( xNextExpiryTime <= xTimeNow ) { /* Has the expiry time elapsed between the command to start/reset a timer was issued, and the time the command was processed? */ if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ { /* The time between a command being issued and the command being processed actually exceeds the timers period. */ xProcessTimerNow = pdTRUE; } else { vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); } } else { if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) { /* If, since the command was issued, the tick count has overflowed but the expiry time has not, then the timer must have already passed its expiry time and should be processed immediately. */ xProcessTimerNow = pdTRUE; } else { vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); } } return xProcessTimerNow; }
BaseType_t xNetworkBuffersInitialise( void ) { BaseType_t xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { /* In case alternative locking is used, the mutexes can be initialised here */ ipconfigBUFFER_ALLOC_INIT( ); /* * HT: The use of counting semaphores is perfect, good invention * It is just that I didn't find the time yet to adopt the newer FreeRTOS kernel * which supports it. I tried it and it crashed. Must dive into it some day */ xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ); configASSERT( xNetworkBufferSemaphore ); if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. The buffer storage comes from the network interface, and different hardware has different requirements. */ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers ); for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ ) { /* Initialise and set the owner of the buffer list items. */ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) ); } uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
BaseType_t xNetworkBuffersInitialise( void ) { BaseType_t xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { /* In case alternative locking is used, the mutexes can be initialised here */ ipconfigBUFFER_ALLOC_INIT(); xNetworkBufferSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ); configASSERT( xNetworkBufferSemaphore ); if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. The buffer storage comes from the network interface, and different hardware has different requirements. */ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers ); for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ ) { /* Initialise and set the owner of the buffer list items. */ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) ); } uxMinimumFreeNetworkBuffers = ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
portBASE_TYPE xNetworkBuffersInitialise( void ) { portBASE_TYPE xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFERS, ipconfigNUM_NETWORK_BUFFERS ); configASSERT( xNetworkBufferSemaphore ); if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. The buffer storage comes from the network interface, and different hardware has different requirements. */ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers ); for( x = 0; x < ipconfigNUM_NETWORK_BUFFERS; x++ ) { /* Initialise and set the owner of the buffer list items. */ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) ); } } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }