Sysfs_gpio.c
4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#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;
}