Search code examples
goioembedded-linux

How to manage I/Os with Golang on linux embedded system?


I have an linux embedded system. I can manage I/Os with shell commands. This commands change out status of GPIO #48 :

/sys/class/gpio# echo 48 > /sys/class/gpio/export
/sys/class/gpio# echo out > /sys/class/gpio/gpio48/direction
/sys/class/gpio# echo high > /sys/class/gpio/gpio48/direction
/sys/class/gpio# echo low > /sys/class/gpio/gpio48/direction

How can I manage I/Os with Goland efficiently ? Is it possible to manage them without going through the shell commands ?


Solution

  • On Linux GPIO interface is exported via sys filesystem in /sys/class/gpio hierarchy so as in your shell example you just need to write data into these files, something like:

    // To export pin 48 (same as echo 48 > /sys/class/gpio/export)
    ioutil.WriteFile("/sys/class/gpio/export", []byte("48"), 0666)
    ...
    

    Depending on your platform and needs you may want to consider some pre-existing package (e.g. go-rpio for Raspberry Pi or periph which is more general and supports much more than GPIO).

    If you want more efficient/faster solution than writing sysfs files you might also consider memory-mapped GPIO access where you basically directly access GPIO periphery via memory range given to it by the kernel. This requires somewhat deeper knowledge of your target platform (understanding its GPIO registers and their mapping). You can read about that approach in detail in this blogpost.

    EDIT: As @0andriy pointed out in his comment gpio syssfs is deprecated. That applies for both your Bash example above and my answer how to do same thing in Go. Instead a new ABI was introduced and libgpiod to interact with it. Go port is available here https://github.com/warthog618/gpiod.