rust-embedded / gpio-cdev

Rust interface to the Linux GPIO Character Device API (/dev/gpiochip...)
Apache License 2.0
213 stars 37 forks source link

LineEventHandle drops events #37

Closed chriskuech closed 3 years ago

chriskuech commented 4 years ago

LineEventHandle seems to be dropping events, as evident in the repro below, but also in a more optimized repro just filtering for FALLING_EDGES and knowing the min/max rate that these events are emitted, versus the actual interval between events.

Repro

The following snippet run on a Raspberry Pi Zero (ARM32).

for e in Chip::new("/dev/gpiochip0")?
            .get_line(pin)?
            .events(
                LineRequestFlags::INPUT,
                EventRequestFlags::BOTH_EDGES,
                "read",
            )? {
    println!("{}", e.event_type());
}

Observed

LineEventHandle yields multiple events of the same type in sequence.

Expected

LineEventHandle strictly alternates between each type.

chriskuech commented 4 years ago

Any idea whether this is a problem with this module (solvable by accessing the chip directly in Rust or C) or if it's a kernel issue (unavoidable on my hardware)?

posborne commented 4 years ago

@chriskuech I would suspect we are showing exactly what is coming form the kernel just based on the code being relatively straightforward. Can you compare the results against gpiomon (part of libgpiod) on the same hardware?

svenvdvoort commented 3 years ago

I ran a small test on my Raspberry Pi 3B rv. 2 (running Raspbian Stretch, kernel 4.14.79-v7+) with a push button connected to the Raspberry via a pull down resistor. When running the Rust gpio-cdev library, it gave the same results as @chriskuech found. Then when I tried with the gpiomon tool that was mentioned, the same thing happens. Below is a sample from the output from this tool. I think this is a problem in either the kernel or the hardware of the Raspberry Pi, since both tools show the same output.

event:  RISING EDGE offset: 17 timestamp: [1605984447.660500295]
event:  RISING EDGE offset: 17 timestamp: [1605984447.742679310]
event: FALLING EDGE offset: 17 timestamp: [1605984447.877804968]
event: FALLING EDGE offset: 17 timestamp: [1605984447.877831791]
event:  RISING EDGE offset: 17 timestamp: [1605984447.933583786]
event: FALLING EDGE offset: 17 timestamp: [1605984448.113989925]
event:  RISING EDGE offset: 17 timestamp: [1605984448.302215250]
chriskuech commented 3 years ago

I haven't done any tests, but I found an alternative library (in a different language) specifically for raspberry pis that works well. That library mitigates the issue by implementing retries, which confirms that its a hardware problem.

fpagliughi commented 3 years ago

I wonder if the mechanical switch isn’t bouncing like crazy and the driver/ISR just can’t keep up. The two falling edges are 27microseconds apart. Was there a rising edge in between them? That’s mighty fast for a mechanical switch.