Linux中断与轮询

时间:2014-03-26 13:41:20

标签: c linux linux-kernel real-time interrupt

我正在开发一个带有DSP和ARM的系统。在ARM上有一个Linux操作系统。我有一个DSP向ARM(Linux)发送数据 - 在Linux中有一个内核模块,它读取从DSP接收的数据。内核模块正在唤醒以使用DSP与ARM之间的硬件中断来读取数据。

我想编写一个用户空间应用程序,每当有来自DSP的新数据时,它将从内核空间(内核模块)读取数据。
问题是:

  

有什么方法可以做到这一点,从内核到用户空间的软件中断,或者每隔10ms从用户空间轮询(用内核读取已知的内存地址)。?

知道:

  • 从DSP到内核的数据必须在很短的时间内到达 - 100us。
  • 从内核到用户空间的数据可能需要10毫秒到30毫秒。
  • 正在读取的数据被认为很小 - 大约100个字节。

3 个答案:

答案 0 :(得分:7)

我会在read创建一个设备并拥有userland程序块。无需等待10毫秒,这可以通过阻止来有效处理。

使用poll的意义上的轮询(是的,我明白这不是你的意思)会正常工作,但没有理由调用两个函数(第一个poll和那么read)当一个函数无论如何都可以做到。无需每10分钟执行一次,您可以在处理完上次阅读后的内容后立即再次致电poll

不建议每隔10毫秒检查一次已知的内存位置。这不仅是一个丑陋的黑客,而且比你想象的更复杂(你必须将包含该内存位置的页面映射到用户空间),以及繁忙等待的形式,它不必要地消耗CPU,它还具有5ms的平均延迟和最糟糕的延迟为10毫秒,这是完全没必要的。 read的平均和最差情况延迟大约为零(嗯,不完全,但差不多......它的速度和唤醒被阻止的任务一样快)。

中断(即信号)非常有效,但与简单的读取和阻塞相比,使程序更加复杂/扭曲(必须编写信号处理程序,可能不使用处理程序中的某些功能,必须与主应用程序通信等) )。虽然技术上是一个很好的解决方案,但我建议不要使用它们,因为程序不需要比必要的更复杂。

答案 1 :(得分:1)

轮询没有优势等待。这个过程仍然需要安排并切换到所有这一切,然后在部分时间内进行无用的轮询。

Linux从中断返回时运行调度程序,因此当您在内核中断处理程序中唤醒等待任务并且它具有高优先级设置时(显然应该给它实时优先级),任务将立即安排。你通过民意调查赢得了胜利。

(字符)设备文件的标准接口相当快,所以只需实现阻塞读取,轮询(阻塞系统调用,不实际轮询任何东西)和可能异步读取(使用实时信号),但我怀疑在读取系统调用中等待专用线程的性能将优于AIO。而且写起来也更容易。你应该在内核源代码中找到足够的例子。

答案 2 :(得分:0)

您似乎没有提及任何困难时间限制,因此您可以采用任何一种方法。然而,正如Martin James所说,民意调查为应用程序带来了一些开销,你可能并不想要。

就个人而言,我会使用内核触发的中断或事件标志。虽然你可能没有严格的时间限制,但我认为你想要的东西更确定,而不是。内核中断会让你更接近它。