概述
文章目录
- 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设备
最后
以上就是会撒娇铃铛为你收集整理的输入子系统的全部内容,希望文章能够帮你解决输入子系统所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复