kernel(十)按键

参考: Documentation/devicetree/bindings/gpio/gpio_keys.txt

drivers/input/keyboard/gpio_keys.c

查看 TQ210 原理图

mach-smdkv210.c 中添加头文件<linux/gpio_keys.h>

定义 keys 的平台设备

/* gpio keys (add by JerryGou) */
static struct gpio_keys_button buttons[] = {
	[0] = {
		.code = KEY_UP,
		.gpio = S5PV210_GPH0(0),
		.active_low = 1,
		.desc = "up",
		.type = EV_KEY,
		.debounce_interval = 50,    //表示抖动延时 50ms
	},
	[1] = {
		.code = KEY_DOWN,
		.gpio = S5PV210_GPH0(1),
		.active_low = 1,
		.desc = "down",
		.type = EV_KEY,
		.debounce_interval = 50,
	},
	[2] = {
		.code = KEY_LEFT,
		.gpio = S5PV210_GPH0(2),
		.active_low = 1,
		.desc = "left",
		.type = EV_KEY,
		.debounce_interval = 50,
	},
	[3] = {
		.code = KEY_RIGHT,
		.gpio = S5PV210_GPH0(3),
		.active_low = 1,
		.desc = "right",
		.type = EV_KEY,
		.debounce_interval = 50,
	},
	[4] = {
		.code = KEY_ENTER,
		.gpio = S5PV210_GPH0(4),
		.active_low = 1,
		.desc = "enter",
		.type = EV_KEY,
		.debounce_interval = 50,
	},
};

static struct gpio_keys_platform_data tq210_keys_pdata = {
	.buttons = buttons,
	.nbuttons = ARRAY_SIZE(buttons),
	.rep = 1,     //表示允许重复输入
};

static struct platform_device tq210_keys = {
	.name = "gpio-keys",
	.dev = {
		.platform_data =  &tq210_keys_pdata,
	},
	.id = -1,
};

其中 debounce_interval 表示抖动延时 50msrep=1 表示允许重复输入。


配置内核

Device Drivers --->
        Input device support --->
                [*] Keyboards --->
                        <*> GPIO Buttons
要让按键支持控制台,需要配置 /etc/inittab ,在开一个 tty
tty2::askfirst:-/bin/sh
编译内核,运行测试

成功注册 gpio_keys,设备文件为/dev/input/event1
现在按 Enter 键(key5), LCD 效果如下

用户空间程序测试效果:

用户空间测试程序 key_input.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/fcntl.h>
#include <string.h>
#include <signal.h>

int fd = -1;
struct input_event ev;

void sig_handle(int sig)
{
	int rc = -1;
		
	rc = read(fd, &ev, sizeof(struct input_event));
	if (rc < 0)
	{
		perror("read");
		return;
	}
	if (EV_KEY == ev.type)
	{
		if (1 == ev.value)
			printf("key %d, value:%d\n", ev.code, ev.value);
		else
			printf("key %d, value:%d\n", ev.code, ev.value);
	}
}

int main(int argc, char *argv[])
{
	size_t rb;
	int version;
	char name[20];
	
	int oflags = 0;
	
	if (argc != 2)
	{
		fprintf(stderr, "Usage:%s /dev/eventx\n", argv[0]);
		exit(1);
	}

	if ((fd = open(argv[1], O_RDONLY)) < 0)
	{
		perror("open error");
		exit(1);
	}
	
#if 0	
	if (ioctl(fd, EVIOCGNAME(sizeof(name)-1), name) < 0)
	{
		perror("getname error");
		exit(1);
	}
	printf("name=%s\n", name);
	
	if (ioctl(fd, EVIOCGVERSION, &version) < 0)
	{
		perror("getversion error");
		exit(1);
	}
	printf("version=0x%x\n", version);

	while(1)
	{
		rb = read(fd, &ev, sizeof(struct input_event));
		
		if (rb < (int)sizeof(struct input_event))
		{
			perror("read error");
			exit(1);
		}

		if (EV_KEY == ev.type)
		{
			if (1 == ev.value)
				printf("key %d is pressed\n", ev.code);
			else
				printf("key %d is releassed\n", ev.code);
		}
	}
#else
	signal(SIGIO, sig_handle);
	fcntl(fd, F_SETOWN, getpid());
	oflags = fcntl(fd, F_GETFL);
	fcntl(fd, F_SETFL, oflags | FASYNC);
	while (1)
		sleep(1);
#endif
	close(fd);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jerrygou/article/details/80916998