lulu爱 发表于 2014-11-30 11:07:37

中断线程化的设计实现二

之前的中断线程化的设计阐述了理论,具体的实现各个os可能有所不同,叫法可能也有所不同。

基于raw-os的中断线程化的实现可以采用raw-os的workqueue去实现。让我们来温顾一下workqueue。我们在helper2416的网卡驱动中采用了workqueue的处理方式,中断上半部采取了收取网卡数据,然后把数据交给中断下半部的workqueue的处理。我们现在换一种思考方式,使用workqueue是否能把整个中断上下半部一次性搬到外面任务去做,答案很显然,肯定是可以的。

我们来看一下具体的实现方式。假设有以下的中断和中断服务函数

Void irq1_handle()
{
//中断服务函数

}


void Irq1_entry()
{

// irq1中断入口函数

}

如何把irq1整个中断线程化呢?我们可以这样做:

1 使用apiwork_queue_create创建一个可以指定优先级的任务,比如说创建了wq1。

2 上面的Irq1_entry()函数改造如下:

void Irq1_entry()
{

// irq1中断入口函数

//唤醒外面的workqueue任务来处理中断服务函数
sche_work_queue(wq1, arg, msg, irq1_handle)

//可能需要清中断源,各个芯片不同。
}




在上面的调用函数中尤其需要注意sche_work_queue的第一个参数wq1,以及irq1_handle,即分别指定了唤醒哪一个workqueue以及分发哪一个中断服务函数。

基本的实现过程就如上所说。下面我们来具体讨论下如何划分workqueue的优先级,由上面可知,中断的服务函数都在workqueue中实现了,一个问题很显然,是否每一个中断都需要背后的一个workqueue支持?大部分的中断其实先后次序倒一下都能容忍的,因为频率并不快,或者重要性并不高。这种情况下完全可以按照先来后到的处理方式去处理,也就是说大部分的中断需要一个workqueue共用去处理即可,剩下的几个频率快的中断可以采用一对一的分配方式,只要任务优先级拉高即可。

从上面的中断入口函数Irq1_entry来看,整个消耗的时间约等于sche_work_queue的消耗时间,这个时间是固定的,而且很迅速。有一些中断服务函数如果本身执行时间很短,时间上小于等于Irq1_entry的执行时间,则没有意义再去触发workqueue,因为workqueue本身会触发任务调度,显然会浪费效率。对于这样的中断服务函数很短的我们可以这样做。

void Irq1_entry()
{

// irq1中断入口函数

//任务来处理中断服务函数
your_irq_handle();

//可能需要清中断源,各个芯片不同。
}


综上所述,我们可以把整个系统的中断全部线程化,进一步提升了整个系统的实时性,具体的好处可以参考之前的文章。
页: [1]
查看完整版本: 中断线程化的设计实现二