У меня есть задача, связанная с Posix Timer (timer_create ()), который выполняется каждые 20 мс / 50 Гц.По большей части работает нормально, за исключением каждых 334,5 секунд (приблиз.), Таймер запускается на 10 мс раньше для одного цикла.В течение следующих 334,5 секунд все интервалы снова равны 20 мс.
Я включил соответствующий код для настройки таймера.Приложение работает на Gumstix Verdex Pro XL6P с версией Gumstix по умолчанию для Linux.У меня также это запланировано с помощью алгоритма планирования FIFO.
В моей интуиции сказано, что это проблема целочисленного переполнения.Может быть, что-то еще использует тот же сигнал?Мне постоянно удавалось воспроизводить пропуски между исполнениями и сеансами на плате.
Проблема не в том, чтобы остановить показ, но мне бы очень хотелось понять, почему это происходит.
Вот код для настройки таймера:
//------------------------------------------------------------------------------
// 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--;
}
Заранее спасибо.