跳转到主要内容

用于控制Jetson GPIO通道的模块

项目描述

Jetson.GPIO - Linux for Tegra

Jetson TX1, TX2, AGX Xavier和Nano开发板包含一个40针GPIO引脚头,类似于Raspberry Pi中的40针引脚头。这些GPIO可以通过Jetson GPIO库包中提供的Python库进行控制,以实现数字输入和输出。该库与Raspberry Pi的RPi.GPIO库具有相同的API,以便为将运行在Raspberry Pi上的应用程序迁移到Jetson板提供一种简单的方法。

本文档将介绍Jetson GPIO库包的内容,如何配置系统和运行提供的示例应用程序,以及库API。

包组件

除了本文档之外,Jetson GPIO库包还包含以下内容

  1. lib/python/子目录包含实现所有库功能的Python模块。gpio.py模块是主组件,将被导入到应用程序中并提供所需的API。《gpio_event.py》和《gpio_pin_data.py》模块被gpio.py模块使用,不应直接导入到应用程序中。

  2. 《samples/`子目录包含示例应用程序,有助于熟悉库API并开始应用程序的开发。`simple_input.py`和`simple_output.py`应用程序展示了如何分别执行对GPIO引脚的读写操作,而`button_led.py`, `button_event.py`和`button_interrupt.py`则展示了如何使用忙等待、阻塞等待和中断回调分别使用按钮按下操作来闪烁LED。

安装

以下是在您的系统上安装Jetson.GPIO python模块的方法。对于示例应用程序,请将此存储库克隆到您的系统。

使用pip

安装此库最简单的方法是使用`pip`。

sudo pip install Jetson.GPIO

手动下载

您可以克隆此git存储库,或将其作为归档文件下载并解压。您可以将库文件放在系统上的任何位置。您可以通过手动设置`PYTHONPATH`从该目录直接使用库,或者使用`setup.py`进行安装。

sudo python3 setup.py install

设置用户权限

为了使用Jetson GPIO库,必须首先设置正确的用户权限/组。

创建一个新的gpio用户组。然后,将您的用户添加到新创建的组中。

sudo groupadd -f -r gpio
sudo usermod -a -G gpio your_user_name

通过将99-gpio.rules文件复制到rules.d目录中安装自定义udev规则。

如果您已下载Jetson.GPIO源代码

sudo cp lib/python/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/

如果您已通过包安装了Jetson.GPIO,例如在虚拟环境中使用pip安装

sudo cp venv/lib/pythonNN/site-packages/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/

要使新规则生效,您需要重新启动或通过运行以下命令重新加载udev规则

sudo udevadm control --reload-rules && sudo udevadm trigger

运行示例脚本

设置所需权限后,可以使用《code>samples/`目录中提供的示例应用程序。以下描述了每个应用程序的操作

  1. simple_input.py:此应用程序使用BCM引脚编号模式,读取40引脚排上12号引脚的值并将其打印到屏幕上。

  2. simple_out.py:此应用程序使用Raspberry Pi的BCM引脚编号模式,每隔2秒在BCM引脚18(或排上板子引脚12)输出交替的高低电平。

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

  4. button_event.py:此应用程序使用BOARD引脚编号。它需要一个连接到引脚18和GND的按钮、一个将按钮连接到3V3的拉上电阻以及一个连接到引脚12的LED和限流电阻。应用程序执行与button_led.py相同的操作,但通过阻塞等待按钮按下事件来代替连续检查引脚值,以减少CPU使用率。

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

如果将Jetson.GPIO添加到PYTHONPATH,则可以运行这些示例应用程序

python3 <name_of_application_to_run>

或者,如果未将Jetson.GPIO添加到PYTHONPATH,可以使用`run_sample.sh`脚本来运行这些示例应用程序。在`samples/`目录中,可以使用以下命令执行此操作

./run_sample.sh <name_of_application_to_run>

也可以使用以下命令查看脚本的用法

./run_sample.sh -h
./run_sample.sh --help

完整库API

Jetson GPIO库提供了RPi.GPIO库提供的所有公共API。以下将讨论每个API的使用

1. 导入库

要导入Jetson.GPIO模块,请使用

import Jetson.GPIO as GPIO

