Linux应用程序之按键响应

Linux中的按键检测通过循环读取设备文件/dev/input/event[x](其中x可以为0,1,2…)设备文件获取按键事件,一般由主线程循环获取按键事件,然后通过消息队列通知其他子线程,从而做出响应。  

在Linux内核中,按键事件用input_event结构体描述,该结构体在头文件<linux/input.h>中定义,同时该文件还定义了有关按键事件的API函数接口、标准按键编码等。

input_event结构体定义如下:

struct input_event {
	struct timeval time;
	__u16 type;
	__u16 code;
	__s32 value;
};

      <linux/input.h>还定义了常用标准按键编码:

#define KEY_RESERVED		0
#define KEY_ESC			1
#define KEY_1			2
#define KEY_2			3
#define KEY_3			4
#define KEY_4			5
#define KEY_5			6
#define KEY_6			7

在用户态,我们只需要循环读取设备文件/dev/input/eventx,就可以得到相应的键盘事件,代码如下:

#include <linux/input.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>

#define  KEY_EVENT_DEV1_NAME    "/dev/input/event1"

int sysKeyScan(void)
{
	int l_ret = -1;
	int i = 0;
	
	int key_fd  = 0;
	struct input_event key_event  = {0};
	
	key_fd = open(KEY_EVENT_DEV1_NAME, O_RDONLY);
	if(key_fd <= 0)
	{
		printf("---open /dev/input/event1 device error!---\n");
		return l_ret;
	}
	
	while(1)
	{
		l_ret = lseek(key_fd, 0, SEEK_SET);
		l_ret = read(key_fd, &key_event, sizeof(key_event));
		
		if(l_ret)
		{
			if(key_event.type == EV_KEY
				&& (key_event.value == 0 || key_event.value == 1))
			{
				printf("key %d %s\n", key_event.code, (key_event.value) ? "pressed" : "released");
				
				if(key_event.code == KEY_ESC)
				{
					break;
				}
				
			}
		}

	}
	
	close(key_fd);
	
	return l_ret;
	
}

int main(int arg, char *arc[])
{
	printf("---This is a key event test!---\n");
	
	sysKeyScan();
	
	return 0;
}


有时候,我们的的Linux内核也可以把不同的按键封装到不同的event中,例如数字键键盘事件通过event1通知用户态,而功能键通过event0通知用户态。此时我们可以使用poll函数来同时监测多个等待事件,若事件未发生,进程睡眠,放弃CPU控制权,直到有键盘事件发生,poll将唤醒睡眠的进程,并执行相应的操作。代码如下:

#include <linux/input.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdint.h>

#define  KEY_EVENT_DEV0_NAME    "/dev/input/event0"
#define  KEY_EVENT_DEV1_NAME    "/dev/input/event1"

int sysKeyScan(void)
{
	int l_ret = -1;
	int i = 0;

	int key_fd[2]  = {0};
	struct pollfd key_fds[2] = {0};
	struct input_event key_event  = {0};

	key_fd[0] = open(KEY_EVENT_DEV0_NAME, O_RDONLY);
	if(key_fd[0] <= 0)
	{
		printf("---open /dev/input/event0 device error!---\n");
		return l_ret;
	}

	key_fd[1] = open(KEY_EVENT_DEV1_NAME, O_RDONLY);
	if(key_fd[1] <= 0)
	{
		printf("---open /dev/input/event1 device error!---\n");
		return l_ret;
	}

	for(i = 0; i < 2; i++)
	{
		key_fds[i].fd = key_fd[i];
		key_fds[i].events = POLLIN;
	}

	while(1)
	{
		l_ret = poll(key_fds, 2, -1);

		for(i = 0; i < 2; i++)
		{
			l_ret = lseek(key_fd[i], 0, SEEK_SET);
			l_ret = read(key_fd[i], &key_event, sizeof(key_event));

			if(l_ret)
			{
				if(key_event.type == EV_KEY
					&& (key_event.value == 0 || key_event.value == 1))
				{

					printf("key value(%d) %s", key_event.code, key_event.value ? "press" : "release");

				}
			}
		}
	}

	close(key_fd[0]);
	close(key_fd[1]);

	return l_ret;

}

int main(int argc, char *argv[])
{
	printf("---This is a key event test!---\n");

	sysKeyScan();

	return 0;
}





  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 我可以给您提供一些参考资料,以帮助您编写 Linux 按键驱动程序:Linux 内核文档,Linux 驱动开发完整指南,Linux 设备驱动程序开发,Linux 中断管理和应用,以及 Linux 设备树编程教程。 ### 回答2: 编写一个Linux按键驱动程序需要遵循以下步骤: 1. 首先,需要了解目标按键的硬件接口和读取机制。查阅相关文档或资料,了解按键的连接方式、传输协议和读取方式等。 2. 创建一个新的Linux驱动程序源代码文件,并命名为键盘驱动程序。例如,可以使用C语言编写,文件扩展名为.c。 3. 在驱动程序源代码中,包括头文件和相关库函数的声明。 4. 在驱动程序初始化函数中,初始化按键设备并分配相关资源。这包括设置设备的名称、类型和设备号等。 5. 按键设备初始化后,需要为其注册一个字符设备。使用`register_chrdev()`函数可以实现字符设备的注册。 6. 编码驱动程序的读取函数,该函数会在有按键按下时触发。通过该函数可以读取按键的状态,并作出相应的响应。 7. 在驱动程序中,实现对中断的处理函数。这个函数将在按键按下时被调用,以便在硬件级别完成按键的读取。 8. 编译驱动程序源代码,生成内核模块文件。 9. 将内核模块文件加载到Linux内核中,可以使用insmod命令加载驱动程序。 10. 测试驱动程序的功能和稳定性。通过按下按键触发中断,并观察对应的驱动程序是否成功读取到按键状态。 11. 如果需要,可以加入其他功能,如设置按键的触发条件、处理多个按键的同时按下等。 注意:以上步骤是一个简单的指导,实际编写一个Linux按键驱动程序可能涉及更多复杂的细节和特定的硬件要求。在编写过程中,可以参考相关的文档、教程和示例代码,并在遇到问题时查阅相关资料或寻求专业帮助。 ### 回答3: 编写Linux键盘驱动程序通常涉及以下几个步骤: 1. 头文件与宏定义:包含必要的头文件,如"linux/input.h"和"linux/module.h"。同时,在代码中定义所需的宏,如MODULE_LICENSE和MODULE_AUTHOR等。 2. 输入设备的注册和注销:使用input_register_device()函数将键盘输入设备注册到Linux系统中,并使用input_unregister_device()函数在驱动程序退出时注销该设备。 3. 初始化和释放资源:在驱动程序加载时,需要进行初始化操作,如分配内存,注册中断处理函数等。在驱动程序卸载时,需要进行资源的释放操作。 4. 中断处理函数:编写中断处理函数来处理接收到的键盘输入。这个函数需要根据传入的参数判断按下还是释放,并根据键码值进行相应的处理。 5. 键盘输入事件的生成:使用input_report_key()函数向系统报告键盘事件,并使用input_sync()函数将键盘事件传递给输入子系统。 6. Makefile文件:编写Makefile文件用来编译驱动程序,并生成对应的ko文件。 编写一个完整的Linux键盘驱动程序需要对硬件,中断处理和输入子系统有一定的了解。同时,还需要关注Linux内核版本和所使用的硬件平台之间的差异,以确保驱动程序的正确性和兼容性。以上只是一个简要的概述,实际编写驱动程序需要更多的细节和代码实现才能完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值