内核驱动中断编程顶半部和底半部(下)

一、底半部实现机制之tasklet方法

①tasklet是基于软中断实现的,其优先级高于进程而低于硬件中断,同样不能做休眠操作。

②内核描述tasklet的数据结构

目前主要关注两个成员:func和data

func:指向的函数即为延后处理函数,形参unsigned long是要传递的参数

data:给延后处理函数传递的参数

③使用tasklet实现底半部编程的大体步骤总结

1)定义tasklet对象

struct tasklet_struct A; //定义tasklet对象

2)初始化tasklet对象,使用taskle_init函数

 tasklet_init(&A,  //初始化对象
    		  A_function, //给tasklet对象指定一个延后处理函数
    		  (unsigned long)&g_data //给延后处理函数传递的参数
    		);

3)根据需求编写延后处理函数(A_function)

void A_function(unsigned long data)
{
    //data用来保存给延后处理函数传递的参数
    //data=(unsigned long)&data
    //使用时注意数据类型强转
    ......;
    //该函数为底半部程序内容,应该做一些不紧急的
    //耗时时间长的内容
}

4)使用过tasklet_schedule函数向内核注册添加tasklet对象,也就是说内核tasklet对象的延后处理函数一旦注册成功,内核就会在适当的时候调用延后处理函数

注:在有顶半部中断处理函数的情况下,一般都是在顶半部代码中进行注册,如果没有顶半部时,根据需求在适当代码处注册

tasklet_schedule(&A);

二、底半部实现机制之工作队列方法

①工作队列诞生的原因就是解决tasklet的延后处理函数不能休眠的问题,这样可以在需要的场合在延后处理函数中进行休眠操作。

②工作队列基于进程实现,所以其延后处理函数可以进行休眠操作,但是优先级最低

③内核描述工作队列的数据结构

主要关注成员func:制定一个延后处理函数,此函数中可以进行休眠操作。

④使用工作队列实现底半部编程的大体步骤总结

1)定义工作队列对象

struct work_struct A;

2)使用INIT_WORK宏,初始化工作队列对象

INIT_WORK(&A,A_function);//添加一个延后处理函数

3)根据用户需求编写延后服务程序

      void A_function(struct work_struct *work)
      {
      		//work = &A; 
      		
      		//做不紧急,耗时较长的内容     		
      }  	

4)使用schedule_work函数向内核注册延后服务程序

schedule_work(&A); //一旦登记完成,内核会在适当的时候执行延后处理函数

三、底半部实现机制之软中断方法

①软中断实现延后执行的特点

1)软中断对应的延后处理函数优先级高于进程低于硬件中断

2)软中断延后处理函数同样不能进行休眠操作

3)软中断延后处理函数同一时刻能够运行在多个CPU核上,"效率更高"

注:内核要求其延后处理函数必须具备可重入性,就是尽量不要访问全局变量,如果非要访问,必须要进行互斥保护,但这种互斥访问最终降低代码的执行效率

②tasklet基于软中断实现,但是其延后处理函数同一时刻只能运行在一个CPU核上,tasklet开发难度降低,它的出现就是替代软中断

③软中断的延后处理代码不能向tasklet和工作队列一样insmod和rmmod,只能和uImage编译在一起,无形也加大了开发的难度

四、总结

如果要进行延后执行,并且发现延后服务函数需要休眠,只能用工作队列

如果要进行延后执行,并且发现无休眠并且考虑效率,用tasklet

如果要进行延后执行,并且无休眠并且无效率考虑,用工作队列[安全]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值