社区导航

 
查看: 497|回复: 1

[原创] mtk7688 之openwr下的gpio应用编程

[复制链接]

3541

TA的帖子

5

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

荣誉会员勋章

发表于 2018-4-16 13:39:02 | 显示全部楼层 |阅读模式
本帖最后由 wateras1 于 2018-4-16 13:42 编辑

                                                             mtk7688 之openwr下的gpio应用编程
             在上一篇我是在终端中通过读写文件实现了对GPIO的操作(http://bbs.eeworld.com.cn/thread-641726-1-1.html), 这篇主要是对上一篇的应用程序编写,通过读写文件来实现相关功能,相关代码如下:
#ifndef __GPIO_H__
#define __GPIO_H__

#ifdef __cplusplus
extern "C" {
#endif


/* GPIO value */
#define GPIO_HIGH     1
#define GPIO_LOW      0

/* GPIO direction code */
#define GPIO_INPUT       0
#define GPIO_OUTPUT      1
#define GPIO_OUTPUT_HIGH 2
#define GPIO_OUTPUT_LOW  3

/* GPIO error code */
#define GPIO_SUCCESS            1
#define GPIO_INVALID_RESOURCE  -1
#define GPIO_ERROR_READ        -2
#define GPIO_ERROR_WRITE       -3
#define GPIO_ERROR_DIRECTION   -4


/**
* Read specified GPIO pin
*
* @param pin_number specified the pin
*
* @return integer value of GPIO if success.
*  return negative integer error code if fail.
*/
int  gpio_read(int pin_number);



/**
* Write specified GPIO pin
*
* @param pin_number specified the pin
*
* @param value could be GPIO_HIGH or GPIO_LOW
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int  gpio_write(int pin_number, int value);


/**
* set direction of specified GPIO pin
*
* @param pin_number specified the pin
*
* @param direction could be GPIO_IN or GPIO_OUT, GPIO_OUT_HIGH, GPIO_OUT_LOW
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int  gpio_set_direction(int pin_number, int direction);

/**
* get direction of specified GPIO pin
*
* @param pin_number specified the pin
*
* @return positive integer direction code if success.
*  return negative integer error code if fail.
*/
int  gpio_get_direction(int pin_number);


/**
* export specified GPIO pin
*
* @param pin_number specified the pin
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int gpio_export(int pin_number);


/**
* unexport specified GPIO pin
*
* @param pin_number specified the pin
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int gpio_unexport(int pin_number);

/**
* Return 1 if specified GPIO pin is exported
*
* @param pin_number specified the pin
*
* @return 1 if GPIO pin is exported.
*  return 0 if GPIO pin is not exported
*/
int gpio_is_exported(int pin_number);



#ifdef __cplusplus
}
#endif


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "gpio.h"

#define FILENAME_SIZE  128

#define GPIO_PATH "/sys/class/gpio"

/**
* Export specified GPIO pin
*
* @param pin_number specified the pin
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int gpio_export(int pin_number) {
        char buf[FILENAME_SIZE];
        int  fp;
        int  length;

        if ( gpio_is_exported(pin_number) )
                return GPIO_SUCCESS;

        //write to export file
        fp = open(GPIO_PATH "/export", O_WRONLY);
        if ( fp == -1) {
                return GPIO_INVALID_RESOURCE;
        }

        length = snprintf(buf, sizeof(buf), "%d", pin_number);
        if (write(fp, buf, length * sizeof(char)) == -1) {
                close(fp);
                return GPIO_INVALID_RESOURCE;
        }

        close(fp);
        return gpio_is_exported(pin_number);
}


/**
* Return 1 if specified GPIO pin is exported
*
* @param pin_number specified the pin
*
* @return 1 if GPIO pin is exported.
*  return 0 if GPIO pin is not exported
*/
int gpio_is_exported(int pin_number) {
        char  buf[FILENAME_SIZE];
        struct stat dir;

        //check if the gpioXX directory exists
        snprintf(buf, sizeof(buf), GPIO_PATH "/gpio%d/", pin_number);
        if (stat(buf, &dir) == 0 && S_ISDIR(dir.st_mode)) {
                return GPIO_SUCCESS;
        } else {
                return 0;
        }
}


/**
* unexport specified GPIO pin
*
* @param pin_number specified the pin
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int gpio_unexport(int pin_number) {
        char buf[FILENAME_SIZE];
        int  fp;
        int  length;

        //write to unexport file
        fp = open(GPIO_PATH "/unexport", O_WRONLY);
        if ( fp == -1) {
                return GPIO_INVALID_RESOURCE;
        }

        length = snprintf(buf, sizeof(buf), "%d", pin_number);
        if (write(fp, buf, length * sizeof(char)) == -1) {
                close(fp);
                return GPIO_INVALID_RESOURCE;
        }

        close(fp);
        return GPIO_SUCCESS;
}


/**
* Read specified GPIO pin
*
* @param pin_number specified the pin
*
* @return integer value of GPIO if success.
*  return negative integer error code if fail.
*/
int  gpio_read(int pin_number) {
        char buf[FILENAME_SIZE];
        int  fp;

        if ( !gpio_is_exported(pin_number) ) {
                if ( 1 != gpio_export(pin_number) )
                        return GPIO_INVALID_RESOURCE;
        }

        //read value file
        snprintf(buf, sizeof(buf),  "%s/gpio%d/value", GPIO_PATH, pin_number);
        fp = open(buf, O_RDWR);
        if ( fp == -1) {
                return GPIO_INVALID_RESOURCE;
        }

        if ( lseek(fp, 0, SEEK_SET) < 0 ) {
                close(fp);
        }


        if (read(fp, buf, 2 * sizeof(char)) != 2) {
                close(fp);
                return GPIO_ERROR_READ;
        }

        close(fp);

        return (int) strtol(buf, NULL, 10);
}


/**
* Write specified GPIO pin
*
* @param pin_number specified the pin
*
* @param value  could be GPIO_HIGH or GPIO_LOW
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int  gpio_write(int pin_number, int value) {
        char buf[FILENAME_SIZE];
        int  fp;
        int  length;


        if ( !gpio_is_exported(pin_number) ) {
                if ( 1 != gpio_export(pin_number) )
                        return GPIO_INVALID_RESOURCE;
        }

        //write to value file
        snprintf(buf, sizeof(buf),  "%s/gpio%d/value", GPIO_PATH, pin_number);
        fp = open(buf, O_RDWR);
        if ( fp == -1) {
                return GPIO_INVALID_RESOURCE;
        }

        if ( lseek(fp, 0, SEEK_SET) < 0 ) {
                close(fp);
        }

        length = snprintf(buf, sizeof(buf), "%d", value);
        if ( write(fp, buf, length * sizeof(char)) == -1) {
                close(fp);
                return GPIO_ERROR_WRITE;
        }

        close(fp);

        return GPIO_SUCCESS;
}


/**
* set direction of specified GPIO pin
*
* @param pin_number specified the pin
*
* @param direction could be GPIO_INPUT or GPIO_OUTPUT, GPIO_OUTPUT_HIGH, GPIO_OUTPUT_LOW
*
* @return 1 if success.
*  return negative integer error code if fail.
*/
int  gpio_set_direction(int pin_number, int direction) {
        char buf[FILENAME_SIZE];
        int  fp;
        int  length;

        if ( !gpio_is_exported(pin_number) ) {
                if ( 1 != gpio_export(pin_number) )
                        return GPIO_INVALID_RESOURCE;
        }

        //write direction file
        snprintf(buf, sizeof(buf),  "%s/gpio%d/direction", GPIO_PATH, pin_number);
        fp = open(buf, O_RDWR);
        if ( fp == -1) {
                return GPIO_INVALID_RESOURCE;
        }

        if ( lseek(fp, 0, SEEK_SET) < 0 ) {
                close(fp);
                return GPIO_INVALID_RESOURCE;
        }

        switch (direction) {
                case GPIO_OUTPUT:
                        length = snprintf(buf, sizeof(buf), "out");
                        break;
                case GPIO_INPUT:
                        length = snprintf(buf, sizeof(buf), "in");
                        break;
                case GPIO_OUTPUT_HIGH:
                        length = snprintf(buf, sizeof(buf), "high");
                        break;
                case GPIO_OUTPUT_LOW:
                        length = snprintf(buf, sizeof(buf), "low");
                        break;
                default:
                        close(fp);
                        return GPIO_ERROR_DIRECTION;
        }

        if (write(fp, buf, length * sizeof(char)) == -1) {
                close(fp);
                return GPIO_ERROR_WRITE;
        }

        close(fp);

        return GPIO_SUCCESS;
}


/**
* get direction of specified GPIO pin
*
* @param pin_number specified the pin
*
* @return positive integer direction code if success.
*  return negative integer error code if fail.
*/
int  gpio_get_direction(int pin_number) {
        char buf[FILENAME_SIZE];
        int  fp;
        int  length;
        int  result;

        if ( !gpio_is_exported(pin_number) ) {
                if ( 1 != gpio_export(pin_number) )
                        return GPIO_INVALID_RESOURCE;
        }

        //read direction file
        snprintf(buf, sizeof(buf),  "%s/gpio%d/direction", GPIO_PATH, pin_number);
        fp = open(buf, O_RDONLY);
        if ( fp == -1) {
                return GPIO_INVALID_RESOURCE;
        }

        if ( lseek(fp, 0, SEEK_SET) < 0 ) {
                close(fp);
                return GPIO_INVALID_RESOURCE;
        }

        memset(buf, '\0', sizeof(buf));
        length = read(fp, buf, sizeof(buf));
        close(fp);

        if (length <= 0) {
                return GPIO_INVALID_RESOURCE;
        }

        if (strncmp(buf, "out", 3) == 0) {
                result = GPIO_OUTPUT;
        } else if (strncmp(buf, "in", 2) == 0) {
                result = GPIO_INPUT;
        } else if (strncmp(buf, "high", 4) == 0) {
                result = GPIO_OUTPUT_HIGH;
        } else if (strncmp(buf, "low", 3) == 0) {
                result = GPIO_OUTPUT_LOW;
        } else {
                result = GPIO_ERROR_DIRECTION;
        }

        return result;

}



#include "gpio.h"
#include <unistd.h>
#include <stdio.h>

void blink(int pin) {
        printf("blink GPIO %d for 100 times\n", pin);
        fflush(stdout);

        if ( 1 == gpio_export(pin) ) {
                if ( 1 == gpio_set_direction(pin, GPIO_OUTPUT) ) {
                        //blink
                        int value = GPIO_HIGH;
                        int i;
                        for ( i = 0; i < 100; i++ ) {
                                printf("blink %d\n", i);
                                value = (value == GPIO_HIGH) ? GPIO_LOW : GPIO_HIGH;
                                gpio_write( pin, value );
                                sleep(1);
                        }
                }
        }
}



int main() {
        blink(11);  //blink on gpio11
}


  
这个GPIO封装的还是不错,对于已经集成了相关GPIO驱动的功能的openwrt来说,还是很方便的,这个主要涉及linux的应用开发,没有涉及到具体的GPIO的驱动+GPIO的应用开发,灵活性感觉还是很一般,接下来我就完整的围绕openwrt系统来实现一个GPIO的闪烁的功能,
主要涉及到GPIO的驱动的编写以及内核加载,GPIO应用开发的编写以及opkg的安装。

此内容由EEWORLD论坛网友wateras1原创,如需转载或用于商业用途需征得作者同意并注明出处


此帖出自RF/无线论坛

example.c

554 Bytes, 下载次数: 3

gpio.c

6.9 KB, 下载次数: 2

gpio.h

3.23 KB, 下载次数: 2

淘宝:https://viiot.taobao.com/Q群243090717
多年专业物联网行业经验,个人承接各类物联网外包项目


回复

使用道具 举报

1838

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-4-16 14:37:46 | 显示全部楼层
学习


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2018-12-16 16:49 , Processed in 0.905192 second(s), 16 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表