www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式IoT

1. 說(shuō)明

在Linux中,可以對(duì)GPIO進(jìn)行相關(guān)的控制,具體的做法就是利用字符設(shè)備驅(qū)動(dòng)程序?qū)ο嚓P(guān)的gpio進(jìn)行控制。由于操作系統(tǒng)的限制,在Linux上又無(wú)法直接在應(yīng)用程序的層面上對(duì)底層的硬件進(jìn)行操作。本文主要通過(guò)一個(gè)點(diǎn)亮紅外燈的實(shí)例,再次理解Linux下的應(yīng)用程序與驅(qū)動(dòng)程序的交互,同時(shí)加深驅(qū)動(dòng)程序編寫流程的理解。

2.方法一:采用通用sysfs文件系統(tǒng)的方式

這種方式是利用內(nèi)核配置sysfs文件系統(tǒng)

這種方式是將gpio映射到sysfs文件系統(tǒng)中,也就是操作/sys/class/gpio里的文件來(lái)對(duì)GPIO進(jìn)行相關(guān)的配置。應(yīng)用程序可以直接操作這個(gè)文件對(duì)GPIO進(jìn)行設(shè)置。

如果采用腳本的方式:

#bin/bash echo 87 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio87/direction
echo 1 > /sys/class/gpio/gpio87/value

以上的腳本中首先需要計(jì)算GPIO的編號(hào),比如需要采用PC(23),那么C組是第三組那么可以利用公式

其中num是GPIO的編號(hào),n是第幾組gpio,m是當(dāng)前的gpio的序號(hào)。經(jīng)過(guò)計(jì)算PC23的GPIO編號(hào)為87。

所以當(dāng)執(zhí)行

echo 87 > /sys/class/gpio/export 

會(huì)在/sys/class/gpio/文件夾中生成gpio87這個(gè)目錄,里面有些文件可以設(shè)置GPIO的值。

執(zhí)行echo out > /sys/class/gpio/gpio87/direction表示設(shè)置該GPIO為輸出,最后向GPIO寫值即可。

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

以上的方式實(shí)踐起來(lái)比較的容易,應(yīng)用程序完全不需要關(guān)注底層驅(qū)動(dòng)做了哪些事情,只是按照步驟進(jìn)行操作即可,程序的可預(yù)知性不強(qiáng)。但是操作簡(jiǎn)單。

如果要用在C程序中,也可以分為以下幾步:

第一步:在/sys/class/gpio/生成gpio相關(guān)的文件夾

第二步:設(shè)置gpio輸入輸出方向

第三步:寫gpio的值

具體操作代碼可以參考附錄1:采用sysfs文件系統(tǒng)的方式控制GPIO。

3. 方法二:自己編寫GPIO驅(qū)動(dòng)的方式

該方式主要利用字符設(shè)備驅(qū)動(dòng)程序,通過(guò)ioctl函數(shù)進(jìn)行控制。相比用sysfs文件系統(tǒng)的方式,這種方式的操作流程更加的清晰。但是需要完成的工作量較大,既要理解驅(qū)動(dòng)又要熟悉Linux應(yīng)用編程。下面來(lái)介紹這種方式。

3.1 什么是ioctl

ioctl是設(shè)備驅(qū)動(dòng)程序中對(duì)設(shè)備的I/O通道進(jìn)行管理的函數(shù)。所謂對(duì)I/O通道進(jìn)行管理,就是對(duì)設(shè)備的一些特性進(jìn)行控制。其函數(shù)原型如下:

#include  int ioctl(int fd, int cmd, ...);

ioctl()執(zhí)行成功時(shí)返回0,失敗則返回-1并設(shè)置全局變量errorno值。

其中函數(shù)中的參數(shù)cmd交互協(xié)議可以劃分為四個(gè)位段:

對(duì)于cmd的宏的定義如下:

// include/uapi/asm-generic/ioctl.h /* used to create numbers */ #define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0) #define _IOR(type,nr,size)  _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) #define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) 

對(duì)于實(shí)際gpio驅(qū)動(dòng)的編寫,我們可以做如下的交互協(xié)議

#define IOCTL_MAGIC 'g' #define GPIO_OUT_LOW        _IOW(IOCTL_MAGIC, 0x00, unsigned long) #define GPIO_OUT_HIG        _IOW(IOCTL_MAGIC, 0x01, unsigned long) #define GPIO_INPUT            _IOR(IOCTL_MAGIC, 0x02, unsigned long) 

