That would be the prvEMACHandlerTask
when calling the function prvEMACRxPoll
. I placed a breakpoint at every single occurrence of pxGetNetworkBufferWithDescriptor( GMAC_RX_UNITSIZE, xBlockTime )
but this one, since it will come up constantly. No breakpoint was reached and I ran directly into the ASSERT call which checks if the scheduler is disabled.
static uint32_t prvEMACRxPoll( void )
{
unsigned char * pucUseBuffer;
uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
static NetworkBufferDescriptor_t * pxNextNetworkBufferDescriptor = NULL;
const UBaseType_t xMinDescriptorsToLeave = 2UL;
const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
uint8_t * pucDMABuffer = NULL;
for( ; ; )
{
BaseType_t xRelease = pdFALSE;
/* If pxNextNetworkBufferDescriptor was not left pointing at a valid
* descriptor then allocate one now. */
if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
{
pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( GMAC_RX_UNITSIZE, xBlockTime );
}
if( pxNextNetworkBufferDescriptor != NULL )
{
/* Point pucUseBuffer to the buffer pointed to by the descriptor. */
pucUseBuffer = ( unsigned char * ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
}
else
{
/* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
* messages will be flushed and ignored. */
pucUseBuffer = NULL;
}
/* Read the next packet from the hardware into pucUseBuffer. */
ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, GMAC_RX_UNITSIZE, &ulReceiveCount, &pucDMABuffer );
if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
{
/* No data from the hardware. */
break;
}
if( pxNextNetworkBufferDescriptor == NULL )
{
/* Data was read from the hardware, but no descriptor was available
* for it, so it will be dropped. */
iptraceETHERNET_RX_EVENT_LOST();
continue;
}
iptraceNETWORK_INTERFACE_RECEIVE();
#if ( ipconfigZERO_COPY_RX_DRIVER != 0 )
{
pxNextNetworkBufferDescriptor = pxPacketBuffer_to_NetworkBuffer( pucDMABuffer );
if( pxNextNetworkBufferDescriptor == NULL )
{
/* Strange: can not translate from a DMA buffer to a Network Buffer. */
break;
}
}
#endif /* ipconfigZERO_COPY_RX_DRIVER */
pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
pxNextNetworkBufferDescriptor->pxInterface = pxMyInterface;
pxNextNetworkBufferDescriptor->pxEndPoint = FreeRTOS_MatchingEndpoint( pxMyInterface, pxNextNetworkBufferDescriptor->pucEthernetBuffer );
if( pxNextNetworkBufferDescriptor->pxEndPoint == NULL )
{
FreeRTOS_printf( ( "NetworkInterface: can not find a proper endpoint\n" ) );
xRelease = pdTRUE;
}
else
{
xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;
if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
{
/* xSendEventStructToIPTask() timed out. Release the descriptor. */
FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue a packet!\n" ) );
xRelease = pdTRUE;
}
}
/* Release the descriptor in case it can not be delivered. */
if( xRelease == pdTRUE )
{
/* The buffer could not be sent to the stack so must be released
* again. */
vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
iptraceETHERNET_RX_EVENT_LOST();
}
/* Now the buffer has either been passed to the IP-task,
* or it has been released in the code above. */
pxNextNetworkBufferDescriptor = NULL;
ulReturnValue++;
}
return ulReturnValue;
}
static void prvEMACHandlerTask( void * pvParameters )
{
UBaseType_t uxCount;
uxLowestSemCount = GMAC_TX_BUFFERS + 1;
#if ( ipconfigZERO_COPY_TX_DRIVER != 0 )
NetworkBufferDescriptor_t * pxBuffer;
#endif
uint8_t * pucBuffer;
BaseType_t xResult = 0;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
uint32_t ulISREvents = 0U;
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
configASSERT( xEMACTaskHandle );
for( ; ; )
{
xResult = 0;
vCheckBuffersAndQueue();
/* Wait for a new event or a time-out. */
xTaskNotifyWait( 0U, /* ulBitsToClearOnEntry */
EMAC_IF_ALL_EVENT, /* ulBitsToClearOnExit */
&( ulISREvents ), /* pulNotificationValue */
ulMaxBlockTime );
if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
{
/* Wait for the EMAC interrupt to indicate that another packet has been
* received. */
xResult = prvEMACRxPoll();
}
if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
{
while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
{
#if ( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
if( pxBuffer != NULL )
{
vReleaseNetworkBufferAndDescriptor( pxBuffer );
TX_STAT_INCREMENT( tx_release_ok );
}
else
{
TX_STAT_INCREMENT( tx_release_bad );
}
}
#else /* if ( ipconfigZERO_COPY_TX_DRIVER != 0 ) */
{
TX_STAT_INCREMENT( tx_release_ok );
}
#endif /* if ( ipconfigZERO_COPY_TX_DRIVER != 0 ) */
uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
if( uxCount < ( GMAC_TX_BUFFERS - 1 ) )
{
/* Tell the counting semaphore that one more TX descriptor is available. */
xSemaphoreGive( xTXDescriptorSemaphore );
}
}
}
if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
{
/* Future extension: logging about errors that occurred. */
}
gmac_enable_management( GMAC, true );
if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )
{
/* Something has changed to a Link Status, need re-check. */
prvEthernetUpdateConfig( pdFALSE );
}
gmac_enable_management( GMAC, false );
}
}
BTW: Please let me know if I can help you helping me out by highlighting more of my quoted code through comments or cutting some to reduce bloat