【问题标题】:Linux External Event Handling - IRQ vs. Polling kthreadLinux 外部事件处理 - IRQ 与轮询 kthread
【发布时间】:2013-06-28 20:40:02
【问题描述】:

我正在将设备驱动程序从 QNX 移植到 Linux。在 QNX 中,旧驱动程序使用带有无限循环的 pthread 来监视中断的发生,而不是注册一个真正的中断处理程序。为了演示使用 register_irq() 代替专用轮询线程的功效,我在 Linux 中编写了两个驱动程序。每个的相关代码如下所示,问题在底部。

IRQ

编写处理程序

irqreturn_t timing_interrupt_handler(int irq, void *dev_id) {

  u32 test;

  /* read device interrupt command/status register */
  test = ioread32(timing_card[3].base);

  /* sanity check that the device reported the interrupt */
  if ( test & (1 << 2) ) {

    /* clear interrupt status */
    iowrite32( 0x0d, timing_card[3].base);

    /* toggle digital output line */
    test = ioread32(timing_card[2].base);
    if ( test & 0x01 ) 
      iowrite32(test & ~0x1, timing_card[2].base);
    else
      iowrite32(test |  0x1, timing_card[2].base);

  }

  return IRQ_HANDLED;
}

注册处理程序

rc = request_irq(irq_line, timing_interrupt_handler,
               IRQF_SHARED, "timing", timing_card);
if ( rc ) {
  printk(KERN_ALERT "Failed to register irq %d\n", irq_line);
  return rc;
}

轮询线程

编写线程函数

int poll_irq(void *data) {

  u32 test;

  /* until module unload */
  while ( !kthread_should_stop() ) {

    /* read device interrupt command/status register */
    test = ioread32(timing_card[3].base);

    /* sanity check that the device reported the interrupt */
    if ( test & (1 << 2) ) {

      /* clear interrupt status */
      iowrite32( 0x0d, timing_card[3].base);

      /* toggle digital output line */
      test = ioread32(timing_card[2].base);
      if ( test & 0x01 ) 
        iowrite32(test & ~0x1, timing_card[2].base);
      else
        iowrite32(test |  0x1, timing_card[2].base);      
      }
      else
        usleep_range(9, 11);
  }

  return 0;
}

开始讨论

kthread = kthread_create(poll_irq, 0x0, "poll_IRQ_test");
wake_up_process(kthread);

问题

当我在示波器上放置两条迹线时——一条监控卡的数字输入(这将触发中断)和一条监控卡的数字输出(它将对中断作出反应),我可以测量对事件的反应时间。

第一个“正确的”方法,注册一个 IRQ,大约需要 80 微秒。

第二种方法,运行一个无限线程,大约需要 15-30 微秒。

什么给了?第一个的好处是它不会浪费太多的处理能力,但为什么响应时间会受到如此巨大的影响呢?真的,有这个投票线程有多糟糕?如何去调查并最终证明轮询线程对 CPU 造成的额外负担?

感谢您的宝贵时间!

最好的

斯科特

【问题讨论】:

    标签: linux linux-kernel linux-device-driver interrupt irq


    【解决方案1】:

    中断响应时间受您的系统(无论它是什么)需要传递中断的时间以及您的 CPU(无论它是什么)需要从某种节能睡眠模式唤醒的时间的影响。

    轮询线程消耗 CPU 时间和功率。 要测量它们,请使用 toppowertop 之类的东西,或者直接在硬件上测量功耗。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多