我有一个任务链接到Posix定时器(timer_create()),每20毫秒/ 50赫兹执行一次。 大部分工作正常,除了每334.5秒(大约)定时器执行一个周期提前10毫秒。 对于接下来的334.5-ish秒,间隔又是20ms。
我已经包含了configuration定时器的相关代码。 该应用程序在Gumstix的默认版本的Linux上运行Gumstix Verdex Pro XL6P。 我也有它预定的FIFO调度algorithm。
我的直觉说这是一个整数溢出的问题。 也许有什么别的使用相同的信号? 我一直能够重现跳过,在执行和董事会会议。
这个问题不是一个阻碍,但我真的很想明白为什么会这样。
这里是configuration定时器的代码:
//------------------------------------------------------------------------------ // Create a timer which fires at the specified time and calls a timer event // handler. // // handler : function to be called when the timer expires // us : number of microseconds to add to timer // ms : number of milliseconds to add to timer // sec : number of seconds to add to timer //------------------------------------------------------------------------------ void createTimer(void (*handler)(void), uint32 us, uint32 ms, uint32 sec) { struct sigaction sigact; struct sigevent sigev; timer_t timerid; struct itimerspec itval; struct itimerspec oitval; timer_info_t* newTimer = NULL; // Initialize signalNum. if (timers == NULL) signalNum = SIGRTMAX; if (signalNum < SIGRTMIN) exitWithError("no avaiable signals, unable to create timers"); sigemptyset(&sigact.sa_mask); sigact.sa_flags = SA_SIGINFO; sigact.sa_sigaction = signalHandler; // Set up sigaction to catch signal if (sigaction(signalNum, &sigact, NULL) == -1) exitWithError("sigaction() failed, unabled to creat timers"); // Create the POSIX timer to generate signo sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = signalNum; sigev.sigev_value.sival_ptr = &timerid; long ret = timer_create(CLOCK_REALTIME, &sigev, &timerid); if (ret == 0) { // Prevent overflow in calculation of nsec below. if (ms >= 1000) { sec += (ms / 1000); ms = ms % 1000; } itval.it_value.tv_sec = sec; itval.it_value.tv_nsec = (long)(us * 1000L) + (long)(ms * 1000L * 1000L); // Configure it as a repeat timer. itval.it_interval.tv_sec = itval.it_value.tv_sec; itval.it_interval.tv_nsec = itval.it_value.tv_nsec; if (timer_settime(timerid, 0, &itval, &oitval) != 0) exitWithError("time_settime() error!"); } else exitWithError("timer_create() error!"); newTimer = (timer_info_t*)malloc(sizeof(timer_info_t)); newTimer->timer = timerid; newTimer->handler = handler; newTimer->sigNum = signalNum; newTimer->next = NULL; // Check to see if this is the first time through. if (timers == NULL) { timers = newTimer; atexit(deleteTimers); } else lastTimer->next = newTimer; lastTimer = newTimer; signalNum--; }
提前致谢。
我的猜测是你正在使用ntp,并且正在这些时间间隔中转换时间。 您可以尝试使用CLOCK_MONOTONIC
,但根据http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html也可能会受到影响。