/ sys é um sistema de arquivos completamente baseado em RAM para acesso a estruturas de dados do kernel. Isso inclui as interfaces GPIO .
Tudo o que você precisa fazer é abrir o pseudofile normalmente e usar uma única gravação para gravar os dados. Se for bem sucedido, e todos os dados (exceto possivelmente qualquer espaço em branco como newlines) foram escritos, o kernel assegura que aceitou tudo. Em outras palavras:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define GPIO_EXPORT_PATH "/sys/class/gpio/export"
static int gpio_export(int pin)
{
char buffer[32];
ssize_t written;
int fd;
char *const q = buffer + sizeof buffer;
char *p = buffer + sizeof buffer;
if (pin < 0)
return errno = EINVAL;
*(--p) = '\n';
do {
*(--p) = '0' + (pin % 10);
pin /= 10;
} while (pin > 0);
do {
fd = open(GPIO_EXPORT_PATH, O_WRONLY);
} while (fd == -1 && errno == EINTR);
if (fd == -1)
return errno;
do {
written = write(fd, p, (size_t)(q - p));
} while (written == -1 && errno == EINTR);
if (written == -1) {
const int saved_errno = errno;
close(fd);
return errno = saved_errno;
}
if (close(fd))
return errno;
/* Not all written?
* It is okay if the last char, '\n' was not written. */
if (written != (ssize_t)(q - p) &&
written != (ssize_t)(q - 1 - p))
return errno = EIO; /* Partial write, data not accepted! */
return errno = 0;
}
Observe que quando fazemos o write()
, verificamos que todos os caracteres (exceto a nova linha final) foram escritos. Este é o requisito de atomicidade que você precisa. Também gosto de ter cuidado e verifique se close()
também não falha. (Embora isso não ocorra atualmente, é a única maneira de relatar certos erros, então eu gosto de estar preparado para o momento em que esses erros são relatados. Se eles ocorrerem.)