linux内核模块编程(八)----中断下半部workqueue之使用

先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题
在这里插入图片描述
一 why
前一篇博文中, 我们介绍了中断下半部以及tasklet的实现方式,同时我们知道除了tasklet可以实现中断下半部处理之外,workqueue也可以实现中断下半部处理。那么为什么还需要workqueue呢?workqueue和tasklet之间有什么区别呢?

1. tasklet运行在中断上下文,在tasklet的处理函数中不能调用休眠函数,比如sleep函数或者kmalloc函数等等
2. workqueue运行在进程上下文,可以执行休眠的动作

二 what
实际上workqueue的基本实现在内核中很类似,驱动中只要初始化一个workqueue的对象,内核会将这个workqueue放到一个队列上去,workqueue的方法调用是由内核自己调度的,驱动一般无法控制,只能启动一个workqueue,如下
在这里插入图片描述
三 how
a. 初始化

// 结构体
struct work_struct {
	atomic_long_t data;
	struct list_head entry;
	work_func_t func;     //下半部的实现方法
#ifdef CONFIG_LOCKDEP
	struct lockdep_map lockdep_map;
#endif
};

// 方法
typedef void (*work_func_t)(struct work_struct *work);

// 初始化
struct work_struct myworkqueue;
#define INIT_WORK(_work, _func)						\
	__INIT_WORK((_work), (_func), 0)

b. 在上半部中放入到内核线程中----启动

schedule_work(struct work_struct * work);

一般步骤

1. 驱动中先注册一个中断
2. 注册中断的时候,同时初始化中断下半部workqueue
3. 实现中断处理函数,在中断处理程序中,启动下半部workqueue
4. 实现下半部处理函数

一般框架如下

static int __init key_drv_init(void)
{
	int ret = 0;

	//1. 设定一个全局的设备对象
	key_dev = (key_desc_t *)kzalloc(sizeof(key_desc_t), GFP_KERNEL);
	if (key_dev == NULL) {
		printk("kzalloc failure\n");
		return -EINVAL;
	}
	
	......

	//4. 注册中断
	key_dev->irqno = get_irqno_from_node();
	ret = request_irq(key_dev->irqno, key_irq_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
		"key3_exit10", NULL);

	// 初始化中断下半部workqueue
	INIT_WORK(&key_dev->myworkqueue, key_irq_bottom_half_workqueue);
	return 0;
}

中断处理函数

irqreturn_t key_irq_handler(int irq_no, void *devid)
{
	printk("-----------------\n");

	//启动中断下半部开始调度
	schedule_work(&key_dev->myworkqueue);
	......

	return IRQ_HANDLED;
}

中断下半部处理函数

void key_irq_bottom_half_workqueue(struct work_struct *work)
{
	......
}

我们发现,workqueue的初始化过程基本上和tasklet一模一样,只是调用的接口函数不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值