在此之前得确认1. 用户组gpio是否存在
getent group | grep gpio
(如果没创建就groupadd -r gpio
创建)2. 当前用户是否已经加入gpio用户组groups | grep gpio
(如果没加入就usermod -aG gpio 当前用户名
加入)
不过一般Jetson
把以下内容写到/etc/udev/rules.d/99-gpio.rules
中去
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", GROUP="gpio", MODE="0660"
#SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", \
# PROGRAM="/bin/sh -c 'chown root:gpio /dev/%k; chmod 660 /dev/%k'"
SUBSYSTEM=="pwm", KERNEL=="pwmchip*", ACTION=="add", \
PROGRAM="/bin/bash -c 'chown root:gpio /sys%p/{,un}export; chmod 220 /sys%p/{,un}export'"
SUBSYSTEM=="pwm", KERNEL=="pwmchip*", ACTION=="change", \
PROGRAM="/bin/bash -c 'chown root:gpio /sys%p/%E{EXPORT}/{period,duty_cycle,enable}; chmod 660 /sys%p/%E{EXPORT}/{period,duty_cycle,enable}'"
SUBSYSTEM=="spidev", KERNEL=="spidev*", ACTION=="add", \
GROUP="gpio", MODE="0660"
然后运行
sudo udevadm control --reload-rules && sudo udevadm trigger
打算使用JetsonTX2的IO口,跟着Jetson.GPIO 2.1.1 PyPI的教程[1]来复制规则,发现不行,重启了也不行,最后鉴定为他的规则有问题,搞了好久,垃圾东西。
安装了Jetson.GPIO 2.1.1之后,按照教程将他的规则文件复制到/etc/udev/rules.d/
中
pip install Jetson.GPIO
sudo updatedb
locate 99-gpio.rules
# 然后将返回的路径复制到/etc/udev/rules.d/去
sudo cp 返回的路径venv/lib/pythonNN/site-packages/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/
重启,没用
Jetson.GPIO提供的规则文件如下
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", \
PROGRAM="/bin/sh -c 'chown root:gpio /dev/%k; chmod 660 /dev/%k'"
SUBSYSTEM=="pwm", KERNEL=="pwmchip*", ACTION=="add", \
PROGRAM="/bin/bash -c 'chown root:gpio /sys%p/{,un}export; chmod 220 /sys%p/{,un}export'"
SUBSYSTEM=="pwm", KERNEL=="pwmchip*", ACTION=="change", \
PROGRAM="/bin/bash -c 'chown root:gpio /sys%p/%E{EXPORT}/{period,duty_cycle,enable}; chmod 660 /sys%p/%E{EXPORT}/{period,duty_cycle,enable}'"
SUBSYSTEM=="spidev", KERNEL=="spidev*", ACTION=="add", \
GROUP="gpio", MODE="0660"
在网上查了一下发现可以使用udevadm test进行调试看看规则是否起作用
sudo udevadm info --name=/dev/gpiochip0 --query=path
和sudo udevadm info --name=/dev/gpiochip0 --query=all
可以查询设备路径信息
nvidia@nvidia-desktop /e/u/rules.d> sudo udevadm info --name=/dev/gpiochip0 --query=path
/devices/2200000.gpio/gpiochip0
sudo udevadm test path
可以让规则生效并且输出过程
nvidia@nvidia-desktop:~$ sudo udevadm test $(udevadm info -q path -n /dev/gpiochip0) 2>&1
calling: test
version 237
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.
Load module index
Network interface NamePolicy= disabled on kernel command line, ignoring.
Parsed configuration file /lib/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /lib/udev/rules.d/01-md-raid-creating.rules
Reading rules file: /lib/udev/rules.d/39-usbmuxd.rules
Reading rules file: /lib/udev/rules.d/40-usb-media-players.rules
Reading rules file: /lib/udev/rules.d/40-usb_modeswitch.rules
Reading rules file: /lib/udev/rules.d/40-vm-hotadd.rules
Reading rules file: /lib/udev/rules.d/50-apport.rules
Reading rules file: /lib/udev/rules.d/50-firmware.rules
Reading rules file: /lib/udev/rules.d/50-udev-default.rules
Reading rules file: /lib/udev/rules.d/55-dm.rules
Reading rules file: /lib/udev/rules.d/55-ippusbxd.rules
Reading rules file: /etc/udev/rules.d/55-primesense-usb.rules
Reading rules file: /lib/udev/rules.d/56-lvm.rules
Reading rules file: /lib/udev/rules.d/60-block.rules
Reading rules file: /lib/udev/rules.d/60-bridge-network-interface.rules
Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /lib/udev/rules.d/60-crda.rules
Reading rules file: /lib/udev/rules.d/60-drm.rules
Reading rules file: /lib/udev/rules.d/60-evdev.rules
Reading rules file: /lib/udev/rules.d/60-gpsd.rules
Reading rules file: /lib/udev/rules.d/60-i2c-tools.rules
Reading rules file: /lib/udev/rules.d/60-input-id.rules
Reading rules file: /lib/udev/rules.d/60-inputattach.rules
Reading rules file: /lib/udev/rules.d/60-jetson-gpio-common.rules
Reading rules file: /lib/udev/rules.d/60-libfreenect0.5.rules
Reading rules file: /lib/udev/rules.d/60-libgphoto2-6.rules
Reading rules file: /lib/udev/rules.d/60-libopenni-sensor-pointclouds0.rules
Reading rules file: /lib/udev/rules.d/60-libopenni2-0.rules
Reading rules file: /lib/udev/rules.d/60-libsane1.rules
Reading rules file: /lib/udev/rules.d/60-openobex.rules
Reading rules file: /lib/udev/rules.d/60-pcmcia.rules
Reading rules file: /lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-dm.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /lib/udev/rules.d/60-qemu-system-common.rules
Reading rules file: /lib/udev/rules.d/60-sensor.rules
Reading rules file: /lib/udev/rules.d/60-serial.rules
Reading rules file: /lib/udev/rules.d/61-gdm.rules
Reading rules file: /lib/udev/rules.d/61-gnome-settings-daemon-rfkill.rules
Reading rules file: /lib/udev/rules.d/61-persistent-storage-android.rules
Reading rules file: /lib/udev/rules.d/63-md-raid-arrays.rules
Reading rules file: /lib/udev/rules.d/64-btrfs.rules
Reading rules file: /lib/udev/rules.d/64-md-raid-assembly.rules
Reading rules file: /lib/udev/rules.d/64-xorg-xkb.rules
Reading rules file: /lib/udev/rules.d/65-libwacom.rules
Reading rules file: /lib/udev/rules.d/66-snapd-autoimport.rules
Reading rules file: /lib/udev/rules.d/69-cd-sensors.rules
Reading rules file: /lib/udev/rules.d/69-libmtp.rules
Reading rules file: /lib/udev/rules.d/69-lvm-metad.rules
Reading rules file: /lib/udev/rules.d/69-md-clustered-confirm-device.rules
Reading rules file: /lib/udev/rules.d/69-wacom.rules
Reading rules file: /lib/udev/rules.d/70-joystick.rules
Reading rules file: /lib/udev/rules.d/70-mouse.rules
Reading rules file: /lib/udev/rules.d/70-power-switch.rules
Reading rules file: /lib/udev/rules.d/70-printers.rules
Reading rules file: /lib/udev/rules.d/70-spice-vdagentd.rules
Reading rules file: /lib/udev/rules.d/70-touchpad.rules
Reading rules file: /lib/udev/rules.d/70-u2f.rules
Reading rules file: /lib/udev/rules.d/70-uaccess.rules
Reading rules file: /lib/udev/rules.d/71-power-switch-proliant.rules
Reading rules file: /lib/udev/rules.d/71-seat.rules
Reading rules file: /lib/udev/rules.d/73-seat-late.rules
Reading rules file: /lib/udev/rules.d/73-special-net-names.rules
Reading rules file: /lib/udev/rules.d/73-usb-net-by-mac.rules
Reading rules file: /lib/udev/rules.d/75-net-description.rules
Reading rules file: /lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /lib/udev/rules.d/77-mm-cinterion-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-dell-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-ericsson-mbm.rules
Reading rules file: /lib/udev/rules.d/77-mm-fibocom-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-haier-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-huawei-net-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-longcheer-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-mtk-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-nokia-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-pcmcia-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-qdl-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-sierra.rules
Reading rules file: /lib/udev/rules.d/77-mm-simtech-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-telit-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-ublox-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-usb-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-usb-serial-adapters-greylist.rules
Reading rules file: /lib/udev/rules.d/77-mm-x22x-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-zte-port-types.rules
Reading rules file: /lib/udev/rules.d/78-graphics-card.rules
Reading rules file: /lib/udev/rules.d/78-sound-card.rules
Reading rules file: /lib/udev/rules.d/80-debian-compat.rules
Reading rules file: /lib/udev/rules.d/80-drivers.rules
Reading rules file: /lib/udev/rules.d/80-ifupdown.rules
Reading rules file: /lib/udev/rules.d/80-iio-sensor-proxy.rules
Reading rules file: /lib/udev/rules.d/80-libinput-device-groups.rules
Reading rules file: /lib/udev/rules.d/80-mm-candidate.rules
Reading rules file: /lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /lib/udev/rules.d/80-udisks2.rules
Reading rules file: /lib/udev/rules.d/80-uvcdynctrl.rules
Reading rules file: /lib/udev/rules.d/84-nm-drivers.rules
Reading rules file: /lib/udev/rules.d/85-brltty.rules
Reading rules file: /lib/udev/rules.d/85-nm-unmanaged.rules
Reading rules file: /lib/udev/rules.d/85-regulatory.rules
Reading rules file: /etc/udev/rules.d/90-alsa-asound-tegra.rules
Reading rules file: /lib/udev/rules.d/90-alsa-restore.rules
Reading rules file: /lib/udev/rules.d/90-bolt.rules
Reading rules file: /lib/udev/rules.d/90-console-setup.rules
Reading rules file: /lib/udev/rules.d/90-fwupd-devices.rules
Reading rules file: /lib/udev/rules.d/90-libgpod.rules
Reading rules file: /lib/udev/rules.d/90-libinput-model-quirks.rules
Reading rules file: /lib/udev/rules.d/90-pulseaudio.rules
Reading rules file: /etc/udev/rules.d/91-xorg-conf-tegra.rules
Reading rules file: /etc/udev/rules.d/92-hdmi-audio-tegra.rules
Reading rules file: /lib/udev/rules.d/95-cd-devices.rules
Reading rules file: /lib/udev/rules.d/95-dm-notify.rules
Reading rules file: /lib/udev/rules.d/95-ucm-soundcard-name.rules
Reading rules file: /lib/udev/rules.d/95-upower-csr.rules
Reading rules file: /lib/udev/rules.d/95-upower-hid.rules
Reading rules file: /lib/udev/rules.d/95-upower-wup.rules
Reading rules file: /lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /etc/udev/rules.d/99-gpio.rules
Reading rules file: /etc/udev/rules.d/99-nv-l4t-usb-device-mode.rules
Reading rules file: /etc/udev/rules.d/99-nv-l4t-usb-host-config.rules
Reading rules file: /etc/udev/rules.d/99-nv-ufs-mount.rules
Reading rules file: /etc/udev/rules.d/99-nv-wifibt.rules
Reading rules file: /lib/udev/rules.d/99-systemd.rules
Reading rules file: /etc/udev/rules.d/99-tegra-devices.rules
Reading rules file: /etc/udev/rules.d/99-tegra-mmc-ra.rules
Reading rules file: /etc/udev/rules.d/99-video-device.rules
rules contain 393216 bytes tokens (32768 * 12 bytes), 41041 bytes strings
25987 strings (224102 bytes), 22534 de-duplicated (186515 bytes), 3454 trie nodes used
PROGRAM '/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'' /lib/udev/rules.d/60-jetson-gpio-common.rules:23
starting '/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport''
Process '/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'' succeeded.
PROGRAM '/bin/sh -c 'chown root:gpio /dev/gpiochip0; chmod 660 /dev/gpiochip0'' /etc/udev/rules.d/99-gpio.rules:23
starting '/bin/sh -c 'chown root:gpio /dev/gpiochip0; chmod 660 /dev/gpiochip0''
Process '/bin/sh -c 'chown root:gpio /dev/gpiochip0; chmod 660 /dev/gpiochip0'' succeeded.
handling device node '/dev/gpiochip0', devnum=c254:0, mode=0600, uid=0, gid=0
set permissions /dev/gpiochip0, 020600, uid=0, gid=0
preserve already existing symlink '/dev/char/254:0' to '../gpiochip0'
ACTION=add
DEVNAME=/dev/gpiochip0
DEVPATH=/devices/2200000.gpio/gpiochip0
MAJOR=254
MINOR=0
OF_COMPATIBLE_0=nvidia,tegra186-gpio
OF_COMPATIBLE_N=1
OF_FULLNAME=/gpio@2200000
OF_NAME=gpio
SUBSYSTEM=gpio
USEC_INITIALIZED=2764256
net.ifnames=0
Unload module index
Unloaded link configuration context.
可以看到Process '/bin/sh -c 'chown root:gpio /dev/gpiochip0; chmod 660 /dev/gpiochip0'' succeeded.
但是后面三行又将其设置回来了set permissions /dev/gpiochip0, 020600, uid=0, gid=0
,很迷,问了很久ChatGPT也没问出来,最后看到ChatGPT说SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", GROUP="gpio", MODE="0660"
权限这样设置,而且树莓派的GPIO也是这样设置[2],最后参考这个形式修改规则文件就行了(Jetson.GPIO什么shaB写法,不过为什么好像没查到别人有遇到这个问题)。
最后将规则文件改成一下格式就行了。
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", GROUP="gpio", MODE="0660"
#SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", \
# PROGRAM="/bin/sh -c 'chown root:gpio /dev/%k; chmod 660 /dev/%k'"
SUBSYSTEM=="pwm", KERNEL=="pwmchip*", ACTION=="add", \
PROGRAM="/bin/bash -c 'chown root:gpio /sys%p/{,un}export; chmod 220 /sys%p/{,un}export'"
SUBSYSTEM=="pwm", KERNEL=="pwmchip*", ACTION=="change", \
PROGRAM="/bin/bash -c 'chown root:gpio /sys%p/%E{EXPORT}/{period,duty_cycle,enable}; chmod 660 /sys%p/%E{EXPORT}/{period,duty_cycle,enable}'"
SUBSYSTEM=="spidev", KERNEL=="spidev*", ACTION=="add", \
GROUP="gpio", MODE="0660"
只能认为/dev/
里面的设备不能用PROGRAM="/bin/sh -c 'chown root:gpio /dev/%k; chmod 660 /dev/%k'"
这种方式来修改权限,如果没有设置 GROUP="gpio", MODE="0660"
默认可能就会采用默认设置root 600
,即使用PROGRAM="/bin/sh -c 'chown root:gpio /dev/%k; chmod 660 /dev/%k'"
修改了权限,最后也被默认权限给覆盖了,而 GROUP="gpio", MODE="0660"
能够覆盖默认的root 600
。
真是的,明明系统就已经提供了 GROUP="", MODE=""
这类的方式来修改权限,为什么Jetson.GPIO还要用PROGRAM
命令来修改。
[1] Jetson.GPIO 2.1.1 - PyPI (拉跨)
[2] 树莓派GPIO权限设置