3.2 gpio驅(qū)動(dòng)程序的編寫

gpio屬于字符設(shè)備驅(qū)動(dòng),所以可以通過(guò)字符設(shè)備驅(qū)動(dòng)程序的框架來(lái)完善gpio控制驅(qū)動(dòng)。

先寫出模板

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  /*DEV INIT*/ static int __init gpio_init(void) {
} /*DEV EXIT*/ static void __exit gpio_exit(void) {
}

module_init(gpio_init);
module_exit(gpio_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("ZFJ");
MODULE_DESCRIPTION("GPIO driver for test");

然后完善里面的功能。需要申請(qǐng)字符設(shè)備驅(qū)動(dòng),并且提供write,read和ioctl函數(shù)。

安裝字符設(shè)備驅(qū)動(dòng)函數(shù)的通用寫法

第一步:申請(qǐng)?jiān)O(shè)備號(hào)

可以采用register_chrdev_region進(jìn)行靜態(tài)申請(qǐng)或者采用alloc_chrdev_region動(dòng)態(tài)申請(qǐng)?jiān)O(shè)備號(hào)。

第二步:注冊(cè)字符設(shè)備

在這一步中,需要向內(nèi)核注冊(cè)設(shè)備,并且填充fops結(jié)構(gòu)體,完善read,write及ioctl函數(shù),由于這里只是控制gpio,所以只會(huì)用到ioctl函數(shù)。

第三步:向sysfs文件系統(tǒng)注冊(cè)設(shè)備

通過(guò)調(diào)用class_create函數(shù),可以向sysfs注冊(cè)設(shè)備。

第四步:生成設(shè)備節(jié)點(diǎn)

通過(guò)調(diào)用device_create生成設(shè)備節(jié)點(diǎn),應(yīng)用程序通過(guò)控制設(shè)備節(jié)點(diǎn)來(lái)對(duì)gpio進(jìn)行控制。

以上的具體代碼可以參考附錄2:GPIO驅(qū)動(dòng)程序。

3.3 編譯及驗(yàn)證

程序編寫完成后,編譯內(nèi)核驅(qū)動(dòng)程序需要編寫Makefile文件。具體的程序代碼可以參考附錄。

obj-m:=gpio.o KDIR:=/home/xxx/xxx/xxx/kernel #內(nèi)核的具體目錄 PWD:=$(shell pwd) all: make ARCH=mips CROSS_COMPILE=mips-linux-gnu- -C $(KDIR) M=$(PWD) modules clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *symvers *Module.markers

在宿主機(jī)上交叉編譯后會(huì)生成.ko文件,將該文件傳到開發(fā)板即可。

在開發(fā)板上,輸入insmod gpio.ko看到掛載完成表示成功。

如果要測(cè)試該驅(qū)動(dòng)程序是否成功,可以寫一個(gè)測(cè)試程序來(lái)進(jìn)行測(cè)試。

測(cè)試程序可以讓其輸入兩個(gè)參數(shù),第一個(gè)是傳入的GPIO的編號(hào),第二個(gè)是GPIO的電平,用字符串on/off來(lái)表示。

核心操作就是

第一步:打開設(shè)備

gpiofd = open("/dev/gpiodrv0", O_RDWR)

第二步:通過(guò)ioctl進(jìn)行引腳設(shè)置

ioctl(gpiofd, gpio_state, gpio)

目前設(shè)置的引腳狀態(tài)如下

第三步:關(guān)閉設(shè)備

close(gpiofd);

經(jīng)過(guò)以上幾步,即可編寫一個(gè)完整的測(cè)試程序。

最后是進(jìn)行交叉編譯生成可執(zhí)行文件即可。下面是TFM_V2上點(diǎn)亮紅外燈的操作。

測(cè)試程序的代碼可以參考附錄3:測(cè)試程序。

4. 將GPIO驅(qū)動(dòng)集成到內(nèi)核中

由于前面已經(jīng)將問(wèn)題驅(qū)動(dòng)模塊單獨(dú)編譯,此時(shí)若想集成到內(nèi)核中,則需要做以下幾件事:

4.1 向內(nèi)核中添加文件

由于GPIO驅(qū)動(dòng)屬于字符設(shè)備驅(qū)動(dòng),所以應(yīng)該放在kernel/drivers/char目錄中。

