heinbali01 wrote on Saturday, August 20, 2016:
I implemented a QueueSet
I’m not sure if that is useful / necessary.
I thought of a single working queue with each element having the size of the struct EMACEvent_t
:
For example:
typedef enum
{
eEMAC_SendPacket,
eEMAC_CheckPHY,
eEMAC_TXDone,
eEMAC_RXDone,
...
} eEMACEvent_t;
typedef struct
{
eEMACEvent_t eEventType;
void *pxData;
} EMACEvent_t;
So for every event, 8 bytes will be queued. The field pxData
may point to a Network Buffer or remain NULL if not in use.
The boolean parameter bReleaseAfterSend
will always be pdTRUE
if you define :
#define ipconfigZERO_COPY_TX_DRIVER 1
So xNetworkInterfaceOutput()
can be implemented as I described here above. Just queue the Network Buffer.
a single queue, but then it is possible that the IRQ handler might be way
down the queue if NetworkOutput pushed alot of sends into the queue
There is an alternative: you can define:
#define ipconfigUSE_LINKED_RX_MESSAGES 1
It will add a pxNextBuffer
pointer to each Network Buffer ( see include/FreeRTOS_IP.h
).
Now suppose that you receive a mix of ISR-events and packets to be sent:
You can put the packets together (link them) by setting the pxNextBuffer
field:
switch( xMsg.eEventType )
{
case eEMAC_SendPacket:
{
NetworkBufferDescriptor_t * pxNew = ( NetworkBufferDescriptor_t * ) xMsg.pxData;
pxNew->pxNextBuffer = NULL;
if( pxFirst == NULL )
{
pxFirst = pxNew;
}
if( pxLast != NULL )
{
pxLast->pxNextBuffer = pxNew;
}
pxLast = pxNew;
}
break;
case eEMAC_CheckPHY:
...
In that way you can empty the working queue each time the task wakes up.
If you want you can also write me directly ( h point tibosch at freertos point org ), then maybe we can go quicker through all this. And I’m not sure if all these implementation details are interesting for everyone