I want to have separate Rx and Tx Buffer per MAC, so that the buffer depletions can be monitored accurately and it provides some level of memory segregation for my Safety-Critical tasks.
So there are separate Tx and Rx buffers per MAC in my proto code.
e.g.
static NetworkBufferDescriptor_t xNetworkTxBuffers[XPAR_XEMACPS_NUM_INSTANCES][ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
static NetworkBufferDescriptor_t xNetworkRxBuffers[XPAR_XEMACPS_NUM_INSTANCES][ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
then you will need separate semaphores as well
/* The semaphore used to obtain network buffers. */
static xSemaphoreHandle xNetworkBufferSemaphore[XPAR_XEMACPS_NUM_INSTANCES][RX_TX_DIRECTION] = { NULL };
( I knew it was trouble - as I by design the stack buffer ownership could be spread across tasks EMACTask and IPTask mainly, yet I took a punt)
I tried this and it works for UDP, yet not for fast ICMP pings - the problem is that I had to duplicate the buffers in ICMP when I do the vRetunEthernetFrames(), as the Rx buffer is to be duplicated onto the tx buffer (due to separate buffers) using pxDuplicateNetworkBufferWithDescriptor.
and then
there is contention in the list access for EMAC1 - the list contained within differs,
failing this call
listIS_CONTAINED_WITHIN( &xFreeBuffersList[xEMACUnit][eBufferType], &( pxReturn->xBufferListItem ) )
I think the semaphore for EMAC1 is not accessed correctly and fails, EMAC0 is OK and continues working as normal.
And this only occurs when both the EMAC does a ping simultaneously using
e.g.
ping -f -c 83333 -s 1472 10.10.0.200 // EMAC1 - stops in like 2 sec
ping -f -c 83333 -s 1472 199.168.0.200 // EMAC0 - continues working
However, with UDP the data flow is different and works.
/* If there is a semaphore available, there is a network buffer
* available. */
if( xSemaphoreTake( xNetworkBufferSemaphore[xEMACUnit][eBufferType] , uxBlockTimeTicks ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and
* interrupts. */
ipconfigBUFFER_ALLOC_LOCK();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList[xEMACUnit][eBufferType] );
if( ( bIsValidNetworkDescriptor( pxReturn ) != pdFALSE_UNSIGNED ) &&
**listIS_CONTAINED_WITHIN( &xFreeBuffersList[xEMACUnit][eBufferType], &( pxReturn->xBufferListItem ) )** )
{
( void ) uxListRemove( &( pxReturn->xBufferListItem ) );
}
else
{
xInvalid = pdTRUE;
}
}
So as the moral of my prototype - am I right in assuming that the Multimode Freertos IPStack is designed for a single buffer pool, as this can be considered as a design constraint and stick to the existing design