4.2 修改Kconfig

如果要通過(guò)配置manuconfig配置是否選擇gpio,則需要配置Kconfig。這樣可以通過(guò)宏來(lái)控制是否加載驅(qū)動(dòng)模塊。

這里選擇在頭部添加這一條。此時(shí)查看圖形配置界面

4.3 讓驅(qū)動(dòng)編譯到內(nèi)核中

通過(guò)Kconfig只是選擇了編譯的宏,如果讓驅(qū)動(dòng)正真編譯到內(nèi)核中,還需要修改Makefile。也就是修改kernel/drivers/char/Makefile

這個(gè)宏表示當(dāng)配置了TFM_V2_GPIO宏時(shí),tfmv2_gpio.c將會(huì)編譯成驅(qū)動(dòng),內(nèi)核啟動(dòng)時(shí),該驅(qū)動(dòng)自動(dòng)加載。

下圖是Linux啟動(dòng)后自動(dòng)加載的tfm_v2的gpio驅(qū)動(dòng)。

同時(shí)啟動(dòng)后再dev目錄中可以看到生成的設(shè)備

5. 總結(jié)

由于應(yīng)用層不能直接操作gpio,但是應(yīng)用程序可以調(diào)用驅(qū)動(dòng)程序的接口來(lái)操作gpio。這也是為什么控制gpio這么麻煩的原因。

文章中敘述了兩種操作gpio的辦法,第一種是利用sysfs文件系統(tǒng)的方式,這種方式操作起來(lái)簡(jiǎn)單,方便應(yīng)用程序的調(diào)用,第二種是寫一個(gè)驅(qū)動(dòng)函數(shù)的方式,通過(guò)ioctl進(jìn)行控制,這種辦法雖然操作起來(lái)比較麻煩,但是app調(diào)用起來(lái)也比較容易。并且可以知道調(diào)用過(guò)程,思路清晰。

通過(guò)這次的總結(jié),對(duì)Linux的驅(qū)動(dòng)的內(nèi)核層與應(yīng)用層要區(qū)分清楚,同時(shí)也加深對(duì)驅(qū)動(dòng)程序編寫流程的理解。

附錄1:采用sysfs文件系統(tǒng)的方式控制GPIO

