Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,142 Views

Ethernet link on DE2-115

Hi, 

 

I am using DE2-115 to do Ethernet UDP data transferring with the simple_socket_server template. Everything seems correct but the link will fail for several seconds at the beginning every time I run the code (the return value of sendto is -1). The data rate is about 4Mbps. 

 

Please give me some idea if there is some bug in the following code. 

 

void SSSSimpleSocketServerTask() 

int tx_buffer_size = SSS_TX_BUF_SIZE; 

int udp_socket; 

int l=0; 

char data[100]={0}; 

struct sockaddr_in cliaddr; 

struct sockaddr_in seraddr; 

 

if((udp_socket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0) 

printf("Error of socket creating"); 

cliaddr.sin_family = AF_INET; 

cliaddr.sin_port = htons(UDP_PORT); 

cliaddr.sin_addr.s_addr = INADDR_ANY; 

 

seraddr.sin_family = AF_INET; 

seraddr.sin_port = htons(UDP_PORT); 

seraddr.sin_addr.s_addr = inet_addr("192.168.1.12"); 

 

setsockopt(udp_socket, SOL_SOCKET, SO_SNDBUF, (const char*)&tx_buffer_size, sizeof(tx_buffer_size)); 

 

if ((bind(udp_socket, (struct sockaddr *)&cliaddr, sizeof(cliaddr))) < 0) 

alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE,"[sss_task] Bind failed"); 

 

printf("[sss_task] Simple Socket Server listening on port %d\n", UDP_PORT); 

 

while(1) 

// printf("t\n"); 

/***** Problem here, l will be -1 for the first several seconds *****/ 

l = sendto(udp_socket, data, 100, 0, (struct sockaddr *)&seraddr, sizeof(seraddr)); 

if(l<0) 

printf("%d",l); 

// usleep(100); 

}
0 Kudos
8 Replies
Altera_Forum
Honored Contributor I
62 Views

Are you sure the Ethernet link has already been established when you start the SSS task? 

Probably the driver initialization code sends a PHY reset command, so you need to wait a short time before the link becomes active again whenever you restart your application. 

Do you have some debug printf in your console, showing when autonegotiation is actually performed? 

 

Moreover, what do you mean with 'several seconds' : a few seconds or much longer time? 

You can try to wait longer than this time (with a sleep) before calling sendto: this way you will understand if the problem is related to a needed delay or it's a pathological problem affecting the first packet transmitted.
Altera_Forum
Honored Contributor I
62 Views

Hi Cris, 

 

Thanks a lot for your reply and I fixed the error according to your suggestion. I do have another problem now: Am I able to send the packet faster? The current data rate obviously is not satisfying. If I do not want to change SOPC, is there anything I can do to increase the data rate? 

 

Thanks!  

 

 

--- Quote Start ---  

Are you sure the Ethernet link has already been established when you start the SSS task? 

Probably the driver initialization code sends a PHY reset command, so you need to wait a short time before the link becomes active again whenever you restart your application. 

Do you have some debug printf in your console, showing when autonegotiation is actually performed? 

 

Moreover, what do you mean with 'several seconds' : a few seconds or much longer time? 

You can try to wait longer than this time (with a sleep) before calling sendto: this way you will understand if the problem is related to a needed delay or it's a pathological problem affecting the first packet transmitted. 

--- Quote End ---  

Altera_Forum
Honored Contributor I
62 Views

What's your current data rate? 

You should now have a figure far above 1Mbyte/s without any particular optimization. 

 

For performance, remind that every sendto call will send a separate UDP packet which includes some header overhead (42 bytes), so you optimize the speed by increasing the data payload. 

Ideally the best situation would be calling sendto with such a data length that the full packet lenght is used. For an Ethernet link, the maximum packet size is 1536 bytes, so you can transmit up to 1536-42 bytes of payload at once. If you exceed this quota by a single byte, then a new UDP packet has to be generated, thus adding more 42 bytes.
Altera_Forum
Honored Contributor I
62 Views

Hi Cris, 

 

As you said, the packets I sent were 1400 bytes, leading to the data rate of arround 15Mbps. So do you have any suggestion to dump these data from NIOS to FPGA logic cell? I used to use PIO but seems not very promising. 

 

Thanks 

 

 

--- Quote Start ---  

What's your current data rate? 

You should now have a figure far above 1Mbyte/s without any particular optimization. 

 

For performance, remind that every sendto call will send a separate UDP packet which includes some header overhead (42 bytes), so you optimize the speed by increasing the data payload. 

Ideally the best situation would be calling sendto with such a data length that the full packet lenght is used. For an Ethernet link, the maximum packet size is 1536 bytes, so you can transmit up to 1536-42 bytes of payload at once. If you exceed this quota by a single byte, then a new UDP packet has to be generated, thus adding more 42 bytes. 

--- Quote End ---  

Altera_Forum
Honored Contributor I
62 Views

hi mickey 

I'm not sure I understand your request. 

Do you want to increase the 15Mbps figure or are you asking a way to transfer Ethernet UDP data to and from another fpga device? 

If it's the second one, please explain better what you need.
Altera_Forum
Honored Contributor I
62 Views

Hi Cris, 

 

Sorry I didn't make it clear. What I mean is after the Ethernet UDP packet(char data[1400]) is received in SSS, how should I offload these data to the FPGA so that my Verilog code can do further process for these data? (for instance, my verilog code has an input 

input [7:0] eth_data 

how will this input get the data[1400] received in Nios?) 

 

I used to use 9bit PIO and IOWR to transmit these data, but the data rate and stability seems not satisfying. 

 

Please give me some idea! 

 

Thank!  

 

 

--- Quote Start ---  

hi mickey 

I'm not sure I understand your request. 

Do you want to increase the 15Mbps figure or are you asking a way to transfer Ethernet UDP data to and from another fpga device? 

If it's the second one, please explain better what you need. 

--- Quote End ---  

Altera_Forum
Honored Contributor I
62 Views

As you realized, PIO is definitely a very inefficient way to transfer data. 

A common solution is wrapping your code into an Avalon MM slave interface and then using dma to transfer data. In this way your cpu only needs to initiate the dma transfer upon reception of the udp packet, then it is free for other task while the transfer is going on. 

If you don't like a MM slave you can implement in your Verilog a serial interface (e.g. spi) and again use dma to transfer data. 

However, I guess you now use PIO as a parallel bus with 8bit data and a write signal; then the MM slave solution is quite straightforward with minimal effort.
Altera_Forum
Honored Contributor I
62 Views

You can offload the data from Rx to a hardware path, like in this example: 

 

http://www.alterawiki.com/wiki/nios_ii_udp_offload_example
Reply