Python 如何为 GPIO 事件读取匿名 linux 文件

Python how to read an anonymous linux file for a GPIO event

正在研究新的 linux gpio 实现的 python 3 实现。初始设置效果很好:

class gpioevent_request(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
                ('lineoffset', ctypes.c_ulong),
                ('handleflags', ctypes.c_ulong),
                ('eventflags', ctypes.c_ulong),
                ('consumer_label', ctypes.c_char * 32),
                ('fd', ctypes.c_int),
                ]

class gpioevent_data(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
                ('timestamp', ctypes.c_ulonglong),
                ('id', ctypes.c_ulong),
                ]

self.event = gpioevent_request()
self.eventData = gpioevent_data()
...
# Open /dev/gpiochipx with os.open and set up the event structure
...
fcntl.ioctl(self._fd, GPIO_GET_LINEEVENT_IOCTL, self.event)

当我尝试读取存储在由 GPIO_GET_LINEEVENT_IOCTL 调用创建的匿名 linux 文件中的事件信息时,我的挑战就来了。

如果我尝试 os.read 我得到无效参数响应:

os.read(self.event.fd, bytesToRead)

如果我尝试 libc read,它会读取文件,但我的数据(时间戳和 ID)全部为零:

import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library('c'))
self.f_read = libc.read
self.f_read(self.event.fd, ctypes.byref(self.eventData), ctypes.sizeof(self.eventData))

使用 epoll 似乎确实会在我的输入引脚上的上升沿或下降沿触发文件,但它会间歇性地工作:

p = select.epoll()
p.register(self.event.fd, select.EPOLLIN | select.EPOLLET | select.EPOLLPRI)

非常感谢任何见解。

我怀疑您根本不想 _pack_ 您的 ctypes.Structures。文档说

By default, Structure and Union fields are aligned in the same way the C compiler does it. It is possible to override this behavior be specifying a pack class attribute in the subclass definition.

由于这些是您与 libc 调用共享的结构,因此您会希望它们采用与过去查看它们时相同的默认布局。