【发布时间】:2016-05-10 14:18:18
【问题描述】:
我有一个机器人在 Beaglebone Black 上的 PREEMPT-RT 修补 Linux 操作系统上运行具有实时优先级的控制代码。所有代码都是用 C 语言编写的,运行频率为 500Hz。
在运行代码时,我经常注意到几百毫秒范围内的延迟,我已将其追踪到我编写的数据记录函数。这种延迟导致我的机器人控制失败,因为我有很多取决于实时功能。
代码的相关部分如下。为了清楚起见,我已经删减了很多代码,但如果需要,我会编辑这篇文章。
FILE *file;
int main(int argc, char** argv) {
file = fopen(logname, "w");
while (1) {
/* Control code stuff*/
logData();
time_msec = time_msec + controlLoopTime;
}
}
void logData() {
if (time_msec - logTimer_msec >= LOG_TIMER) {
logTimer_msec = time_msec;
if (!bLogCreated) {
fprintf(file,
"SensorData1 SensorData2 SensorDataN"
);
bLogCreated = TRUE;
}
// log data to file
fprintf(file,
"%.2f %.2f\n",
sensorData1, sensorData2, sensorDataN
);
}
}
我需要以良好的速率(可能是 100-125Hz)记录来自多个变量(可能是 20-50)的数据。不需要以控制速率(每 2 毫秒)记录数据,但我已将其减少到 12 毫秒,但我仍然每隔几分钟就会看到延迟峰值。
fprintf 调用可能存在延迟问题。这是 BeagleBone Black、我的代码的限制,还是仅仅是数据记录的性质?
这里提出了一个类似的问题,但似乎没有解决我的问题:Finding latency issues (stalls) in embedded Linux systems
【问题讨论】:
-
默认情况下,非 tty 文件句柄是块缓冲的。所以在
fprintfing 4096 字节之后,缓冲区将被刷新到磁盘,这可能会导致延迟。您不能将实际的日志记录外包给一个单独的线程吗?将日志消息排队并在您的日志线程中出列。 -
这段代码是否作为正常进程的一部分运行?它是否控制任何会阻塞设备驱动程序的互斥锁、信号量等?
-
@jekso:创建一个日志记录 (p) 线程,并使用双链表之类的东西作为队列(头部入队,尾部出队)和 pthread_cond_wait/notify 来发出新条目的信号。跨度>
-
@wallyk 据我了解您的问题,此代码不会阻止任何设备驱动程序。这是我正在运行的唯一会写入内存的进程。如果需要,我可以发布更多相关的代码部分。
-
代码是否进行任何其他与系统相关的调用(如 open、close、gettimeofday 等)?我们不需要看逻辑,只看它与系统的交互。显而易见的问题是记录器如何获取它正在记录的数据?
标签: c real-time embedded-linux latency preempt-rt