/* Copyright (c) 2011, RidgeRun
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the RidgeRun.
 * 4. Neither the name of the RidgeRun nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ #include  #include  #include  #include  #include  #include  #include  /****************************************************************
 * Constants
 ****************************************************************/ #define SYSFS_GPIO_DIR "/sys/class/gpio" #define POLL_TIMEOUT (3 * 1000) /* 3 seconds */ #define MAX_BUF 64 /****************************************************************
 * gpio_export
 ****************************************************************/ int gpio_export(unsigned int gpio) { int fd, len; char buf[MAX_BUF];

 fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY); if (fd < 0) {
 perror("gpio/export"); return fd;
 }

 len = snprintf(buf, sizeof(buf), "%d", gpio);
 write(fd, buf, len);
 close(fd); return 0;
} /****************************************************************
 * gpio_unexport
 ****************************************************************/ int gpio_unexport(unsigned int gpio) { int fd, len; char buf[MAX_BUF];

 fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY); if (fd < 0) {
 perror("gpio/export"); return fd;
 }

 len = snprintf(buf, sizeof(buf), "%d", gpio);
 write(fd, buf, len);
 close(fd); return 0;
} /****************************************************************
 * gpio_set_dir
 ****************************************************************/ int gpio_set_dir(unsigned int gpio, unsigned int out_flag) { int fd, len; char buf[MAX_BUF];

 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);

 fd = open(buf, O_WRONLY); if (fd < 0) {
 perror("gpio/direction"); return fd;
 } if (out_flag)
 write(fd, "out", 4); else write(fd, "in", 3);

 close(fd); return 0;
} /****************************************************************
 * gpio_set_value
 ****************************************************************/ int gpio_set_value(unsigned int gpio, unsigned int value) { int fd, len; char buf[MAX_BUF];

 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);

 fd = open(buf, O_WRONLY); if (fd < 0) {
 perror("gpio/set-value"); return fd;
 } if (value)
 write(fd, "1", 2); else write(fd, "0", 2);

 close(fd); return 0;
} /****************************************************************
 * gpio_get_value
 ****************************************************************/ int gpio_get_value(unsigned int gpio, unsigned int *value) { int fd, len; char buf[MAX_BUF]; char ch;

 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);

 fd = open(buf, O_RDONLY); if (fd < 0) {
 perror("gpio/get-value"); return fd;
 }

 read(fd, &ch, 1); if (ch != '0') {
 *value = 1;
 } else {
 *value = 0;
 }

 close(fd); return 0;
} /****************************************************************
 * gpio_set_edge
 ****************************************************************/ int gpio_set_edge(unsigned int gpio, char *edge) { int fd, len; char buf[MAX_BUF];

 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);

 fd = open(buf, O_WRONLY); if (fd < 0) {
 perror("gpio/set-edge"); return fd;
 }

 write(fd, edge, strlen(edge) + 1);
 close(fd); return 0;
} /****************************************************************
 * gpio_fd_open
 ****************************************************************/ int gpio_fd_open(unsigned int gpio) { int fd, len; char buf[MAX_BUF];

 len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);

 fd = open(buf, O_RDONLY | O_NONBLOCK ); if (fd < 0) {
 perror("gpio/fd_open");
 } return fd;
} /****************************************************************
 * gpio_fd_close
 ****************************************************************/ int gpio_fd_close(int fd) { return close(fd);
} /****************************************************************
 * Main
 ****************************************************************/ int main(int argc, char **argv, char **envp) { struct pollfd fdset[2]; int nfds = 2; int gpio_fd, timeout, rc; char *buf[MAX_BUF]; unsigned int gpio; int len; if (argc < 2) { printf("Usage: gpio-int\n\n"); printf("Waits for a change in the GPIO pin voltage level or input on stdin\n"); exit(-1);
 }

 gpio = atoi(argv[1]);

 gpio_export(gpio);
 gpio_set_dir(gpio, 0);
 gpio_set_edge(gpio, "rising");
 gpio_fd = gpio_fd_open(gpio);

 timeout = POLL_TIMEOUT; while (1) { memset((void*)fdset, 0, sizeof(fdset));

 fdset[0].fd = STDIN_FILENO;
 fdset[0].events = POLLIN;

 fdset[1].fd = gpio_fd;
 fdset[1].events = POLLPRI;

 rc = poll(fdset, nfds, timeout); if (rc < 0) { printf("\npoll() failed!\n"); return -1;
 } if (rc == 0) { printf(".");
 } if (fdset[1].revents & POLLPRI) {
 len = read(fdset[1].fd, buf, MAX_BUF); printf("\npoll() GPIO %d interrupt occurred\n", gpio);
 } if (fdset[0].revents & POLLIN) {
 (void)read(fdset[0].fd, buf, 1); printf("\npoll() stdin read 0x%2.2X\n", (unsigned int) buf[0]);
 }

 fflush(stdout);
 }

 gpio_fd_close(gpio_fd); return 0;
}

附錄2:GPIO驅(qū)動(dòng)程序

