Linux中断编程

基本概念

中断是指CPU在执行程序时,由于内外部事件或由程序预先安排的事件,导致CPU 暂停当前程序,转而处理突发事件,服务完毕后CPU再返回继续运行被暂时中断的程序。中断可分为内部中断和外部中断。内部中断来自CPU内部(除0错误、溢出等),外部中断来自外设,如时钟芯片等。

根据中断入口跳转方法的不同,可将中断分为向量中断和非向量中断。实现向量中断的CPU会为不同中断分配不同的中断号,当检测到某中断到来时,会自动跳到该中断号对应的地址执行。而非向量中断会是所有中断共用一个地址入口,中断到来时,进入该地址,然后通过中断标志来识别具体是哪个中断,也就是会进行二次跳转。改写向量表(RAM区)中的函数地址,就实现了中断向量重定向。

ARM嵌入式系统芯片和X86芯片基本都包含可编程中断控制器(PIC),通过读写PIC的寄存器可以屏蔽、使能某个中断或者获取中断状态。

       Linux中断处理架构

因为中断会打断进程的正常调度和运行,因此要求中断程序尽可能短小。那么对于复杂耗时的任务,就需要实现一个实用的中断处理机制了。Linux将中断程序分为两部分:上半部和下半部,上半部完成比较紧急的功能,一般只是登记寄存器中的中断状态并清除中断标志,然后将该中断对应的下半部程序挂到执行队列中去。

                           


举个例子,像VxWorks的网络驱动,一般包接收中断到来后,会通过isr_irq()函数释放信号量,然后dsr_irq()被唤醒,执行包的读取工作。当然信号量的操作需要锁保护。

Linux中断编程

1、申请和释放中断

使用request_irq将终端号与具体的中断(上半部)回调函数对应起来,可以设置中断触发方式,如电平触发和边沿触发。对应的释放函数是free_irq。使用方法与socket的申请释放类似。

2、使能和屏蔽中断

disable_irq可以屏蔽一个中断源,这里注意使用的时候不用引起系统死锁。对应的恢复函数为enable_irq。

3、下半部机制

下半部处理机制包括软中断、tasklet、workqueue、中断线程化,用于任务调度的PendSV就是典型的软中断。这里工作队列位于进程上下文,因此其处理函数中允许睡眠,而软中断和tasklet运行于中断上下文,是原子执行的,其处理函数不能睡眠。

可以看到异步通知中的信号(SIGNAL)机制也类似于中断,其与中断区别是:硬中断是由外设对CPU的中断,软中断是中断后半部的处理机制,信号是内核(or进程)对进程的中断。在系统调用场景下会说通过软中断(SWI、BKPT指令陷入内核,那么这里的软中断是指软件指令引发的内核状态切换(如ARM从用户态切到内核态),与软中断不是同一个概念。

那么系统调用是不是中断?不是。系统调用是只是CPU从用户态切入内核态(通过TRAP指令),是CPU模式切换,并不是进程上下文切换,即系统调用、中断不等于进程调度,系统调用会将用户上下文即esp寄存器等压入进程空间的内核栈。(进程切换的时候,用户态的寄存器信息会保存在task_struct内,即PCB,位于内核空间,可以看一下之前写的:嵌入式操作系统的任务调度)当系统调用或中断处理程序返回时,CPU要从内核模式切换回用户模式,此时会执行操作系统的调用程序。如果发现就绪队列中有比当前进程更高的优先级的进程,则会发生进程切换:当前进程信息被保存,切换到就绪队列中的那个高优先级进程;否则,直接返回当前进程的用户模式,不会发生上下文切换。像fork等与进程操作相关的系统调用一般就会引起进程调度。

每个进程都拥有两个堆栈:用户空间的堆栈和内核空间堆栈

用户进程:执行用户空间的代码的程序,使用用户堆栈

系统进程:执行内核空间代码(系统调用或中断)的程序,使用内核堆栈(系统堆栈)

系统调用一般会调用到copy_from_user和copy_from_user来执行将用户空间与内核空间数据拷贝,如前文:简单讲讲文件系统中f_op的read、write等。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值