Linux input subsystem

最近学习了一下Linux的输入子系统编程,做个记录。

简单分为3个部分,一是注册输入设备和键值,二是gpio的配置和申请,最后是中断来临后键值的上报流程。

linux设备的注册都是固定套路,主要区别还是在于硬件平台的不同需要做不同的处理。

static struct input_dev *key_dev;

static irqreturn_t key_interrupt(int irq, void *dummy) //中断处理函数
{ 
	int flag;

	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0));		// 设置gpio为input模式
	flag = gpio_get_value(S5PV210_GPH0(2));                     // 读取gpio判断是抬起还是按下
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));		// 再次设置为中断模式

	input_report_key(key_dev, KEY_LEFT, !flag);  //上报键值
	input_sync(key_dev);         //上报同步值
	return IRQ_HANDLED; 
}

static int __init key_init(void) 
{ 
	int error = -1;

	key_dev = input_allocate_device();  // 向内核申请输入设备

	input_set_capability(key_dev, EV_KEY, KEY_LEFT);   //注册键值
	
	error = input_register_device(key_dev);   //注册输入设备

	error = gpio_request(S5PV210_GPH0(2), "GPH0_2");  // 申请gpio

	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));		// 配置gpio为中断模式
	
	request_irq(IRQ_EINT2, key_interrupt, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "button-x210", NULL)    //配置中断触发方式,上升沿加下降沿触发

	return 0;
}

static void __exit key_exit(void) 
{ 
	input_unregister_device(key_dev); 
	free_irq(IRQ_EINT2, button_interrupt);  //释放gpio
}

module_init(key_init); 
module_exit(key_exit); 

代码去掉了错误处理,便于理解流程。

另外通过open /dev/uinput 然后wirte 同样可以上报键值,对于一些小按键很方便。

你可能感兴趣的:(linux,drive,c/c++)