从/ dev /输入读取(Read from /dev/input)

2019-08-21 20:34发布

我有一个USB RFID读卡器可模拟键盘。 所以,当我把一个卡,它我看到一个终端窗口-即字符串"0684a24bc1"

但我想在我的C程序中读取它。 有当我使用没有问题: scanf("%s",buff);

但是,当我用下面的代码中,我得到了很多(约500字节)无法识别数据。 为什么? 我想有非阻塞读。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

int main(int argc, char ** argv) {
  int fd;
  char buf[256];

  fd = open("/dev/input/event3", O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd == -1) {
    perror("open_port: Unable to open /dev/ttyAMA0 - ");
    return(-1);
  }

  // Turn off blocking for reads, use (fd, F_SETFL, FNDELAY) if you want that
  fcntl(fd, F_SETFL, 0);


  }

while(1){
  n = read(fd, (void*)buf, 255);
  if (n < 0) {
    perror("Read failed - ");
    return -1;
  } else if (n == 0) printf("No data on port\n");
  else {
    buf[n] = '\0';
    printf("%i bytes read : %s", n, buf);
  }
sleep(1);
printf("i'm still doing something");

}
  close(fd);
  return 0;
}

Answer 1:

根据Linux的输入文档 ,部分5,在/ dev /输入/ eventX设备返回数据如下:

您可以使用阻塞和非阻塞读取,还可以选择()在/ dev /输入/ eventX设备,你会总是得到的读取输入事件的整数。 它们的布局是:

 struct input_event { struct timeval time; unsigned short type; unsigned short code; unsigned int value; }; 

“时间”是时间戳,它返回该事件发生的时间。 类型是例如EV_REL相对时刻,EV_KEY一个按键或释放。 多种类型的定义在include / linux / input.h。

“代码”是事件代码,例如REL_X或KEY_BACKSPACE,再次的完整列表是在包括/ LINUX / input.h。

“值”是事件中携带的值。 无论是对EV_REL的相对变化,对于EV_ABS(操纵杆...),或者为0,EV_KEY释放,1代表按键和2自动重复绝对新值。



Answer 2:

#include <fcntl.h>
#include <unistd.h>
#include <poll.h>

int main(int argc, char *argv[])
{
    int timeout_ms = 5000;
    char input_dev[] = "/dev/input/event17\0";
    int st;
    int ret;
    struct pollfd fds[1];

    fds[0].fd = open(input_dev, O_RDONLY|O_NONBLOCK);

    if(fds[0].fd<0)
    {
        printf("error unable open for reading '%s'\n",input_dev);
        return(0);
    }

    const int input_size = 4096;
    unsigned char input_data[input_size];
    memset(input_data,0,input_size);

    fds[0].events = POLLIN;

    int exit_on_key_press_count = 10;

    while(true)
    {
        ret = poll(fds, 1, timeout_ms);

        if(ret>0)
        {
            if(fds[0].revents)
            {
                ssize_t r = read(fds[0].fd,input_data,input_size);

                if(r<0)
                {
                    printf("error %d\n",(int)r);
                    break;
                }
                else
                {
                    printf("total bytes read %d/%d\n",(int)r,input_size);

                    for(int i = 0; i<r;i++)
                    {
                        printf("%02X ",(unsigned char)input_data[i]);
                    }
                    printf("\n");
                    memset(input_data,0,input_size);

                    exit_on_key_press_count--;
                    if(exit_on_key_press_count<1)
                        break;
                }
            }
            else
            {
                printf("error\n");
            }
        }
        else
        {
            printf("timeout\n");
        }
    }

    close(fds[0].fd);
    return 0;
}

$ sudo的./keypressed

总字节读四千零九十六分之七十二

35 49 C9 5C 00 00 00 00 38 27 0B 00 00 00 00 00 04 00 04 00 5A 00 07 00 35 49 C9 5C 00 00 00 00 38 27 0B 00 00 00 00 00 01 00 50 00 01 00 00 00 35 49 C9 5C 00 00 00 00 38 27 0B 00 00 00 00 00 00 00 00 00 00 00 00 00

这是原始数据,转换为一些关键的,我需要阅读“Linux的输入文档”链接abave ...



Answer 3:

您的代码显然是错误的,在开放条件下的事件设备/dev/input/ 。 即使你的错误信息矛盾的选择:

perror("open_port: Unable to open /dev/ttyAMA0 - ");

从读出/dev/input/eventN文件返回与事件描述(如指针移动或按下按钮),而不是文本的二进制数据。 你可能想打开某种串口仿真设备来代替。



文章来源: Read from /dev/input
标签: c linux