文件IO方式操作GPIO

来源:互联网 发布:cad制作软件 编辑:程序博客网 时间:2024/06/17 03:30
原文地址:http://blog.csdn.net/xukai871105/article/details/38456079
0 前言
    本文描述如果通过文件IO sysfs方式控制EasyARM GPIO端口。通过sysfs方式控制GPIO,先访问/sys/class/gpio目录,向export文件写入GPIO编号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO方向,而value可控制GPIO输出或获得GPIO输入。
    Linux学习可从应用出发,先不纠结Linux驱动编写,先把Linux给玩起来。

    【相关博文】
    【EasyARM i.mx28学习笔记——安装和使用tftp】
    【树莓派学习笔记——Shell脚本操作GPIO】
    【 Linux学习笔记——例说makefile 索引博文】

    【代码仓库】
    代码仓库位于bitbucket——easyarm-gpio-sysfs,请使用Hg克隆或者直接下载zip包。请不要使用任何版本的IE浏览器访问链接,除非你已经知道所使用的IE浏览器符合HTML5标准。推荐使用谷歌或者火狐浏览器访问,若使用国产双核浏览器请切换到极速模式。

1 暴露GPIO操作接口
[cpp] view plain copy
  1. static int gpio_export(int pin)  
  2. {  
  3.     char buffer[BUFFER_MAX];  
  4.     int len;  
  5.     int fd;  
  6.   
  7.     fd = open("/sys/class/gpio/export", O_WRONLY);  
  8.     if (fd < 0) {  
  9.         fprintf(stderr, "Failed to open export for writing!\n");  
  10.         return(-1);  
  11.     }  
  12.   
  13.     len = snprintf(buffer, BUFFER_MAX, "%d", pin);  
  14.     if (write(fd, buffer, len) < 0) {  
  15.         fprintf(stderr, "Fail to export gpio!");  
  16.         return -1;  
  17.     }  
  18.      
  19.     close(fd);  
  20.     return 0;  
  21. }  

2 隐藏GPIO操作接口
[cpp] view plain copy
  1. static int gpio_unexport(int pin)  
  2. {  
  3.     char buffer[BUFFER_MAX];  
  4.     int len;  
  5.     int fd;  
  6.   
  7.     fd = open("/sys/class/gpio/unexport", O_WRONLY);  
  8.     if (fd < 0) {  
  9.         fprintf(stderr, "Failed to open unexport for writing!\n");  
  10.         return -1;  
  11.     }  
  12.   
  13.     len = snprintf(buffer, BUFFER_MAX, "%d", pin);  
  14.     if (write(fd, buffer, len) < 0) {  
  15.         fprintf(stderr, "Fail to unexport gpio!");  
  16.         return -1;  
  17.     }  
  18.      
  19.     close(fd);  
  20.     return 0;  
  21. }  

3 配置GPIO方向
[cpp] view plain copy
  1. static int gpio_direction(int pin, int dir)  
  2. {  
  3.     static const char dir_str[] = "in\0out";  
  4.     char path[DIRECTION_MAX];  
  5.     int fd;  
  6.   
  7.     snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);  
  8.     fd = open(path, O_WRONLY);  
  9.     if (fd < 0) {  
  10.         fprintf(stderr, "failed to open gpio direction for writing!\n");  
  11.         return -1;  
  12.     }  
  13.   
  14.     if (write(fd, &dir_str[dir == IN ? 0 : 3], dir == IN ? 2 : 3) < 0) {  
  15.         fprintf(stderr, "failed to set direction!\n");  
  16.         return -1;  
  17.     }  
  18.   
  19.     close(fd);  
  20.     return 0;  
  21. }  
    【简单说明】
    【1】dir_str[dir == IN ? 0 : 3], dir == IN ? 2 : 3 如果输入为常数宏IN, 取dir_str[0]=“in”;若输入常数宏为OUT,取dir_str[0]=“out”。此处巧妙的使用了在数组中的“\0”。

4 控制GPIO输出
[cpp] view plain copy
  1. static int gpio_write(int pin, int value)  
  2. {  
  3.     static const char values_str[] = "01";  
  4.     char path[DIRECTION_MAX];  
  5.     int fd;  
  6.   
  7.     snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", pin);  
  8.     fd = open(path, O_WRONLY);  
  9.     if (fd < 0) {  
  10.         fprintf(stderr, "failed to open gpio value for writing!\n");  
  11.         return -1;  
  12.     }  
  13.   
  14.     if (write(fd, &values_str[value == LOW ? 0 : 1], 1) < 0) {  
  15.         fprintf(stderr, "failed to write value!\n");  
  16.         return -1;  
  17.     }  
  18.   
  19.     close(fd);  
  20.     return 0;  
  21. }  

5 获得GPIO输入
[cpp] view plain copy
  1. static int gpio_read(int pin)  
  2. {  
  3.     char path[DIRECTION_MAX];  
  4.     char value_str[3];  
  5.     int fd;  
  6.   
  7.     snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", pin);  
  8.     fd = open(path, O_RDONLY);  
  9.     if (fd < 0) {  
  10.         fprintf(stderr, "failed to open gpio value for reading!\n");  
  11.         return -1;  
  12.     }  
  13.   
  14.     if (read(fd, value_str, 3) < 0) {  
  15.         fprintf(stderr, "failed to read value!\n");  
  16.         return -1;  
  17.     }  
  18.   
  19.     close(fd);  
  20.     return (atoi(value_str));  
  21. }  

6 GPIO翻转操作
    【main函数】
[cpp] view plain copy
  1. int main(int argc, char *argv[])  
  2. {  
  3.     int i = 0;  
  4.     gpio_export(P24);  
  5.   
  6.     gpio_direction(P24, OUT); // GPIO为输出状态  
  7.     for (i = 0; i < 10; i++) {  
  8.         printf("LED Blink\n");  
  9.         gpio_write(P24, i % 2);  
  10.         usleep(500 * 1000);  
  11.     }  
  12.     gpio_write(P24, 0); // 恢复输出低电平  
  13.   
  14.     gpio_unexport(P24);  
  15.     return 0;  
  16. }  

    【makefile】——此处的代码tab显示可能存在问题,请以代码仓库为主。
[plain] view plain copy
  1. # 可执行文件  
  2. TARGET=test  
  3. # 源文件  
  4. SRCS=gpio-sysfs.c  
  5.   
  6. # 目标文件  
  7. OBJS=$(SRCS:.c=.o)  
  8.   
  9. # 指令编译器和选项  
  10. CROSS=arm-fsl-linux-gnueabi-  
  11. CC=$(CROSS)gcc  
  12. STRIP=$(CROSS)strip  
  13. CFLAGS=-Wall -std=gnu99 -O2  
  14.   
  15. $(TARGET):$(OBJS)  
  16.  $(CC) -o $@ $^  
  17.  $(STRIP) $@  
  18.   
  19. clean:  
  20.  rm -rf $(TARGET) $(OBJS)  
  21.   
  22. # 连续动作,先清除再编译链接,复制到tftpboot中  
  23. install:clean $(TARGET)  
  24.  @echo 复制到tftpboot目录  
  25.  cp $(TARGET) ~/tftpboot  
  26.  @echo 复制结束  
  27.   
  28. # 编译规则 $@代表目标文件 $< 代表第一个依赖文件  
  29. %.o:%.c  
  30.  $(CC) $(CFLAGS) -o $@ -c $< 
阅读全文
0 0
原创粉丝点击