什么是中断
实际上就是一种通知机制,通知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)
1644

被折叠的 条评论
为什么被折叠?



