Search code examples
schedulerinterruptrtossimulateisr

Simulate a Hardware Timer Interrupt in C


I want to understand RTOSs better and therefore started implementing a scheduler. I want to test my code, but unfortunately I have no HW lying around right now. What is an easy way to pretend executing an ISR corresponding to timer in C?

EDIT: Thanks to the answer of Sneftel I was able to simulate a timer interrupt. The code below is inspired by http://www.makelinux.net/alp/069. The only thing I am missing is to do it in a nested way. So if the ISR is running another timer interrupt would cause a new instance of the ISR preempting the first one.

#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<signal.h>
#include<sys/time.h>
#include<string.h>

#ifdef X86_TEST_ENVIRONMENT
void simulatedTimer(int signum)
{
  static int i=0;
  printf("System time is %d.\n", i);  
}
#endif

int main(void)
{
  #ifdef X86_TEST_ENVIRONMENT
  struct sigaction sa; 
  struct itimerval timer; 
  /* Install timer_handler as the signal handler for SIGVTALRM.  */ 
  memset (&sa, 0, sizeof (sa)); 
  sa.sa_handler = &simulatedTimer; 
  sigaction (SIGVTALRM, &sa, NULL); 
  /* Configure the timer to expire after 250 msec...  */ 
  timer.it_value.tv_sec = 0;  
  timer.it_value.tv_usec = CLOCK_TICK_RATE_MS * 1000; 
  /* ... and every 250 msec after that.  */ 
  timer.it_interval.tv_sec = 0;  
  timer.it_interval.tv_usec = CLOCK_TICK_RATE_MS * 1000; 
  /* Start a virtual timer. It counts down whenever this process is executing.  */ 
  setitimer (ITIMER_VIRTUAL, &timer, NULL);
  #endif

  #ifdef X86_TEST_ENVIRONMENT
  /* Do busy work.  */
  while (1);
  #endif
  return 0;
}

Solution

  • The closest thing in POSIX terms is probably signal handlers; SIGALRM is fired asynchronously within the process in much the same way that an ISR is. There's significant differences in what's safe to do, though, so I wouldn't go too far with the analogy.