四、GPIO控制
GPIO(General-purpose input/output )是一种通用型输入输出接口,其脚位可由使用者编程控制。根据实际需要,这些脚位可以被设置为通用输入(GPI)、通用输出(GPO),或兼具输入输出功能(GPIO)。
Jetson Orin Nano系列的40PIN GPIO引脚定义如下:
1 在JetPack 5系统中使用GPIO
1.1 使用命令行控制GPIO
获取GPIO口的引脚名称与编号
以31号引脚为例,454为GPIO口编号,PQ.06为引脚名称
- 提升至root权限,启用GPIO口
sudo bash
echo 454 > /sys/class/gpio/export
- 设置GPIO为输入模式
echo in > /sys/class/gpio/PQ.06/direction
- 获取GPIO当前状态,返回值1为高电平,0为低电平
cat /sys/class/gpio/PQ.06/value
- 设置GPIO为输出模式
echo out > /sys/class/gpio/PQ.06/direction
- 设置GPIO输出,1为高电平,0为低电平
echo 1 > /sys/class/gpio/PQ.06/value
您也可以使用以下脚本进行测试
#!/bin/bash
trap 'echo PQ.06 > /sys/class/gpio/unexport; echo "GPIO PQ.06 is released"' EXIT
echo "setting GPIO PQ.06"
echo PQ.06 > /sys/class/gpio/export 2>/dev/null
# set Pin output mode
echo out > /sys/class/gpio/PQ.06/direction
# blink
while true
do
echo 0 > /sys/class/gpio/PQ.06/value
sleep 0.5
cat /sys/class/gpio/PQ.06/value
sleep 0.5
echo 1 > /sys/class/gpio/PQ.06/value
sleep 0.5
cat /sys/class/gpio/PQ.06/value
sleep 0.5
done
1.2 使用python控制GPIO
1.2.1 安装JETSON.GPIO包
- 如果您不确定您的环境是否正常,或者您尝试使用conda环境运行脚本请执行以下指令安装Jetson官方的GPIO库
pip install JETSON.GPIO
Jetson GPIO库提供了四种给I / O引脚编号的方法。
- BOARD:物理引脚编号(40针接口顺序)。
- BCM:Broadcom SoC 的 GPIO 编号(常用)。
- CVM:CVM/CVB 连接器的信号名称。
- TEGRA_SOC:Tegra SoC 信号名称。
import time
import RPi.GPIO as GPIO
# define pin number
output_pin = 31
# set pin as BOARD mode
GPIO.setmode(GPIO.BOARD)
# set pin mode
GPIO.setup(output_pin, GPIO.OUT)
print("Press CTRL+C to exit")
curr_value = GPIO.HIGH
try:
while True:
time.sleep(1)
print("pin {} now is {}".format(output_pin, curr_value))
GPIO.output(output_pin, curr_value)
# blink
curr_value ^= GPIO.HIGH
finally:
GPIO.cleanup()
其他具体用法和例程可参考项目官网
1.3使用C/C++控制GPIO
- 安装libgpio-dev
sudo apt install libgpio-dev
参考例程:
/**
* License - MIT.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gpiod.h>
#define GPIO_CHIP "/dev/gpiochip0"
#define GPIO_LED 3
int main()
{
int ret = 0;
struct gpiod_chip *gpiochip;
struct gpiod_line *gpioline;
// Open driver.
gpiochip = gpiod_chip_open(GPIO_CHIP);
if (NULL == gpiochip) {
printf("Error in gpiod_chip_open.\n");
ret = -1;
goto out1;
}
// Get gpio.
gpioline = gpiod_chip_get_line(gpiochip, GPIO_LED);
if (NULL == gpioline) {
printf("Error in gpiod_chip_get_line.\n");
ret = -1;
goto out2;
}
// Set gpio direction.
ret = gpiod_line_request_output(gpioline, "gpio", 0);
if (ret != 0) {
printf("Error in gpiod_line_request_output.\n");
ret = -1;
goto out2;
}
// Blink.
for (int i = 0; i < 10; i++) {
printf("%d times.\n", i);
gpiod_line_set_value(gpioline, 1);
sleep(1);
gpiod_line_set_value(gpioline, 0);
sleep(1);
}
// Release.
gpiod_line_release(gpioline);
out2:
gpiod_chip_close(gpiochip);
out1:
return ret;
}
- 编译源文件
g++ test_gpio.cc -o test_gpio -lgpiod
- 执行测试程序
./test_gpio
2 在JetPack 6系统中使用GPIO
2.1使用libgpiod控制GPIO
在 JetPack 6.2/r36.4.3 中,NVIDIA已经移除了传统的 sysfs GPIO 接口(/sys/class/gpio)不建议再使用 sysfs 来控制 GPIO。推荐使用Linux统一的 libgpiod 管理 GPIO
- 安装前置软件包
sudo apt-get install busybox automake autoconf libtool
- 验证安装是否成功
jetson@jetson-desktop:~$ gpioinfo
gpiochip0 - 164 lines:
line 0: "PA.00" "regulator-vdd-3v3-sd" output active-high [used]
line 1: "PA.01" unused input active-high
line 2: "PA.02" unused input active-high
line 3: "PA.03" unused input active-high
line 4: "PA.04" unused input active-high
line 5: "PA.05" unused input active-high
line 6: "PA.06" unused input active-high
line 7: "PA.07" unused input active-high
line 8: "PB.00" unused input active-high
line 9: "PC.00" unused input active-high
...........
- 读取 GPIO 状态
gpioget $(gpiofind "PQ.06")
- 将 GPIO 设置为输出模式
sudo busybox devmem 0x2430070 w 0x004
各个引脚对应的寄存器地址从 官方文档 中可以查询到
- 保持高电平:
gpioset --mode=wait `gpiofind "PQ.06"`=1
- 保持低电平:
gpioset --mode=wait `gpiofind "PQ.06"`=0
2.2 使用python控制GPIO
在JetPack6 系统中仍需要修改寄存器内容来更改引脚GPIO模式以使用高级语言控制GPIO
- 将 PQ.06 引脚设置为输出模式
sudo busybox devmem 0x2430070 w 0x004
- 如果您尝试使用 conda 环境运行脚本请执行以下指令安装 Jetson 官方的 GPIO 库
pip install JETSON.GPIO
- 建议执行以下指令,重新安装系统自带的 JETSON.GPIO 库
sudo rm -rf /usr/lib/python3*/dist-packages/Jetson
sudo rm -rf /usr/local/lib/python3*/dist-packages/Jetson
git clone https://github.com/NVIDIA/jetson-gpio.git
cd jetson-gpio
sudo pip3 install .
Jetson GPIO 库提供了四种给I / O引脚编号的方法。
- BOARD:物理引脚编号(40针接口顺序)。
- BCM:Broadcom SoC 的 GPIO 编号(常用)。
- CVM:CVM/CVB 连接器的信号名称。
- TEGRA_SOC:Tegra SoC 信号名称。
import time
import RPi.GPIO as GPIO
# define pin number PQ.06
output_pin = 31
# set pin as BOARD mode
GPIO.setmode(GPIO.BOARD)
# set pin mode
GPIO.setup(output_pin, GPIO.OUT)
print("Press CTRL+C to exit")
curr_value = GPIO.HIGH
try:
while True:
time.sleep(1)
print("pin {} now is {}".format(output_pin, curr_value))
GPIO.output(output_pin, curr_value)
# blink
curr_value ^= GPIO.HIGH
finally:
GPIO.cleanup()
其他具体用法和例程可参考项目官网
2.3使用C/C++控制GPIO
在JetPack6 系统中仍需要修改寄存器内容来更改引脚GPIO模式以使用高级语言控制GPIO
- 将 PQ.06 引脚设置为输出模式
sudo busybox devmem 0x2430070 w 0x004
- 安装libgpio-dev
sudo apt install libgpiod-dev
参考例程:
/**
* License - MIT.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gpiod.h>
#define GPIO_CHIP "/dev/gpiochip0"
#define GPIO_LED 106
int main()
{
int ret = 0;
struct gpiod_chip *gpiochip;
struct gpiod_line *gpioline;
// Open driver.
gpiochip = gpiod_chip_open(GPIO_CHIP);
if (NULL == gpiochip) {
printf("Error in gpiod_chip_open.\n");
ret = -1;
goto out1;
}
// Get gpio.
gpioline = gpiod_chip_get_line(gpiochip, GPIO_LED);
if (NULL == gpioline) {
printf("Error in gpiod_chip_get_line.\n");
ret = -1;
goto out2;
}
// Set gpio direction.
ret = gpiod_line_request_output(gpioline, "gpio", 0);
if (ret != 0) {
printf("Error in gpiod_line_request_output.\n");
ret = -1;
goto out2;
}
// Blink PQ.06
for (int i = 0; i < 10;30; i++) {
printf("%d times.\n", i);
gpiod_line_set_value(gpioline, 1);
sleep(1);
gpiod_line_set_value(gpioline, 0);
sleep(1);
}
// Release.
gpiod_line_release(gpioline);
out2:
gpiod_chip_close(gpiochip);
out1:
return ret;
}
- 编译源文件
g++ test_gpio.cc -o test_gpio -lgpiod
- 执行测试程序
./test_gpio