NVIDIA Jetson之GPIO功能测试

Posted ZONG_XP

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NVIDIA Jetson之GPIO功能测试相关的知识,希望对你有一定的参考价值。

0 背景

Jetson TX1、TX2、AGX Xavier 和 Nano 开发板包含一个 40 针 GPIO 接头,类似于 Raspberry Pi 中的 40 针接头。NV 官方给出了一个 GPIO 库,是 Python 版本,与 Raspberry Pi 的 RPi.GPIO 库相同,本文对该库的内容及使用方法做一个介绍。

1 安装方法

直接通过 pip 安装即可

sudo pip install Jetson.GPIO

下载示例代码

git clone https://github.com/NVIDIA/jetson-gpio.git

在 jetson-gpio 工程中

  1.  lib/python 路径包含实现所有库功能的 Python 模块,gpio.py 模块是将被导入应用程序并提供所需 API 的主要组件,而 gpio_event.py 和 gpio_pin_data.py 是被 gpio.py 引用的,不能被应用程序直接调用
  2. samples 路径列举了一些应用示例,具体含义如下
  • simple_input.py:此应用程序使用 BCM 引脚编号模式并读取 40 引脚接头的引脚 12 处的值并将该值打印到屏幕上。

  • simple_out.py:此应用程序使用 Raspberry Pi 的 BCM 引脚编号模式,并每 2 秒在 BCM 引脚 18(或 BOARD 引脚 12)上输出交替的高低值。

  • button_led.py:此应用程序使用 BOARD 引脚编号。它需要一个连接到引脚 18 和 GND 的按钮,一个将引脚 18 连接到 3V3 的上拉电阻,以及连接到引脚 12 的 LED 和限流电阻。应用程序读取按钮状态并保持 LED 每次亮起 1 秒按钮被按下。

  • button_event.py:此应用程序使用 BOARD 引脚编号。它需要一个连接到引脚 18 和 GND 的按钮、一个将按钮连接到 3V3 的上拉电阻以及连接到引脚 12 的 LED 和限流电阻。该应用程序执行与 button_led.py 相同的功能,但执行阻塞等待按钮按下事件而不是不断检查引脚的值以减少 CPU 使用率。

  • button_interrupt.py:此应用程序使用 BOARD 引脚编号。它需要一个连接到引脚 18 和 GND 的按钮、一个将按钮连接到 3V3 的上拉电阻、连接到引脚 12 的 LED 和限流电阻以及连接到引脚 13 的第二个 LED 和限流电阻。应用程序缓慢闪烁只有在按下按钮时,第一个 LED 才会连续快速闪烁第二个 LED 5 次。

2 API 功能

2.1 设置模式

支持四种模式,GPIO.BOARD, GPIO.BCM, GPIO.CVM, GPIO.TEGRA_SOC,每种模式的含义如下

  • BOARD(the pin number of the 40 pin GPIO header):就是开发板上 40pin 的丝印引脚序号
  • BCM(the Broadcom SoC GPIO numbers):是芯片的引脚编号,指芯片未焊接时的从初始引脚标注起周围一圈引脚的编号
  • CVM 和 TEGRA_SOC 使用字符串代替数字,分别对应于CVM / CVB连接器和 Tegra SoC 上的信号名称

对于 Jetson 系列的板子,需要将模式设置为 BOARD,直接和板子上标的一致

GPIO.setmode(GPIO.BOARD)

可以使用下边的方法来获取设置是否成功

mode = GPIO.getmode()

得到的结果会是 GPIO.BOARD, GPIO.BCM, GPIO.CVM, GPIO.TEGRA_SOC 或者 None 中的一种

2.2 输入引脚

在调用 gpio 引脚前,第一步需要定义好是输入还是输出方向。

设置引脚为输入方向

GPIO.setup(channel, GPIO.IN)

其中,channel 为具体的引脚号,比如 30、25等等

读取引脚的输入值

state = GPIO.input(channel)

返回值为 GPIO.LOW 或 GPIO.HIGH,即低信号或高信号

2.3 输出引脚

设置引脚为输出方向

GPIO.setup(channel, GPIO.OUT)

也支持指定默认输出是高还是低

GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

当然,也支持同时设置多个引脚的方向,如

channels = [18, 12, 13]
GPIO.setup(channels, GPIO.OUT)

定义好之后,设置引脚的输出值,支持多种模式

