Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12618 Discussions

UART Serial port blocking mode fgetc function not able to fetch required data bytes

Jayeshkumar
Beginner
1,546 Views

Hi,

We have written c code where we are opening the uart serial port in blocking mode and we are using fgetc function to read the data. we are using for loop and if we keep the for loop for 800000 iterations then fgetc functions fetches only 493000 data bytes and then gets hanged and if we use for loop for 400000 iterations then fgetc functions fetches only 230000 data bytes and then gets hanged. Actual our requirement is to read 800000 data bytes through uart serial port but we are unable to achieve it and do not know the issue.

We are using quartus 18.1 and Nios II edition of the same.

Please kindly help us to resolve it

0 Kudos
14 Replies
ShengN_Intel
Employee
1,504 Views

Hi,


Have you use the highest baud rate? If yes probably have to increase iterations in order to read more data bytes.


You need approximately 1300000 iterations to read around 800000 data bytes.


Best Regards,

Sheng

p/s: If any answer from community or Intel support are helpful, please feel free to mark as solution and give Kudos.


0 Kudos
ShengN_Intel
Employee
1,476 Views

Hi,


Let me know if you have any further update or consideration?


Thanks

Best Regards

Sheng


0 Kudos
ShengN_Intel
Employee
1,443 Views

Since there are no feedback for this thread, I shall set this thread to close pending. If you still need further assistance, you are welcome reopen this thread within 20days or open a new thread, some one will be right with you.


0 Kudos
Jayeshkumar
Beginner
1,424 Views

Ok.

We have not used highest baud rate,  and we cannot do it as other peripheral applications will affect. We are using 9600 baud rate

 

From You: You need approximately 1300000 iterations to read around 800000 data bytes.

Can you please explain why it is so? 

 

For time being we have done some work around solution but the core issue still exists and we are not able to get required data using uart serial port in blocking mode using fgetc function. We are using unsigned char array to store the data.

 

0 Kudos
ShengN_Intel
Employee
1,401 Views

Hi,


Check this out https://stackoverflow.com/questions/59106619/writing-to-uart-serial-port-receiving-response-losing-bytes-when-using-nonblo

The response is coming back at 9600 baud, which is likely much slower per byte than one iteration of the loop requires.


Since the baud rate can't be increased, the only way is to increase iterations. Based on previous post:

800000/493000 = 1.62 iterations per byte (approximately)

400000/230000 = 1.74 iterations per byte (approximately)

Average = (1.62+1.74)/2 = 1.68 iterations per byte (approximately)

Iterations to get required data bytes = 800000*1.68 = 1344739 iterations (approximately)

Let me know if you manage to get required data bytes by increasing iterations.


Best Regards,

Sheng

p/s: If any answer from community or Intel support are helpful, please feel free to mark as solution and give Kudos.


0 Kudos
Jayeshkumar
Beginner
1,393 Views

Hi,

I have gone through the link where the issue is with non blocking mode and we are using blocking mode. So it will not apply same to our issue. Please clarify further. 

What i understand that in non-blocking mode the execution of code does not halt and iterations keep running while in blocking mode the iteration does not end unless the byte is received.

Please provide some reference link for blocking mode uart serial port if such issues have come in past.

Thanks,

0 Kudos
ShengN_Intel
Employee
1,383 Views

Hi,

 

I can't find any related past similar issue on blocking mode serial port uart.

May be you can try adding delay to the for loop if don't want to increase baud rate or iterations.

9600 baud rate means 960 bytes per second so meaning one byte takes about 1ms.

It takes about 2 iterations per byte so meaning one iteration runs at 0.5ms.

Therefore probably can add a 0.5ms delay to for loop. delay(0.5); / usleep(500);

Check this link there are some similarities.

 

Or may be can access the uart core directly via status register or control register for flag check this manual  (Page 146).

 

Best Regards,

Sheng

p/s: If any answer from community or Intel support are helpful, please feel free to mark as solution and give Kudos.

 

0 Kudos
ShengN_Intel
Employee
1,344 Views

One more thing is in blocking mode, UART will block if the SW buffer is full. The size of the SW buffer for both RX and TX is set to ALT_AVALON_UART_BUF_LEN of 64 in altera_avalon_uart.h.


