Есть ли в Golang эквивалент ioctl, который помогает управлять GPIO?
Я пишу ардуино-подобную библиотеку для raspberryPi в голанге. Существует 2 основных способа взаимодействия с ABI ядра Linux GPIO: один с помощью / sys / class / gpio / * (не рекомендуется) или / dev / gpiochip[0-9]*. Я хотел бы использовать последнее, потому что первое не реагирует. Я взглянул на библиотеку под названием libgpiod. Код был прост для понимания, но использование ioctl затрудняло перенос на Golang (особенно потому, что я новичок). Я хотел бы иметь возможность перенести эту строку:rv = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info); // из libgpio lib / core.c ln:273. Спасибо.
2 ответа
Вы можете получить доступ к uAPI GPIO chardev в Go, используя мою библиотеку gpiod .
Это чистый Go, который полностью поддерживает GPIO uAPI v1 и v2, что позволяет вам плавно переходить от старых ядер с v1 к новым ядрам с v2, и я не знаю ни одной другой библиотеки Go, которая могла бы это сделать.
Или, если вы настаиваете на написании другого, не стесняйтесь использовать его в качестве справочного круга. Вы можете найти фактические вызовы ioctl в uapi.go.
Думаю, вы бы написали:
rv, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd),
uintptr(GPIO_GET_CHIPINFO_IOCTL),
uintptr(unsafe.Pointer(&syscallinfo)))
один тонкий момент - это преобразование вашего указателя (&syscallinfo) в uintptr для использования в syscall / ioctl; когда это делается как однострочный, как этот, он в конечном итоге будет выделен в нужном месте для использования в системном вызове. Uintptr, которое является целым числом, достаточно большим для значения указателя, но не указателем, обычно не рассматривается сборщиком мусора как ссылка на выделенный объект, но в этом особом случае так оно и есть.
(Я адаптировал это из https://github.com/stapelberg/hmgo/blob/master/internal/gpio/reset.go и просматривал соответствующие части исходной базы Go, чтобы найти примеры используемого возвращаемого значения, а также свою работу познакомил меня с неправильным поведением сборщиков мусора.)