FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
6673 Discussions

Need some tips reagarding the sss example

Altera_Forum
Honored Contributor II
1,463 Views

Hi, 

 

I need some tips regarding the simple socket server example. I'm trying to write som data to the ddr2 sdram and so far I have only modified the functions sss_handle_receive() and sss_exec_command(). It seems to work well when I just send a few bytes. The problem arise when I try to send like 1 KB of data. It actually writes the data to the memory, but the recv() function never returns if I try to send more data after this. I'm not much of a SW guy, so if anyone have a clue of what the problem is, I would be most appreciative. 

 

Regards
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
781 Views

The standard version of sss wait for a carriage return character before calling sss_exec_command(). 

Since the rx buffer has a size of SSS_RX_BUF_SIZE (normally defined 1500), I think that some data is discarded if you send more than SSS_RX_BUF_SIZE bytes without a cr character; this if you use the example without any software change in sss_handle_receive(). 

I also started with the sss example and modified it in order to forward data received. I can transmit big data sizes without losing any. 

 

Regards 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

Hi Cris, 

 

Thanks for the reply. I have redefined the rx buffer to 4000, so I don't fill up the buffer. I send a cr character to call the sss_exec_command() before the buffer is full. Doesn't the memset() function clear the buffer of all the data you have read? 

 

Regards
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

Yes. The group of instructions ending with the memset() will free your rx buffer in order to accept more data, but the free space you get depends from how much rx data you can process. 

I mean that maybe your problem is due to the fact the sss_exec_command() can't process data at the rate it arrives. 

Some questions which can help to identify the problem: 

Do the communication fail immediately or after a while? 

Do you have a bottleneck in your sss_exec_command() function? 

Do you send back anything after you have processed the command? 

Have you checked if your buffer gets full? (for example I used to set a pio output or LED if free_rx_space= SSS_RX_BUF_SIZE-(conn->rx_wr_pos-conn->rx_buffer) drops below a certain threshold) 

 

You may also replace code in your sss_handle_receive() with this simple echo test, in order to test if the overall connection is working. In this way you exclude possible problems in command processing and in buffer management. 

 

while(conn->state != CLOSE) { 

rx_code = recv(conn->fd, conn->rx_buffer, SOCKET_RX_BUF_SIZE, 0); 

if (rx_code <= 0) { 

conn->state = CLOSE; 

break;  

bytes_to_process = rx_code; 

memcpy(tx_buf, conn->rx_buffer, bytes_to_process); 

if (send(conn->fd, tx_buf, bytes_to_process, 0) < 0) 

conn->state = CLOSE;; 

 

 

Regards 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

The communication fails after a while, but it seems to fail at a certian point. I have a Matlab function which transmits 1400 bytes. I'm able to transmit these bytes correctly two times, but something always goes wrong when I try to send these bytes a third time. My sss_exec_command function is as follows: 

 

void sss_exec_command(SSSConn* conn) { int free_rx_space; int bytes_to_process = conn->rx_wr_pos - conn->rx_rd_pos; while(bytes_to_process--) { IOWR_32DIRECT(DDR2_SDRAM_BASE, sdram_addr, *(conn->rx_rd_pos)); sdram_addr++; conn->rx_rd_pos = conn->rx_rd_pos + 2; bytes_to_process--; } free_rx_space = SSS_RX_BUF_SIZE-(conn->rx_wr_pos-conn->rx_buffer); counter = counter + 1; if (teller >= 255) { printf("Free buffer space: %d \n", free_rx_space); counter = 0; } return; }  

 

I don't send back anything, and as you can see from the code above I tried to look at the free buffer space. It printed out the same number every time, 218. I also tried your echo test and it worked fine. Did you have to make changes in other methods than the sss_exec_command() and the sss_handle_recieve() ?
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

The code seems to be correct, provided the direct access to memory doesn't corrupt any data (are code/stack/etc. stored on ddr2, too?) 

I'm concerned about the 218 value you get for the free buffer space. 

Since your sss_exec_command function immediately processes ALL the recvd data you should always have: conn->rx_wr_pos-conn->rx_buffer<=1400 

If you set SSS_RX_BUF_SIZE to 4000, you MUST have free_space>=2600 

Probably you have an error in the handle_receive function, where the buffer is managed and used data is released. Did you modify the template code? 

 

Anyway, since you process immediately all the received data there's a much more efficient way to do this job. 

You don't need the standard code with rd and wr pointers in the rx buffer, but you can simply use a plain rx buffer >1400 bytes long, like in the previous echo example. After the recv(), you copy it directly to you memory. 

This is what I indeed use and it's much efficient, safer and faster. 

 

Regard
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

I have discovered that my program/stack/heap etc. are all stored on the ddr2. How do I know which addresses Nios use in the ddr2? Is it recommended to keep this on a different memory? Thanks for the help so far.  

 

Regards
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

 

--- Quote Start ---  

I have discovered that my program/stack/heap etc. are all stored on the ddr2. How do I know which addresses Nios use in the ddr2? Is it recommended to keep this on a different memory? Thanks for the help so far.  

 

--- Quote End ---  

 

 

Solution 1 

In order to choose where your program sections (code/stack/etc.) are loaded into ddr2 you must use a custom linker script, but I've never used it with Nios IDE, so I can't tell you how to do it. 

 

Solution 2 

If you have another memory device, you can move there all program sections: open your system library project properties and you'll find where each section is mapped to, and possibly can move it. 

 

Solution 3 (best) 

Anyway, instead of using IOWR_32DIRECT I'd rather alloc a memory buffer and I'd use it to write data: the linker will automatically adjust addresses and will avoid it overlaps other memory sections. 

Example: 

char bigbuffer[BIG_BUFFER_SIZE]; 

while(bytes_to_process--) { 

bigbuffer[sdram_addr++] = *(conn->rx_rd_pos)); 

conn->rx_rd_pos = conn->rx_rd_pos + 1; 

/* this avoids memory corruption when your memory gets filled */ 

if (sdram_addr >= BIG_BUFFER_SIZE) 

sdram_addr = 0;  

 

Hope this will help you 

 

Regards 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

Hi, I'm working with rastafari on this project and have the same problem. 

 

I'm looking into your solution 3 with the memory buffer, instead of writing directly to the SDRAM. Will the linker utilize the SDRAM for storing the buffer? We are trasmitting images from the pc, so the buffer needs to contain up to 1920x1080 8-bit pixelvalues. Are there any problems with using a buffer of this size? 

 

Thanks for your help, it's greatly appreciated.
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

 

--- Quote Start ---  

 

I'm looking into your solution 3 with the memory buffer, instead of writing directly to the SDRAM. Will the linker utilize the SDRAM for storing the buffer? We are trasmitting images from the pc, so the buffer needs to contain up to 1920x1080 8-bit pixelvalues. Are there any problems with using a buffer of this size? 

--- Quote End ---  

 

 

I just tested this in my project with a 2000x4000 char buffer and I hadn't any problem.  

I recommend to define the buffer as a global variable or as static variable inside the function, otherwise I think the compiler would try to allocate it runtime on the stack! 

 

To be sure the buffer resides in sdram, open the system Library properties and make sure that sdram (or whatever name you used in sopc builder for ddr2) is selected for r/w data memory section.
0 Kudos
Altera_Forum
Honored Contributor II
781 Views

Thanks for your help. Solution 3 did the trick. The problem was obviously overwriting of some important stuff.

0 Kudos
Reply