linux驱动 -- 输入子系统

1:输入子系统介绍

        一个统一的输入设备的开发框架, 统一生成设备文件, 统一返回固定格式值。

2:输入子系统开发设备

        键盘、鼠标、触摸屏等等。

3:输入子系统运行框架

        应用层:操作设备文件+open+close+read+write

        输入子系统:为中间层

        驱动层:注册设备为输入子系统,把输入设备的事件告诉给输入子系统

4:输入子系统的开发


            无需再去注册生产设备文件,也无需做上层的交互->不需要返回有效数据
    在输入子系统中:
            1:需要把设备注册为输入子系统的设备
            函数原型:
                    input_register_device(struct input_dev * dev);
            2:在内核层上报输入设备的行为、事件
            比如按键摁下需要告诉输入子系统
            松开也需要告诉输入子系统
            采用中断的方式确定按键摁下

5:内核接口函数

头文件:

#include "linux/input.h"

函数功能:上报事件给输入子系统
    任何输入子系统注册设备,一旦发生任何事件都应该上报给输入子系统
    上报事件函数原型:
        

input_event(struct input_dev * dev ,unsigned int typedef,
    unsigned int code,int value);

函数参数:
    dev:
        上报给你注册哪个输入子系统设备
        核心结构体
    type:
        上报事件的类型->
            EV_SYN->代表上报了一个同步消息
            数据就会产生同步(输入子系统是有类似缓冲区概念)
            EV_KEY->
            代表上报了按键事件
    code:
        上报具体的什么事件
        EV_SYN ->这个地方固定填写 0
        EV_KEY ->
        这个地方则代表你上报按键的具体是哪个按键!
        KEY_1 KEY_2 KEY_Q ......
    value:
        代表具体上报值
        如果你用 EV_SYN ->此处固定填 0
        如果你用 EV_KEY ->代表你上报按键的具体的状态
        0->按键松开
        1->按键按下

函数功能:向内核注册输入子系统
函数原型:

 int input_register_device(struct input_dev *dev);

函数参数:
    dev:
        输入子系统的核心结构体需要用->input_allocate_device(void)开辟
        struct input_dev
        {
            const char *name;
            unsigned long evbit[BITS_TO_LONGS(EV_CNT)]
            这是记录当前注册输入子系统支持的事件
            其中相关重要参数
                EV_SYN:同步事件
                EV_KEY:输入子系统支持 按键事件
                EV_REL:相对事件
                EV_ABS:绝对坐标
                EV_REP:重复事件->列如按下不松手
                通过函数set_bit();设置
                用法:set_bit(EV_KEY,dev->evbit);
            unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
                往keybit里面添加支持的键值,这个为键盘设备,摁下后会是一个世界编码表。
            
        }
函数返回值:
        注册输入子系统成功返回 0
        注册输入子系统失败返回非 0

6:按键输入代码参考示例

#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/of.h"
#include "linux/cdev.h"
#include "linux/fs.h"
#include "linux/gpio.h"
#include "linux/of_gpio.h"
#include "linux/device/class.h"
#include "linux/device.h"
#include "linux/platform_device.h"
#include "linux/miscdevice.h"
#include "asm/uaccess.h"
#include "linux/input.h"
#include "linux/irq.h"
#include "linux/interrupt.h"
int irqnum;
int gpio_num;
int value =0 ;
struct input_dev * mykeyp;
irqreturn_t mykey_irq(int irqnum, void * arg)
{
	value = gpio_get_value(gpio_num);
	if(value == 0)//按键松开
	{
		input_event(mykeyp,EV_KEY,KEY_1,0);
	}else//按键按下!
	{
		input_event(mykeyp,EV_KEY,KEY_1,1);
	}
	input_sync(mykeyp);
	return 0;
}
int mykey_probe(struct platform_device * devp)
{
	int ret = 0;
	gpio_num = of_get_named_gpio(devp->dev.of_node,"xyd-gpios",0);
	gpio_request(gpio_num,"xyd_key");
	gpio_direction_input(gpio_num);
	//1:获取中断号
	irqnum = platform_get_irq(devp,0);
	//2:注册中断
	ret =devm_request_irq(&devp->dev,irqnum,mykey_irq,0,"key_irq",NULL);
	ret = ret ;
	//3:注册按键为输入子系统设备
	mykeyp = input_allocate_device();
	mykeyp->name = "xyd_key";
	set_bit(EV_KEY,mykeyp->evbit);//按键事件支持
	set_bit(EV_REP,mykeyp->evbit);//重复事件支持
	set_bit(KEY_1,mykeyp->keybit);//支持按键 1
	mykeyp->keycodemax = 1;
	return input_register_device(mykeyp);
}
struct of_device_id key_id_table={
	.compatible = "xyd_key",
};
struct platform_driver keyplat={
	.driver={
	.name = "xyd_key",
	.of_match_table = &key_id_table,
	},
	.probe = mykey_probe,
};
static int __init mykey_init(void)
{
	return platform_driver_register(&keyplat);
}
static void __exit mykey_exit(void)
{ }
module_init(mykey_init);
module_exit(mykey_exit);
MODULE_LICENSE("GPL");

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值