mikluz
Posts: 17
Joined: Thu Mar 31, 2016 11:52 am
Location: Szczecin, Poland

How to get most precise timer or sleep function on Raspberry

Tue Apr 26, 2016 1:26 pm

Hi,

I'm using Raspberry Pi 3 @ Raspbian
I've been trying to get the most precise timer or sleep function to achieve around 1-2us (micro seconds) resolution.
I've tried a few approaches and the best I could achieve was around 100-120us

Here is what I tested so far:
1. usleep()

Code: Select all

    const useconds_t usec = 200000;
    clock_gettime(CLOCK_MONOTONIC, &start);
    usleep(usec);    
    clock_gettime(CLOCK_MONOTONIC, &stop);
    
    exec_time = ( stop.tv_sec - start.tv_sec ) + ( stop.tv_nsec - start.tv_nsec ) / 1000000000.0;
    printf("I. Sleep(%d) took time: %f\n", (unsigned int)usec, exec_time);
Output is:
"I. Sleep(50) took time: 0.000137"

2. Using clock()

Code: Select all

   clock_gettime(CLOCK_MONOTONIC, &start);
   const clock_t start_tick = clock();    
   clock_t current_tick = clock();
   clock_gettime(CLOCK_MONOTONIC, &stop);

    printf("II. Current tick - start to: %u\n", (unsigned int)(current_tick-start_tick));
    
    exec_time = ( stop.tv_sec - start.tv_sec ) + ( stop.tv_nsec - start.tv_nsec ) / 1000000000.0;
    printf("II. Sleep took time: %f\n", exec_time);
Output is:
"II. Current tick - start = 3
II. Sleep took time: 0.000030"

3. Using clock_nanosleep()

Code: Select all

    struct timespec deadline;
    clock_gettime(CLOCK_MONOTONIC, &deadline);

    // Add the time you want to sleep
    deadline.tv_nsec += 50000;

    // Normalize the time to account for the second boundary
    if(deadline.tv_nsec >= 1000000000) 
   {
        deadline.tv_nsec -= 1000000000;
        deadline.tv_sec++;
    }
     struct timespec start3, stop3;
    clock_gettime(CLOCK_MONOTONIC, &start3);
    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL);
    clock_gettime(CLOCK_MONOTONIC, &stop3);
    
    exec_time = ( stop3.tv_sec - start3.tv_sec ) + (double)( stop3.tv_nsec - start3.tv_nsec ) / (double)1000000000.0;
    printf("III. clock_nanosleep took time: %f\n", exec_time);
Output is:
"III. clock_nanosleep took time: 0.000109"

1. So, as you see, methods I and III can't be lower than 100us. With method II I think clock_gettime() has some overhead, but I don't know how to figure out: "how many clock() ticks is 1us?".
2. I'm aware I'm compiling and running this code in a user space, so that might be a limitation. The question is how low I can get in the user space? 1us is it too much I expect? Would I get it compiling and running this proc in kernel space as a driver or kernel module?
3. Is there something I'm doing wrong with my implementations? Any hints how to make it more precise?

In the meantime I will try invoking asm nop instructions... I'm wondering what I will get.

Thanks for your advice!
Raspberry Pi 3 @ Raspbian

User avatar
joan
Posts: 14747
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How to get most precise timer or sleep function on Raspb

Tue Apr 26, 2016 1:33 pm

Use a busy wait.

pigpio has the gpioDelay function which uses busy waits for a short delay.

wiringPi's delayMicroseconds does pretty much the same.

They will still be subject to Linux reschedules but the chances are pretty slim.

What are you trying to do? There may be a better method.

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: How to get most precise timer or sleep function on Raspb

Tue Apr 26, 2016 1:59 pm

mikluz wrote: I've been trying to get the most precise timer or sleep function to achieve around 1-2us (micro seconds) resolution.
I've tried a few approaches and the best I could achieve was around 100-120us

You are not going to be able to do what you want; because, the RPi is not an MCU, its a full blown SBC running a truly non pre-emptive multi-user multi-tasking operating system. Not to mention, with an OS that has been optimized to reduce system-wide latency to a minimum. In order to achieve what you are trying to accomplish you would have to shutdown the timer-interrupts, task switching, and general system operation (session based task swapping) so that your precise timing gives you the resolution you want.

