Программа получения удушения Linux C

У меня есть следующий цикл, который должен работать чуть выше 40 Гц (24 мс между каждым запуском). Он отлично работает в течение пары секунд или минут, но затем снижается до 20 Гц без видимой (по крайней мере, для меня) причины.

Я попытался запустить код на луковом Omega 2 (который работает с openwrt) и ноутбуке с Ubuntu с тем же результатом. (код опустился до 25 Гц на Omega2 и 20 Гц на моем ноутбуке)

Как я могу заставить его продолжать работать на нужной скорости? Я проверил осциллографом на выходе, и функции 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() возвращает текущее время в секундах в виде числа с плавающей запятой.

double now() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    double time = tv.tv_sec;
    time = time + (tv.tv_usec / 1000000.0);
    return time;
}

0 ответов

Другие вопросы по тегам