Esse exemplo do elinux usa E / S mapeadas na memória . O kernel também exporta uma interface de espaço do usuário via /sys/class/gpio
, 1 que também está documentada no elinux . Trabalhando em C, você usaria baixo nível read()
/ em write()
vez de echo
, obviamente. Não use funções baseadas em fluxo de nível superior.
Alguns programadores ficam um pouco chateados quando instruídos a usar uma interface de arquivo para coisas que eles acreditam que devem ser feitas com chamadas do sistema. Isso é puramente uma questão de estilo - eles representam exatamente a mesma coisa . Não há "sobrecarga adicional de E / S", etc., acessando um arquivo nesse caso porque não é um arquivo real, é uma interface do kernel. Exatamente como qualquer outro sistema ABI que você já usou, apenas diferente. O uso de /proc
e /sys
nós tem sido preferido pelos desenvolvedores do kernel, mas ainda vejo pessoas determinadas a usar chamadas do sistema onde podem - por exemplo sysfs()
, apesar do fato de man 2 sysfs
dizer claramente:
Essa chamada de sistema derivada do System-V é obsoleta; não use. Em sistemas com / proc, as mesmas informações podem ser obtidas via / proc / filesystems; use essa interface.
Essa é uma página de manual da biblioteca C que diz para você usar a /proc
interface . Se isso não é bom o suficiente para convencê-lo, nada é. /sys
é o mesmo tipo de coisa. Ponto é: só porque você está usando um nó de arquivo em vez de algum API C específico não significa que você não está fazendo a programação real, ou que o desempenho vai sofrer, etc. etc. Algumas pessoas podem dizer que é realmente um bom recurso. É também o método recomendado pelas pessoas que escreveram o kernel do SO.
Uma rápida introdução à interface GPIO pode ser encontrada em [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)
Parece haver vários tutoriais e outros online, além do elinux. Só uso I2C, caso contrário, daria uma resposta mais direta.
Se você estiver interessado em escrever o código de espaço do kernel acessando o GPIO, pode dar uma olhada aqui , embora eu pense que isso é realmente útil apenas se você quiser escrever um driver para um dispositivo específico e criar sua própria API de espaço do usuário.
1. Como as E / S mapeadas por mem também devem usar leitura / gravação, não tenho certeza se um método oferece uma vantagem significativa sobre o outro aqui. O uso da /sys
interface certamente será mais portátil, se você estiver procurando por um código que será executado em outras coisas que não um pi framboesa.