向量中断:cpu为不同的中断分配中断号,当中断发生时,自动调到中断号相应地址执行;
非向量中断:共享一个入口地址,进入后通过软件中断标志来识别到底是哪个中断。
非向量中断程序
int int_src = read_int_staus(); //读硬件中断相关寄存器
switch(int_src)
{
case dev_a
case dev b
....
};
申请中断;
int request_irq(irqno,irq_handler,flags,devname,dev_id);
注意:此函数前提是先写好设备树文件;
irqno就是要申请的硬件中断号
irq_handler是对应中断处理函数
flag中断触发方式
若dev_id是在flag设为IRQF_SHARED(中断共享时用到)
释放中断free_irq(irqno,dev_id);
底半部机制:
tasklet,工作队列跟软中断;
用得比较多 的是tasklet,在需要调用的时候引用tasklet_schedule(&mytask);
注意是在中断返回之前调用;
tasklet运行于中断上下文不能休眠 基于软中断实现
工作队列运行于进程上下文
内核定时器;
timer-list
struct timer_list{
unsigned long expires;//定时器到期时间
void (*fun)(long) //函数指针,定时时间到了过后,执行的函数
long data;作为参数传入fun函数
};
初始化定时器;void init_timer(struct timer_list *timer);
增加定时器: void add_timer(&timer);
删除定时器:void del_timer(&timer);
修改/设置定时器的时间:mod_timer(&timer,expires);expire= jiffies+HZ表示1s后,expires = jiffies+100 表示延时100ms后执行fun,以此类推
修改时间以最后一次的为准,也就是无论修改多少次,最后他只会计时一次,也就是最后一次设置的时间