My c6748 application appears to be dropping received frames from a SOCK_RAWETH socket.
When I send 10 frames to the c6748 in a row, it only gets around to processing the first 2.
On the other hand, when I insert a pause (5 ms) between each frame being sent, all 10 frames are received.
Could this problem be related to internal socket buffers being filled?
I tried setting a higher value for SO_RCVBUF to no avail.
Pseudocode from my application is shown below:
Loop:
call recvnc()
copy received packet into temporary variable
call recvncfree()
process the packet as stored in the temporary variable
Thanks
Corey
Corey,
Which version of the NDK and BIOS are you using?
What is the CPU load of the target?
Why are you using recvnc, if you are just going to copy the packet. It seems like you should just be using the standard recv.
Todd
NDK version: 2.20.03.24
BIOS version: 5.41.07.24
The CPU is virtually idle while this loop is executing.
I am aware that recvnc() combined with a copy is more-or-less equivalent to recv().
The reason I am doing this is that I am under the impression that Raw sockets do not support recv(). Is this true?
To make sure we are clear, my socket is created with the following code line:
hRawSocket = socket(AF_RAWETH, SOCK_RAWETH, 0x801);
In any case, why would this all lead to packets being dropped? I assume there is an underlying buffering system (i.e. "socket buffer") that will stow away received packets until the next time you call recvnc().
Sorry. I missed the SOCK_RAWETH in the original post.
What does the raw stats look like? Put "raweths" in your watch window. Hopefully this will shed some light.
OK got the stats.
Procedure A: Boot the DSP and send it 5 packets in a row. The receive stats are:
RcvTotal 2RcvDrops 0
Note: My application also processed 2 out of the 5 packets.
Procedure B. Boot the DSP and remotely bring down and up, again, ehe link (in linux, use ifconfig down/up). The receive stats are:
RcvTotal 5
RcvDrops 5
This suggests:
Why does the driver miss these packets? Perhaps the driver has only two buffers being ping-pong'd for DMA. Can someone take a look at the Ethernet driver and determine the length of the buffer chain set up in the buffer descriptors?
The "raweths" statistics are maintained in the NDK stack.
Have you plugged a statistics function into the driver? Look in the csl_emac.c file for a description.
ecfg.pfcbStatistics = &StatisticsUpdate;
There is a dummy one in the ethdriver.c called StatisticsUpdate.The statistics are in the
EMAC_Statistics Stats;
field.
You can call the EMAC_getStatistics() directly also, but the stats are cleared after every Rx and Tx in the driver.
I'll find a evm6748 and reproduce the problem here.
I have not plugged a statistics function into the driver as indicated by the fact that grep'ing my project files for "pfcbStatistics" returns only the line you mentioned:
That function is defined as:
static void StatisticsUpdate( Handle hApplication ){ if( (Uint32)hApplication != 0x12345678 ) { return; }}
Looking at the numbers recorded in my previous post for "RcvTotal" and "RcvDrops", it is apparent that the statistics are NOT cleared after every Rx and Tx. Are you sure we are looking at the same version of NDK. Remember, my version is: 2.20.03.24.
I appreciate that you will be trying to reproduce the problem with the c6748. When trying to reproduce the problem, it is important that the remote send multiple packets in one atomic operation so that there will be know pause between the transmission of packets, since (as mentioned in my first post) the problem does NOT occur when a small pause occurs between the transmission of packets. Hence, it appears that the problem is a timing-driven one. Let me know if you are having trouble reproducing the problem and I will try to help.
The pfcbStatistics field is in the driver code, not the NDK. Which NSP are you using (NSP supply the driver, NDK is the generic stack)?
In the NSP I'm looking at, 1.10.00.03, the pfcbStatistics function is called after each transmit and receive with the following comment
Uint32 EMAC_TxServiceCheck(Handle hEMAC){ ... /* Read the stats and reset to zero */ /* This is necessary to clear the interrupt */ emacUpdateStats(pd); /* Tell the application */ (*localDev.Config.pfcbStatistics)(pd->hApplication);
I am using NSP 1_00_00_09, but it looks like we have modified code in the "ethdriver.c". I am not sure why it is modified (by the previous developer of the project) but I suspect it was done to allow promiscuous mode or possibly to allow a custom protocol field in the MAC header.
Here is the diff from the original version of "ethdriver.c" (from 1.00.00.09) to my version:
36c36< #define PKT_MAX 64---> #define PKT_MAX 190405c405< ---> volatile Int32 pktSize = 0;422a423> pktSize = sizeof(hPkt);439c440,441< EMAC_CONFIG_MODEFLG_RMII;---> EMAC_CONFIG_MODEFLG_RMII |> EMAC_CONFIG_MODEFLG_PASSALL;
Should this modification have a bad effect?
Is there any other information you need in order to help on this issue?
Thanks. Nothing jumps out. Do you have a simple PC or Linux app that sends the data? Can you attach it (along with the source)? I want to limit the variables when I test it out here (I found a board).
Attached is the source for sending raw packets to the DSP. Unzip the the archive and do:
# cd ethtest
# make clean
# make
To send packets, e.g. 5 packets and assuming eth1, do:
./eth-send eth1 5
There are a couple things to keep in mind that could prevent this from working with your c6748 receiving code.
1. The code assumes the receiving device is in promiscuous mode, i.e. will accept packets with a non-matching destination MAC address.
If this seems to be the problem, run instead, "eth-send-mac", as follows, and substitute the MAC address that the c6748 is set as:
# ./eth-send-mac eth1 1 01:23:45:67:89:AB
2. The code fills in a custom protocol field in the MAC header. If this is the problem, look at line 21 of ethlib.c:
#define CUSTOM_PROTOCOL 0x0801
You should modify this to be a protocol that the c6748's raw ethernet stack will accept.
For example, 0x0800 will identify the packet as an ordinary IP packet.
Recompile and try again.
Let me know if this works.
Todd,
I don't get it. It told me that it attached the code. It was a .zip file. What happened. Do you have an email address to which I can send the code?
I understand that this thread has moved outside the forum, so I will mark it as closed.
We have moved to email correspondence, but for the benefit of the community, we will post the results when a solution is found. This thread may turn out to be quite useful to developers at that time.
Hi Corey,
This issue was recently brought to my attention. I am trying to reproduce the problem locally. I received the updated driver files mentioned in the post, as well as some Linux side apps that will communicate with the target board.
However, I believe the NDK you are using was updated for promiscuous mode (I suspect I was working with the previous developer of your project, Mitch, in order to get promiscuous mode working).
Do you know if this is true? The reason I'm inquiring is because I get the following run time error when building against the file "preprocessor.c":
NIMUIoctl NIMU_ETH_PROMISC failed, retcode = -1
The standard version of nimu.c doesn't have a case for NIMU_ETH_PROMISC. I'm guessing that this was added in order to get promiscuous mode working. Or maybe I'm missing something else?
Thanks,
Steve