/**
 * drviers/char/tfmv2_gpio.c
 *
 * GPIO driver
 *
 */ #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define DEVICE_NAME "gpiodrv" #define GPIO_MAJOR            0 #define IOCTL_MAGIC 'g' #define GPIO_OUT_LOW        _IOW(IOCTL_MAGIC, 0x00, unsigned long) #define GPIO_OUT_HIG        _IOW(IOCTL_MAGIC, 0x01, unsigned long) #define GPIO_INPUT            _IOR(IOCTL_MAGIC, 0x02, unsigned long) static struct cdev cdev; static struct class *gpio_class; static dev_t devno; /*OPEN*/ static int gpio_open(struct inode *inode, struct file *filp) { int ret = 0;

 filp->private_data = &cdev; return ret;
} /*RELEASE*/ static int gpio_release(struct inode *inode, struct file *filp) { return 0;
} /*READ*/ static ssize_t gpio_read(struct file *filp, char __user *buff, size_t count, loff_t *offp) { return 0;
} /*IOCTL*/ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int ret = 0,err = 0; if (_IOC_TYPE(cmd) != IOCTL_MAGIC) return -EINVAL; if (arg > 128) return -EINVAL; //申請(qǐng)gpio引腳 err = gpio_request(arg,NULL); if(err)
 { //printk("gpio_ioctl request err!\n"); } switch(cmd) { case GPIO_OUT_LOW:
 gpio_direction_output(arg,0); break; case GPIO_OUT_HIG:
 gpio_direction_output(arg,1); break; case GPIO_INPUT:
 gpio_direction_input(arg);
 ret = gpio_get_value(arg); break; default:
 ret = -EINVAL; break;
 } return ret;
} static struct file_operations gpio_fops = { .owner = THIS_MODULE,
 .open = gpio_open,
 .release = gpio_release,
 .read = gpio_read,
 .unlocked_ioctl = gpio_ioctl,

}; /*DEV SETUP*/ static int gpio_setup(struct cdev *cdevp, dev_t dev) { int ret = 0;

 cdev_init(cdevp, &gpio_fops);
 cdevp->owner = THIS_MODULE;
 cdevp->ops = &gpio_fops;
 ret = cdev_add(cdevp, dev, 1); if (ret)
 printk(KERN_ALERT"add gpio setup failed!\n"); return ret;
} /*DEV INIT*/ static int __init gpio_init(void) { struct device *dev; int ret; unsigned int gpio_major;

 printk("init gpio driver module...\n"); //1.申請(qǐng)主次設(shè)備號(hào) devno = MKDEV(GPIO_MAJOR, 0);
 gpio_major = MAJOR(devno); if (gpio_major)
 ret = register_chrdev_region(devno, 1, DEVICE_NAME); else ret = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME); if (ret < 0) {
 printk(KERN_ALERT"failed in registering dev.\n"); return ret;
 } //2.加入字符設(shè)備結(jié)構(gòu)體 ret = gpio_setup(&cdev, devno); if (ret < 0) {
 printk(KERN_ALERT"failed in setup dev.\n"); return ret;
 } //3.在class目錄中創(chuàng)建文件 gpio_class = class_create(THIS_MODULE, DEVICE_NAME); if (IS_ERR(gpio_class)) {
 printk(KERN_ALERT"failed in creating class.\n"); return -1;
 } //4.生成設(shè)備節(jié)點(diǎn) dev = device_create(gpio_class, NULL, devno, NULL, DEVICE_NAME "%d", 0); if (IS_ERR(dev)) {
 printk(KERN_ALERT"failed in creating class.\n"); return -1;
 } return ret;
} /*DEV EXIT*/ static void __exit gpio_exit(void) {
 cdev_del(&cdev);
 unregister_chrdev_region(devno, 1);
 device_destroy(gpio_class, devno);
 class_destroy(gpio_class);
}

module_init(gpio_init);
module_exit(gpio_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("ZFJ");
MODULE_DESCRIPTION("GPIO driver for test");

附錄三:測(cè)試程序

/**
 *  test.c
 *
 *  Copyright (C) 2014 W.J, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */ #include  #include  #include  #include  #include  #include  #include  #include  #define GPIO(X)   X #define GPIO_IOC_MAGIC 'g' /* general APIs - GPIO_IOC_MAGIC */ enum {
 IOC_OUTPUT_CLR,
 IOC_OUTPUT_SET,
 IOC_SET_INPUT,
}; #define GPIO_IOC_OUTPUT_LOW        _IOW(GPIO_IOC_MAGIC, IOC_OUTPUT_CLR, unsigned int) #define GPIO_IOC_OUTPUT_HIG        _IOW(GPIO_IOC_MAGIC, IOC_OUTPUT_SET, unsigned int) #define GPIO_IOC_INPUT            _IOR(GPIO_IOC_MAGIC, IOC_SET_INPUT, unsigned int) int main(int argc, char **argv) { int gpiofd = 0, gpio = 0; int gpio_state = 0; if (argc != 3) { printf("Usage: gpio-pin \n\n"); printf("gpio test\n"); exit(-1); 
 } 

 gpio = atoi(argv[1]); if ((gpiofd = open("/dev/gpiodrv0", O_RDWR)) < 0) {
 perror("open"); return -1;
 } if(strcmp(argv[2],"on")==0)
 {
 gpio_state = GPIO_IOC_OUTPUT_HIG;
 } else if(strcmp(argv[2],"off")==0)
 {
 gpio_state = GPIO_IOC_OUTPUT_LOW;
 } else {
 gpio_state = GPIO_IOC_INPUT;
 } if ((gpio_state = ioctl(gpiofd, gpio_state, gpio)) < 0) {
 perror("ioctl err"); return -1;
 } printf("GPIO state:%d\n", gpio_state);
 close(gpiofd); return 0;
}


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