channels = [18, 12, 13] # or use tuples
GPIO.output(channels, GPIO.HIGH) # or GPIO.LOW
# set first channel to HIGH and rest to LOW
GPIO.output(channel, (GPIO.LOW, GPIO.HIGH, GPIO.HIGH))

2.4 检查方向

可以使用下边的接口来检查某个引脚是输入引脚还是输出引脚

GPIO.gpio_function(channel)

 返回值是 GPIO.IN 或 GPIO.OUT

2.5 清除引脚功能

程序运行结束后,最好有一个清除操作,将引脚恢复到默认状态

GPIO.cleanup()

如果不想把所有引脚的状态清除,也可以选择清除指定引脚

GPIO.cleanup(chan1) # cleanup only chan1
GPIO.cleanup([chan1, chan2]) # cleanup only chan1 and chan2
GPIO.cleanup((chan1, chan2))  # does the same operation as previous statement

3 中断功能

在监测输入引脚的状态时,为了防止不停地轮询,占用 cpu 资源,API 提供了三种接口来改进

3.1 wait_for_edge()

此函数会阻塞调用线程,直到检测到提供的边缘为止,如

GPIO.wait_for_edge(channel, GPIO.RISING)

第二个参数表示要检测的变化信号,支持  GPIO.RISING, GPIO.FALLING 或 GPIO.BOTH,及上升沿触发、下降沿触发或都触发,另外也可以设置超时时间

# timeout is in milliseconds
GPIO.wait_for_edge(channel, GPIO.RISING, timeout=500)

函数的返回是检测到的信号,或者超时后返回 None

3.2 event_detected()

此函数可用于定期检查自上次调用以来是否发生了事件,可以按如下方式设置和调用该函数

# set rising edge detection on the channel
GPIO.add_event_detect(channel, GPIO.RISING)
run_other_code()
if GPIO.event_detected(channel):
    do_something()

同样的,也支持上升沿、下降沿或上升下降沿几种触发方式

3.3 回调函数

在新的线程中执行回调函数,因此,主程序和回调函数可以并发运行来对事件进行响应,如

# define callback function
def callback_fn(channel):
    print("Callback called from channel %s" % channel)

# add rising edge detection
GPIO.add_event_detect(channel, GPIO.RISING, callback=callback_fn)

也可以指定多个回调函数

def callback_one(channel):
    print("First Callback")

def callback_two(channel):
    print("Second Callback")

GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, callback_one)
GPIO.add_event_callback(channel, callback_two)

但需要注意的是,多个回调函数会按顺序执行,而不是同时执行,这与 python 的线程机制有关。为了防止多个事件对回调函数的多次调用,可以选择设置去抖动时间:

# bouncetime set in milliseconds
GPIO.add_event_detect(channel, GPIO.RISING, callback=callback_fn,
bouncetime=200)

如果不需要检测变化,可以使用清除功能

GPIO.remove_event_detect(channel)

4 PWM 功能

samples/simple_pwm.py 显示了如何使用 PWM 功能,有两点需要注意:

(1)并不是每个开发板都有 PWM 功能,Jetson Nano 支持 2 个 PWM 通道,Jetson AGX Xavier 支持 3 个 PWM 通道。Jetson TX1 和 TX2 不支持任何 PWM 通道。

(2)jetson 板子默认没有开启 PWM 功能,需要使用 jetson-io 工具来配置,使能 PWM 功能,方法参考《NVIDIA Jetson之SPI功能使能》进行设置

5 C++ 接口

除了官方给出的 Python 接口,也有 C++ 接口的 GPIO API,功能与 python 的相同,使用方法类似,安装方法

git clone https://github.com/pjueon/JetsonGPIO
cd JetsonGPIO/build
make all
sudo make install

编译方法

g++ -o your_program_name your_source_code.cpp -lpthread -lJetsonGPIO

上述介绍的 API 接口实现方法,这里不再赘述,直接查看项目说明即可

以上是关于NVIDIA Jetson之GPIO功能测试的主要内容,如果未能解决你的问题,请参考以下文章

NVIDIA Jetson之GPIO引脚设置

NVIDIA Jetson之SPI功能使能

NVIDIA Jetson之benchmark测试

Jetson Xavier NX (15) -- Jetson.GPIO

Jetson Xavier NX (15) -- Jetson.GPIO

NVIDIA Jetson之UART功能开发