我有一个机器人运行控制代码,在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)的数据。不需要以控制速率(每2ms)记录数据,但我将其减少到12ms,并且我仍然每隔几分钟看到延迟峰值。
延迟可能是fprintf
电话的问题。这是BeagleBone Black的限制,我的代码,还是数据记录的本质?
此处也提出了类似的问题,但似乎没有解决我的问题:Finding latency issues (stalls) in embedded Linux systems
答案 0 :(得分:2)
使用for (var i = 1; i <= 7; i++) {
var date = new Date();
date.setDate(date.getDate() + i);
$("body").append("<div id='day" + i + "'>" + ("0" + date.getDate()).slice(-2) + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + date.getFullYear() + "</div>");
}
是一个巨大的时间汇,特别是对于R / T日志记录。以二进制记录并编写实用程序以便稍后打印出来。
而不是:
fprintf
执行:
fprintf(file,"%.2f %.2f %.2f",data1,data2,data3);
更好:
fwrite(&data1,sizeof(double),1,file);
fwrite(&data2,sizeof(double),1,file);
fwrite(&data3,sizeof(double),1,file);
如果它仍然太慢,请将结构附加到一个响铃队列并让一个单独的线程写出条目。
如果磁盘写入无法跟上[now]二进制数据,请保留环形队列,并且只有在检测到致命错误时才会丢弃队列中的队列
另外,考虑在写入时使用struct data {
double data1;
double data2;
double data3;
time_t event_time;
...
};
struct data data;
fwrite(&data,sizeof(struct data),1,file);
来访问文件。在这里查看我的答案[带基准]:read line by line in the most efficient way *platform specific*