用于控制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库包还包含以下内容
-
lib/python/
子目录包含实现所有库功能的Python模块。gpio.py模块是主组件,将被导入到应用程序中并提供所需的API。《gpio_event.py》和《gpio_pin_data.py》模块被gpio.py模块使用,不应直接导入到应用程序中。 -
《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/`目录中提供的示例应用程序。以下描述了每个应用程序的操作
-
simple_input.py
:此应用程序使用BCM引脚编号模式,读取40引脚排上12号引脚的值并将其打印到屏幕上。 -
simple_out.py
:此应用程序使用Raspberry Pi的BCM引脚编号模式,每隔2秒在BCM引脚18(或排上板子引脚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五次。
如果将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文档可能位于以下位置:
- Jetson下载中心;搜索“L4T文档”包。
- docs.nvidia.com.
在文档中,可以通过搜索以下内容找到相关主题。
- 硬件设置。
- 配置40引脚扩展头。
- Jetson-IO。
- 平台适配和启动。
- 引脚复用更改。
项目详情
Jetson.GPIO-2.1.6.tar.gz的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | af8ff56b554e1f36662d19fff3d23e7c5ac261ac51ce7b1894447e64746760a2 |
|
MD5 | 1a2f2553de5bf97111e61cdb27194202 |
|
BLAKE2b-256 | ab8ffb59c8dd6ad3d983c7dbe2e4c1e2af7343031760960cefe0bfeb2ab0e946 |