kidoman / embd

Embedded Programming Framework in Go
http://embd.kidoman.io
MIT License
1.28k stars 156 forks source link

RPI gpio delays #52

Open wujiang opened 8 years ago

wujiang commented 8 years ago

It looks like Raspberry pi needs some time after export to link the digital pin properly.

package main

import (
        "fmt"
        "os"
        "time"
)

func main() {
        exporter, _:= os.OpenFile("/sys/class/gpio/export", os.O_WRONLY, os.ModeExclusive)
        defer exporter.Close()
        exporter.WriteString("10")

        defer func() {
                unexporter, _:= os.OpenFile("/sys/class/gpio/unexport", os.O_WRONLY, os.ModeExclusive)
                defer unexporter.Close()
                unexporter.WriteString("10")
        }()

        // time.Sleep(50 * time.Millisecond)
        fi, _:= os.Stat("/sys/class/gpio/gpio10/direction")
        fmt.Println(fi.Mode())
}

Without the sleep, the output is -rw-r--r--. With the sleep, the output is -rwxrwx--- which is correct.

This affects SetDirection directly.

SpComb commented 8 years ago

The open /sys/class/gpio/gpio21/direction: permission denied error when running as a non-root user is due to a race with raspian's udev rules (/etc/udev/rules.d/99-com.rules) for gpio group access:

http://raspberrypi.stackexchange.com/questions/23162/gpio-value-file-appears-with-wrong-permissions-momentarily

Using the changes to in #61 to allow the use of pre-exported gpio pins, we can use a helper script to export the gpio pins and wait for udev to settle:

#!/bin/sh
#
# raspbian uses udev to assign /sys/class/gpio group write permissions, but this is racy between gpio export and writing to .../direction:
# http://raspberrypi.stackexchange.com/questions/23162/gpio-value-file-appears-with-wrong-permissions-momentarily
# export beforehand and wait for udev before running

for gpio in "$@"; do
    [ -e /sys/class/gpio/gpio$gpio ] || echo $gpio > /sys/class/gpio/export
done

echo "$0: Waiting for gpio devices to settle..." >&2

udevadm settle

IMO this is the best way to deal with the timing race in #52 and #53.