Working on a python 3 implementation of the new linux gpio implementation. The initial setup works great:
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)
My challenge comes when I try to read the event information that is stored in the anonymous linux file created by the GPIO_GET_LINEEVENT_IOCTL call.
If I try os.read I get an invalid argument response:
os.read(self.event.fd, bytesToRead)
If I try libc read then it will read the file but I get all zeros for my data (timestamp and 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))
using epoll does seem to trigger the file on the rising or falling edge on my input pin but it works intermittently:
p = select.epoll()
p.register(self.event.fd, select.EPOLLIN | select.EPOLLET | select.EPOLLPRI)
Any insight is appreciated greatly.
My suspicion is that you don't want to _pack_
your ctypes.Structures
at all. The docs say
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.
Since these are structures you're sharing with libc calls, you'll want them in the same default layout that it's used to seeing them.