我是靠谱客的博主 会撒娇铃铛,最近开发中收集的这篇文章主要介绍输入子系统,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

          • input子系统简介
          • input_dev 结构体:
          • 输入设备的注册与注销:
          • 输入设备的事件报告
          • 键盘驱动示例:

input子系统简介

就我们生活中的输入设备无非就是键盘、鼠标、触摸屏等。
输入子系统将输入设备分为三种类型,分别是键盘设备、鼠标设备和操作杆设备。
他们之间最主要的区别在于他们输入的数据类型不同。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于注册上述不同设备类型,只要符合要求的类型即可

input_dev 结构体:
Struct  input_dev{
const char* name;//设备名称
const char* phys;//设备文件路径
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//支持设备的类型(按键、相对、绝对等)
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//对应按键类型,设置键值
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//对应鼠标类型,表示输入坐标相对值
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];//对应手柄,表示输入坐标绝对值
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//对应杂项设备
unsigned int repeat_key;//存储最后一次设备输入的键值
int rep[REP_CNT];//自动重复参数的当前值
}
输入设备的注册与注销:
*1分配input_dev结构体
struct  input_dev *input_allocate_device(void)
*2将结构体input_dev结构体注册到内核,之前应该初始化好结构体里的变量和内容
Int  input_register_device(struct input_dev *dev)
*3将设备结构体input_dev结构体注销
void input_unregister_device(struct input_dev *dev)
*4 与分配结构体相对应,释放input_dev结构体
void input_free_device(struct input_dev *dev)
输入设备的事件报告

例如按下按键,会触发中断,此时cpu执行中断服务函数。但是内核不知道此时按键的值,所以在中断服务函数里面需要添加事件报告,目的很纯粹就是想将键位码转换为linux内核可以认识的键盘编码。

*向内核上报一个键盘事件
void input_report_key(struct input_dev *dev,//当前输入设备 
unsigned int code,//键值编码
Int value)//用0或者1表示按下或者释放的状态
*向内核上报一个REL事件
void input_report_rel(struct input_dev *dev,//当前输入设备 
unsigned int code,//事件码
Int value)//事件的值

*向内核上报一个ABS事件
void input_report_abs(struct input_dev *dev,//当前输入设备 
unsigned int code,//事件码
Int value)//事件值

*完成了事件的上报,还需要调用一个函数来实现内核的同步
void input_sync(struct input_dev *dev)//将事件同步到内核中
键盘驱动示例:
  • *0修改设备树,新增设备树节点
    在这里插入图片描述
  • *1注册输入设备(使用platform驱动模型)
    static int mykeypad_probe(struct platform_device *pdev)
    {
    mykeypad_dev=input_allocate_device(); //向内核申请 input_dev 结构体
    对input_dev结构体一系列初始化(内部的变量设置等)
    ret = input_register_device(mykeypad_dev); //注册input_dev
    利用platform_get_resource()+ioremap()函数得到寄存器地址从而进行寄存器配置
    ret = devm_request_irq(&pdev->dev, //中断号申请
    platform_get_irq(pdev, 0),//绑定的设备
    mykeypad_irq,//中断服务函数
    0,//触发方式
    "mykey",//中断名
    (void*)&key_value);//设备ID
    }
    
  • *2实现中断服务函数
    static irqreturn_t mykeypad_irq (int irq, void *dev_id)//实现事件的报告
    {
    ssize_t key_value;
    if(((*keyadc_ints)&(1<<1)) != 0) {/*上报事件*/
    key_value = ((*keyadc_data)&(0x3f));
    if(key_value == 24) {
    input_event(mykeypad_dev,EV_KEY,KEY_A,1); //上报EV_KEY类型,button按键,1(下) 
    }
    else if(key_value == 17) {
    input_event(mykeypad_dev,EV_KEY,KEY_B,1);//上报EV_KEY类型,button按键,1(按下)
    }
    。。。。。
    }
    input_sync(mykeypad_dev); // 上传同步事件,告诉系统有事件出现
    return IRQ_HANDLED;
    }
    
  • *3输入设备注销((使用platform驱动模型))
    static int mykeypad_remove(struct platform_device *pdev){
    iounmap(keyadc_xxx);//取消LRADC_xxx一些列映射
    。。。。
    input_unregister_device(mykeypad_dev); //卸载类下的驱动设备
    input_free_device(mykeypad_dev); //释放驱动结构体
    }
    
  • *4 注册paltform_driver驱动
    static struct of_device_id mykeypad_match_table[]={//匹配compatible属性
    {.compatible = "mykeypad",},
    };
    static struct platform_device_id mykeypad_device_ids[] = {//一个驱动匹配多少设备
    {.name = "mykeypad",},
    };
    static struct platform_driver mykeypad_driver=
    {	.probe = mykeypad_probe, 
    .remove = mykeypad_remove, 
    .driver={ 
    .name = "mykeypad", 
    .of_match_table = mykeypad_match_table, 
    },
    .id_table = mykeypad_device_ids,
    }module_platform_driver(mykeypad_driver);取代odule_init()module_exit()出入口
    
  • *5编译成.ko调试
    直接insmod挂载 在/sys/device/virtual/input下产生一个input0设备

最后

以上就是会撒娇铃铛为你收集整理的输入子系统的全部内容,希望文章能够帮你解决输入子系统所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部