GPIO communication of Android hardware communication

First, why communicate with hardware

1.1. Most of the software developers are doing server/client applications on mobile phones. To put it bluntly, these are just data processing, data storage, reading, and analysis.

1.2 But with the development of the field of intelligence, people are no longer satisfied with directly touching the hardware manually. After all, this process needs to go to the machine first, reach out and press a button to control a certain behavior of the machine, and more want to pass a Small mobile phones can control more things, such as controlling cars, controlling lights, controlling any kind of machine, and even remotely controlling machines thousands of miles away. At this time, simple upper-layer applications can no longer meet the requirements, and some kind of persistent connection with the hardware needs to be established to facilitate the control of the hardware at all times.

Two, GPIO introduction

2.1 What is gpio

GPIO (General Purpose I/O Ports) means general-purpose input/output ports. In layman's terms, it is some pins through which high and low levels can be output or the state of the pins can be read through them-whether it is high or low. level

GPIO is the pin of the chip, the pin is programmable, and the working mode of the pin can be set: input mode (detecting input signal), output mode (output 0 or 1). It can be used for embedded development, driver development and so on.

2.2 Example of a simple control light

As shown in the figure above, when the GPIO port of P21 outputs 1, LED403 lights up, and when it outputs 0 or no output, LED403 goes out. Call the function of pulling the GPIO port high when the light needs to be turned on, and call the function of pulling the GPIO port low when the light needs to be turned off to realize the control. The operation of the function eventually becomes writing data to the hardware register of this GPIO, and the state of the hardware will change as the data of the register changes. 

Three GPIO application examples

3.1 Project Background

The gpio is used in an access control face recognition unlocking system. The face recognition software runs on the android development board, and the development board is connected to open the door lock. This lock is no different from our usual motor lock. After the face recognition is successful, send the gpio command to control lock switch

3.2 gpio running process

First, check if there is a "/sys/class/gpio" folder in the system. If not, please add it when compiling the kernel:

Device Drivers
—> GPIOSupport
—> /sys/class/gpio/… (sysfsinterface)。

Instructions for using /sys/class/gpio:

1. gpio_operation operates the mapping from the IO port GPIO to the file system through the /sys/file interface;

2. The directory controlling GPIO is located at /sys/class/gpio;

3. The /sys/class/gpio/export file is used to notify the system of the GPIO pin number that needs to be exported and controlled. First, give it read and write permissions; adb
shell chmod 0666 /sys/class/gpio/export

4. /sys/class/gpio/unexport is used to notify the system to cancel the export of GPIO pin numbers, first grant it read and write permissions;
adb shell chmod 0666 /sys/class/gpio/export

5. The /sys/class/gpio/gpiochipX directory saves the information of the GPIO registers in the system, including the initial number base, register name, and total number of pins controlled by each register.

