heinbali01 wrote on Thursday, August 18, 2016:
Hi Glen,
Very glad to hear that you are developing a +TCP driver for the ASIX 88796C chip.
You mention “ip4, ip6”? Is that IPv6?
+TCP will be extended soon with IPv6. If anyone is interested in testing it, please let it know.
Sorry to drop in so late in this discussion.
When you write :
xSemaphoreTake(AsixSPIMutex,0);
result=SendPkt((uint8_t *) pxDescriptor->pucEthernetBuffer, ulTransmitSize);
xSemaphoreGive(AsixSPIMutex);
Is that symbolically? I hope you always test the outcome of xSemaphoreTake()?
One thing is clear: xNetworkInterfaceOutput() will only be called from the IP-task.
Do you want xNetworkInterfaceOutput() to wait for the SPI-transfer to be finished?
Beside sending there is a second thing to do: use the same SPI-bus to receive messages. It is custom in +TCP to create an extra task called prvEMACHandlerTask(). It is a “Deferred Interrupt Handler”, it handles events that were detected from within some ISR. The ISR may be triggered by the EMAC, the PHY or the DMA or a SPI controller. If any of the devices need attention, it will vTaskNotifyGiveFromISR() the prvEMACHandlerTask().
If I were you, I would let prvEMACHandlerTask() send all packets to the EMAC! You stop using the couple:
vTaskNotifyGiveFromISR();
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
and you start using :
xQueueSendFromISR ();
xQueueReceive();
Now xNetworkInterfaceOutput() will just forward the NetworkBuffer to the prvEMACHandlerTask() by calling xQueueSend().
Make sure FreeRTOSIPConfig.h contains :
#define ipconfigZERO_COPY_TX_DRIVER 1
Now when the IP-task sends a packet, the parameter bReleaseAfterSend will always be true:
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t bReleaseAfterSend )
bReleaseAfterSend == pdTRUE means that the Network Buffer must be released by you, failing to release it would cause a memory leak.
bReleaseAfterSend == pdFALSE means that the Network Buffer may not be released and that the driver can only temporarily inspect it. After returning from xNetworkInterfaceOutput(), the contents of the Network Buffer may change.
So when ipconfigZERO_COPY_TX_DRIVER == 1, your driver will own the NetworkBuffer and it can forward them to the prvEMACHandlerTask(), who will send them.
Within prvEMACHandlerTask() you will check many things:
● Reception of packets
● Sending of packets (from the queue)
● Check the Link Status of the PHY
● Check and report any errors
If you want to implement this suggestion, please have a look at FreeRTOS_IP_Private.h for the definition of eIPEvent_t and IPStackEvent_t. You can make some equivalent enum and struct for your prvEMACHandlerTask().
Advantages: no more problems with priority inversion. You will never hold-up the IP-task while waiting for the SPI bus.
Within prvEMACHandlerTask() you can easily decide which direction gets priority: TX or RX. You can let this depend on the actual working load.
If you have more questions, don’t hesitate to shoot!
Good luck