3

How can I find the Linux tick rate of my Raspberry Pi 2. I have a Raspberry Pi 2 with Raspbian OS.

Is it 100 or 1000 HZ ? Can I read it from the command line or a C program ?

I want to know this value because I am using some timers which need precision.

Reference: http://www.makelinux.net/books/lkd2/ch10lev1sec2 http://elinux.org/High_Resolution_Timers

  • What do you actually want to do? The Linux scheduling tick rate has little relevance to how accurately you can time an event. – joan Sep 23 '15 at 21:31
  • Actually, my goal is to read an input (GPIO) and start a program (ffmpeg) when the input goes high and send a signal (kill) when the input goes low. Ideally, it would be a C programm that uses event instead of polling and it would have debouncing. – ssinfod Sep 24 '15 at 2:17
  • So in effect you want to know GPIO interrupt latency. Provided the events are more than a few, say 50, µs apart then you can expect a latency of about 50-70 µs before a C based user process is informed of the GPIO level change. – joan Sep 24 '15 at 6:16
2

I want to know this value because I am using some timers which need precision.

The precision of timers is not constrained by HZ or USER_HZ (see man 7 time); you've probably looked at /proc/timer_list by now and recognized there is a nanosecond resolution timer in the kernel, whereas USER_HZ is normally 100 or 1000 and HZ is 100 or 250. There's also CLOCKS_PER_SEC in userspace, which is stipulated by POSIX to be 1000000 and is used by clock().

#include <stdio.h>            
#include <time.h>             
#include <unistd.h>           

int main (void) {             
    printf (                  
        "%d %d\n",            
        sysconf(_SC_CLK_TCK),  // A.k.a USER_HZ
        CLOCKS_PER_SEC        
    );                        
    return 0;                 
}

Again, USER_HZ and HZ are probably irrelevant to your purposes. The normative way to time an event is via clock() (or the newer clock_gettime(), see below) or gettimeofday(), which also has microsecond resolution. It should be pretty accurate; although the latency of system calls on a multitasking OS may be a factor, you should still at least get a precise measurement in milliseconds.

Latency for sleep operations is greater, so despite the existence of nanosleep(), don't bother with anything finer than milliseconds and don't expect that to always be bang on either (I believe this is the point where HZ comes into play, as it determines the granularity of the scheduler).

You can experiment with this by arranging sleeps and measuring the actual time elapsed. Here's an example using clock_gettime(), which uses the nanosecond resolution clock on the pi. Note this may have to be compiled:

gcc --std=gnu99 test.c

Since this clock function is a POSIX extension.

#include <stdio.h>                                             
#include <stdlib.h>                                            
#include <time.h>                                                                                          

// std=gnu99                                                   

#define TEST_CLOCK CLOCK_REALTIME                              

int main (int argc, char* const argv[]) {                      
// Get duration.                                               
    unsigned long long duration = 2500000000;                  
    if (argc > 1) {                                            
        char *check;                                           
        unsigned long long n = strtoull(argv[1], &check, 0);   
        if (check != argv[1]) duration = n;                    
    }                                                          
    printf("Duration %llu ns.\n", duration);                   

// Check precision.                                            
    struct timespec ts;                                        
    int check = clock_getres(TEST_CLOCK, &ts);                 
    if (check == -1) perror("Could not determine resolution"); 
    else printf("Clock resolution %ld ns.\n", ts.tv_nsec);     

// Time a sleep.                                               
    ts.tv_sec = duration / 1000000000;                         
    ts.tv_nsec = duration % 1000000000;                        
    struct timespec start, end;                                
    check = clock_gettime(TEST_CLOCK, &start);                 
    int check2 = nanosleep(&ts, NULL);                         
    int check3 = clock_gettime(TEST_CLOCK, &end);              
    if (check) {                                               
        perror("Starting timer fail");                         
        return 1;                                              
    }                                                          
    if (check2) {                                              
        perror("Sleep fail");                                  
        return 1;                                              
    }                                                          
    if (check3) {                                              
        perror("End timer fail");                              
        return 1;                                              
    }                                                          

// Report.                                                     
    double actual = (double)(end.tv_sec - start.tv_sec);       
    actual += (double)end.tv_nsec / 1000000000.0               
        - (double)start.tv_nsec / 1000000000.0;                
    printf("Elapsed: %lf seconds.\n", actual);                          

    return 0;                                                  
}

I think this is clear; if you don't provide an argument, it will sleep for 2.5 s. If you do, it is interpreted in nanoseconds.

On an intel 64-bit desktop I get an accuracy in the sub millisecond range (variation shows up in the 5th decimal place). On a pi B it shows up in the 4th decimal place.

> ./a.out 5000000000
Duration 5000000000 ns.
Clock resolution 1 ns.
Elapsed: 5.000215 seconds

As always, see the relevant man pages for more explanation.

  • I've added an example including clock_getres(), which will confirm and test the resolution of the high res clock. – goldilocks Sep 24 '15 at 13:54
  • Thanks, I see that my RPI2 has a HZ of 100. I would vote +1 but I don't have enough reputation yet ! – ssinfod Sep 24 '15 at 14:42
  • If it answers your question, please tick the big checkmark at the top -- not just so I get points, but because our "answered questions" ratio is relevant to the site graduating from beta status. – goldilocks Sep 24 '15 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.