Linux系统开发专栏

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

“小涛哥,快醒醒,快醒醒..”小王使劲推着睡梦中的我,“你不是说今天要讲昨天有关的典型模板实例吗…”

“啊?小姐啊,现在才早上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);   //释放中断
  ..
}

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

 

“小王,看,小涛哥说话算数吧,上边给出了所有模版,结合前一篇,相信你可以看的很顺利的。好了,我要补补刚的觉了,中间不许叫我哈,想我也不行”我打打哈欠说。

posted on 2010-10-25 08:59  ☆&寒 烟☆  阅读(2613)  评论(1编辑  收藏  举报