概述
Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq()
int request_irq(unsigned int irq, //irq是要申请的硬件中断号
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname, //设备名 中断属于哪个设备的
void *dev_id);
handler是向系统登记的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数
irqflags是中断处理的属性,若设置IRQF_DISABLED,标明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置IRQF_SHARED,则多个设备共享中断,
dev_id在中断共享时会用到,一般设置为这个设备的device结构本身或者NULL。
快速/慢速中断区别
快速中断保证中断处理的原子性(不被打断),而慢速中断则不保证。换句话说,也就是“开启中断”标志位(处理器IF)在运行快速中断处理程序时是关闭的,因此在服务该中断时,不会被其他类型的中断打断;而调用慢速中断处理时,其它类型的中断仍可以得到服务,默认情况是慢速中断。
共享中断
共享中断就是将不同的设备挂到同一个中断信号线上。Linux对共享的支持主要是为PCI设备服务。共享中断也是通过request_irq函数来注册的,但有三个特别之处:
1)申请共享中断时,必须在flags参数中指定 IRQF_SHARED位
2)dev_id参数必须是唯一的。 //因为共享中断 中断号相同,所以需要dev_id来区别是哪个设备中断
3)共享中断的处理程序中,不能使用disable_irq(unsigned int irq) ,因为这个会关闭该中断的所有设备
中断处理程序void (*handler)
中断处理程序。特别之处在于中断处理程序是在中断上下文中运行的,它的行为受到某些限制:
1) 不能向用户空间发送或接受数据 因为用户空间和进程对应,进程变了用户空间会变,中断不对应任何进程,不属于 进程
2) 不能使用可能引起阻塞的函数
3) 不能使用可能引起调度的函数 。防止用户空间发生变化
5、 中断处理函数流程
操作系统还有一个进程上下文,如驱动中的读写函数就是进程上下文
用户的应用程序,fread 通过内核 调用 驱动中的.read操作。read是进程主动调用的,属于进程上下文。中断上下文是硬件发出的,不是进程主动调用的。
中断处理函数的流程
void short_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* 判断是否是本设备产生了中断 因为共享中断产生中断会调用该中断号的所有设备 所以每个设备需要判断是否自己产生 中断,否则处理会出错*/
value = inb(short_base);
if (!(value & 0x80)) return; //不是本身设备产生的中断 返回
/* 清除中断位(如果设备支持自动清除,则不需要这步) */
outb(value & 0x7F, short_base);
/* 中断处理,通常是数据接收 */
。。。。。。。。。
/* 唤醒等待数据的进程 */
ake_up_interruptible(&short_queue); //接收数据 可能会阻塞别的进程,所以需要唤醒
}
卸载中断当设备不再需要使用中断时(通常在驱动卸载时), 应当把它们返还给系
void free_irq(unsigned int irq, void *dev_id)
最后
以上就是虚心紫菜为你收集整理的linux中断处理程序,linux 中断处理的全部内容,希望文章能够帮你解决linux中断处理程序,linux 中断处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复