Is there an ioctl equivalant in Golang that helps with controling GPIO

757 Views Asked by At

I am writing an Arduino-like library for the raspberryPi in golang. There are 2 main ways to interface with the GPIO linux kernel ABI one using /sys/class/gpio/* (deprecated) or /dev/gpiochip[0-9]*. I would like to use the latter because well, the former is deprecated.

I took a look at a library called libgpiod. The code was simple to understand but the usage of ioctl made it difficult to port to Golang (especially because I am beginner).

I would like to be able to port this line:

rv = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info); //from libgpio lib/core.c ln:273.
2

There are 2 best solutions below

3
On

I think you would write:

rv, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd),
                              uintptr(GPIO_GET_CHIPINFO_IOCTL), 
                              uintptr(unsafe.Pointer(&syscallinfo)))

one subtle bit is the conversion of your pointer (&syscallinfo) into a uintptr for use in the syscall/ioctl; when done as a 1-liner like this, it will end up allocated in the right place for use in the syscall. A uintptr, which is an integer large enough for a pointer value but not actually a pointer, would not normally be treated by the garbage collector as a reference to the allocated object, but in this special case, it is.

(I adapted this from https://github.com/stapelberg/hmgo/blob/master/internal/gpio/reset.go and perusing relevant bits of the Go source base to find examples of the return value being used, plus my work has acquainted me somewhat with how garbage collectors (mis)behave.)

0
On

You can access the GPIO chardev uAPI in Go using my gpiod library.

It is pure Go, and fully supports both GPIO uAPI v1 and v2, allowing you to seamlessly transition from old kernels with v1 to new kernels with v2, and I'm not aware of any other Go library out there that can do that.

Or if you insist on writing another feel free to use it as a reference wheel. You can find the actual ioctl calls in uapi.go.