0%

Ubuntu系统下操作GPIO

最近有项目需要用到RK3568的GPIO进行功能开发,找到关于GPIO操作例程,特此记录一下,例程是基于英伟达开发板的,简单修改一下就可以应用到RK3568,中间可能需要修改设备树,这里略过设备树修改,以后会再专门讲解
首先使用shell命令测试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
echo 192 > /sys/class/gpio/export
#导出编号为192的gpio
#如果这个gpio导出成功,会多出一个文件夹/sys/class/gpio/gpio192/
echo 192 > /sys/class/gpio/unexport
#取消导出

echo out > /sys/class/gpio/gpio192/direction
#设置为输出
echo 1 > /sys/class/gpio/gpio192/value
#输出高

echo in > /sys/class/gpio/gpio192/direction
#设置为输入
cat /sys/class/gpio/gpio192/value
#读取输入值

#也可以直接向value中写入high或low,gpio被设置成输出,并输出对应电平
echo high > /sys/class/gpio/gpio192/value
#设置为输出,并输出高电平

#上述命令都会需要root权限

每个芯片都有自己的gpio编号计算公式,需要先将引脚编号转换成数字编号再进行操作

例如瑞芯微RK3399的gpio编号计算方式:

1
2
3
4
GPIOn_Kx
编号 = n*32 + (K-A)*8 + x

GPIO1_B3 = 1*32 + (B-A)*8 + 3 = 43

.h文件

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
/*
NVIDIA Jetson Xavier NX 控制GPIO
在linux系统中以文件io的方式控制GPIO示例,开发板为NVIDIA Jetson Xavier NX,其它公司的开发板也可使用。
此代码功能:GPIO-09接入蜂鸣器,高电平开启,低电平关闭。
*/

#ifndef NVIDIAGPIO_H
#define NVIDIAGPIO_H

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>

using namespace std;

#define ON "1" //开启
#define OFF "0" //关闭
#define BUZZER "436" //控制蜂鸣器引脚
#define DIRECTION_OUT "out" //方向为输出
#define DIRECTION_IN "in" //方向为输出

class NvidiaGpio
{
public:
NvidiaGpio();
~NvidiaGpio();

int openGpio(const char *port); //导入GPIO
int closeGpio(const char *port); //导出GPIO

int setGpioDirection(const char *port, const char *direction); //设置GPIO输入/输出模式

int writeGpioValue(const char *port, const char *value); //设置GPIO值
int readGpioValue(const char *port); //读取GPIO值
};

#endif // NVIDIAGPIO_H

.cpp文件

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
#include "nvidiagpio.h"

NvidiaGpio::NvidiaGpio()
{

}

NvidiaGpio::~NvidiaGpio()
{

}

int NvidiaGpio::openGpio(const char *port)
{
int fd = -1;
const char *path = "/sys/class/gpio/export";

if((fd = open(path, O_WRONLY)) == -1) {
perror("Failed to open gpio! ");
return -1;
}

write(fd, port, sizeof(port));
close(fd);

return 0;
}

int NvidiaGpio::closeGpio(const char *port)
{
int fd = -1;
const char *path = "/sys/class/gpio/unexport";

if((fd = open(path, O_WRONLY)) == -1) {
perror("Failed to close gpio! ");
return -1;
}

write(fd, port, sizeof(port));
close(fd);

return 0;
}

int NvidiaGpio::setGpioDirection(const char *port, const char *direction)
{
int fd = -1;
char path[40] = {0};
sprintf(path, "/sys/class/gpio/gpio%s/direction", port);

if((fd = open(path, O_WRONLY)) == -1) {
perror("Failed to set GPIO dirention! ");
return -1;
}

write(fd, direction, sizeof(direction));
close(fd);

return 0;
}

int NvidiaGpio::writeGpioValue(const char *port, const char *value)
{
int fd = -1;
char path[40] = {0};
sprintf(path, "/sys/class/gpio/gpio%s/value", port);

if((fd = open(path, O_WRONLY)) == -1) {
perror("Failed to set GPIO value! ");
return -1;
}

write(fd, value, sizeof(value));
close(fd);

return 0;
}

int NvidiaGpio::readGpioValue(const char *port)
{
int fd = -1;
int value = 0;
char path[40] = {0};
sprintf(path, "/sys/class/gpio/gpio%s/value", port);

if((fd = open(path, O_RDONLY)) == -1) {
perror("Failed to set GPIO value! ");
return -1;
}

char tmp[2] = {0};
read(fd, tmp, 1);
close(fd);

value = atoi(tmp);

return value;
}

main.cpp文件

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
#include <iostream>
#include "nvidiagpio.h"

using namespace std;

int main()
{
cout << "Hello World!" << endl;

NvidiaGpio *gpio = new NvidiaGpio();

if(gpio->openGpio(BUZZER) != 0) { //打开gpio
exit(1);
}

usleep(10*1000);

if(gpio->setGpioDirection(BUZZER, DIRECTION_OUT) != 0) { // 设置GPIO方向
gpio->closeGpio(BUZZER);
exit(1);
}

usleep(10*1000);

if(gpio->writeGpioValue(BUZZER, ON) != 0) { //设置高电平为输出,开启蜂鸣器
gpio->closeGpio(BUZZER);
exit(1);
}

int ret = 0;
ret = gpio->readGpioValue(BUZZER);
cout<<"get gpio value: "<<ret<<endl;

sleep(1);

if(gpio->writeGpioValue(BUZZER, OFF) != 0) { //设置低电平为输出,关闭蜂鸣器
gpio->closeGpio(BUZZER);
exit(1);
}

ret = gpio->readGpioValue(BUZZER);
cout<<"get gpio value: "<<ret<<endl;

gpio->closeGpio(BUZZER);

return 0;
}