使用sysfs操作GPIO

您所在的位置:网站首页 sysfs驱动 使用sysfs操作GPIO

使用sysfs操作GPIO

#使用sysfs操作GPIO| 来源: 网络整理| 查看: 265

在Linux中,可以在用户空间使用sysfs和mmap(/dev/mem)方式操作GPIO,本次实验的平台为IMX8MM(飞凌OKMX8MM-C开发板),主要介绍sysfs操作GPIO步骤,并附完整代码。

使用sysfs操作GPIO

sysfs是一个基于内存的文件系统,可以向用户模式应用程序提供详细的内核数据结构信息。使用sysfs操作GPIO时,需要先导出IO口,然后设置IO方向及中断模式。具体介绍见https://www.kernel.org/doc/Documentation/gpio/sysfs.txt。

1、确定GPIO编号

使用cat /sys/kernel/debug/gpio查看GPIO信息:

root@okmx8mm:~# cat /sys/kernel/debug/gpio gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio: gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio: gpio-38 ( |? ) out hi gpio-44 ( |cd ) in hi IRQ gpio-51 ( |VSD_3V3 ) out lo gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio: gpio-80 ( |status ) out hi gpio-83 ( |usb_otg1_vbus ) out lo gpio-89 ( |WLAN_EN ) out lo gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio: gpio-118 ( |headphone detect ) in lo IRQ gpio-124 ( |GPIO Key HOME ) in hi IRQ gpio-127 ( |GPIO Key UP ) in hi IRQ gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio: gpio-130 ( |GPIO Key DOWN ) in hi IRQ gpio-137 ( |spi_imx ) out hi gpio-141 ( |spi_imx ) out hi

在这儿我要使用GPIO5_IO00,由上面gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio可以看到,GPIO5对应的编号范围为128~159,所以GPIO5_IO00对应的编号为128(128 + 0),依次类推,GPIO5_IO01的编号为129。

2、GPIO配置

进入/sys/class/gpio,可以看到以下内容:

root@okmx8mm:~# cd /sys/class/gpio root@okmx8mm:/sys/class/gpio# ls export gpiochip0 gpiochip32 gpiochip96 gpio118 gpiochip128 gpiochip64 unexport 其中export用于导出GPIO到用户空间,例如导出编号为128(GPIO5_IO00): echo 128 > export

当前目录下会生成gpio128目录,当系统重启时,导出的IO口会消失,所以每次使用时,最好先导出IO口。

unexport用于取消导出的GPIO,例如: echo 128 > unexport

这儿我需要使用GPIO5_IO00和GPIO5_IO01,所以需要运行以下指令:

echo 128 > export echo 129 > export

进入其中一个目录可以看到:

root@okmx8mm:/sys/class/gpio/gpio128# ls active_low device direction edge power subsystem uevent value

其中direction用于设置IO方向(in、out),edge用于设置中断模式(none、rising、falling、both),value用于读取IO电平,具体内容见https://www.kernel.org/doc/Documentation/gpio/sysfs.txt。

这儿我把GPIO5_IO00设置为中断输入模式,GPIO5_IO01设置为输出模式:

root@okmx8mm:/sys/class/gpio/gpio128# echo "in" > direction root@okmx8mm:/sys/class/gpio/gpio128# echo "rising" > edge root@okmx8mm:/sys/class/gpio/gpio128# cd ../gpio129 root@okmx8mm:/sys/class/gpio/gpio129# echo "out" > direction

测试时可以使用echo 1 > value设置GPIO5_IO01输出高电平;echo 0 > value设置GPIO5_IO01输出低电平。 最后配置结果如下:

root@okmx8mm:/sys/class/gpio/gpio129# cat /sys/kernel/debug/gpio gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio: gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio: gpio-38 ( |? ) out hi gpio-44 ( |cd ) in hi IRQ gpio-51 ( |VSD_3V3 ) out lo gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio: gpio-80 ( |status ) out hi gpio-83 ( |usb_otg1_vbus ) out lo gpio-89 ( |WLAN_EN ) out lo gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio: gpio-118 ( |headphone detect ) in lo IRQ gpio-124 ( |GPIO Key HOME ) in hi IRQ gpio-127 ( |GPIO Key UP ) in hi IRQ gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio: gpio-128 ( |sysfs ) in lo IRQ gpio-129 ( |sysfs ) out lo gpio-130 ( |GPIO Key DOWN ) in hi IRQ gpio-137 ( |spi_imx ) out hi gpio-141 ( |spi_imx ) out hi 3、测试

使用epoll读取GPIO5_IO00中断,并翻转GPIO5_IO01,完整代码如下:

// // Created by txfly on 2020/8/25. // #include #include #include #include #include int main(int argc, char *argv[]) { // int fd = open("/sys/class/gpio/export", O_WRONLY); // if (fd == -1){ // write(fd, "128", 3); // write(fd, "129", 3); // } // close(fd); // 前面手动导出过,这儿就不做处理了 // 中断输入 int trigger = open("/sys/class/gpio/gpio128/value", O_RDWR | O_NONBLOCK); if (trigger == -1) { printf("Fail to open GPIO5_IO00\n"); exit(1); } // LED int led = open("/sys/class/gpio/gpio129/value", O_WRONLY); if (led == -1) { printf("Fail to open GPIO5_IO01\n"); exit(1); } // epoll int epfd = epoll_create(1); struct epoll_event ev, events; ev.events = EPOLLPRI; ev.data.fd = trigger; int n = epoll_ctl(epfd, EPOLL_CTL_ADD, trigger, &ev); if (n == -1) { printf("Fail to add a file descriptor to the interface. \n"); exit(1); } char buf = 0; while (1) { n = epoll_wait(epfd, &events, 1, -1); if (n > 0) { lseek(trigger, 0, SEEK_SET); n = read(trigger, &buf, 1); printf("read, buf=%c\tlen=%d\n", buf, n); if (buf == '0') { write(led, "0", 1); } else { write(led, "1", 1); } } else { break; } } close(led); close(trigger); close(epfd); }

版权声明:本文为「txfly」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://www.jianshu.com/p/0f702330bdc8



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3