中断的上下半部

因为输入类设备的输入都是异步事件,因此一般使用中断来处理和响应。

中断处理程序处于中断上下文中,不能和用户空间数据交互(不能使用copy_to(from)_to_usr函数);中断处理程序不能交出CPU(不能休眠,不能schedule);ISR运行事件尽可能短,越长则系统响应特性越差。

中断的上下半部

当中断处理程序比较长时,为了提供响应特性,linux内核处理中断的方案是:人为地将处理程序分为两部分,即中断上半部、中断下半部。中断上半部标记中断,调度下半部;下半部负责真正的操作(比如读取按键键值、从网卡读取缓冲数据等)。

中断下半部的两种实现机制

tasklet机制(小任务机制)

tasklet机制的引入主要是考虑到支持SMP,提高SMP多个cpu的利用率(不同tasklet可以在不同的CPU上运行)。

tasklet属于中断上、下文,因此不能被阻塞、不能睡眠,不能被打断。

workqueue机制(工作队列机制)

workqueue机制的特点是下半部会交给worker thread,因此下半部属于进程上、下文,可以被重新调度,可以阻塞,也可以睡眠。

workqueue有两种初始化方式。

静态初始化:调用DECLARE_WORK,初始化中断的上半部,然后在中断上半部调用schedule_work()来启动中断下半部。

动态初始化:调用INIT_WORK,初始化中断的上半部,然后在中断上半部调用queue_work()启动我们的中断下半部。

如何选择中断下半部的实现机制

1,必须立即进行紧急处理的极少量任务放在中断的上半部中。

  • 此时屏蔽了与自己同类型的中断,由于任务量少,所以可以迅速不受打扰地处理完紧急任务(除非优先级比自己高,被抢占了)。

2,需要较少时间的中等数量的急迫任务放在tasklet中。

  • 此时不会屏蔽任何中断(包括与自己的顶半部同类型的中断),所以不影响顶半部队紧急事务的处理。
  • 同时又不会进行用户进程调度,从而保证了自己急迫任务得以迅速完成。

3,需要较多时间且不急迫的大量任务放在workqueue中

  • 此时操作系统会尽快处理完这个任务,单如果任务量太大,期缴操作系统也会有机会调度别的用户进程运行,从而保证不会因为这个任务需要运行而导致其他用户进程无法进行。

4,可能引起睡眠的任务放在workqueue中

  • 因为在workqueue中睡眠是安全的,在需要获得大量的内存时,在需要获取信号量时,在需要执行阻塞式I/O操作时,用workqueue很合适。

tasklet机制示例

不使用tasklet机制的中断函数

static irqreturn_t button_interrupt(int irq, void *dummy) 
{ 
	int flag;
 
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0));		// input模式
	flag = gpio_get_value(S5PV210_GPH0(2));
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));		// eint2模式
 
	input_report_key(button_dev, KEY_LEFT, !flag);
	input_sync(button_dev);
	return IRQ_HANDLED; 
}

使用tasklet机制后的代码

 

workqueue机制示例

include/linux/workqueue.h

DECLARE_WORK 宏定义

DECLARE_WORK是Linux内核中用于定义工作队列的宏。这个宏定义一个工作队列结构,并初始化其回调函数。

DECLARE_WORK(name, func)

  • name 是你要定义的工作队列的名称。

  • func 是当工作被执行时,需要调用的函数

下面是一个使用该宏的例子:

#include <linux/workqueue.h>
 
void work_handler(struct work_struct *work)
{
    // 工作处理代码
    printk(KERN_INFO "Work is being processed.\n");
}
 
DECLARE_WORK(my_work, work_handler);
 
// 在需要的时候,可以将工作队列推到默认工作队列:
schedule_work(&my_work);

在这个例子中,我们定义了一个名为my_work的工作,并指定了处理函数work_handler。然后我们可以通过调用schedule_work函数来安排这个工作执行。

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小白20200202

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值