Linux标准使用 sysfs 方式控制 GPIO,先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO 编号,使得该 GPIO 的操作接口从内核空间显示到用户空间,GPIO 的操作接口包括 direction 和 value 等,direction 控制 GPIO 方向,而 value 可控制 GPIO 输出或获得 GPIO 输入。文件 IO 方式操作 GPIO,通常使用到的4个函数为 open、close、read、write。
应用层代码简单使用示例如下 :
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <semaphore.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <regex.h>
#include <libgen.h>
#include <poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdarg.h>
#include <math.h>
#include <getopt.h>
#include <ctype.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/syscall.h>
#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/reboot.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/un.h>
#include <sys/shm.h>
#include <stddef.h>
/* common bus head file
#include <linux/input.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <linux/spi/spidev.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <linux/netlink.h>
*/
static int gpio_fd;
int Linux_Gpio_Config(char *pin, char *mode, char *value)
{
static int dev_fd, export_fd, dir_fd, ret;
char DEV_PATH[64], EXPORT_PATH[64], DIRECT_PATH[64];
char buf[10];
sprintf(DEV_PATH, "/sys/class/gpio/gpio%s/value", pin);
sprintf(EXPORT_PATH, "/sys/class/gpio/export");
sprintf(DIRECT_PATH, "/sys/class/gpio/gpio%s/direction", pin);
export_fd = open(EXPORT_PATH, O_WRONLY);
if(export_fd == -1)
{
perror("export open failed!\n");
return -1;
}
write(export_fd, pin, strlen(pin));
dev_fd = open(DEV_PATH, O_RDWR);
if(dev_fd == -1)
{
perror("dev open faield!\n");
return -1;
}
dir_fd = open(DIRECT_PATH, O_RDWR);
if(dir_fd == -1)
{
perror("dir open failed!\n");
return -1;
}
memset(buf, 0, sizeof(buf));
strcpy(buf, mode);
ret = write(dir_fd, buf, strlen(mode));
if(ret == -1)
{
perror("dir write failed!\n");
close(export_fd);
close(dir_fd);
close(dev_fd);
return -1;
}
memset(buf, 0, sizeof(buf));
strcpy(buf, value);
ret = write(dev_fd, buf, strlen(value));
if(ret == -1)
{
perror("dev write failed!\n");
return -1;
}
close(export_fd);
close(dir_fd);
return dev_fd;
}
int main(int argc,char *argv[])
{
int ret;
gpio_fd = Linux_Gpio_Config("94", "out", "0");//example config gpio94
ret = write(gpio_fd, "0", 1);//output 0
if(ret == -1)
{
perror("dev write failed!\n");
return -1;
}
ret = write(gpio_fd, "1", 1); //output 1
if(ret == -1)
{
perror("dev write failed!\n");
return -1;
}
return 0;
}
Linux GPIO驱动部分调用函数说明:
int gpiod_ get_ raw_value(const struct gpio_desc *desc)
void gpiod_set_ raw_value(struct gpio_desc *desc, int value)
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
void gpiod_set_ raw_value_cansleep(struct gpio_desc *desc, int value)
int gpiod_direction_ output_raw(struct gpio_desc *desc, int value)
raw- value的意思就是不在乎DTS里面的ACTIVE,我set高电平,就是高电平。