2012年10月26日 星期五

Linux GPIO user mode 使用方法

以下是 GPIO 的使用方法, interrupt 還沒試過...



 /* 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 <stdio.h>  
 #include <stdlib.h>  
 #include <string.h>  
 #include <errno.h>  
 #include <unistd.h>  
 #include <fcntl.h>  
 #include <poll.h>  
  /****************************************************************  
  * 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 <gpio-pin>\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;  
 }  







reference:https://www.ridgerun.com/developer/wiki/index.php/Gpio-int-test.c

沒有留言:

張貼留言