我想运行间隔为5毫秒的计时器。我创建了一个Linux计时器,当调用sigalrm_handler
时,我正在检查上次调用的已用时间。我得到的时间如下:4163,4422,4266,4443,4470 4503,4288微秒,当我希望间隔大约为5000微秒时,可能的误差最小。我不知道为什么这个间隔不是恒定的,但是它变化并且远低于应该的间隔。
这是我的代码:
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();
}
答案 0 :(得分:1)
我想运行间隔为5毫秒的计时器。
你可能无法可靠,因为它小于合理的PC硬件可以处理的。
作为经验法则,50 Hz(或者可能是100Hz)可能是您可以获得的最高可靠频率。它不是软件问题,而是硬件问题。
考虑一下典型的处理器缓存(几兆字节)。你可能需要几毫秒来填充它。或者想一想处理页面错误的时间;它可能需要超过一毫秒。
英特尔爱迪生不是一款速度最快的处理器。如果将数字转换为字符串并在某个屏幕上显示该字符串可能需要大约一毫秒(但我让你去检查),我不会感到惊讶。这可以解释你的数字。
关于软件,另请参阅time(7)(或者在内核中考虑一些busy waiting方法 ;我不建议这样做。
通过在shell中运行一些/proc/interrupts
命令,多次查看cat /proc/interrupts
(参见proc(5))。您可能会发现内核的中断频率低于每一秒或几毫秒一次。
BTW您的信号处理程序调用非异步信号安全函数(undefined behavior也是如此)。阅读signal(7)& signal-safety(7)
所以看起来你的整个方法都是错误的。
也许你想要一些RTOS,至少如果你需要一些硬real-time(然后,你可能会考虑将你的硬件升级到更快,更昂贵的东西)。