Почему я не могу очистить буфер перед использованием команды read ()? (linux, evdev-input, read, flush) - PullRequest
0 голосов
/ 10 января 2019

Пожалуйста, извините меня за мой английский, я не родной.

Устройство ввода Linux: / dev / input / event0 или / dev / input / by-id / usb-Logitech_G29_Driving_Force_Racing_Wheel-event-joystick

Проблема: Я не хочу читать буферизованные данные.


Уважаемый Stackoverflow,

1 - Я открыл устройство ввода в Linux.

2 - Я написал код для поворота устройства влево или назад к центру. (Это игровое колесо, поэтому, когда я открываю приложение, я должен быть уверен, что колесо расположено в центре)

3 - Я закрыл файловые дескрипторы и открыл точно такое же устройство для того, чтобы не читать старые буферизованные данные.

4 - Когда я хочу получить данные с функцией чтения, я получаю старые буферизованные данные, которые они получили, когда я поворачиваю устройство в центр. (Первая позиция равна 0, когда я хочу повернуть колесо в центр, оно изменяется с 35 на 0)

Так как я могу очистить буферизованные данные без написания второго приложения? Потому что, если я написал два приложения, первое из которых настроено на колесо устройства по центру, а второе - для получения данных, значит, все в порядке. Я имею в виду, если я закрываю файловый дескриптор из другого приложения, linux удаляет данные, но если я пытаюсь сделать это в том же приложении, появляются буферы.

Что я пытался очистить буфер:

  • Сначала я попытался выполнить поиск в google, stackoverflow и почти все прочитал.
  • FSYNC ()
  • fflush (стандартный вывод) и fflush (стандартный вывод)
  • ioctl (fd, I_FLUSH, FLUSHRW)
  • tcflush (fd, TCIOFLUSH)
  • закрыть (fd) перед прочтением. ( Я думаю, что это из-за того же приложения, Linux дает мне тот же файловый дескриптор. Если я выйду из программы и запустите снова, так что нет буфера )

$ gcc -o test_prog test.c && ./test_prog

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include <strings.h>
#include <stropts.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <linux/input.h>

// set the wheel position to center of it
void set_autocenter(int fd, int autocenter) {
    struct input_event ie;

    ie.type = EV_FF;
    ie.code = FF_AUTOCENTER;
    ie.value = 0xFFFFUL * autocenter / 100;

    if (write(fd, &ie, sizeof(ie)) == -1) {
        perror("error set_auto_center");
    }
}

int main(int argc, char *argv[]) {
    int fd_joystick;
    struct input_event ev = {0};
    const char *device_wheel = "/dev/input/by-id/usb-Logitech_G29_Driving_Force_Racing_Wheel-event-joystick";

    if ((fd_joystick = open(device_wheel, O_RDWR)) < 0) {
        perror("device could't opened.");
        return 0;
    }

    set_autocenter(fd_joystick, 100);

    while (1) {

        /* Problem starts from here 
         * When I first call read function it gives me garbage data which gets from
         * function of set_autocenter. Because this function changes the direction of wheel
         */

        if ( read(fd_joystick, &ev, sizeof(struct input_event)) == sizeof(struct input_event)) {
            printf("Event Type: %d Event Code: %d Event Value: %d\n", ev.type, ev.code, ev.value);
        }
     }

     return 1;
}

$ cat / proc / bus / input / devices

I: Bus=0003 Vendor=046d Product=c24f Version=0111
N: Name="Logitech G29 Driving Force Racing Wheel"
P: Phys=usb-0000:00:14.0-11/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11:1.0/0003:046D:C24F.0040/input/input61
U: Uniq=
H: Handlers=event0 js0 
B: PROP=0
B: EV=20001b
B: KEY=1ff 0 0 0 0 0 0 ffff00000000 0 0 0 0
B: ABS=30027
B: MSC=10
B: FF=300040000 0
...