Here a few comments about your NetworkInterface.c :
static void prvPHYKeepAliveHandlerTask( void * pvParameters)
// _HT_ I recommend not to make a separate task for checking the PHY.
// Only one task should have access to the PHY (read/write).
// Also, as long as you device receives packets, you may assume that the
// PHY status is high. It can be quite disturbing if you poll the PHY
// **while receiving data**.
static void prvEMACDeferredInterruptHandlerTask( void *pvParameters )
// _HT_ In this task you can also check the PHY status regularly.
// Just pass a different timeout value to ulTaskNotifyTake().
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t xReleaseAfterSend )
// _HT_ I assum that you are not using a zero-copy driver?
// It does not make sense to send a packet as long as the Link Status is low
// so I would test for it:
if( phy_link_state == pdTRUE )
mac_async_write(ÐERNET_MAC_0, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
// _HT_ xNetworkInterfaceInitialise() is supposed to return pdPASS only if the EMAC is
// initialised correctly, and when the PHY Link Status is high:
BaseType_t xNetworkInterfaceInitialise( void )
return ( phy_link_state == true ) ? pdPASS : pdFAIL;
Answering your 3 questions:
- Why do we need to set the MDC clock divider?
To get a proper clock speed for the MDIO, I think.
- Is the EMAC handler asleep by default and only called when there is an event from the GMAC? I suppose in this case we register the callback to the GMACHandler to wake up the task?
Yes of cause, when an important ISR has happened, the network task should be woken up, just like you see here:
void xRxCallback( uint32_t ulStatus )
if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
/* let the prvEMACHandlerTask know that there was an RX event. */
ulISREvents |= EMAC_IF_RX_EVENT;
/* Only an RX interrupt can wakeup prvEMACHandlerTask. */
vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
Also I would let the task sleep for at most a second, so that the PHY link status can be checked.
- For a MQTT IoT application where I have under 30 sensors connected to this board, reporting once per minute, for this device in particular, is it worth trying to get a zero-copy driver to work? I should be pretty good at 10 mbps, and to save RAM I limit the MTU to the DHCP minimum (578?)
It doesn’t sound like it can be easily done, and for now you wouldn’t need a zero-copy driver. The latter is useful on a fast LAN, not when communicating with a server on the Internet.