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

wateras1   2018-4-16 13:39 楼主
mtk7688 之openwr下的gpio应用编程 在上一篇我是在终端中通过读写文件实现了对GPIO的操作(https://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 #include #include #include #include #include #include #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 #include 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原创,如需转载或用于商业用途需征得作者同意并注明出处 本帖最后由 wateras1 于 2018-4-16 13:42 编辑

    example.c (2018-4-16 13:42 上传)

    554 Bytes, 下载次数: 4

    gpio.c (2018-4-16 13:42 上传)

    6.9 KB, 下载次数: 3

    gpio.h (2018-4-16 13:42 上传)

    3.23 KB, 下载次数: 3

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

回复评论 (1)

学习
点赞  2018-4-16 14:37
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复