我有以下循环,应该在40Hz以上运行(每次运行之间24ms)。它可以在几秒到几分钟内工作,但随后降至20Hz,因为没有明显的(至少不是我)理由。
我尝试在洋葱Omega 2(运行openwrt)和具有相同结果的ubuntu笔记本电脑上运行代码。 (代码在omega2上降至25Hz,在我的笔记本电脑上降至20Hz)
我如何强制它继续以正确的速度运行?我已经在示波器上检查了输出,并且即使程序受到限制,send_brk和send_dmx函数也似乎运行得很好,所以我不认为它们是问题所在。
double t1 = now();
double t2 = now();
while ( 1 ) {
// Attempt receive UDP data
int x = read(sock, &DMX[1], SIZE - 1);
t2 = now();
double dt = t2 - t1;
if(dt < 0.024){
usleep(500);
continue;
}
t1 = t2;
printf("Frame in %f %f/sec\n", dt, 1.0/dt);
if (x < 0) {
if(errno != EAGAIN){
fprintf(stderr, "Error reading from socket %s\n", strerror(errno));
}
}
send_brk();
send_dmx();
}
调用的函数在这里:
send_brk()发送持续88us的串行中断
void send_brk() {
ioctl(fd, TIOCSBRK);
double start = now();
while((now() - start) < 0.000088){
}
ioctl(fd, TIOCCBRK);
}
send_dmx()将长度为512的字节缓冲区写入串口
void send_dmx() {
// setmode(TX);
int n = write(fd, DMX, SIZE);
if(n == -1) {
if (errno != EAGAIN) {
fprintf(stderr, "Error writing to serial %s\n", strerror(errno));
exit(1);
}
}
if (n != SIZE) {
printf("couldn't write full frame =(\n");
}
}
和now()以float形式返回当前时间秒。
double now() {
struct timeval tv;
gettimeofday(&tv, NULL);
double time = tv.tv_sec;
time = time + (tv.tv_usec / 1000000.0);
return time;
}