您的位置:首页 > 运维架构 > Linux

Linux内核开发之中断与时钟(二)

2012-12-11 17:46 253 查看
“小涛哥,快醒醒,快醒醒..”小王使劲推着睡梦中的我,“你不是说今天要讲昨天有关的典型模板实例吗…”
“啊?小姐啊,现在才早上8点,还让人睡觉不,别吵”我一头钻进被子里说。
“不管,谁让你昨天不说完,还卖个小关子,害我昨天晚上都没睡好,想了一晚上…”
我揉揉蒙蒙的眼说:“行,权当看在你渴求的心情上,但只此一次,下不为例,我还想好好睡懒觉呢..”
昨天我们讲了有关中断方面的东西,鉴于小王你不太懂,我今天就专门拿出一章来说说前边中断的使用典型模版,你照抄也方便不是:
1)在中断分类中,我们说到了有关向量中断和非向量中断,向量中断就是入口地址不同,进不同的地址做不同的事。那非向量中断则是进同一地址,至于区分就放在了进去后用条件判断,请看下边的模板:
irq_handler()
{
...
int int_src = read_int_status();   //读硬件的中断相关寄存器
switch(int_src)  //判断中断源
{
case DEV_A:
dev_a_handler();
break;
case DEV_B:
dev_b_handler();
break;
....
default:
break;
}
}

2)在底半部机制中,我们讲了tasklet,工作队列和软中断先来看tasklet

tasklet使用模版:

void xxx_do_tasklet(unsigned long);
DECLARE_TASKLET(XXX_tasklet, xxx_do_tasklet, 0);
void xxx_do_tasklet(unsigned long)   //中断处理底半部
{
.....
}
irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)  //中断处理顶半部
{
...
tasklet_schedule(&xxx_tasklet);
}
int __init xxx_init(void)   //设备驱动模块加载函数
{
..
result= request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, "XXX",NULL);  //申请中断
...
}
void __exit xxx_exit(void)   //设备驱动卸载模块
{
..
free_irq(xxx_irq, xxx_interrupt);   //释放中断
..
}
工作队列模版:

struct work_struct xxx_wq;
void xxx_do_work(unsigned long);
void xxx_do_work(unsigned long)   //中断处理底半部
{
.....
}
irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)  //中断处理顶半部
{
...
schedule_work(&xxx_wq);
}
int xxx_init(void)   //设备驱动模块加载函数
{
..
result= request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, "XXX",NULL);  //申请中断
...
INIT_WORK(&xxx_wq, (void (*)(void *))xxx_do_work, NULL);
...
}
void __exit xxx_exit(void)   //设备驱动卸载模块
{
..
free_irq(xxx_irq, xxx_interrupt);   //释放中断
..
}

3)在上节最后我还给你讲了有关中断共享的东西吧,小王,也把模版给你:

irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)  //中断处理顶半部
{
...
int status = read_int_status();  //获取终端源
if(!is_myint(dev_id, status))  //判断是否是本设备的中断
{
return  IRQ_NONE://立即返回
}
..
return IRQ_HANDLED;
}
int __init xxx_init(void)   //设备驱动模块加载函数
{
..
result= request_irq(xxx_irq, xxx_interrupt, SA_SHIRQ, "XXX",xxx_dev);  //申请共享中断
...
}
void __exit xxx_exit(void)   //设备驱动卸载模块
{
..
free_irq(xxx_irq, xxx_interrupt);   //释放中断
..
}

共享中断中,我们仔细看一下其实也没什么,不是。就是在和前边中断中要修改一下中断标志,在中断处理中判断一下是否是自己本地的中断,这个我都用红色的标识出来了。

“小王,看,小涛哥说话算数吧,上边给出了所有模版,结合前一篇,相信你可以看的很顺利的。好了,我要补补刚的觉了,中间不许叫我哈,想我也不行”我打打哈欠说。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: