direwolf
direwolf copied to clipboard
Error writing to /sys/class/gpio/export, GPIO failure
Updates to Raspberry Pi OS bookworm (Debian 12) are disabling sysfs access to gpio,
After an apt-get upgrade, direwolf will not run if using gpio,
Dire Wolf version 1.7 KM6LYW-4 Includes optional support for: gpsd hamlib cm108-ptt dns-sd Reading config file /run/direwolf.tnc.conf Audio device for both receive and transmit: plughw:0,0 (channel 0) Channel 0: 1200 baud, AFSK 1200 & 2200 Hz, A+, 44100 sample rate / 3. Error writing "16" to /sys/class/gpio/export, errno=22 Invalid argument
Some discussion and a temporary solution (freeze kernel version) is here
https://forums.raspberrypi.com/viewtopic.php?t=359540
Thanks for reporting this. There is a new application program interface to gpio pins. When I first heard of it, I tried it on the RPi and it did not work yet. I put it on the back burner and never got back to it. I guess this will change my priorities.
I'm not seeing this issue on a fully patched mainline Bookworm (not anything bleeding edge that comes with rpi-update) on an Rpi4. Following the testing links from above:
$ uname -a Linux rpi4-bookworm 6.1.0-rpi6-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.58-1+rpt2 (2023-10-27) aarch64 GNU/Linux
$ echo "16" > /sys/class/gpio/export $
$ sudo raspi-gpio get 3 GPIO 3: level=1 fsel=4 alt=0 func=SCL1 pull=UP
Dire Wolf version 1.7 Includes optional support for: gpsd cm108-ptt
Reading config file /etc/ax25/direwolf.conf Audio device for both receive and transmit: plughw:1,0 (channel 0) Channel 0: 1200 baud, AFSK 1200 & 2200 Hz, E+, 44100 sample rate / 3. Ready to accept AGW client application 0 on port 8000 ... Ready to accept KISS TCP client application 0 on port 8001 ... Virtual KISS TNC is available on /dev/pts/0 Created symlink /tmp/kisstnc -> /dev/pts/0 [0L] KI6ZHD-8>BEACON:KI6ZHD/k KI6ZHD-1/b SCLARA/n 44.128.0.1/ip : Linpac in Santa Clara <0x20>
Yah, i think this is a Pi5 thing, they have multiple gpio adapters, and you somehow add the adapter address to the pin address to get the actual pin. I don't have all the info, to be honest. I've switched to the "gpiozero" python module which makes it all transparent, but I'm not sure how to implement it in C. the /sys gpio stuff is deprecated (deprecating)
Ok, I have a Pi5 on order but I don't know when it will ship. I'm surprised we would see different OS behavior depending on the hardware.
The individual file sysfs interface has been deprecated for some time now. You are supposed to use libgpiod: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git. It's actually a much better interface in my opinion.
Understood and WB2OSZ has already committed this new interface into DW 1.8-DEV but I'm curious why I cannot reproduce this issue. If it's only exposed when using new Rpi5 hardware, that doesn't make much sense unless it's exposed only give a new kernel or firmware only used on the Rpi5 hardware.
A preliminary version of PTT with gpiod/libgpiod is now available in the "dev" branch. I did a little bit of testing on an RPi 3 and it works for a simple case. It needs more testing under a variety of situations. Here is how to use it.
(1) Install packages gpiod and libgpiod-dev. (2) cd to direwolf source dir. "git pull" to get latest source. (3) Rebuild direwolf, starting with the cmake step so the new packages are noticed. (4) When direwolf starts, notice that libgpiod is listed in optional features. (5) run "gpioinfo" command to get list of gpio chip names and corresponding I/O lines. For an RPi 3, the name is "gpiochip0." I have not tried on other models yet. (6) In your config file, change PTT line from "PTT GPIO n" to "PTT GPIOD gpiochip0 n" where n is the I/O line number.
I'm not happy about the additional user complexity of having to determine the gpio chip name. If it turns out to be gpiochip0 for all RPi models, maybe that could be made the default, still leaving the option for specifying for other single board computers.
Note that many pins also have names, and you can find the pins by their name instead of worrying what chip they’re on. The pin names are defined in the device tree of whatever platform you’re running. That way they’re abstracted from whatever GPIO chip they’re on. Because while the internal stuff will probably come up on gpiochip0, there is no guarantee that it will from the kernel.
Here's my pi5 8GB:
pi@pi5one:~ $ gpioinfo
gpiochip0 - 32 lines:
line 0: "-" unused input active-high
line 1: "2712_BOOT_CS_N" "spi10 CS0" output active-low [used]
line 2: "2712_BOOT_MISO" unused input active-high
line 3: "2712_BOOT_MOSI" unused input active-high
line 4: "2712_BOOT_SCLK" unused input active-high
line 5: "-" unused input active-high
line 6: "-" unused input active-high
line 7: "-" unused input active-high
line 8: "-" unused input active-high
line 9: "-" unused input active-high
line 10: "-" unused input active-high
line 11: "-" unused input active-high
line 12: "-" unused input active-high
line 13: "-" unused input active-high
line 14: "PCIE_SDA" unused input active-high
line 15: "PCIE_SCL" unused input active-high
line 16: "-" unused input active-high
line 17: "-" unused input active-high
line 18: "-" unused input active-high
line 19: "-" unused input active-high
line 20: "PWR_GPIO" "pwr_button" input active-low [used]
line 21: "2712_G21_FS" unused input active-high
line 22: "-" unused input active-high
line 23: "-" unused input active-high
line 24: "BT_RTS" unused input active-high
line 25: "BT_CTS" unused input active-high
line 26: "BT_TXD" unused input active-high
line 27: "BT_RXD" unused input active-high
line 28: "WL_ON" "wl_on_reg" output active-high [used]
line 29: "BT_ON" "shutdown" output active-high [used]
line 30: "WIFI_SDIO_CLK" unused input active-high
line 31: "WIFI_SDIO_CMD" unused input active-high
gpiochip1 - 4 lines:
line 0: "WIFI_SDIO_D0" unused input active-high
line 1: "WIFI_SDIO_D1" unused input active-high
line 2: "WIFI_SDIO_D2" unused input active-high
line 3: "WIFI_SDIO_D3" unused input active-high
gpiochip2 - 17 lines:
line 0: "RP1_SDA" unused input active-high
line 1: "RP1_SCL" unused input active-high
line 2: "RP1_RUN" "RP1 RUN pin" output active-high [used]
line 3: "SD_IOVDD_SEL" "vdd-sd-io" output active-high [used]
line 4: "SD_PWR_ON" "sd_vcc_reg" output active-high [used]
line 5: "SD_CDET_N" unused input active-high
line 6: "SD_FLG_N" unused input active-high
line 7: "-" unused input active-high
line 8: "2712_WAKE" unused input active-high
line 9: "2712_STAT_LED" "ACT" output active-low [used]
line 10: "-" unused input active-high
line 11: "-" unused input active-high
line 12: "PMIC_INT" unused input active-high
line 13: "UART_TX_FS" unused input active-high
line 14: "UART_RX_FS" unused input active-high
line 15: "-" unused input active-high
line 16: "-" unused input active-high
gpiochip3 - 6 lines:
line 0: "HDMI0_SCL" unused input active-high
line 1: "HDMI0_SDA" unused input active-high
line 2: "HDMI1_SCL" unused input active-high
line 3: "HDMI1_SDA" unused input active-high
line 4: "PMIC_SCL" unused input active-high
line 5: "PMIC_SDA" unused input active-high
gpiochip4 - 54 lines:
line 0: "ID_SD" unused input active-high
line 1: "ID_SC" unused input active-high
line 2: "PIN3" unused input active-high
line 3: "PIN5" unused input active-high
line 4: "PIN7" unused input active-high
line 5: "PIN29" unused input active-high
line 6: "PIN31" unused input active-high
line 7: "PIN26" unused input active-high
line 8: "PIN24" unused input active-high
line 9: "PIN21" unused input active-high
line 10: "PIN19" unused input active-high
line 11: "PIN23" unused input active-high
line 12: "PIN32" unused input active-high
line 13: "PIN33" unused input active-high
line 14: "PIN8" unused input active-high
line 15: "PIN10" unused input active-high
line 16: "PIN36" unused input active-high
line 17: "PIN11" unused input active-high
line 18: "PIN12" unused input active-high
line 19: "PIN35" unused input active-high
line 20: "PIN38" unused input active-high
line 21: "PIN40" unused input active-high
line 22: "PIN15" unused input active-high
line 23: "PIN16" unused input active-high
line 24: "PIN18" unused input active-high
line 25: "PIN22" unused input active-high
line 26: "PIN37" unused input active-high
line 27: "PIN13" unused input active-high
line 28: "PCIE_RP1_WAKE" unused input active-high
line 29: "FAN_TACH" unused input active-high
line 30: "HOST_SDA" unused input active-high
line 31: "HOST_SCL" unused input active-high
line 32: "ETH_RST_N" "phy-reset" output active-low [used]
line 33: "-" unused input active-high
line 34: "CD0_IO0_MICCLK" "cam0_reg" output active-high [used]
line 35: "CD0_IO0_MICDAT0" unused input active-high
line 36: "RP1_PCIE_CLKREQ_N" unused input active-high
line 37: "-" unused input active-high
line 38: "CD0_SDA" unused input active-high
line 39: "CD0_SCL" unused input active-high
line 40: "CD1_SDA" unused input active-high
line 41: "CD1_SCL" unused input active-high
line 42: "USB_VBUS_EN" unused output active-high
line 43: "USB_OC_N" unused input active-high
line 44: "RP1_STAT_LED" "PWR" output active-low [used]
line 45: "FAN_PWM" unused output active-high
line 46: "CD1_IO0_MICCLK" "cam1_reg" output active-high [used]
line 47: "2712_WAKE" unused input active-high
line 48: "CD1_IO1_MICDAT1" unused input active-high
line 49: "EN_MAX_USB_CUR" unused output active-high
line 50: "-" unused input active-high
line 51: "-" unused input active-high
line 52: "-" unused input active-high
line 53: "-" unused input active-high
I'm not sure how to interperet what to use in my direwolf.conf for GPIO 17... PTT GPIOD gpiochip4 17
...which does correspond with physical pin#11 on the board?
FYI for those still needing one, I recently got 4 pi5-8's from Parallax and they arrived within a few days after purchase. They still have a some in stock, as well as a bunch of pi5-4's.
UPDATE EDIT I just tested that... now direwolf runs, but the GPIO is not being toggled during transmit. I tested my hardware with a simple python script using gpiozero and all is working properly on that end.
Another observation I made... now my gpioinfo shows that line 17 is a "unused output active-high" after running my python test script. If I reboot it reverts to input, and then after running direwolf it does not change.
de ko6blz k
I realized I was not using the latest dev branch WRT my previous post. I have since updated to the dev branch, and now when I start direwolf, PTT is turned on immediately and does not turn off. After the beacon wait period, the terminal shows the beacon TX, but PTT remains on. If I shut down direwolf the PTT remains on until the radio times out; the ptt adapter remains lit until I either use gpiozero to turn it off or I reboot.
Did you do this?
(1) Install packages gpiod and libgpiod-dev. (2) cd to direwolf source dir. "git pull" to get latest source. (3) Rebuild direwolf, starting with the cmake step so the new packages are noticed. (4) When direwolf starts, notice that libgpiod is listed in optional features. (5) run "gpioinfo" command to get list of gpio chip names and corresponding I/O lines. For an RPi 3, the name is "gpiochip0." I have not tried on other models yet. (6) In your config file, change PTT line from "PTT GPIO n" to "PTT GPIOD gpiochip0 n" where n is the I/O line number.
Yes I completed all of those steps which ended in my last result (PTT turns on and remains on when direwolf is started. This is with PTT GPIOD gpiochip4 17
in my conf file. Again for clarity, before when PTT was not working at all I had not yet installed libgpio-dev or updated with "git pull" (gpiod was already installed). After installing libgpio-dev and recompiling with per your listed steps, PTT is stuck on.
Not sure if this is at all related, but after adding libgpio-dev and updating direwolf, somehow a non-working cm108 w/ PTT now works properly. Before when I tx with the cm108, my mouse would stop responding randomly, requiring a reboot to get it back. After completing your listed steps, I tested the CM108 and it has been stable for several hours now (before it would take 5min or less for the mouse to freeze).
So now with a working cm108, this issue is not a problem for me. I am still happy to help with any troubleshooting on this issue on my pi5 (I have a backup pi5 with direwolf dev installed that I can run tests on without worries of breaking my working setup). So please let me know if there is anything other experiments you'd like me to try. It's the least I can do to repay all the hours you and other devs have put into this project.
After I got back to playing with gpio, and stumbed on the fix when I let my pi5 direwolf tx a few times (without a radio connected). After seeing my PTT LED turn off during tx, and back on during rx, I finally realized the problem was simply an inverted output. With my python script my ptt circuit was behaving as expected... on==on and off==off. It seems direwolf gpiod inverts the output, and my direwolf.conf had to be changed accordingly. So now my pi5 is happily digipeating with gpio using PTT GPIOD gpiochip4 -17
.
This worked great on a Libre board (LePotato), thanks! The settings were GPIOD gpiochip1 -94
to get to pin #18. So, this is my vote to please not default to gpiochip0
.
The Radio Interface Guide, in https://github.com/wb2osz/direwolf-doc , has been updated with more details about using gpiod. Using pin names, and not having to specify the ggiochip number, is a very good suggestion. Except... the naming is not consistent so a configuration for one model and OS version and another. There is an example in the Radio Interface Guide cited above. I'm not happy with the current situation and welcome suggestions to make it simpler for users.
Thank you for fixing this! I followed the directions to get the development version installed and now I have my iGate/Digipeater running on a Raspberry Pi 5. For mine, it was gpiochip4, GPIO6 so the line was GPIOD gpiochip4 6. N4JWW