Ese ejemplo de elinux usa IO mapeado en memoria . El núcleo también exporta una interfaz de espacio de usuario a través de 1/sys/class/gpio
, que también está documentada en elinux . Trabajando en C usarías bajo nivel / en lugar de , obviamente. No use funciones basadas en flujos de nivel superior.read()
write()
echo
Algunos programadores se molestan un poco cuando se les dice que usen una interfaz de archivo para cosas que creen que deberían hacerse con las llamadas al sistema. Esto es puramente una cuestión de estilo : equivalen exactamente a lo mismo . No hay "gastos generales de E / S adicionales", etc., accediendo a un archivo en este caso porque no es un archivo real, es una interfaz del núcleo. Exactamente como cualquier otro sistema ABI que hayas usado, solo que diferente. El uso de /proc
y /sys
nodos ha sido preferido durante mucho tiempo por los desarrolladores del kernel, pero todavía veo personas decididas a usar llamadas al sistema donde pueden, por ejemplo sysfs()
, a pesar del hecho de que man 2 sysfs
dice claramente:
Esta llamada al sistema derivada de System-V es obsoleta; no lo uses En sistemas con / proc, se puede obtener la misma información a través de / proc / filesystems; use esa interfaz en su lugar.
Esa es una página de manual de la biblioteca C que le dice que use la /proc
interfaz . Si eso no es lo suficientemente bueno como para convencerte, nada lo es. /sys
Es el mismo tipo de cosas. El punto es: solo porque esté usando un nodo de archivo en lugar de alguna API específica de C no significa que no esté haciendo una programación real, o que el rendimiento se verá afectado, etc. etc. Algunas personas podrían decir que en realidad es una buena característica. También es el método recomendado por las personas que escribieron el núcleo del sistema operativo.
Se puede encontrar una introducción rápida a la interfaz GPIO en [kernel-src]/Documentation/ABI/testing/sysfs-gpio
:
GPIOs are only made available to userspace by an explicit
"export" operation. If a given GPIO is not claimed for use by
kernel code, it may be exported by userspace (and unexported later).
Kernel code may export it for complete or partial access.
GPIOs are identified as they are inside the kernel, using integers in
the range 0..INT_MAX. See Documentation/gpio.txt for more information.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
Parecen varios tutoriales y otros en línea además del elinux. Solo he estado usando I2C, de lo contrario te daría una respuesta más directa.
Si está interesado en escribir código de espacio del kernel para acceder a GPIO, puede echar un vistazo aquí , aunque creo que eso realmente solo es útil si desea escribir un controlador para un dispositivo específico y crear su propia API de espacio de usuario.
1. Dado que IO mapeado por mem también debe usar lectura / escritura, no estoy seguro si un método proporciona una ventaja significativa sobre el otro aquí. El uso de la /sys
interfaz ciertamente será más portátil, si está buscando código que se ejecute en otras cosas que no sean una frambuesa pi.