一、引言

本文主要讲解了两部分内容,但目标相同,在Android中操作硬件的GPIO口。一是用过DTS,写一个驱动程序来完成;二是用过sysfs。

二、使用sys操作GPIO

首先,看看系统中有没有“/sys/class/gpio”这个文件夹。如果没有请在编译内核的时候加入 Device Drivers —> GPIO Support —> /sys/class/gpio/… (sysfs interface)。

/sys/class/gpio 的说明:

1、 gpio_operation 通过/sys/文件接口操作IO端口 GPIO到文件系统的映射

2、 控制GPIO的目录位于/sys/class/gpio

3、 /sys/class/gpio/export文件用于通知系统需要导出控制的GPIO引脚编号

4、 /sys/class/gpio/unexport 用于通知系统取消导出

5、 /sys/class/gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数 导出一个引脚的操作步骤

使用流程

1、 首先计算此引脚编号
引脚编号 = 控制引脚的寄存器基数 + 控制引脚寄存器位数

2、 向/sys/class/gpio/export写入此编号
比如12号引脚,在shell中可以通过以下命令实现,

echo 12 > /sys/class/gpio/export

命令成功后生成/sys/class/gpio/gpio12目录,如果没有出现相应的目录,说明此引脚不可导出:
查看gpio对应配置:cat /sys/kernel/debug/gpio //这里可以对应计算出gpio号

3、 direction文件
定义输入输入方向,可以通过下面命令定义为输出

echo out > /sys/class/gpio/gpio12/direction

direction接受的参数:in, out, high, low。high/low同时设置方向为输出,并将value设置为相应的1/0。

4、设置value文件是端口的数值:
为1或0.

echo 1 >/sys/class/gpio/gpio12/value

根据sys编写控制程序

GPIO的配置文件在/sys/class/gpio目录下,控制程序可以分为四个步骤:

1、配置GPIO
在/sys/class/gpio目录下可以看到文件export,调用该文件以实现配置。该文件对所有GPIO编号,从0开始。GPIOn_x的编号为32n+x,例如此处用的GPIO1_6的编号为321+6=38。在终端输入:# echo “38” > /sys/class/gpio/export,在此回到目录/sys/class/gpio下,可以看到产生了一个新的目录./gpio38,里面包含了该IO口的输入输出设置等配置文件。注意:export文件只有root写权限,执行上述命令或者以后用C编写的可执行文件要以ROOT身份执行。

2、设置GPIO的方向(输入输出):
在终端输入:# echo “out” > /sys/class/gpio/gpio38/direction,即设置该GPIO为输出。
3、设置GPIO的输出电平
在终端输入:#echo “1” > /sys/class/gpio/gpio38/value,即设置GPIO输出高电平,输入echo “0” > /sys/class/gpio/gpio38/value设置GPIO输出低电平。
4、关闭GPIO
在终端输入:#echo “38” > /sys/class/gpio/unexport,即删除GPIO配置文件,可以看到目录gpio38已经被删除。

下面是C语言编写的GPIO控制例程,实现LED的每隔一秒闪烁一次。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
FILE *p=NULL;
int i=0;
p = fopen("/sys/class/gpio/export","w");
fprintf(p,"%d",38);
fclose(p);
p = fopen("/sys/class/gpio/gpio38/direction","w");
fprintf(p,"out");
fclose(p);
for(i=0;i<100;i++)
{
p = fopen("/sys/class/gpio/gpio38/value","w");
fprintf(p,"%d",1);
sleep(1);
fclose(p);
p = fopen("/sys/class/gpio/gpio38/value","w");
fprintf(p,"%d",0);
sleep(1);
fclose(p);
}
p = fopen("/sys/class/gpio/unexport","w");
fprintf(p,"%d",38);
fclose(p);
return 0;
}