一、输入子系统驱动层分析
输入子系统由驱动层、输入子系统核心、事件处理层三部分组成。一个输入事件,如鼠标移动、键盘按下等通过Driver->Inputcore->Event handler->userspace的顺序到达用户控件的应用程序,具体的流程可以用下图描叙。
1、驱动层:将底层的硬件输入转化为统一事件形式,向输入核心(Input Core)汇报;6
2、输入子系统核心:承上启下,为驱动层提供输入设备注册与操作接口,如:input_register_device,通知事件处理层对事件进行处理,在/Proc下产生相应的设备信息;
3、事件处理层:主要是和用户空间交互。(Linux中在用户空间将所有的设备都当初文件来处理,由于在一般的驱动程序中都有提供fops接口,以及在/dev下生成相应的设备文件nod,这些操作在输入子系统中由事件处理层完成);
4、设备描述:
struct input_dev {
const char *name; //名字
const char *phys;
const char *uniq;
struct input_id id; //输入id
unsigned long evbit[NBITS(EV_MAX)]; // 表示能产生哪类事件
unsigned long keybit[NBITS(KEY_MAX)]; // 表示能产生哪些按键
unsigned long relbit[NBITS(REL_MAX)]; // 表示能产生哪些相对位移事件, x,y,滚轮
unsigned long absbit[NBITS(ABS_MAX)]; // 表示能产生哪些绝对位移事件, x,y
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)];
...
}
实现设备驱动核心工作是:向系统报告按键、触摸屏等输入事件event,通过input_event结构描述,不再需要关心文件操作接口。驱动报告事件经过inputCore和Eventhandler到达用户空间。
b、注册输入设备函数:int input_register_device(struct input_dev *dev)
c、注销输入设备函数:void input_unregister_device(struct input_dev *dev)
d、驱动实现——初始化(事件支持):--> probe函数
set_bit()告诉input输入子系统支持哪些事件,哪些按键。例如:
set_bit()告诉input输入子系统支持哪些事件,哪些按键。例如:
/* 设置按键能产生哪类事件 */
set_bit(EV_KEY,buttons_dev->evbit);
set_bit(EV_REP,buttons_dev->evbit);
/* 设置能产生这类操作的哪些事件 */
set_bit(KEY_L,buttons_dev->keybit);
set_bit(KEY_S,buttons_dev->keybit);
set_bit(KEY_ENTER,buttons_dev->keybit);
set_bit(KEY_LEFTSHIFT,buttons_dev->keybit);
struct input_dev中有两个成员为:
evbit:事件类型(包括EV_RST,EV_REL,EV_MSC,EV_KEY,EV_ABS,EV_REP等)
在input.h中有这些类的定义:
#define EV_SYN 0x00 //同步事件
#define EV_KEY 0x01 //按键类,如键盘或按钮
#define EV_REL 0x02