This is where combining an MCU with the Raspberry PI is a great idea. Whether you use an Arduino, the Gert-board (with embedded arduino), or make your own AtMega328 based arduino-like MCU, you will get better real-time functioning in your controller than trying to do what an MCU is supposed to do within your RPi. Some folks think that because the RPi has GPIO pins that it can be used in the place of an MCU, and this is simply not true. There are place and projects where the precise timing of the MCU is indispensable.
marcus
:ugeek:

mikluz
Posts: 17
Joined: Thu Mar 31, 2016 11:52 am
Location: Szczecin, Poland

Re: How to get most precise timer or sleep function on Raspb

Tue Apr 26, 2016 2:16 pm

Yeah, I want to write my own implementations on the certain protocols using GPIO ports.

And you see, Raspbian (Linux) can do the trick in the kernel mode and it's working fine (of course bounded with a certain tolerance).

I'm aware of the constraints that operating system has. So, I will probably start writing my own kernel driver/module and will see how quick I can get.

The next step, in the future, will of course be programming some sort of microcontrollers (AVR, STE or so) but I want to do it step by step. First get to know more about Raspbian and GPIO/SPI/I2C programming at the high level, and then I will step down into microcontrollers world :).
Raspberry Pi 3 @ Raspbian

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: How to get most precise timer or sleep function on Raspb

Tue Apr 26, 2016 3:50 pm

Here is some sample Python code that counts in a time.time() based loop:

Code: Select all

from time import time

def ptimer(m, n):
    d=0; c=0; clast=0; tm=time()
    print(" #   timer_value        count_C  delta_C")
    print((d, tm, c))
    while (d<m):
        if (time()-tm >= n):
            tm = time()
            d += 1
            if (d>=2):
                print((d, tm, c, abs(c-clast)))
            else:
                print((d, tm, c,))
            clast=c; c=0
        else:
            c += 1
    return
Put this code above :roll: in a file called ptimer.py and run it in the REPL:

Code: Select all

>>> from ptimer import *
>>> ptimer(22,7)
The loop will iterate 22 times and display the iteration number, the timer value (with some fine granularity), the free running C counter, and the delta C (from the last free running count).

Try it.

You will notice that the timer value drifts very slightly forward (because of when the timer gets reset in the count loop) and that the PI 3B running python2 will count (free running) to about 4.5 million every seven second (in this case)... but, look at the delta C!! ... its all over the place.

Here is a similar counter for BASIC; could run it in Chipmunk BASIC:

Code: Select all

data 9,7
d = 0 : c = 0
read m,n
t = timer
print d,t,c
while d <= m
   if timer-t >= n then 
      t = timer
      d = d+1
      print d,t,c
      c = 0
   else 
      c = c+1
   endif
wend
end
marcus
:ugeek:

User avatar
joan
Posts: 14747
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How to get most precise timer or sleep function on Raspb

Tue Apr 26, 2016 4:18 pm

I'm none the wiser as to why you need precise timing.

You generally would need precise timing to bit bang. But you don't need to bit bang SPI or I2C on the Pi - there are inbuilt hardware peripherals to handle I2C and SPI. You only have to bit bang SPI and I2C on micro-controllers like the Arduino.

mikluz
Posts: 17
Joined: Thu Mar 31, 2016 11:52 am
Location: Szczecin, Poland

Re: How to get most precise timer or sleep function on Raspb

Wed Apr 27, 2016 7:08 am

Thanks joan for replies, and for mentioning pigpio library (I will try that!).

The simple answer to your questions is that I want to write my own implementation of 1-wire protocol. That is why I need precise timing to be able to synchronize with slaves.

Regarding SPI and I2C I will for sure use existing libraries/solutions :)
Raspberry Pi 3 @ Raspbian

User avatar
joan
Posts: 14747
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How to get most precise timer or sleep function on Raspb

Wed Apr 27, 2016 7:34 am

mikluz wrote:Thanks joan for replies, and for mentioning pigpio library (I will try that!).

The simple answer to your questions is that I want to write my own implementation of 1-wire protocol. That is why I need precise timing to be able to synchronize with slaves.

