timerarduinointel-edison

Linux timer interval


I want to run a timer with interval of 5 ms. I created a Linux timer and when a sigalrm_handler is called I'm checking elapsed time from a previous call. I'm getting times like: 4163, 4422, 4266, 4443, 4470 4503, 4288 microseconds when I want intervals to be about 5000 microseconds with a least possible error. I don't know why this interval is not constant but it varies and is much lower than it should be.

Here is my code:

static int time_count;  
static int counter;  
struct itimerval timer={0};  


void sigalrm_handler(int signum)  
{  
  Serial.print("SIGALRM received, time: ");  
  Serial.println(micros()-time_count);  
  time_count=micros();  
}  


void setup() {  
  Serial.begin(9600);   
  timer.it_value.tv_sec = 1;  

  timer.it_interval.tv_usec = 5000;  

  signal(SIGALRM, &sigalrm_handler);  
  setitimer(ITIMER_REAL, &timer, NULL);  
  time_count = micros();  
}  

Solution

  • I want to run a timer with interval of 5 ms.

    You probably cannot get that period reliably, because it is smaller than a reasonable PC hardware can handle.

    As a rule of thumb, 50 Hz (or perhaps 100Hz) is probably the highest reliable frequency you could get. And it is not a matter of software, but of hardware.

    Think of your typical processor cache (a few megabytes). You could need a few milliseconds to fill it. Or think of time to handle a page fault; it probably would take more than a millisecond.

    And Intel Edison is not a top-fast processor. I won't be surprised if converting a number to a string and displaying that string on some screen could take about a millisecond (but I leave you to check that). This could explain your figures.

    Regarding software, see also time(7) (or consider perhaps some busy waiting approach inside the kernel; I don't recommend that).

    Look also into /proc/interrupts several times (see proc(5)) by running a few times some cat /proc/interrupts command in a shell. You'll probably see that the kernel gets interrupted less frequently than once every one or a few milliseconds.

    BTW your signal handler calls non-async-signal-safe functions (so is undefined behavior). Read signal(7) & signal-safety(7).

    So it looks like your entire approach is wrong.

    Maybe you want some RTOS, at least if you need some hard real-time (and then, you might consider upgrading your hardware to something faster and more costly).