Other Parts Discussed in Thread: HALCOGEN
Hi,
In ethernet driver generated by HalCoGen I found one serious issue. Problem is in code testing the NULL pointer taken by the DMA engine.
In short EMAC_BUF_DESC_EOQ flag in file HL_emac.c. Here is part from TRM:
32.2.6.4.9 End of Queue (EOQ) Flag
When set, this flag indicates that the descriptor in question was the last descriptor in the transmit queue
for a given transmit channel, and that the transmitter has halted. This flag is initially cleared by the
software application prior to adding the descriptor to the transmit queue. This bit is set by the EMAC when
the EMAC identifies that a descriptor is the last for a given packet (the EOP flag is set), and there are no
more descriptors in the transmit list (next descriptor pointer is NULL).
The software application can use this bit to detect when the EMAC transmitter for the corresponding
channel has halted. This is useful when the application appends additional packet descriptors to a transmit
queue list that is already owned by the EMAC. Note that this flag is valid on EOP descriptors only.
This contain obvious request, that SW must clear this flag prior add fragments into transmit queue. But current code didn't do it.
Details:
Manipulation with this descriptors have two parts. One is starting transmit (function EMACTransmit) and second after transmit done (function EMACTxIntHandler)
EMACTransmit set all flags only for first fragment packet. When one packet have multiple memory fragments, current code only add EOP flag on last part. Other flags still unchanged. All fragments between first and last are unchanged too (if exist, of course).
EMACTxIntHandler clear many flags, but never EOQ flag.
Problem is when upper layer use generate multiple fragments packets. With LwIP it is not rare. All fragment descriptors are used again and again. After some time it is normal, that many fragments have EOQ positive prior add into queue. And we have race, SW could be faster than contoller and in this case testo for EOQ have false positivity. Result it lost packets on transition in volume which can't be ignored.
This code, including problem is shared probably around all Hercules family MCUs.
Jiri Dobry
PS: do you have a plan to create better code for this completely? It have many crazy parts. For example pooling "infinite" loop inside "interrupt function". Or conversion magic number 0xFCF78600 into pointer. (In "safety" code? WTF?)
Frankly spoken, I hope that other Hercules code without sources and without another option (flash driver) have better quality.