go-rpio: EdgeDetection crashes Raspberry Pi 3
Using Detect and running a very basic program on the Raspberry Pi 3, will result in the whole Raspberry Pi locking up (and needing a forced restart).
This only happens on a pin with very many rises/falls, currently I am using this for a RF receiver, so there are quite a lot of rises/falls.
The code I am using is this …
package main
import (
"fmt"
"time"
rpio "github.com/stianeikeland/go-rpio"
)
// This program is just going to be
// a POC of the sender working.
// This should and WILL be cleaned up
// I do not care, I will not fucking
// write the report without having
// the time to do this properly
// Raspberry Pi 3 GPIO
// https://i.imgur.com/PPFf2ul.png
const rx_pin_nr = 2
var preamble = [8]int{1, 0, 1, 0, 1, 0, 1, 0}
var sfd = [8]int{1, 0, 1, 0, 1, 0, 1, 1}
var rx_pin rpio.Pin
func main() {
// initialize go-rpio
err := rpio.Open()
if err != nil {
fmt.Println(err)
}
// set our pin as a output
rx_pin = rpio.Pin(rx_pin_nr)
rx_pin.Input()
rx_pin.Detect(rpio.RiseEdge)
for {
// sendData(test)
fmt.Println("Running stuff")
time.Sleep(100 * time.Millisecond)
}
}
func check_sync() {
}
Not even doing anything with it. I don’t know what the solution would be, but I think that we could get the interrupt etc. if we used such a system as epoll (http://man7.org/linux/man-pages/man7/epoll.7.html), I know it is uses for another Go system for GPIO interaction here - https://godoc.org/github.com/kidoman/embd
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16
Solved! tl;dr: Add
dtoverlay=gpio-no-irqto/boot/config.txtand restart your pi.Explanation: Thanks, roffe, for the example - finally something I could reproduce. I realized that the difference between the unit test which works fine and the cases where something useful is connected to pin is that the number of edges generated is much higher than the number of calls to
EdgeDetected(). (Single button press generates many edges too due to “switch bounce effect”.)Every edge event generates interruption as the side effect, but these are not handled by the system and after some number of unhandled interruptions it freezes.
In some update of Linux kernel (to which I switched after implementing the event detection functionality) the way the interruptions are handled changed. It worked before “by accident”. More info here: https://github.com/raspberrypi/linux/issues/2550#issuecomment-398082371
The solution above will disable all gpio interruption requests. But it is just workaround since it might break some other programs. Therefore I’ll try to figure out a better solution. Either by disabling irq from within go-rpio, or better by reimplementing the detection functionality and actually handle the interruptions.
But disabling irq using dtoverlay in config should be good enough for now.
@Drahoslav7 haven’t had time to test it, currently in the mid of getting all the code to work together before the deadline. Will test it out 😃 - But wouldn’t it be awesome, to have actual interrupts?