6. First, you need to calculate the pin number, pin number = register base of the control pin + number of digits of the control pin register (generally, the calculation method is different for different platforms, and it is mainly calculated according to the platform; check the gpio corresponding configuration: cat
/ sys/kernel/debug/gpio // Here you can calculate the corresponding gpio number
Check whether gpio is reused or has been applied for use: /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins

7. Write this number to /sys/class/gpio/export, such as pin 12, which can be realized by the following command in the shell. After the command is successful, the /sys/class/gpio/gpio12 directory will be generated. If there is no corresponding directory, indicating that this pin cannot be exported:
echo 12 > /sys/class/gpio/export;

8. The direction file defines the input and input directions, which can be defined as output through the following commands, and the parameters accepted by direction: in, out, high, low. in/out is set as input or output port, high/low is set as output at the same time, and the value is set to the corresponding 1/0;

echo out > direction //Set the gpio as an output port

9. The value file is the value of the port, which is 1 or 0: 1 is set to high level, and 0 is set to low level.
echo 1 > value

adb shell chmod 0666 /sys/class/gpio/export //export grant permission 0666

adb shell chmod 0666 /sys/class/gpio/unexport //unexport grants permission 0666

adb shell echo 62 > /sys/class/gpio/export //Notify the system that the GPIO62 of the control needs to be exported

adb shell chmod 0666 /sys/class/gpio/gpio62/direction //Give permission to the direction attribute of GPIO62 0666

adb shell chmod 0666 /sys/class/gpio/gpio62/value //Give permission to the value attribute of GPIO62 0666

adb shell echo out > /sys/class/gpio/gpio62/direction //write out to the direction attribute of GPIO62, set GPIO as output

adb shell echo 1 > /sys/class/gpio/gpio62/value //write 1 to the value attribute of GPIO62, set GPIO to high level
 

Four Runtime.exec () introduction

4.1 Runtime.exec() literally understands that some kind of operation is performed at runtime, and its main function is to call an external executable program or command, such as a shell command. In layman's terms, you need to run programs outside the JVM, and you need to use Runtime

4.2 Execute the steps of external program command

​​​​​​​​Step 1: Obtain an instance of this class through Runtime.getRuntime(). The Runtime class is a single instance, and each Java application has an instance of this class.

Runtime runtime=Runtime.getRuntime();

​​​​​​​​Step 2: Use the exec method to execute a string command and return a process object. A process is a process that can do some process-related things.

Process process =runtime.exec("su");

Exect related methods

// 在单独的进程中执行指定的外部可执行程序的启动路径或字符串命令
public Process exec(String command)
// 在单独的进程中执行指定命令和变量
public Process exec(String[] cmdArray)
// 在指定环境的独立进程中执行指定命令和变量
public Process exec(String command, String[] envp)
// 在指定环境的独立进程中执行指定的命令和变量
public Process exec(String[] cmdArray, String[] envp)
// 在指定环境和工作目录的独立进程中执行指定的字符串命令
public Process exec(String command, String[] envp, File dir)
// 在指定环境和工作目录的独立进程中执行指定的命令和变量
public Process exec(String[] cmdarray, String[] envp, File dir)
// 参数说明:
	cmdarray // 包含所调用命令及其参数的数组。数组第一个元素是命令,其余是参数
	envp	 // 字符串数组,其中每个元素的环境变量的设置格式为 name=value,如果子进程应该继承当前进程的环境,则该参数为null
	dir		 // 子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为null
    
// 参数cmdArray 示例:shutdown -s -t 3600
String arr[] = {"shutdown","-s","-t","3600"};
Process process = Runtime.getRuntime().exec(arr[]);
/*
注意:
	在调用这个方法时,不能将命令和参数放在一起,eg:String arr[] = {"shutdown -s -t 3600"};
	这样会导致程序把“shutdown -s -t 3600”当成是一条命令的名称,然后去查找“shutdown -s -t 3600”这条命令,它当然会找不到,所以就会报错
*/

 

Common methods:

// 导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。
int waitFor()
/*	如果已终止该子进程,此方法立即返回。
	如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程,0 表示正常终止 */

// 杀掉子进程
void destroy()

// 返回子进程的出口值,值 0 表示正常终止
int exitValue()

// 获取子进程的错误流
InputStream getErrorStream()
// 获取子进程的输入流
InputStream getInputStream()
// 获取子进程的输出流
OutputStream getOutputStream()

Step 3: The input stream and error information stream obtained through Process instance.getInputStream() and Process instance.getErrorStream() are provided by the buffer pool to the current Java program, instead of directly obtaining the standard output stream and standard error stream of the external program

The capacity of the buffer pool is fixed, so if the external program continuously outputs content to the buffer pool during operation, when the buffer pool is full, the external program will stop running until the buffer pool has space to receive the output content of the external program. (This problem will occur when using the xcopy command to copy a large number of files)

Therefore, the current Java program needs to continuously read the contents of the buffer pool to free up space for the buffer pool.

DataOutputStream os = new DataOutputStream(process.getOutputStream());

Step 4: Output stream sends instruction message 

dataOutputStream.writeBytes(instruct);
dataOutputStream.flush();
dataOutputStream.close();

4.3 Examples

public  void chmod(String instruct) {
	try {
		Runtime runtime=Runtime.getRuntime();
		Process process =runtime.exec("su");
		DataOutputStream dataOutputStream = new DataOutputStream(process.getOutputStream());
		dataOutputStream.writeBytes(instruct);
		dataOutputStream.flush();
		dataOutputStream.close();
	} catch (Exception ex) {
		ex.printStackTrace();
	}
}

 Five completion process Demo example

/**
 * 控制门禁锁的打开和关闭
 */
public class GpioEntranceGuardTest {

//gpio引脚编码变量,不同的功能有不同的引脚编码
private  String gpio_number="178";

/**
 * 初始化gpio
 */
public  void gpioInt() {
	//写入编号
	String exportPath = "echo " + gpio_number + " > /sys/class/gpio/export";
	chmod(exportPath);

	//定义输入输出方向
	String directionPath = "echo out > " + " /sys/class/gpio/gpio" + gpio_number
			+ "/direction";
	chmod(directionPath);

	//赋予引脚编号的读写权限
	String permissionGpio = "chmod 0777 /sys/class/gpio/"+gpio_number+"/value";
	chmod(permissionGpio);
}

/**
 * 获取gpio编号对应的值,即是高电屏,或低电平
 * @return
 */
public  int getValue() {
	File localFile = new File("/sys/class/gpio/gpio" + gpio_number
			+ "/value");
	if (!localFile.exists())
		System.out.println(localFile.getAbsoluteFile() + " not exist!");
	while (true) {
		try {
			FileReader localFileReader = new FileReader(localFile);
			char[] arrayOfChar = new char[1];
			int i = localFileReader.read(arrayOfChar, 0, 1);
			localFileReader.close();
			if (i == 1) {
				int j = arrayOfChar[0];
				if (j == 48)
					return 0;
				return 1;
			}
		} catch (FileNotFoundException localFileNotFoundException) {
			localFileNotFoundException.printStackTrace();
			return -1;
		} catch (IOException localIOException) {
			localIOException.printStackTrace();
			return -1;
		}
	}
}

//发送指令,设置gpio值,即设置高电屏,或低电平
public  void setValue(int paramInt) {
	String exportPath1 = "echo " + paramInt + " > /sys/class/gpio/gpio"+gpio_number+"/value";
	chmod(exportPath1);
}

/**
 * 执行外部程序指令
 * @param instruct 指令
 */
public  void chmod(String instruct) {
	try {
		Runtime runtime=Runtime.getRuntime();
		Process process =runtime.exec("su");
		DataOutputStream dataOutputStream = new DataOutputStream(process.getOutputStream());
		dataOutputStream.writeBytes(instruct);
		dataOutputStream.flush();
		dataOutputStream.close();
	} catch (Exception ex) {
		ex.printStackTrace();
	}
}

Guess you like

Origin blog.csdn.net/qq_29848853/article/details/130256038