基于input系统的按键驱动

什么是中断

 实际上就是一种通知机制,通知cpu发生了某种需要立即处理的事件

内部中断

cpu执行程序的过程发生了如硬件错误、运算错误(模0、溢出等)

外部中断

外设发生的某种情况,如通过引脚的高低电平来通知cpu事件(如鼠标点击)

通知流程

当设备产生事件时,设备会通过引脚进行信号传输,在中断控制器的引脚中设计出相应的寄存器,将信号存入寄存器中,cpu读取数据通过总线去中断控制器进行访问,会去寄存器中寻找相应的数据。


中断处理原理

向量中断

向量中断主要是中断服务由一个函数指针数组组成,每个区域都指向一个函数,当发生中断事件,即可去调用该函数

非向量中断

非向量中断是指的每一个中断服务器程序都在一个大框架内,每次调用都去该框架中调用非中断处理程序        

input子系统

input子系统就是linux管理所有输入设备的系统(如键盘、触摸屏、鼠标等)。其中核心层和事件层都由厂家和内核工程师写好,驱动层需要自己写。核心层是用来连接设备驱动和事件层的匹配

设备驱动思想

1、定于成对象

2、对象如何初始化

3、对象怎么注册

struct input_handler {  
    void *private;  
  
    void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);  
    bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);  
    bool (*match)(struct input_handler *handler, struct input_dev *dev);  
    int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);  
    void (*disconnect)(struct input_handler *handler, struct input_dev *dev);  
    void (*start)(struct input_handle *handle);  
    void (*fops_poll)(struct file *file, poll_table *wait);  
    int (*fops_read)(struct file *file, char __user *buffer, size_t count, loff_t *ppos);  
    int minor;  
    const char *name;  
    const char *id_table_name;  
    struct module *module;  
    const struct file_operations *fops;  
    struct list_head h_list;  /* List of input handles associated with the handler */  
    struct list_head node;    /* List of handlers */  
  
    /* Obsolete and unused */  
    void (*init)(void);  
    void (*setup)(struct input_handle *handle);  
    int (*accept)(struct input_handler *handler, struct input_dev *dev,  
                  const struct input_device_id *id);  
};  

struct input_dev {  
    const char *name;  
    const char *phys;  
    const char *uniq;  
    struct input_id id;  
  
    unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];  
  
    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)];  
  
   
    struct device dev;  //继承事件,所有事件的父类
  
    struct list_head h_list;  
    struct list_head node;  
};

struct input_handle {  
    void *private;  
  
    int open;  
    const char *name;  
  
    struct input_dev *dev;  
    struct input_handler *handler;  
  
    struct list_head d_node;  /* Used in input_dev->h_list */  
    struct list_head h_node;  /* Used in input_handler->h_list */  
};

 input子系统实例实现

1、创建input_dev结构体变量

struct input_dev* input_allocate_device*(void)

2、初始化input_dev结构体变量

(1)name

(2)事件类型

(3)子事件类型

3、注册input_dev结构体变量

int input_register_device(struct input_dev* dev)

4、上报事件

 事件上报结构体

open驱动节点后,read(fd,buffer的类型是inputevent,size)

struct timeval {  
    long tv_sec;         // 秒  
    long tv_usec;        // 微秒  
};  
  
struct input_event {  
    struct timeval time; // 时间戳  
    __u16 type;          // 事件类型  
    __u16 code;          // 事件代码  
    __s32 value;         // 事件值  
};

 上报数据需要调用input_sync,内核中有个同步buffer,需要上报一个同步一个

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);
void input_report_sync(struct input_dev *dev);

5、注销input_dev结构体变量

void input_unregister_device(struct input_dev* dev)

6、释放input_dev结构体变量

void input_free_device(struct input_dev* dev)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值