马上:GPIO
Rockchip-瑞芯微RK系列上的板卡,有很多GPIO,可以控制的通用引脚。我司的应用有控制LED灯,接收人体感应器高低状态(高==感应到人),控制4G模块电路开关
每个板卡方案上都会预留几组GPIO bank, 看板卡的规格书,一般都会标注着编号,硬件上的编号不是软件上的编号,不同Android版本上计算的方式也有差异,一般方案商会提供api, 或者提供软件编号
工作原理
I/O 输入输出,简单了解即可
linux sysfs 方式控制 GPIO
android 同样适用,一般方案商也采用这种方式,也有厂商隐藏IO文件,通过他们提供的sdk操作
- 访问目标GPIO目录,sys/class/gpio/ 看目标GPIO是否有挂载,没有采用export 挂载IO端口 ,
echo xx > > /sys/class/gpio/export
- 目标GPIO目录下的
direction
,有两个常用的模式 in , out ; 输入输出很好理解 - 目标GPIO目录下的
value
,也有两个常用的值0, 1; 低电平,高电平 (有些外设默认拉高电平)
Android Java层控制方式,这种效率很低效,因为是调用shell 命令了。因此我开发了JNIGpio ,效率非常高,麻烦点个关注
public class GpioControl {
// 定义GPIO输入输出方式和高低电平
public final static String GPIO_DIRECTION_IN = "in";
public final static String GPIO_DIRECTION_OUT = "out";
public final static String GPIO_VALUE_LOW = "0";
public final static String GPIO_VALUE_HIGH = "1";
public static boolean hasExportGpio(int gpio) {
File file = new File(String.format("/sys/class/gpio/gpio%s", gpio));
return file.exists();
}
public static CommandResult exportGpio(int gpio) {
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("echo ");
sBuilder.append(gpio);
sBuilder.append(" > /sys/class/gpio/export");
return rootCommand(sBuilder.toString());
}
public static CommandResult unExportGpio(int gpio) {
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("echo ");
sBuilder.append(gpio);
sBuilder.append(" > /sys/class/gpio/unexport");
return rootCommand(sBuilder.toString());
}
public static CommandResult setGpioDirection(int gpio, String direction) {
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("echo ");
sBuilder.append(direction);
sBuilder.append(String.format(Locale.ENGLISH, " > /sys/class/gpio/gpio%d/direction", gpio));
return rootCommand(sBuilder.toString());
}
public static CommandResult getGpioDirection(int gpio) {
String read = String.format(Locale.ENGLISH, "cat /sys/class/gpio/gpio%d/direction", gpio);
return rootCommand(read);
}
public static CommandResult writeGpioStatus(int gpio, String value) {
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("echo ");
sBuilder.append(value);
sBuilder.append(String.format(Locale.ENGLISH, " > /sys/class/gpio/gpio%d/value", gpio));
return rootCommand(sBuilder.toString());
}
public static CommandResult readGpioStatus(int gpio) {
String read = String.format(Locale.ENGLISH, "cat /sys/class/gpio/gpio%d/value", gpio);
return rootCommand(read);
}
public static CommandResult rootCommand(String command) {
Process process = null;
DataOutputStream os = null;
InputStream in = null;
CommandResult result = new CommandResult();
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
StringBuilder inString = new StringBuilder();
in = process.getInputStream();
while (in != null && in.available() > 0) {
inString.append((char) in.read());
}
result.flag = true;
if (!TextUtils.isEmpty(inString.toString())) {
result.content = inString.toString().replace("\n", "");
if (!TextUtils.isEmpty(result.content)) {
if (GPIO_VALUE_LOW.equals(result.content)) {
result.level = false;
} else if (GPIO_VALUE_HIGH.equals(result.content)) {
result.level = true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (in != null) {
in.close();
}
if (process != null) {
process.destroy();
}
} catch (Exception ignored) {
}
}
return result;
}
}