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