LINUX内核设计思想之中断和中断处理程序

中断,主要分两种:同步中断和异常中断.同步中断是和处理器时钟同步的,是用户可预见的,如编程失误导致的错误指令(例如除0);异常中断是随机的,用户不可预见的,一般由外设引发,如键盘的按下和弹起的动作.

 

6.1 中断上半部和下半部

在实际应用中,我们不得不面对以下情景:处理器能及时响应中断,如果ISR(中断例程)里面包含比较大的数据量要处理的话(例如网卡),ISR里面会因为停留在中断数据处理时间太长而影响了系统性能.LINUX为解决或者说优化这种问题,提出了中断上半部和中断下半部.中断上半部(top half)--接收到一个中断,立即执行去响应硬件中断;能够允许稍后完成的工作会推迟到下半部--中断下半部(bottom half).

 

6.2 中断的处理例程

当外设向处理器上报一个中断的时候,处理器必须去响应此中断并完成其期望的功能.

 

6.2.1 ISR的注册

驱动程序可以通过下面的函数注册并激活一个中断处理程序,以便处理中断:

Int request_irq(unsigned int irq,

irqreturn_t (*handler)(int,void*,struct pt_regs*),

unsigned long irqflags,

const char *devname,

void *dev_id)

各参数的意义如下:

Irq:表示要分配的中断号,这些值往往就是预定的;

Handler:完成相应中断的功能处理函数;

Irqflags:中断标识符.可以取下面的值:

SA_INTERRUPT:此标识被标识,表明是一个FIQ中断.FIQ中断的产生会把其他中断给屏蔽掉,直到释放此FIQ为止.除时钟中断外,绝大多数中断都不使用此标志;

SA_SAMPLE_RANDOM:此标志表明产生的中断对内核熵池有贡献;

SA_SHIRQ:此标志表明可以在多个ISR共享中断线.

Devname:与中断相关的设备的ASCII文本表示.例如,PC机上键盘中断对应这个值为"keyboard".这些名字会被/proc/irq/proc/interrupt文件使用;

Dev_id:主要用在共享中断的ISR.此域传递唯一的信息以区分所共享中断线的细则中断然后找到相应的ISR去处理.

应用场景:

Request_irq()成功会反回0;

Request_irq()会引起睡眠,不能在中断上下文或其他不允许阻塞的代码中调用.

向内核注册一个ISR示意代码如下:

If(request_irq(irqn,my_interrupt,SA_SHIRQ,"my_device",dev))

{

Printk(KERN_ERR "my_device:cannot register IRQ %d\n",irqn);

Return -EIO;

}

[:]中断处理程序通常会标识为static,因为它从来不会被别的文件代码调用.

6.2.2 ISR的释放

如下:

Void free_irq(unsigned int irq,void *dev_id)

如果指定的中断线是共享的,仅删除dev_id所对应的处理程序.

 

6.3 中断上下文

当执行一个中断处理程序或下半部时,内核所处的场景就是中断上下文.

当代码处于中断上下文的时候,需要注意的点有:

.中断上下文不能睡眠,因为没办法对它进行重新调度;

.代码及工作量必须简短;

.尽量节约中断栈

中断上下文与进程上下文的区别:

中断上下文:不可睡眠;

进程上下文:可睡眠,可调用调度程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值