[Ubuntu] 在 user mode 透過 sysfs 控制 gpio sample code

// gpio.h

#ifndef GPIO_H_
#define GPIO_H_

int gpio_is_requested(unsigned int gpio);
int gpio_request(unsigned int gpio);
int gpio_free(unsigned int gpio);
int gpio_direction_input(unsigned int gpio);
int gpio_direction_output(unsigned int gpio, int value);
int gpio_get_value(unsigned int gpio);
int gpio_set_value(unsigned int gpio, int value);

#endif

// gpio.c

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "gpio.h"

#define GPIO_ROOT "/sys/class/gpio"
#define GPIO_EXPORT GPIO_ROOT "/export"
#define GPIO_UNEXPORT GPIO_ROOT "/unexport"
#define GPIO_DIRECTION GPIO_ROOT "/gpio%d/direction"
#define GPIO_ACTIVELOW GPIO_ROOT "/gpio%d/active_low"
#define GPIO_VALUE GPIO_ROOT "/gpio%d/value"

static int gpio_write_value(const char *pathname, const char *buf, size_t count) {
	int fd;

	if ((fd = open(pathname, O_WRONLY)) == -1) return -1;

	if (write(fd, buf, count) != count) {
		close(fd);
		return -1;
	}

	return close(fd);
}

int gpio_is_requested(unsigned int gpio) {
	int rv;
	char pathname[255];
	snprintf(pathname, sizeof(pathname), GPIO_VALUE, gpio);

	if ((rv = access(pathname, R_OK)) == -1) return -1;

	return (rv == 0);
}

int gpio_request(unsigned int gpio) {
	char buffer[16];
	snprintf(buffer, sizeof(buffer), "%d\n", gpio);
	return gpio_write_value(GPIO_EXPORT, buffer, strlen(buffer));
}

int gpio_free(unsigned int gpio) {
	char buffer[16];
	snprintf(buffer, sizeof(buffer), "%d\n", gpio);
	return gpio_write_value(GPIO_UNEXPORT, buffer, strlen(buffer));
}

int gpio_direction_input(unsigned int gpio) {
	char pathname[255];
	snprintf(pathname, sizeof(pathname), GPIO_DIRECTION, gpio);
	return gpio_write_value(pathname, "in", 3);
}

int gpio_direction_output(unsigned int gpio, int value) {
	char pathname[255];
	char *val;
	snprintf(pathname, sizeof(pathname), GPIO_DIRECTION, gpio);
	val = value ? "high" : "low";
	return gpio_write_value(pathname, val, strlen(val) + 1);
}

int gpio_get_value(unsigned int gpio) {
	int fd;
	char pathname[255];
	char buffer;

	snprintf(pathname, sizeof(pathname), GPIO_VALUE, gpio);

	if ((fd = open(pathname, O_RDONLY)) == -1) return -1;

	if (read(fd, &buffer, sizeof(buffer)) != sizeof(buffer)) {
		close(fd);
		return -1;
	}

	if (close(fd) == -1) return -1;

	return buffer - '0';
}

int gpio_set_value(unsigned int gpio, int value) {
	char pathname[255];
	snprintf(pathname, sizeof(pathname), GPIO_VALUE, gpio);
	return gpio_write_value(pathname, value ? "1" : "0", 2);
}
// test.c

#include <stdio.h>
#include <string.h>

#include "gpio.h"

#define GPIO_MODEM_POWER 11
#define GPIO_MODEM_RESET 2
#define GPIO_SIM_EN 9
#define GPIO_SIM_SEL 8

int main(int argc, char **argv) {
	if (gpio_is_requested(GPIO_SIM_EN) != 1) {
		gpio_request(GPIO_SIM_EN);
		gpio_direction_output(GPIO_SIM_EN, 1);
	}
	if (gpio_is_requested(GPIO_SIM_SEL) != 1) {
		gpio_request(GPIO_SIM_SEL);
		gpio_direction_output(GPIO_SIM_SEL, 0);
	}
	if (gpio_is_requested(GPIO_MODEM_RESET) != 1) {
		gpio_request(GPIO_MODEM_RESET);
		gpio_direction_output(GPIO_MODEM_RESET, 1);
	}
	if (gpio_is_requested(GPIO_MODEM_POWER) != 1) {
		gpio_request(GPIO_MODEM_POWER);
		gpio_direction_output(GPIO_MODEM_POWER, 1);
	}
}

 

 

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *