void vNetworkBufferRelease( xNetworkBufferDescriptor_t * const pxNetworkBuffer ) { BaseType_t xListItemAlreadyInFreeList; /* Ensure the buffer is returned to the list of free buffers before the counting semaphore is 'given' to say a buffer is available. Release the storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used, heap_4 can be used. */ vEthernetBufferRelease( pxNetworkBuffer->pucEthernetBuffer ); pxNetworkBuffer->pucEthernetBuffer = NULL; taskENTER_CRITICAL(); { xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); if( xListItemAlreadyInFreeList == pdFALSE ) { vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); } configASSERT( xListItemAlreadyInFreeList == pdFALSE ); } taskEXIT_CRITICAL(); xSemaphoreGive( xNetworkBufferSemaphore ); iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer ); }
void vReleaseNetworkBufferAndDescriptor( xNetworkBufferDescriptor_t * const pxNetworkBuffer ) { BaseType_t xListItemAlreadyInFreeList; #if( ipconfigIP_TASK_KEEPS_MESSAGE_BUFFER != 0 ) if( pxNetworkBuffer == pxIpTaskMessageBuffer ) return; #endif if( !bIsValidNetworkDescriptor ( pxNetworkBuffer ) ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) ); return ; } /* Ensure the buffer is returned to the list of free buffers before the counting semaphore is 'given' to say a buffer is available. */ /* taskENTER_CRITICAL(); */ ipconfigBUFFER_ALLOC_LOCK(); { { xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); if( xListItemAlreadyInFreeList == pdFALSE ) { vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); } } /* configASSERT( xListItemAlreadyInFreeList == pdFALSE ); */ } ipconfigBUFFER_ALLOC_UNLOCK(); /* taskEXIT_CRITICAL(); */ if( xListItemAlreadyInFreeList ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n", pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } if( !xListItemAlreadyInFreeList ) { xSemaphoreGive( xNetworkBufferSemaphore ); showWarnings(); if( xTCPWindowLoggingLevel > 3 ) FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n", bIsValidNetworkDescriptor( pxNetworkBuffer ), pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer ); }
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) { BaseType_t xTimerIsInActiveList; Timer_t *pxTimer = ( Timer_t * ) xTimer; configASSERT( xTimer ); /* Is the timer in the list of active timers? */ taskENTER_CRITICAL(); { /* Checking to see if it is in the NULL list in effect checks to see if it is referenced from either the current or the overflow timer lists in one go, but the logic has to be reversed, hence the '!'. */ xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); /*lint !e961. Cast is only redundant when NULL is passed into the macro. */ } taskEXIT_CRITICAL(); return xTimerIsInActiveList; } /*lint !e818 Can't be pointer to const due to the typedef. */
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer ) { BaseType_t xListItemAlreadyInFreeList; if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) ); return ; } /* Ensure the buffer is returned to the list of free buffers before the counting semaphore is 'given' to say a buffer is available. */ ipconfigBUFFER_ALLOC_LOCK(); { { xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); if( xListItemAlreadyInFreeList == pdFALSE ) { vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); } } } ipconfigBUFFER_ALLOC_UNLOCK(); if( xListItemAlreadyInFreeList ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n", pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } if( xListItemAlreadyInFreeList == pdFALSE ) { xSemaphoreGive( xNetworkBufferSemaphore ); prvShowWarnings(); if( xTCPWindowLoggingLevel > 3 ) FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n", bIsValidNetworkDescriptor( pxNetworkBuffer ), pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer ); }
void vNetworkBufferRelease( xNetworkBufferDescriptor_t * const pxNetworkBuffer ) { BaseType_t xListItemAlreadyInFreeList; /* Ensure the buffer is returned to the list of free buffers before the counting semaphore is 'given' to say a buffer is available. */ taskENTER_CRITICAL(); { xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); if( xListItemAlreadyInFreeList == pdFALSE ) { vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); } configASSERT( xListItemAlreadyInFreeList == pdFALSE ); } taskEXIT_CRITICAL(); xSemaphoreGive( xNetworkBufferSemaphore ); iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer ); }
NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks ) { NetworkBufferDescriptor_t *pxReturn = NULL; BaseType_t xInvalid = pdFALSE; size_t uxCount; /* The current implementation only has a single size memory block, so the requested size parameter is not used (yet). */ ( void ) xRequestedSizeBytes; if( xNetworkBufferSemaphore != NULL ) { /* If there is a semaphore available, there is a network buffer available. */ if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS ) { /* Protect the structure as it is accessed from tasks and interrupts. */ ipconfigBUFFER_ALLOC_LOCK(); { pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList ); if( bIsValidNetworkDescriptor(pxReturn) && listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) ) { uxListRemove( &( pxReturn->xBufferListItem ) ); } else { xInvalid = pdTRUE; } } ipconfigBUFFER_ALLOC_UNLOCK(); if( xInvalid ) { FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n", pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) ); pxReturn = NULL; } else { { /* Reading UBaseType_t, no critical section needed. */ uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList ); if( uxMinimumFreeNetworkBuffers > uxCount ) { uxMinimumFreeNetworkBuffers = uxCount; } } pxReturn->xDataLength = xRequestedSizeBytes; #if( ipconfigTCP_IP_SANITY != 0 ) { showWarnings(); } #endif /* ipconfigTCP_IP_SANITY */ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 ) { /* make sure the buffer is not linked */ pxReturn->pxNextBuffer = NULL; } #endif /* ipconfigUSE_LINKED_RX_MESSAGES */ if( xTCPWindowLoggingLevel > 3 ) { FreeRTOS_debug_printf( ( "BUF_GET[%ld]: %p (%p)\n", bIsValidNetworkDescriptor( pxReturn ), pxReturn, pxReturn->pucEthernetBuffer ) ); } } iptraceNETWORK_BUFFER_OBTAINED( pxReturn ); } else { iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER(); } } return pxReturn; }
BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr ) { return ( bIsValidNetworkDescriptor( pxDescr ) != 0 ) && ( listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxDescr->xBufferListItem ) ) != 0 ); }
static void prvProcessReceivedCommands( void ) { DaemonTaskMessage_t xMessage; Timer_t *pxTimer; BaseType_t xTimerListsWereSwitched, xResult; TickType_t xTimeNow; while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ { #if ( INCLUDE_xTimerPendFunctionCall == 1 ) { /* Negative commands are pended function calls rather than timer commands. */ if( xMessage.xMessageID < ( BaseType_t ) 0 ) { const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); /* The timer uses the xCallbackParameters member to request a callback be executed. Check the callback is not NULL. */ configASSERT( pxCallback ); /* Call the function. */ pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* INCLUDE_xTimerPendFunctionCall */ /* Commands that are positive are timer commands rather than pended function calls. */ if( xMessage.xMessageID >= ( BaseType_t ) 0 ) { /* The messages uses the xTimerParameters member to work on a software timer. */ pxTimer = xMessage.u.xTimerParameters.pxTimer; if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ { /* The timer is in a list, remove it. */ ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); } else { mtCOVERAGE_TEST_MARKER(); } traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); /* In this case the xTimerListsWereSwitched parameter is not used, but it must be present in the function call. prvSampleTimeNow() must be called after the message is received from xTimerQueue so there is no possibility of a higher priority task adding a message to the message queue with a time that is ahead of the timer daemon task (because it pre-empted the timer daemon task after the xTimeNow value was set). */ xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); switch( xMessage.xMessageID ) { case tmrCOMMAND_START : case tmrCOMMAND_START_FROM_ISR : case tmrCOMMAND_RESET : case tmrCOMMAND_RESET_FROM_ISR : case tmrCOMMAND_START_DONT_TRACE : /* Start or restart a timer. */ if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) { /* The timer expired before it was added to the active timer list. Process it now. */ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); traceTIMER_EXPIRED( pxTimer ); if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) { xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); configASSERT( xResult ); ( void ) xResult; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } break; case tmrCOMMAND_STOP : case tmrCOMMAND_STOP_FROM_ISR : /* The timer has already been removed from the active list. There is nothing to do here. */ break; case tmrCOMMAND_CHANGE_PERIOD : case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); /* The new period does not really have a reference, and can be longer or shorter than the old one. The command time is therefore set to the current time, and as the period cannot be zero the next expiry time can only be in the future, meaning (unlike for the xTimerStart() case above) there is no fail case that needs to be handled here. */ ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); break; case tmrCOMMAND_DELETE : /* The timer has already been removed from the active list, just free up the memory if the memory was dynamically allocated. */ #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) { /* The timer can only have been allocated dynamically - free it again. */ vPortFree( pxTimer ); } #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) { /* The timer could have been allocated statically or dynamically, so check before attempting to free the memory. */ if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) { vPortFree( pxTimer ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ break; default : /* Don't expect to get here. */ break; } } } }