读取输入数据四种方式

162 阅读3分钟

1、查询方式 和 休眠-唤醒方式


#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


/* ./01_get_input_info /dev/input/event0 noblock */
int main(int argc, char **argv)
{
	int fd;
	
	int len;
	struct input_event event;
	
	if (argc < 2)
	{
		printf("Usage: %s <dev> [noblock]\n", argv[0]);
		return -1;
	}
	/** 休眠-唤醒方式 */
	if (argc == 3 && !strcmp(argv[2], "noblock"))
	{
		/** O_NONBLOCK 非阻塞 */
		fd = open(argv[1], O_RDWR);
	}
	else /** 查询方式 */
	{
		fd = open(argv[1], O_RDWR | O_NONBLOCK);
	}
	if (fd < 0)
	{
		printf("open %s err\n", argv[1]);
		return -1;
	}


	while (1)
	{
		len = read(fd, &event, sizeof(event));
		if (len == sizeof(event))
		{
			printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
		}
		else
		{
			printf("read err %d\n", len);
		}
	}

	return 0;
}

POLL方式

#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>


/* ./01_get_input_info /dev/input/event0 */
int main(int argc, char **argv)
{
	int fd;
	int len;
	int ret;
    
	struct input_event event;

	struct pollfd fds[1];

	nfds_t nfds = 1;

	if (argc != 2)
	{
		printf("Usage: %s <dev>\n", argv[0]);
		return -1;
	}

	fd = open(argv[1], O_RDWR);
	if (fd < 0)
	{
		printf("open %s err\n", argv[1]);
		return -1;
	}
	while (1)
	{
		fds[0].fd = fd;
		fds[0].events  = POLLIN;
		fds[0].revents = 0;
		/** 超时等待5s 调用驱动程序 .poll = gpio_drv_poll, 函数 */
		ret = poll(fds, nfds, 5000);
		printf("ret = %d", ret);
		if (ret > 0)
		{
			if (fds[0].revents == POLLIN)
			{
				while (read(fd, &event, sizeof(event)) == sizeof(event))
				{
					printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
				}
			}
		}
		else if (ret == 0)
		{
			printf("time out\n");
		}
		else
		{
			printf("poll err\n");
		}
	}

	return 0;
}

select方式

#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>


/* ./01_get_input_info /dev/input/event0 */
int main(int argc, char **argv)
{
	int fd;
	int len;
	int ret;
	unsigned int evbit[2];
	struct input_event event;
	int nfds;
	struct timeval tv;
	fd_set readfds;
	
	if (argc != 2)
	{
		printf("Usage: %s <dev>\n", argv[0]);
		return -1;
	}

	fd = open(argv[1], O_RDWR);
	if (fd < 0)
	{
		printf("open %s err\n", argv[1]);
		return -1;
	}

	while (1)
	{
		/* 设置超时时间 */
		tv.tv_sec  = 5;
		tv.tv_usec = 0;
		
		/* 想监测哪些文件? */
		FD_ZERO(&readfds);    /* 先全部清零 */	
		FD_SET(fd, &readfds); /* 想监测fd */
		
		/* 函数原型为:
			int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
         * 我们为了"read"而监测, 所以只需要提供readfds
		 */
		nfds = fd + 1; /* nfds 是最大的文件句柄+1, 注意: 不是文件个数, 这与poll不一样 */ 
		ret = select(nfds, &readfds, NULL, NULL, &tv);
		if (ret > 0)  /* 有文件可以提供数据了 */
		{
			/* 再次确认fd有数据 */
			if (FD_ISSET(fd, &readfds))
			{
				while (read(fd, &event, sizeof(event)) == sizeof(event))
				{
					printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
				}
			}
		}
		else if (ret == 0)  /* 超时 */
		{
			printf("time out\n");
		}
		else   /* -1: error */
		{
			printf("select err\n");
		}
	}

	return 0;
}

异步通知

#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

int fd;

void my_sig_handler(int sig)
{
	struct input_event event;
	while (read(fd, &event, sizeof(event)) == sizeof(event))
	{
		printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);		
	}
}

/* ./05_input_read_fasync /dev/input/event0 */
int main(int argc, char **argv)
{
	int len;
	int ret;
	unsigned int evbit[2];
	unsigned int flags;
	int count = 0;
	
	if (argc != 2)
	{
		printf("Usage: %s <dev>\n", argv[0]);
		return -1;
	}

	/* 注册信号处理函数 */
	signal(SIGIO, my_sig_handler);
	
	/* 打开驱动程序 */
	fd = open(argv[1], O_RDWR);
	if (fd < 0)
	{
		printf("open %s err\n", argv[1]);
		return -1;
	}

	/* 把APP的进程号告诉驱动程序  */
	fcntl(fd, F_SETOWN, getpid());
	
	/** 使能异步通知 会调用驱动程序 .fasync  = gpio_drv_fasync,函数 */ 
	flags = fcntl(fd, F_GETFL);         /** 先获取文件状态 */
	fcntl(fd, F_SETFL, flags | FASYNC); /** 设置文件状态标记 追加一个FASYNC状态 */
	
	while (1)
	{
		printf("main loop count = %d\n", count++);
		sleep(2);
	}

	return 0;
}