【发布时间】:2011-07-11 22:10:51
【问题描述】:
我在 linux 中编写了一个自定义设备驱动程序,它必须能够非常快速地响应中断。处理这个问题的代码已经存在于用户空间实现中,但是太慢了,因为它依赖于软件不断检查中断线的状态。经过一番研究,我发现您可以从内核模块注册这些中断线,并执行函数指针给出的函数。但是我们要执行的代码是在用户空间,有没有办法从内核空间模块调用用户空间的函数?
【问题讨论】:
标签: c linux module linux-kernel
我在 linux 中编写了一个自定义设备驱动程序,它必须能够非常快速地响应中断。处理这个问题的代码已经存在于用户空间实现中,但是太慢了,因为它依赖于软件不断检查中断线的状态。经过一番研究,我发现您可以从内核模块注册这些中断线,并执行函数指针给出的函数。但是我们要执行的代码是在用户空间,有没有办法从内核空间模块调用用户空间的函数?
【问题讨论】:
标签: c linux module linux-kernel
从内核调用用户空间函数很不走运,因为内核不知道也不应该知道单个用户空间应用程序的功能和逻辑,更不用说每个用户空间应用程序都有它自己的内存布局,不允许其他进程或内核以这种方式入侵(共享对象是这里的例外,但您仍然不能从内核空间利用它)。那么安全模型呢,你不应该首先在内核上下文中运行用户空间代码(在内核上下文中自动被认为是不安全的代码),因为这会破坏内核的安全模型。那一刻。现在考虑到上述所有内容,以及许多其他动机,您可能需要重新考虑您的方法并专注于内核 用户空间 IPC and Interfaces、文件系统或用户模式帮助程序 API(阅读下文)。
不过,您可以使用usermode-helper API 从内核调用用户空间应用程序。以下 IBM DeveloperWorks 文章将帮助您开始使用 usermode-helper Linux 内核 API:
Kernel APIs, Part 1: Invoking user-space applications from the kernel
【讨论】:
我认为最简单的方法是注册一个字符设备,当设备有一些数据时它就准备好了。
任何尝试从此设备读取数据的进程,然后进入睡眠状态,直到设备准备好,然后被唤醒,此时它可以执行适当的操作。
如果您只是想表示准备就绪,阅读器可以只读取一个空字节。
然后用户空间程序只需要执行一个阻塞的 read() 调用,并且会被适当地阻塞,直到你唤醒它。
您需要了解内核调度程序的等待队列机制才能使用它。
【讨论】:
听起来你的中断线已经通过 gpiolib 提供给用户空间了? (/sys/class/gpio/...)
如果 gpio 边缘触发和 poll() 对您来说足够快,您是否进行了基准测试?这样您就不必从用户空间应用程序轮询状态,但边缘触发将通过 poll() 报告它。请参阅内核源代码中的 Documentation/gpio.txt。
如果通过 sysfs 的边缘触发不够好,那么正确的方法是开发一个内核驱动程序来处理时间关键部分并通过 API(sysfs、设备节点等)将结果导出到用户空间。
【讨论】:
我也面临同样的问题,我看了这个文档http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-6.html,所以打算使用信号。就我而言,没有机会丢失信号,因为
1. 系统是闭环的,信号执行后只有我会得到另一个信号。
2. 我使用的是 POSIX 实时信号。
【讨论】: