1. 程式人生 > >GPIO在使用者空間(Sysfs)中的檢測與控制

GPIO在使用者空間(Sysfs)中的檢測與控制

前段時間在編譯安卓系統時有對GPIO控制的需求,經過一定探索之後找到了一個解決的方案,現分享一下。

主要的思路是:通過Sysfs在使用者空間使用GPIO,核心配置時選擇sysfs下對GPIO的支援,然後系統編譯完成後,在使用者空間通過對sysfs的GPIO目錄下的相關“檔案"進行操作,完成GPIO的檢測與控制。

sysfs中GPIO的目錄為:/sys/class/gpio。目錄下包含檔案:

export:作用為建立節點為x的GPIO埠,具體操作:echo 8 > export,即建立節點號為8的gpio8,此時在/sys/class/gpio下便會多出一個子目錄gpio8/(export建立gpiox節點成功的前提是:沒有任何核心程式碼使用x號gpio埠)。

unexport:作用同export相反,是將建立的gpiox節點取消。

當gpiox建立成功後,進入gpiox目錄便可以進行相應操作:

direction:表明GPIO操作的方向,可以為:in/out,具體操作為:echo “out” > direction

value:對gpiox賦值,具體操作為:echo 1 > value。

下面將C程式碼與大家共享(可交叉編譯到不同平臺進行使用)。

<span style="font-size:14px;">   #include <stdio.h>
   #include <unistd.h>
   #include <sys/stat.h>
   #include <linux/fs.h>
   #include <fcntl.h>
   #include <string.h>
   #include <termios.h>
   #include <sys/ioctl.h>
  
 
 void tdelay(int d)
 {
     volatile int j;
     for(j=0;j<d*1000000;j++);
 }
 //int main(int argc,char **argv)
 int main(void)
 {
	int num = 0;
	for(num = 0; num < 400; num ++)
	{
		int gpio_fd = -1;
		int ret;
   
		char gpio[100];
		sprintf(gpio,"%u",num);
		printf("gpio:%s\n",gpio);
		char dir[]="out";
		gpio_fd = open("/sys/class/gpio/export",O_WRONLY);
		if(gpio_fd < 0){
			printf("open gpio/export failed\n");
			continue;
		}
	 
		ret = write(gpio_fd,gpio,strlen(gpio));
		if(ret < 0){
			printf("write to gpio/export failed\n");
			continue;
		}
		close(gpio_fd);
	 
	 
		char bufdir[100];
		sprintf(bufdir,"/sys/class/gpio/gpio%u/direction",num);
		gpio_fd = open(bufdir,O_RDWR);
		if(gpio_fd < 0){
			printf("open %s failed\n",bufdir);
			continue;
		}

		ret = write(gpio_fd,dir,strlen(bufdir));
		if(ret < 0){
			printf("write to %s failed\n",bufdir);
			continue;
		}
		close(gpio_fd);
	 
		char bufval[100];
		sprintf(bufval,"/sys/class/gpio/gpio%u/value",num);
		gpio_fd = open(bufval,O_RDWR);
		if(gpio_fd < 0){
			printf("open %s failed\n",bufval);
			continue;
		}
	 
     

		int i;
		char off[]="1";
		char on[] = "0";
		for(i=0;i < 10;i++){
			printf("%s led off\n",gpio);
			ret = write(gpio_fd,off,strlen(off));
			if(ret < 0){
				printf("write to %s failed\n",bufval);
				continue;
			}
			tdelay(10);
			printf("%s led on\n",gpio);
			ret = write(gpio_fd,on,strlen(on));
			if(ret < 0){
	
				printf("write to %s failed\n",bufval);
				continue;
			}
			tdelay(10);
		}
		close(gpio_fd);

		gpio_fd = open("/sys/class/gpio/unexport",O_WRONLY);
		if(gpio_fd < 0){
			printf("open gpio/unexport failed\n");
			continue;
		}
		ret = write(gpio_fd,gpio,strlen(gpio));
		if(ret < 0){
			printf("write to gpio/unexport failed\n");
			continue;
		}
		close(gpio_fd);

		printf("test gpio led ok\n");
	}
    return 0;
 }</span>