Sysfs_gpio.c 4.4 KB

#include <stdio.h>
#include "version_choose.h"
#include "JZsdkLib.h"
#include <string.h>
#include <fcntl.h>  // 为了 open 和 O_RDONLY  
#include <unistd.h> // 为了 read 和 close  
#include <stdlib.h> // 为了 strtol
/*

sysfs接口与GPIO(通用输入/输出)模块
需要内核是否支持sysfs GPIO接口,以及你的设备树(device tree)或板级支持包(BSP)是否正确地配置了GPIO引脚

**/

/*******************
 * 
 *  sysfs的gpio引脚注册
 *  引脚号计算公式为 pin = bank * 32 + number, number = group*8 + X
 *  格式为 GPIO + bank + '_' + group + X
 *  其中group  group ∈ {(A=0), (B=1), (C=2), (D=3)}
 *  如 GPIO4_D5
 *  bank = 4 group = 3  X=5
 * 
 *  direction 方向参数 "out" 输出  "in"  输入
 * ******/
T_JZsdkReturnCode SysfsGPIO_Init_ircut(int gpio_num, unsigned char *direction)
{
    unsigned char RmCmdStr[256];    

    //1、声明gpio
    memset(RmCmdStr,0,sizeof(RmCmdStr));
    snprintf(RmCmdStr, 256,"echo %d > /sys/class/gpio/export", gpio_num);
    if( JZsdk_RunSystemCmd(RmCmdStr) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
    {
        JZSDK_LOG_INFO("gpio引脚已注册,或gpio引脚无法注册");
    }

    // 创建gpio目录的路径  
    char gpio_dir[100];  
    snprintf(gpio_dir, sizeof(gpio_dir), "/sys/class/gpio/gpio%d", gpio_num);  
  

    //2、设置方向
    memset(RmCmdStr,0,sizeof(RmCmdStr));
    snprintf(RmCmdStr, sizeof(RmCmdStr), "echo %s > %s/direction", direction, gpio_dir);  
    if (JZsdk_RunSystemCmd(RmCmdStr) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)  
    {  
        JZSDK_LOG_INFO("gpio引脚设置方向失败");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

/*****************
 * 
 *   sysfs_gpio查询引脚状态
 *   
 * 
 * **********************/
T_JZsdkReturnCode SysfsGPIO_CheakStatus(int gpio_num, int *value) 
{  
    char gpio_path[256];  
    char buffer[3]; // 足够存储 "0\n" 或 "1\n"  
    ssize_t bytes_read;  
    int fd;  
  
    // 构造GPIO值的文件路径  
    snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%d/value", gpio_num);  
  
    // 打开GPIO值文件  
    fd = open(gpio_path, O_RDONLY);  
    if (fd == -1) {  
        perror("open");  
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;  
    }  
  
    // 读取文件内容  
    bytes_read = read(fd, buffer, sizeof(buffer) - 1); // 减去1以容纳'\0'  
    if (bytes_read == -1) {  
        perror("read");  
        close(fd);  
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;  
    }  
  
    // 确保字符串以null终止  
    buffer[bytes_read] = '\0';  
  
    // 移除可能的换行符,并转换为整数  
    char *endptr;  
    long int val = strtol(buffer, &endptr, 10);  
    if (*endptr != '\0' || val < 0 || val > 1) {  
        // 转换失败或非预期值  
        close(fd);  
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;  
    }  
  
    // 存储值到value指针指向的位置  
    *value = (int)val;  
  
    // 关闭文件  
    close(fd);  
  
    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;  
}  

/*****************
 * 
 *   设置sysfs_gpio的值
 *   
 * 
 * **********************/
T_JZsdkReturnCode SysfsGPIO_Set_ircut(int gpio_num, int value) 
{  

    // // 构造GPIO方向的文件路径  
    // snprintf(gpio_dir_path, sizeof(gpio_dir_path), "/sys/class/gpio/gpio%d/direction", gpio_num);  
  
    // // 打开GPIO方向文件并设置为输出(如果尚未设置)  
    // fd_dir = open(gpio_dir_path, O_WRONLY);  
    // if (fd_dir == -1) {  
    //     perror("open direction");  
    //     return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;  
    // }  
    // if (write(fd_dir, "out", 3) != 3) { // 设置GPIO为输出  
    //     perror("write direction");  
    //     close(fd_dir);  
    //     return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;  
    // }  
    // close(fd_dir);  
  
    // 构造GPIO值的文件路径  
    unsigned char gpio_value_path[64];
    snprintf(gpio_value_path, sizeof(gpio_value_path), "/sys/class/gpio/gpio%d/value", gpio_num);  
  
    unsigned char RmCmdStr[256];    

    memset(RmCmdStr,0,sizeof(RmCmdStr));
    snprintf(RmCmdStr, 256,"echo %d > %s", value,gpio_value_path);
    if (JZsdk_RunSystemCmd(RmCmdStr) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)  
    {  
        JZSDK_LOG_INFO("gpio引脚设置值失败");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;  
}