700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > LINUX GPIO 基操之应用层操作gpio

LINUX GPIO 基操之应用层操作gpio

时间:2022-02-03 16:28:28

相关推荐

LINUX GPIO 基操之应用层操作gpio

LINUX GPIO 基操之应用层

应用层sysfs操作GPIO相关文件节点介绍如何编写应用程序操作GPIO如何通过寄存器操作GPIO

注:所有文章基于linux-3.13 以上,本系列主要介绍 GPIO的一些基本知识,驱动操作GPIO的接口,应用层通过sysfs操作GPIO的接口,GPIO一些debug信息查看,以及对高通相关GPIO的寄存器操作。分享给刚刚接触外设bsp的小伙伴们。当然后面有时间还会分享GPIO子系统框架和pinctrl子系统框架,先知道黑盒怎么使用,然后咱再打开仔细瞅瞅。有错误不正当点,勿喷,还请指出,一起修改,谢谢!!

本篇为应用层控制接口篇,主要分享,应用层对gpio的操作和如何通过寄存器操作gpio(主要介绍高通的寄存器方式)。

应用层sysfs操作GPIO

相关文件节点介绍

1)导出节点

//下面的动作前提是要先导出对应的gpio,动态生成了对应的节点才能下一步操作echo 1 > /sys/class/gpio/export

2) 设置输入方向,读取对应的值

echo in > /sys/class/gpio/gpio1/directioncat /sys/class/gpio/gpio1/value

3)设置输出方向,设置对应的值

echo out > /sys/class/gpio/gpio1/direction//拉高echo 1 > /sys/class/gpio/gpio1/value//拉低echo 1 > /sys/class/gpio/gpio1/value

4) 设置中断触发方式

//设置的中断触发方式 none rising falling both,echo none > /sys/class/gpio/gpio1/edge// 要结合poll机制来获取对应gpio口的中断

5)销毁对应GPIO节点

echo 1 > /sys/class/gpio/unexport

如何编写应用程序操作GPIO

我们完全可以通过调用system的方式实现上面提到的前三种操作,但是无法实现中断的监控,而且system方式太消耗资源。linux里面万物皆文件,下面重点介绍如何通过open,write,poll等方式对gpio进行操作。

1)需要包含的头文件

#include stdlib.h #include stdio.h #include string.h#include unistd.h#include fcntl.h #include poll.h

2)导出一个节点

tatic int gpio_export(int pin) {char buffer[64]; int len; int fd; fd = open("/sys/class/gpio/export", O_WRONLY); if (fd < 0) {MSG("Failed to open export for writing!\n"); return(-1); } len = snprintf(buffer, sizeof(buffer), "%d", pin); if (write(fd, buffer, len) < 0) {MSG("Failed to export gpio!"); return -1; } close(fd); return 0; }

3)销毁一个节点

static int gpio_unexport(int pin) {char buffer[64]; int len; int fd; fd = open("/sys/class/gpio/unexport", O_WRONLY); if (fd < 0) {MSG("Failed to open unexport for writing!\n"); return -1; } len = snprintf(buffer, sizeof(buffer), "%d", pin); if (write(fd, buffer, len) < 0) {MSG("Failed to unexport gpio!"); return -1; } close(fd); return 0; }

4)读写一个节点

static int gpio_read(int pin) {char path[64]; char value_str[3]; int fd; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); fd = open(path, O_RDONLY); if (fd < 0) {MSG("Failed to open gpio value for reading!\n"); return -1; } if (read(fd, value_str, 3) < 0) {MSG("Failed to read value!\n"); return -1; } close(fd); return (atoi(value_str));} //value: 0-->LOW, 1-->HIGHstatic int gpio_write(int pin, int value) {static const char values_str[] = "01"; char path[64]; int fd; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); fd = open(path, O_WRONLY); if (fd < 0) {MSG("Failed to open gpio value for writing!\n"); return -1; } if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) {MSG("Failed to write value!\n"); return -1; } close(fd); return 0; }

5) 设置方向

//dir: 0-->IN, 1-->OUTstatic int gpio_direction(int pin, int dir) {static const char dir_str[] = "in\0out"; char path[64]; int fd; snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin); fd = open(path, O_WRONLY); if (fd < 0) {MSG("Failed to open gpio direction for writing!\n"); return -1; } if (write(fd, &dir_str[dir == 0 ? 0 : 3], dir == 0 ? 2 : 3) < 0) {MSG("Failed to set direction!\n"); return -1; } close(fd); return 0; }

6)中断方式设置

// none表示引脚为输入,不是中断引脚// rising表示引脚为中断输入,上升沿触发// falling表示引脚为中断输入,下降沿触发// both表示引脚为中断输入,边沿触发// 0-->none, 1-->rising, 2-->falling, 3-->bothstatic int gpio_edge(int pin, int edge){const char dir_str[] = "none\0rising\0falling\0both"; char ptr;char path[64]; int fd; switch(edge){case 0:ptr = 0;break;case 1:ptr = 5;break;case 2:ptr = 12;break;case 3:ptr = 20;break;default:ptr = 0;} snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", pin); fd = open(path, O_WRONLY); if (fd < 0) {MSG("Failed to open gpio edge for writing!\n"); return -1; } if (write(fd, &dir_str[ptr], strlen(&dir_str[ptr])) < 0) {MSG("Failed to set edge!\n"); return -1; } close(fd); return 0; }

7)监控一个gpio中断

如何通过寄存器操作GPIO

首先来看gt对应的寄存器解释

然后就是使用devmem命令来对寄存器进行操作。注意要使用devmem必须打开内核宏CONFIG_DEVMEM。

注:下面都是以sm6350为例

1)打开CONFIG_DEVMEM

CONFIG_DEVMEM=y

控制GPIO1为输出高

devmem 0xf101000 4 0x200devmem 0xf101004 4 0x2

3)控制GPIO1 为输出低

devmem 0xf101000 4 0x200devmem 0xf101004 4 0x0

4)控制GPIO1 为输出上拉和输出下拉

//上拉devmem 0xf101000 4 0x203//下拉devmem 0xf101004 4 0x201

5)控制GPIO1 为输入,同时读取其值

devmem 0xf101000 4 0x0devmem 0xf101004 //读取对应的值,第一位为1 就是高,为0就是低

bg thanks!! ay

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。