Regarding SPI and I2C I will for sure use existing libraries/solutions :)
Search for posts by danjperron.

search.php?st=0&sk=t&sd=d&sr=posts&author=danjperron

Then search within them for wire.

I think it's fair to say he is the 1-wire guru and has published 1-wire code for the DS18B20 which would be of interest to you.

mikluz
Posts: 17
Joined: Thu Mar 31, 2016 11:52 am
Location: Szczecin, Poland

Re: How to get most precise timer or sleep function on Raspb

Wed Apr 27, 2016 8:25 am

Thanks joan,

I've searched for 1 wire code, and what I could only find was python code for reading temperature. This doesn't satisfy my needs, as I know how to use high level api's for reading sensors' values. I'd rather have a glimpse on somebody's C code that implemented 1 wire protocol.

Today I will try asm instructions, if that fails (which I believe it will), I will swap to the kernel mode and try my strength in there.


Thanks.
Raspberry Pi 3 @ Raspbian

User avatar
joan
Posts: 14747
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: How to get most precise timer or sleep function on Raspb

Wed Apr 27, 2016 8:28 am

mikluz wrote:Thanks joan,

I've searched for 1 wire code, and what I could only find was python code for reading temperature. This doesn't satisfy my needs, as I know how to use high level api's for reading sensors' values. I'd rather have a glimpse on somebody's C code that implemented 1 wire protocol.

Today I will try asm instructions, if that fails (which I believe it will), I will swap to the kernel mode and try my strength in there.


Thanks.
danjperron's code is in C.

mikluz
Posts: 17
Joined: Thu Mar 31, 2016 11:52 am
Location: Szczecin, Poland

Re: How to get most precise timer or sleep function on Raspb

Wed Apr 27, 2016 10:11 am

Yeah, I've found it, though it wasn't easy using search option here :)

Here it is: https://github.com/danjperron/BitBangin ... 8B20Scan.c

I'll be looking at it today.
Thanks!
Raspberry Pi 3 @ Raspbian

petersteier
Posts: 8
Joined: Fri Mar 03, 2017 12:17 pm

Re: How to get most precise timer or sleep function on Raspberry

Tue Oct 03, 2017 6:28 pm

The "problem" with the raspberry compared to a bare microcontroller is the complete operating system; it cares for too many things like keyboard, windows on the screen, and network,...
You get a delay with better resolution with the wiringpi library and delayMicroseconds ()
This delay can be very short, however, it becomes unpredictable if the CPU does somethin else also. It is, however, well suited for learning principles of interface timing. Real projects should go for other solutions.

gtoal
Posts: 113
Joined: Sun Nov 18, 2012 12:02 am

Re: How to get most precise timer or sleep function on Raspberry

Fri Jul 13, 2018 3:09 am

given the recent announcement of the RT kernel branch ( viewtopic.php?f=117&t=206747 ), the answers here might need to be updated, for instance the use of nanosleep rather than usleep

See viewtopic.php?p=384910
https://elinux.org/High_Resolution_Timers
https://wiki.linuxfoundation.org/realti ... yclictest/
https://wiki.linuxfoundation.org/realti ... nd-install
https://wiki.linuxfoundation.org/realti ... aselatency
https://rt.wiki.kernel.org/index.php/Fr ... _Questions

I've been trying to get latency down in order to have a Pi access a VIA in a system with a 1.5MHz clock - running the above cyclictest on the current O/S on a Pi Zero W I've see ave latency of 53nS and worst case of 401nS. Unfortunately for my purposes where I have a 2-phase clock and need to perform GPIO reading and writing within a quarter of a 1.5MHz cycle, i.e. 330ns, I'm not quite there yet.
Last edited by gtoal on Fri Jun 07, 2019 8:55 pm, edited 1 time in total.

JamieDDD
Posts: 5
Joined: Thu Jul 12, 2018 2:31 am

Re: How to get most precise timer or sleep function on Raspberry

Fri Jul 13, 2018 3:59 am

This delay can be very short, however, it becomes unpredictable if the CPU does somethin else also. It is, however, well suited for learning principles of interface timing. Real projects should go for other solutions.
https://www.allicdata.com

Return to “C/C++”