Linux内核驱动程序:IRQ触发或超时
在linux内核驱动程序中,我想无限期地重复以下顺序:Linux内核驱动程序:IRQ触发或超时,linux,timeout,kernel,driver,irq,Linux,Timeout,Kernel,Driver,Irq,在linux内核驱动程序中,我想无限期地重复以下顺序: 在时间T,硬件IRQ被启用 在时间T和T+之间“大约”15毫秒,如果触发IRQ,则可以到达IRQ回调。我之所以这样说是因为我没有使用RT内核,如果是14或16毫秒,也可以。在IRQ回调中,我需要写下get cpu_clock(0)并调用wake_up_interruptable。需要终止超时。整个过程需要在5毫秒内重新启动 如果通过T+“大约”15毫秒,IRQ没有被触发,我需要执行一些其他代码。然后应该禁用IRQ。整个过程需要在5毫秒内重
- 在时间T,硬件IRQ被启用
- 在时间T和T+之间“大约”15毫秒,如果触发IRQ,则可以到达IRQ回调。我之所以这样说是因为我没有使用RT内核,如果是14或16毫秒,也可以。在IRQ回调中,我需要写下get cpu_clock(0)并调用wake_up_interruptable。需要终止超时。整个过程需要在5毫秒内重新启动
- 如果通过T+“大约”15毫秒,IRQ没有被触发,我需要执行一些其他代码。然后应该禁用IRQ。整个过程需要在5毫秒内重新启动
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);
然后:
然后:
}
以及:
我正在尝试编写一个健壮但简单的驱动程序。这是正确的实施吗?如何改进此实现?回答我自己的问题:问题是队列延迟工作基于jiffies。当HZ=100时,不可能达到5毫秒(1秒=10毫秒)。HR timer带来了一个很好的解决方案。取消延迟工作会不时生成“警告:在内核/timer.c:1061 del_timer\u sync+0x44/0x64()。如何避免这种情况?此警告对应于WARN_ON(in_irq());似乎从irq上下文中删除计时器不是一个好主意。我将“取消延迟的工作(&priv->timeout);”作为“驱动程序工作”的第一行。没有更多的警告,我认为逻辑没有被破坏,因为priv->interruptCalled'protects'在超时被触发的情况下,即使在IRQ被触发的情况下。
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);
}
}