利用linux 内核所提供的input子系统编写字符设备驱动的步骤:
包含头文件:
#include <linux/input.h>
涉及核心接口体:
struct input_dev {
.........
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 long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
};
第一步:实例化输入设备对应的结构体指针
static struct input_dev *inputdev;
第二步:为输入设备结构体指针指向的对象分配空间。
inputdev = input_allocate_device();
第三步:设置事件分类对应的成员数组和根据事件分类设置编码数组。
可以使用如下两种方法设置:
宏:
BIT_WORD(), BIT_MASK();
利用函数来设置:
set_bit(nr, long *array);
button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);
button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
//set_bit(EV_KEY, evbit);
//set_bit(BTN_0, keybit);
//第四步:向内核注册输入设备
error = input_register_device( );
//反向注册: input_unregister_device();
如果注册失败,需要使用input_free_device(); 释放利用
input_allocate_device(); 分配的空间。
//第五步:在拿到数据的地方向用户态上报。
input_report_abs();
input_report_rel();
input_report_key();
input_sync();
input_mt_sync();
他们都调用input_event();
设备描述:
input_dev结构
实现设备驱动核心工作是:向系统报告按键、触摸屏等输入事件(event,通过input_event结构描述),不再需要关心文件操作接口。驱动报告事件经过inputCore和Eventhandler到达用户空间。
注册输入设备函数:
int input_register_device(struct input_dev *dev)
注销输入设备函数:
void input_unregister_device(struct input_dev *dev)
驱动实现——初始化(事件支持):
set_bit()告诉input输入子系统支持哪些事件,哪些按键。例如:
set_bit(EV_KEY,button_dev.evbit) (其中button_dev是struct input_dev类型)
struct input_dev中有两个成员为:
evbit:
事件类型(包括
EV_RST,EV_REL,EV_MSC,EV_KEY,EV_ABS,EV_REP等)
keybit:
按键类型(当事件类型为EV_KEY时包括
BTN_LEFT,BTN_0,BTN_1,BTN_MIDDLE等)
驱动实现——报告事件:
用于报告EV_KEY,EV_REL,EV_ABS事件的函数分别为void input_report_key(struct
input_dev *dev,unsigned int code,int value)
void input_report_rel(struct
input_dev *dev,unsigned int code,int value)
void input_report_abs(struct
input_dev *dev,unsigned int code,int value)
驱动实现——报告结束:
input_sync()同步用于告诉input core子系统报告结束。
实例:触摸屏设备驱动中,一次点击的整个报告过程如下:
input_reprot_abs(input_dev,ABS_X,x); //x坐标
input_reprot_abs(input_dev,ABS_Y,y); // y坐标
input_reprot_abs(input_dev,ABS_PRESSURE,1);
input_sync(input_dev);//同步结束