这样,您可以在整个应用程序中引用此模块为GPIO。对于使用RPi库的现有代码,您也可以使用RPi.GPIO而不是Jetson.GPIO来导入模块。

2. 引脚编号

Jetson GPIO 库提供了四种引脚编号的方式。前两种对应于 RPi.GPIO 库提供的模式,即 BOARD 和 BCM,分别代表 40 引脚 GPIO 挡板的引脚号和 Broadcom SoC 的 GPIO 号码。剩余两种模式 CVM 和 TEGRA_SOC 使用字符串而不是数字,分别对应 CVM/CVB 连接器和 Tegra SoC 上的信号名称。

要指定您正在使用哪种模式(强制),请使用以下函数调用

GPIO.setmode(GPIO.BOARD)
# or
GPIO.setmode(GPIO.BCM)
# or
GPIO.setmode(GPIO.CVM)
# or
GPIO.setmode(GPIO.TEGRA_SOC)

要检查设置了哪种模式,可以调用

mode = GPIO.getmode()

模式必须是 GPIO.BOARD、GPIO.BCM、GPIO.CVM、GPIO.TEGRA_SOC 或 None 之一。

3. 警告

可能您要使用的 GPIO 已在当前应用程序外部被占用。在这种情况下,如果正在使用的 GPIO 配置为默认方向以外的任何方向(输入),Jetson GPIO 库将警告您。如果您在设置模式和通道之前尝试清理,它也会警告您。要禁用警告,请调用

GPIO.setwarnings(False)

此外,Jetson.GPIO 使用 warnings 模块来发出警告。因此,您可以使用 Python 标准库 - warnings 控制警告消息

4. 设置通道

在使用输入或输出之前,必须设置 GPIO 通道。要将通道配置为输入,请调用

# (where channel is based on the pin numbering mode discussed above)
GPIO.setup(channel, GPIO.IN)

要将通道配置为输出,请调用

GPIO.setup(channel, GPIO.OUT)

也可以指定输出通道的初始值

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

在设置通道为输出时,也可以一次设置多个通道

# add as many as channels as needed. You can also use tuples: (18,12,13)
channels = [18, 12, 13]
GPIO.setup(channels, GPIO.OUT)

5. 输入

要读取通道的值,请使用

GPIO.input(channel)

这将返回 GPIO.LOW 或 GPIO.HIGH。

6. 输出

要设置已配置为输出的引脚的值,请使用

GPIO.output(channel, state)

其中状态可以是 GPIO.LOW 或 GPIO.HIGH。

您还可以向通道列表或元组输出

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

7. 清理

在程序结束时,清理通道是一个好习惯,以确保所有引脚都设置在其默认状态。要清理所有使用的通道,请调用

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

8. Jetson 板信息和库版本

要获取有关 Jetson 模块的信息,请使用/读取

GPIO.JETSON_INFO

这提供了一个包含以下键的 Python 字典:P1_REVISION、RAM、REVISION、TYPE、MANUFACTURER 和 PROCESSOR。字典中的所有值都是字符串,除了 P1_REVISION 是一个整数。

要获取有关库版本的信息,请使用/读取

GPIO.VERSION

这提供了一个 X.Y.Z 版本格式的字符串。

9. 中断

除了忙等待之外,库还提供了三种额外的监控输入事件的方式

wait_for_edge() 函数

此函数在检测到提供的边缘之前会阻塞调用线程。该函数可以按如下方式调用

GPIO.wait_for_edge(channel, GPIO.RISING)

第二个参数指定要检测的边缘,可以是 GPIO.RISING、GPIO.FALLING 或 GPIO.BOTH。如果您只想将等待限制在指定的时间长度内,可以设置一个可选的超时

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

函数返回检测到边缘的通道或如果发生超时则返回 None。

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()

如前所述,您可以检测 GPIO.RISING、GPIO.FALLING 或 GPIO.BOTH 的事件。

当检测到边缘时运行的回调函数

此功能可用于为回调函数运行第二个线程。因此,回调函数可以与主程序并发运行,以响应边缘事件。该功能的使用方法如下:

# 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)

在这种情况下,两个回调函数是顺序运行,而不是并发,因为只有一个线程在运行所有回调函数。

