gpt4 book ai didi

Linux内核驱动: IRQ triggered or timeout

转载 作者:太空狗 更新时间:2023-10-29 11:19:47 27 4
gpt4 key购买 nike

在 linux 内核驱动程序中,我想无限期地重复以下序列:

  • 在时间 T,启用硬件 IRQ
  • 在时间 T 和 T +“大约”15ms 之间,如果触发了 IRQ,则可以到达 IRQ 回调。我之所以这么说是因为我没有使用 RT 内核,如果它是 14 或 16 毫秒,那很好。在IRQ回调中,我需要写下get cpu_clock(0)和call wake_up_interruptible。超时需要被杀死。整个过程需要在5ms内重新开始。
  • 如果 T + “大约” 15ms,IRQ 还没有被触发,我需要执行一些其他代码。然后应该禁用 IRQ。整个过程需要在5ms内重新开始。

因此,到T+“大约”20ms,在最坏的情况下,整个过程需要重新开始。

请注意,如果 IRQ 在 18 毫秒时物理触发,那就太糟糕了,“我错过了火车”。我将在下一个序列中捕获另一个硬件触发器。

在测试时,我按照以下伪代码做了一些事情:

INIT_DELAYED_WORK(&priv->work, driver_work);
INIT_DELAYED_WORK(&priv->timeout, driver_timeout);
request_irq(priv->irq, driver_interrupt, IRQF_TRIGGER_RISING, "my_irq", priv);

然后:

queue_delayed_work(priv->workq, &priv->work, 0ms);

static void driver_work(struct work_struct *work) {
queue_delayed_work(priv->workq, &priv->timeout, 15ms);
priv->interruptCalled = 0;
enable_irq(priv->irq);
}

然后:

static irqreturn_t driver_interrupt(int irq, void *_priv) {
disable_irq_nosync(priv->irq);
priv->interruptCalled = 1;
cancel_delayed_work(&priv->timeout);
priv->stamp = cpu_clock(0);
wake_up_interruptible(&driver_wait);
queue_delayed_work(priv->workq, &priv->work, 5ms);
return IRQ_HANDLED;

}

和:

static void driver_timeout(struct work_struct *work) {
if (priv->interruptCalled == 0) {
disable_irq_nosync(priv->irq);
//Do other small cleanup
queue_delayed_work(priv->workq, &priv->work, 5ms);
}
}

我正在尝试编写一个健壮但简单的驱动程序。这是一个正确的实现吗?我怎样才能改进这个实现?

最佳答案

回答我自己的问题:问题是 queue_delayed_work 是基于 jiffies 的。或者 5ms 是不可能的,因为 HZ=100(1 jiffy = 10ms)。 HR定时器带来了很好的解决方案。

关于Linux内核驱动: IRQ triggered or timeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14800214/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com