Ethernet LDD potential bug

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Ethernet LDD potential bug

Jump to solution
748 Views
PeterFromSweden
Contributor III

Hi

 

I am using CodeWarrior 10.6 and Processor Expert to generate Ethernet LDD. The code supplied runs on TWR-K60N512 and in just a few seconds reproduce my problem.

 

Problem is that I get one more OnFrameTransmitted than actual SendFrame's. When this occurrs it is always when OnFrameTransmitted interrupts an ongoing SendFrame. From a user perspective it is easy to say that I don't want more completed frame receipts than what I have scheduled for sending, but finding logical explanation to it is harder.

 

Please have a try on attached project and se for yourself! More info in main.c on steps to reproduce problem.

 

Regards

/Peter

Original Attachment has been moved to: EthernetPE.zip

0 Kudos
Reply
1 Solution
542 Views
PeterFromSweden
Contributor III

Hi

After investigation of this problem, I think I found the root cause of problem.

SendFrame adds to TxQueue in two steps. First without TX_READY flag and then in next step TX_READY flag is added.

The TX_READY flag is reset when ethernet peripheral has sent it.

InterruptTxFrame checks that TX_READY is reset to determine if OnFrameTransmit should take place.

Now, when interrupt occurrs between step 1 and 2 of SendFrame above, the frame is wrongly interpreted as already sent since the bit TX_READY is not yet set.

One solution is:

1) Add another flag, ETH1_TX_TO1, or-ed to TX_READY in step 2.

LDD_QUEUE_GET_TAIL_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferDescCount - Index).Flags |= ETH1_TX_READY; /* Enable buffer transmission */
LDD_QUEUE_GET_TAIL_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferDescCount - Index).Flags |=
ETH1_TX_READY | /* Enable buffer transmission */
ETH1_TX_TO1; /* Indicate that it has been enabled */

2) Add check for TX_TO1 in RemoveTxFrame

!(LDD_QUEUE_GET_HEAD_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferOffset).Flags & ETH1_TX_READY)) {
!(LDD_QUEUE_GET_HEAD_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferOffset).Flags & ETH1_TX_READY) &&
(LDD_QUEUE_GET_HEAD_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferOffset).Flags & ETH1_TX_TO1)) {

Hope this helps!

Regards

/Peter

View solution in original post

0 Kudos
Reply
1 Reply
543 Views
PeterFromSweden
Contributor III

Hi

After investigation of this problem, I think I found the root cause of problem.

SendFrame adds to TxQueue in two steps. First without TX_READY flag and then in next step TX_READY flag is added.

The TX_READY flag is reset when ethernet peripheral has sent it.

InterruptTxFrame checks that TX_READY is reset to determine if OnFrameTransmit should take place.

Now, when interrupt occurrs between step 1 and 2 of SendFrame above, the frame is wrongly interpreted as already sent since the bit TX_READY is not yet set.

One solution is:

1) Add another flag, ETH1_TX_TO1, or-ed to TX_READY in step 2.

LDD_QUEUE_GET_TAIL_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferDescCount - Index).Flags |= ETH1_TX_READY; /* Enable buffer transmission */
LDD_QUEUE_GET_TAIL_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferDescCount - Index).Flags |=
ETH1_TX_READY | /* Enable buffer transmission */
ETH1_TX_TO1; /* Indicate that it has been enabled */

2) Add check for TX_TO1 in RemoveTxFrame

!(LDD_QUEUE_GET_HEAD_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferOffset).Flags & ETH1_TX_READY)) {
!(LDD_QUEUE_GET_HEAD_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferOffset).Flags & ETH1_TX_READY) &&
(LDD_QUEUE_GET_HEAD_OFFSET_ITEM(DeviceDataPrv->TxQueue, BufferOffset).Flags & ETH1_TX_TO1)) {

Hope this helps!

Regards

/Peter

0 Kudos
Reply