为了防止将多个事件合并为一个而多次调用回调函数,可以设置一个去抖时间。

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

在后台运行的线程将空闲等待事件,直到超时,超时可以设置为以下选项。默认轮询超时为0.2秒。当轮询时间超时,线程将唤醒并检查线程状态。如果线程处于运行状态,它将返回到空闲状态等待另一个事件,否则,线程将退出(事件检测移除)。此过程将一直持续到线程处于退出状态。

# polltime set in seconds
GPIO.add_event_detect(channel, GPIO.RISING, callback=callback_fn,
polltime=1)

如果不再需要边缘检测,可以按以下方式移除。

GPIO.remove_event_detect(channel)

可以设置超时选项以等待移除事件检测,或者默认为0.5秒。建议移除的超时时间至少是轮询时间的两倍。

GPIO.remove_event_detect(channel, timeout=0.5)

10. 检查GPIO通道的功能

此功能允许您检查提供的GPIO通道的功能。

GPIO.gpio_function(channel)

该函数返回GPIO.IN或GPIO.OUT。

11. PWM

有关如何使用PWM通道的详细信息,请参阅samples/simple_pwm.py

Jetson.GPIO库仅支持具有硬件PWM控制器的引脚的PWM。与RPi.GPIO库不同,Jetson.GPIO库不实现软件模拟PWM。Jetson Nano支持2个PWM通道,Jetson AGX Xavier支持3个PWM通道。Jetson TX1和TX2不支持任何PWM通道。

系统pinmux必须配置为将硬件PWM控制器连接到相关引脚。如果未配置pinmux,PWM信号将无法到达引脚!Jetson.GPIO库不会动态修改pinmux配置来实现这一点。有关如何配置pinmux的详细信息,请参阅L4T文档。

在docker容器中使用Jetson GPIO库

以下介绍了如何从docker容器中使用Jetson GPIO库。

构建docker镜像

samples/docker/Dockerfile是Jetson GPIO库的示例Dockerfile。以下命令将基于它构建一个名为testimg的docker镜像。

sudo docker image build -f samples/docker/Dockerfile -t testimg .

运行容器

基本选项

您应将/dev映射到容器中,以访问GPIO引脚。因此,您需要将这些选项添加到docker container run命令中。

--device /dev/gpiochip0 \

如果您想从容器中使用GPU,还需要添加以下选项

--runtime=nvidia --gpus all

以特权模式运行容器

库默认通过检查/proc/device-tree/compatible/proc/device-tree/chosen来确定jetson型号。这些路径只能在特权模式下映射到容器中。

以下示例将按特权模式从容器中运行/bin/bash

sudo docker container run -it --rm \
--runtime=nvidia --gpus all \
--privileged \
-v /proc/device-tree/compatible:/proc/device-tree/compatible \
-v /proc/device-tree/chosen:/proc/device-tree/chosen \
--device /dev/gpiochip0 \
testimg /bin/bash

以非特权模式运行容器

如果您不想以特权模式运行容器,您可以通过环境变量JETSON_MODEL_NAME直接将jetson型号名称提供给库。

# ex> -e JETSON_MODEL_NAME=JETSON_NANO
-e JETSON_MODEL_NAME=[PUT_YOUR_JETSON_MODEL_NAME_HERE]

您可以通过在主机或以特权模式运行samples/jetson_model.py来获取此变量的正确值。

# run on the host or in previlleged mode
sudo python3 samples/jetson_model.py

以下示例将按非特权模式从容器中运行/bin/bash

sudo docker container run -it --rm \
--runtime=nvidia --gpus all \
--device /dev/gpiochip0 \
-e JETSON_MODEL_NAME=[PUT_YOUR_JETSON_MODEL_NAME_HERE] \
testimg /bin/bash

获取L4T文档

L4T文档可能位于以下位置:

在文档中,可以通过搜索以下内容找到相关主题。

  • 硬件设置。
  • 配置40引脚扩展头。
  • Jetson-IO。
  • 平台适配和启动。
  • 引脚复用更改。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

Jetson.GPIO-2.1.6.tar.gz (33.2 kB 查看哈希)

上传时间

支持者