0 Kudos
Jayeshkumar
Beginner
1,326 Views

As you are mentioning about SW Buffer, please let us know what are the conditions when it gets Full and how much to increase its size to get our work done?

0 Kudos
ShengN_Intel
Employee
1,311 Views

Buffer len of 64 means it'll get full when it holds 64 bytes of pending transmit or receive data. May be can try reduce the len (must be a power of two) to ensure that buffer always full before a call to read using fgetc. A call to read something will only block when the SW buffer full. The minimum len is two, one did not work.


0 Kudos
Jayeshkumar
Beginner
1,274 Views

Let me explain you what is our application of UART serial communication. In our system there are two H/W boards Board 1 and Board 2. One board(Board 1) is receiving many bytes(8 to 10 lakhs bytes) from external device using serial uart port (in non-blocking mode). This Board1 is receiving from external world and it is receiving exactly what is being sent and there is no issue in this board receiving data from external device. Board 1 now has uart serial communication with Board 2 in the system where Board 1 need to send these (8 to 10 lakhs bytes) data to Board  2 through uart port. Board 1 is using cyclone II fpga and we are using quartus 6 tool and SOPC for developing platform while Board 2 has cyclone iv and we are using quartus 18.1 tool and platform designer to integrate nios and other IPs (like UART etc). We are seeing that if we keep delay of 5ms means usleep(5000) in our source code when we are transmitting data bytes(using IOWR for writing base address of UART and checking status bit if it is clear means if data is read then only writing again on base address) from Board 1 and we are using blocking uart port to receive data bytes in Board 2(without any delay) it takes 32 minutes(too high) to send and receive almost 3.9 lakhs data bytes. 

if we do not keep any delay in source code of board 1 and transmit data then board 2 is able to receive approx 2.4 lakhs data bytes but after that it is getting stucked. There is not dropping of bytes for 2.4 lakhs data bytes but after approx 2.4 lakhs it is not receiving any data byte (at board 2). Board 1 is able to send full 3.9 lakhs and coming out from for loop, whereas board 2 is getting stucked and not coming out from for loop.

As per your previous advise i tried to reduce the buff length from 64 to 2 (in Board 2 source code) but i am not able to see any improvement and also seeing that even after changing and saving the altera_avalon_uart.h file it is not getting reflected in altera_avalon_uart.h file. 

We are thinking to use flow control mechanism(RTS/CTS) in uart ip core and need clarification from you whether it can solve the issue explained here. Please give us reference document for using flow control in UART IP core.

Please let us know your suggestions to come out from this issue. 

0 Kudos
ShengN_Intel
Employee
1,252 Views

Based on your description, seems like is a buffer overflow issue. There are two different types of buffer overrun: hardware and software buffer overrun. Both types of buffer overrun are more likely to happen when transferring continuous streams of large amounts of data across the serial port

Check this https://forum.micropython.org/viewtopic.php?t=6244. Can try to increase the buffer size may be to 128 in altera_avalon_uart.h. I don't understand this part even after changing and saving the altera_avalon_uart.h file it is not getting reflected in altera_avalon_uart.h file. Have you try to move out the file and make changes. Then paste back to original place by allowing permission.

Check also this https://stackoverflow.com/questions/27322048/serial-uart-buffer-overflow-at-high-speed. Obviously flow control mechanism(RTS/CTS) should able to solve the issue. You can refer to this https://www.intel.com/content/www/us/en/docs/programmable/683130/22-1/introduction.html (page 140, 146). You can also refer to this https://community.intel.com/t5/Nios-II-Embedded-Design-Suite/UART-Core-with-CTS-RTS/m-p/81395 and https://community.intel.com/t5/Nios-II-Embedded-Design-Suite/UART-Core-with-CTS-RTS/td-p/81395?profile.language=zh-TW


0 Kudos
ShengN_Intel
Employee
1,218 Views

Hi,


Any further update or consideration?


0 Kudos
ShengN_Intel
Employee
1,184 Views

Since there are no further feedback for this thread, I shall set this thread to close pending. If you still need further assistance, you are welcome reopen this thread within 20days or open a new thread, some one will be right with you.


0 Kudos
Reply