我有一个嵌入式 Linux 平台(Beagleboard,运行 Angstrom Linux),连接了两个设备:
- 通过 USB 连接的激光测距仪 (Hokuyo UTM 30)
- 通过 SPI 连接的定制外部板
我们编写了一个Linux内核模块,负责SPI数据传输。它有一个 IRQ 处理程序,其中spi_异步 http://www.kernel.org/doc/htmldocs/device-drivers/API-spi-async.html被调用,这又会导致调用异步回调方法。
我的 C++ 应用程序由三个线程组成:
我遇到的问题似乎是由上述模块的交互方式引起的。
问题一:
我的假设是,内核空间中的 IRQ 处理程序和 spi_async 触发的回调比用户空间中运行的任何线程(无论是 SCHED_RR 还是 SCHED_OTHER)具有更高的优先级。这意味着在我的应用程序中转向 SCHED_RR 不应减慢 SPI 传输速度,但这似乎非常错误。是吗?
问题2:
我如何确定这里发生了什么?存在哪些调试辅助工具? (或者也许您不需要任何进一步的信息?)对我来说,主要问题是:为什么只有在激光设备打开时我才会遇到这些问题。 USB驱动会消耗这么多时间吗?
- - - 编辑:
我做出了以下观察:
spi_async 的回调调用wake_up_interruptible(&mydata->readq);
(with wait_queue_head_t readq;
)。从用户空间(我的应用程序)我调用一个函数,结果是poll_wait(file, &mydata->readq, wait);
当 poll 返回用户空间调用read()
.
- 当我的应用程序运行时
SCHED_OTHER
我可以看到回调方法首先在read()
进入我的内核模块中的方法。
- 当我的应用程序运行时
SCHED_RR
已输入读入before退出回调。
这似乎证明用户空间线程的优先级高于回调方法上下文的优先级。有什么方法可以改变这种行为并且仍然有SCHED_RR
对于我的应用程序的线程?
并非所有内核线程都有 RT 优先级。想象一下,一个需要做一些后台工作的定期唤醒线程正在被唤醒。您不希望该线程抢占您的 RT 线程。所以我想你的第一个假设是错误的。
根据您的其他问题:
- 您的主处理循环通过队列接收 SPI 数据
- spi 处理线程向主处理队列提供数据
看来您的主处理线程妨碍了负责 spi 数据传输的 spi 驱动程序线程。
发生的情况如下:
- IRQ 被激发
- spi_async 被调用,这意味着数据传输已排队,将由 spi 主驱动程序创建的线程拾取。
- spi 主线程与您的主处理线程(激光线程)竞争,但该内核线程没有 RT 优先级,因此每次 RR 线程之一运行时它都会丢失。
您可以做的是回到正常的调度,同时使用各种 CONFIG_PREEMPT_ 选项。或者搞乱 spi 主驱动程序,以确保任何延迟的工作都以足够的优先级排队。或者甚至根本不排队。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)