Forum Discussion
cal_uart(with fifo) + NIOSserial.c
As we know, we need uart with fifo to enchance the performance. So we got the cal_uart from Altera, which should tested by ourselves because it is not provided officially by altera.
Now we use cal_uart with 16 byte rx_fifo, 16 byte tx_fifo. We hope the fifo is transparent to linux driver, so the linux driver is still NIOSserial.c, which we changed nothing. But we got : 0. U-boot access the UART sucessful during rx, tx. We think U-boot using pool methed. Is it right? 1. tx data is successful 2. rx data is abnormal. After linux startup, linux will reboot immediately after we receive any data by cal_uart. 3. We try to debug NIOSserial.c using printk . Is it right way to debug in UART driver? thank u in advance.23 Replies
- Altera_Forum
Honored Contributor
Kernel did crased before we modified the FIFO_UART HDL. Kernel started, recevied some datas , crashed and rebooted automaticlly.
You'd better debug tty using JTAG as Console like hippo said. Post some debug information here. Although I am not good at SW, but so many other NIOSII GODs here, haha. - Altera_Forum
Honored Contributor
Hi trk_golf,
Is it possible for you to post the modifications to the Verilog to have the interrupts working correctly (I mean with better performance than the altera_avalon_uart, and no kernel crash) ? Thanks in advance, Best regards Pierre-Olivier - Altera_Forum
Honored Contributor
I am struggling to use CAL_AVALON_UART with uClinux, but only get about 16 chars out before it falls in a heap. As Pierre-Olivier says, it would be wonderful if someone has figured out how to make this work, and could post details http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif
- Altera_Forum
Honored Contributor
Please send your UART testing c file to me , and I tested it what's happen.
[email protected] Then I could post all things in details. - Altera_Forum
Honored Contributor
Dear smalllight,
I actually did not make any testing C file. All I did was a cat /dev/ttyS0 (set to 115200 bauds with stty). Then with minicom on my computer, I send about 5k of data (copy/paste in the minicom teminal). With that test it crashes quite fast. Another test was typing some charcters one by one in the terminal. I did not get anything in the cat /dev/ttyS0 until 64 chars were received (64 is the FIFO length). It works 3 or 4 times, then the system crashes. Thank you for taking some time for this. Best regards, Pierre-Olivier - Altera_Forum
Honored Contributor
Some more details :
I made some new tests with the cal_uart. I don't get any more uClinux crash (don't know why...), but I still get the poor performances of altera_avalon_uart. When I just do a "cat /dev/ttyS0 > /tmp/file &" (/tmp/file is on a ramfs), and that I send lots of characters (10k) from my computer, and that I read the size of /tmp/file, I can see it is not the right size, and that the size is different evrytime I try this. This is exactly what I had with the altera_avalon_uart, except that now I don't receive the "ttyS0 : xx characters overrun". It seems to be normal because we don't take advantage of the FIFO. Could you tell me how to change this ? Thanks a lot, Pierre-Olivier - Altera_Forum
Honored Contributor
I’m Mountain8848 from China([email protected]), and I posted the last post using my colleague's account —smalllight by mistake.
However I received both of your email---- cetic and hootsmon. ------------------------------------------------------------------------------ To hootsmon: I compare your NIOSSerial.c with original one, and find you modified it. I guess the reason of it: After we use cal_uart, during *.ptf to nios2_system.h the cal_uart module is not regarded as a UART class, so nios2_system.h misses below codes:
Maybe you modified NIOSSerial.c in order to compile successfully. I don’t know if it is the problem. NOTICE: 1. I just chang uart to cal_uart with 16byte rx_fifo, 16byte tx_fifo, which should be modified to avoid irq error as: <cal_uart>/uart_pm.pl:l1933:rx_char_ready to rx_not_empty; regenenate in sopc; recompile in quartus 2. cal_uart’s document was said cal_uart should transparent with software. SO nothing was changed in NIOSSerial.c/ NIOSSerial.h. and nios2_system.h , which was generated with uart ones 3. kernel menuconfig: enable UART driver and UART console ------------------------------------------------------------------------------ To cetic: I tested cal_uart and uart in my custom board as your method./* Executing ...scripts/nios2_system.h/altera_avalon_uart.pm */# ifndef __ASSEMBLY__# include <asm/uart_struct.h># endif /* The default uart is always the first one found in the PTF file */# define nasys_printf_uart na_uart0
I sent about 30 chars to cal_uart and uart. 1. per 100ms per 30 chars both uarts lost chars 2. per 200 ms per 30 chars cal_uart is OK, while uart still lost chars 3. send 3KB file to them, if I send quickly both cat process will be terminated abnormal, however the kernel still work fine. BTW, The size of /tmp/file is always smaller then the one of the send file. I am still a newbie in uClinux, I don’t know why. Maybe you should send your datas one packets by one packets to let little Nios have a brake :-) ------------------------------------------------------------------------------ After you give the good news I am very interested to put FIFO_UART to "Post Your Own IP".Cat /dev/ttyS0 > /tmp/file & - Altera_Forum
Honored Contributor
Hi mountain8848,
I am currently making some performance tests on the cal_uart. As you said, there is a (small) performance gain when using the cal_uart but it is not big. I will start modifying the HDL code of the uart to generate the interrupt when the FIFO is half full or 75% full, I will post the results here as soon as it is done. Regarding the post of the files in the 'Post your own IP' section, you should be careful of where the SOPC builder component comes from...do we have all rights on it ? From what I know it is not officially released and it comes from someone inside Altera. Maybe you know more than I do about it, but I would not dare positng it without the authorization of the initial author (that I don't know...). Anyway, lots of thanks for your help, Best regards, Pierre-Olivier - Altera_Forum
Honored Contributor
Thank you very much! I learn much from you!
Best Regards! FeiWu - Altera_Forum
Honored Contributor
Hi all,
here is some good news for those who want a better performance on UART, based on cal_uart. I could achieve a 1MBytes transfer at 115200 bps with no errors when "cat /dev/ttyS0 > /tmp/file&" is the only user task I run (Nios2\s at 72MHz). I get ~1% error on 1MBytes transfer when running several daemons at the same time. I did it with a 64 bytes FIFO and I had the same performances with a 1024 bytes FIFO. To do this I modified the VHDL file generated by cal_uart to change the rx irq conditions. The interrupt is requested when FIFO is 50% full or if bytes are present in buffer after a delay (so that even if FIFO never gets 50% full, bytes can be read). I still have some questions about this : - I don't know anything about the scripts that generate the VHDL from the SOPC builder .ptf file. Can someone tell me where I should add my code so that it is generated in the cal_uart component ? Is this in the em_uart.pl script ? Is there any documentation on how to use this kind of scripts ? For now I have to modify the VHDL file after generating the SOPC builder components, this is not very elegant (see below)... - To adjust performance, I can play with 3 parameters : FIFO size, FIFO level to request IRQ (50% full, 75% full....) and the timer delay. I tried with 64 bytes FIFO, 50% full and 7ms delay. Does anyone have an idea of the parameters commonly used in other FIFO'ed uarts ? If someone is interested, here is the small modifications to do to the uart_ext.vhd file generated when using a cal_uart at 115200 bauds, 8N1, RTSCTS enabled, baudrate divisor writeable, and a 64 bytes FIFO : At line 1288, replace
bysignal tx_not_empty : STD_LOGIC; signal tx_not_full : STD_LOGIC; signal tx_overrun : STD_LOGIC; signal tx_used : STD_LOGIC_VECTOR (5 DOWNTO 0);
At line 1541, replacesignal tx_not_empty : STD_LOGIC; signal tx_not_full : STD_LOGIC; signal tx_overrun : STD_LOGIC; signal tx_used : STD_LOGIC_VECTOR (5 DOWNTO 0); signal rx_counter : STD_LOGIC_VECTOR (18 DOWNTO 0); signal rx_fifo_timeout : STD_LOGIC;
byqualified_irq <= ((((((((((ie_dcts AND dcts_status_bit)) OR ((ie_any_error AND any_error))) OR ((ie_tx_shift_empty AND tx_shift_empty))) OR ((ie_tx_overrun AND tx_overrun))) OR ((ie_rx_overrun AND rx_overrun))) OR ((ie_break_detect AND break_detect))) OR ((ie_framing_error AND framing_error))) OR ((ie_parity_error AND parity_error))) OR ((ie_rx_char_ready AND x_not_empty))) OR ((ie_tx_ready AND tx_not_full));
I hope someone can help me automate this :-) Any comments or help welcome. Regards Pierre-Olivierqualified_irq <= ((((((((((ie_dcts AND dcts_status_bit)) OR ((ie_any_error AND any_error))) OR ((ie_tx_shift_empty AND tx_shift_empty))) OR ((ie_tx_overrun AND tx_overrun))) OR ((ie_rx_overrun AND rx_overrun))) OR ((ie_break_detect AND break_detect))) OR ((ie_framing_error AND framing_error))) OR ((ie_parity_error AND parity_error))) OR ((ie_rx_char_ready AND (rx_used(5) OR rx_fifo_timeout )))) OR ((ie_tx_ready AND tx_not_full)); process (clk, reset_n) begin if reset_n = '0' then rx_fifo_timeout <= '0'; rx_counter <= (others => '0'); elsif clk'event and clk = '1' then if std_logic'(clk_en) = '1' then if rx_counter(18) = '1' then if rx_empty = '1' then rx_counter <= (others => '0'); rx_fifo_timeout <= '0'; else rx_fifo_timeout <= '1'; end if; else rx_counter <= rx_counter + 1; rx_fifo_timeout <= '0'; end if; end if; end if; end process;