从Python脚本到内核模块

从Python脚本到内核模块

所以我有一个 python 脚本来模拟引脚 17(Raspberry Pi)上的 ESC_KEY。

#!/usr/bin/env python
#Imports for Pins,input
import RPi.GPIO as GPIO
import uinput
from time import sleep

#Setup
key_events=( uinput.KEY_ESC, )
device=uinput.Device(key_events)
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#MAIN
while True:
   GPIO.wait_for_edge(17,GPIO.FALLING)
   device.emit(uinput.KEY_ESC,1)
   sleep(2)
   device.emit(uinput.KEY_ESC,0)

是否有一种“简单”的方法将其设置为内核模块,或者是否有人有一些好的文档来创建此内核模块?我需要用C重写它吗?

在 python 中运行时,这似乎会消耗大量资源,我希望作为模块运行时对系统的压力较小。

答案1

有没有一种“简单”的方法将其设置为内核模块

可能不会。另外,这可能有点违背良好的设计原则,因为你所拥有的看起来更像是一个用户空间应用程序;无论如何,有一个内核驱动程序潜伏在它的后台。1

在 python 中运行时,这似乎消耗了大量资源

考虑到它大部分时间都在睡觉,这不是一个好兆头。也许你应该更具体一些。我用 rpi 引脚所做的事情都是基于使用内核接口的 C 或 C++ 的 I2C,像这样简单的事情不会超过 1 MB RSS 或使用任何明显的 CPU 时间。

我需要用C重写它吗?

将其重写为用户空间如果问题是资源(WRT 内核空间代码,是的,仅是 C 和 asm),C 可能会解决您的问题。然而,Python 不应该那么糟糕——这里显然不存在性能问题。同样,您应该更详细地描述问题。

RPi.GPIO 模块是用 C 编写的,您可能想看一下。然而,在我看来,如果你还不了解该语言并且对它不感兴趣,那么仅仅为了这个就不值得学习。

您也可以尝试使用(与语言无关)现有的内核接口直接在 python 中,而不是 RPi.GPIO;这只是读取和写入 中的文件节点的问题/sys/class/gpio。如果您进行搜索,您会在网上找到更多相关内容树莓派交换。脚注中提到的 DMA hack可能如果你试图以非常高的频率做事,那么它有一个优势,但这里的情况并非如此(我怀疑它在这个意义上到底有多大用处,因为它仍然是一个纯粹的用户态实体并受内核延迟的影响)。


1 实际上,在本例中情况并非如此——RPi.GPIO 使用像这样的直接内存地址破解;我认为 C 级 WiringPi 模块也是这样工作的。那是东西制作一个好的内核模块,但内核已经有一个带有用户层接口的 gpio 模块。我想 DMA 黑客攻击的理由是似乎更有效率(而且写起来更有趣)。

相关内容