【问题标题】:Linux timer intervalLinux 定时器间隔
【发布时间】:2018-03-11 14:12:07
【问题描述】:

我想运行一个间隔为 5 毫秒的计时器。我创建了一个 Linux 计时器,当调用 sigalrm_handler 时,我正在检查上一次调用的经过时间。当我希望间隔约为 5000 微秒且误差最小时,我得到的时间如下:4163、4422、4266、4443、4470 4503、4288 微秒。我不知道为什么这个间隔不是恒定的,而是变化的,而且远低于应有的值。

这是我的代码:

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();  
}  

【问题讨论】:

  • 我不明白这个问题,如果你已经让你的计时器工作了会有什么问题?顺便说一句,你能提供一个最小的工作代码块吗?
  • 间隔不是恒定的。它变化多端,远低于 5000 微秒。
  • 编辑您的问题,解释为什么 5 毫秒时间对您如此重要。

标签: timer arduino intel-edison


【解决方案1】:

我想运行一个间隔为 5 毫秒的计时器。

您可能无法可靠地获得该周期,因为它比合理的 PC 硬件可以处理的要小。

作为 经验法则,50 Hz(或者可能是 100Hz)可能是您可以获得的最高可靠频率。而且这不是软件问题,而是硬件问题。

想想您的典型处理器缓存(几兆字节)。您可能需要几毫秒来填充它。或者考虑处理页面错误的时间;这可能需要超过一毫秒。

而且英特尔爱迪生并不是一款速度最快的处理器。如果将数字转换为字符串并在某个屏幕上显示该字符串可能需要大约一毫秒(但我让你检查一下),我不会感到惊讶。这可以解释你的数字。

关于软件,另见time(7)(或者考虑一些busy waiting 方法在内核中;我不建议这样做)。

还可以通过在 shell 中运行几次cat /proc/interrupts 命令来多次查看/proc/interrupts(参见proc(5))。您可能会看到内核被中断的频率低于每毫秒或几毫秒一次。

顺便说一句,您的信号处理程序调用非异步信号安全函数(undefined behavior 也是如此)。阅读signal(7)signal-safety(7)

所以看起来你的整个方法都是错误的。

也许你想要一些RTOS,至少如果你需要一些硬的real-time(然后,你可能会考虑将你的硬件升级到更快、更昂贵的东西)。

【讨论】:

    猜你喜欢
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多