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++

usleep() issue

Altera_Forum
Honored Contributor II
2,141 Views

Hello. 

In this code: 

fprintf(lcd_name, string1); usleep(2000000); fprintf(lcd_name, string2);second string should appear on LCD after 2 sec. But it appears without any delays! 

It's interesting that this code 

printf("a"); usleep(2000000); printf("b");runs right - second string appears in Nios console after 2 sec. 

What's the matter?
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
747 Views

In the first case, you say that the second string appears with no delay. Is there a chance that both strings show up 2 seconds after the routine runs? 

 

My theory is that the usleep is preventing the fprintf code from running. After the usleep expires, both strings are sent to the display. There is an easy way to check this. 

 

printf ("start\n"); usleep(5000000); fprintf(lcd_name, string1); usleep(2000000); fprintf(lcd_name, string2);  

 

With this, you should see the "start" on the console then 7 seconds later (not 5) you should see both strings on the LCD.
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

Your theory is right. 

How to fix it? I need delay before second string. Should I use another delay function? 

 

addition: 

I also try to use the empty loop 

for (i=1 ; i<100000000 ; i++) {}; 

but it doesn't work too.
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

usleep is likely to be implemented as a blocking loop not far different from the for loop.  

On the other hand a true sleep function is supposed to suspend the calling task and release the control to other tasks which possibily run at lower priorities. 

I guess the lcd management driver runs in a lower priority task (or rather in a lower priority isr, if you don't use any OS): then you send the data with fprintf but the driver is not assigned any cpu time until your function has completed. 

 

The solution depends on your application structure. 

If you are using an OS, you should have another sleep "true" function available. 

Also debug into usleep in order to find out how it has been implemented; maybe you can set some project options in order to make it work the proper way. 

If the fprintf and sleep calls are in a isr, make sure it's not a high priority one.
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

I don't use OS on the Nios. 

I wrote my own LCD vhdl driver so I rule LCD using UART (altera_avalon_uart). 'fprintf' transfers string with usual serial protocol. 

I'll try to debug, thanks.
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

Then you must focus on the altera_avalon_uart driver. For sure your fprintf sends the string immediately to the uart HAL driver but data is kept in the transmit buffer until the usleep completes, since this blocking functions prevents the HAL driver from sending data to the actual serial port hardware, as I described above. 

What's your avalon_uart implementation? small or fast? 

If it's the small one, you should have a uart poll call somewhere in a loop: you must place periodic calls to this in the sleep function, too. 

If it's the fast implementation, you probably need to fix irq priorities.
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

Or use a UART with a large enough hardware tx fifo to cover normal lines of debug output and then either discard or spin inside the 'transmit character' function. 

Whatever you do, at some point the decision has to be made whether to 

spin/sleep/discard when the tx buffer is full, having a single hardware fifo and very simple software might actually use the least resource!
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

Hi 

 

my suggestion would be not to use usleep. Instead use the system_clk. For example: 

alt_u32 wait_time = alt_nticks() + xxx; while(wait_time > alt_nticks());Does that make sense?
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

 

--- Quote Start ---  

Hi 

 

my suggestion would be not to use usleep. Instead use the system_clk. For example: 

alt_u32 wait_time = alt_nticks() + xxx; while(wait_time > alt_nticks());Does that make sense? 

--- Quote End ---  

 

 

This wil possibly improve the precision of time delay but it will not solve Hatter's problem: it's still a blocking loop.
0 Kudos
Altera_Forum
Honored Contributor II
747 Views

Maybe the output buffer of fprintf is not flushed until after the second call. Could maybe try to fflush(lcd_name); after the first fprintf.

0 Kudos
Reply