Getting `edge` causes a crash on a Raspberry Pi 4 Model B Rev 1.5
Board Type
Raspberry Pi 4 Model B Rev 1.5
Operating System
Linux 6.6.20+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.20-1+rpt1 (2024-03-07) aarch64 GNU/Linux
Swift Version
Swift version 5.10 (swift-5.10-RELEASE) Target: aarch64-unknown-linux-gnu Prebuild
Description
A pin is configured as an input and should call up a function when it changes (both high->low and low-high).
When getting the value of the edge property an exception is raised.
In my opinion, this is caused by the getter making the following call:
return GPIOEdge(rawValue: getStringValue("gpio "+String(id)+"/edge")!)!
This ends up at readFromFile with the following path: /sys/class/gpio/gpio0/edge.
However, this does not exist on my device, so that nil is returned.
This is unwrapped with ! -> boom.
This is what /sys/class/gpiolooks like:
total 0
drwxrwxr-x 2 root gpio 0 Apr 30 14:39 .
drwxr-xr-x 65 root root 0 Jan 1 1970 ..
--w--w---- 1 root gpio 4096 Apr 30 14:39 export
lrwxrwxrwx 1 root gpio 0 Apr 30 14:39 gpiochip512 -> ../../devices/platform/soc/fe200000.gpio/gpio/gpiochip512
lrwxrwxrwx 1 root gpio 0 Apr 30 14:39 gpiochip570 -> ../../devices/platform/soc/soc:firmware/soc:firmware:gpio/gpio/gpiochip570
--w--w---- 1 root gpio 4096 Apr 30 14:39 unexport
Hi, can you try running your application with sudo and if that doesn't work try executing:
echo the_id_you_are_using >/sys/class/gpio/export
ls /sys/class/gpio
From what I see the gpio file the library needs for the edge feature has not been created at all, the gpiochip ones should point to the controller or similar devices, no the individual gpios.
HI, thanks for the quick response.
Running with sudo makes no difference.
I build this small sample app:
import Foundation
import SwiftyGPIO
let gpios = SwiftyGPIO.GPIOs(for:.RaspberryPi4)
if let pin = gpios[.P17]
{
print("\(pin.edge)")
}
The crash is:
SwiftyGPIO/SwiftyGPIO.swift:73: Fatal error: Unexpectedly found nil while unwrapping an Optional value
💣 Program crashed: System trap at 0x0000007f80e0f3ac
Thread 0 "SwiftyGPIOTest" crashed:
0 0x0000007f80e0f3ac closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 236 in libswiftCore.so
1 0x0000007f80e0f198 closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 199 in libswiftCore.so
2 0x0000007f80e0f088 closure #1 in _assertionFailure(_:_:file:line:flags:) + 327 in libswiftCore.so
3 0x0000007f80e0ec58 _assertionFailure(_:_:file:line:flags:) + 175 in libswiftCore.so
4 GPIO.edge.getter + 491 in SwiftyGPIOTest at /home/dirk/SwiftyGPIOTest/.build/checkouts/SwiftyGPIO/Sources/SwiftyGPIO.swift:73:80
71│ get {
72│ if !exported {enableIO(id)}
73│ return GPIOEdge(rawValue: getStringValue("gpio"+String(id)+"/edge")!)!
│ ▲
74│ }
75│ }
echo 17 >/sys/class/gpio/export gives echo: write error: Invalid argument
sudo echo 17 >/sys/class/gpio/export gives same error.
ls -al /sys/class/gpio returns:
total 0
drwxrwxr-x 2 root gpio 0 May 1 17:38 .
drwxr-xr-x 65 root root 0 Jan 1 1970 ..
--w--w---- 1 root gpio 4096 May 2 09:05 export
lrwxrwxrwx 1 root gpio 0 May 1 17:38 gpiochip512 -> ../../devices/platform/soc/fe200000.gpio/gpio/gpiochip512
lrwxrwxrwx 1 root gpio 0 May 1 17:38 gpiochip570 -> ../../devices/platform/soc/soc:firmware/soc:firmware:gpio/gpio/gpiochip570
--w--w---- 1 root gpio 4096 May 1 17:38 unexport
Ok, the raspberry people broke it in the kernel last month, can you try again with release 1.4.4 and using for:.RaspberryPi4_2024 instead?
It would be great if you could also report back if gpios are actually working when you set some value, I'm still not sure if they changed something else or not, but can't test it right now.
This is a bit better, but I can't get an output pin to change it's value.
My test app is now this:
import Foundation
import SwiftyGPIO
let gpios = SwiftyGPIO.GPIOs(for:.RaspberryPi4_2024)
if let pin = gpios[.P17]
{
print("\(pin.edge)")
pin.edge = .BOTH
print("\(pin.edge)")
}
if let pin = gpios[.P4]
{
pin.value = 1
print("\(pin.value)")
pin.direction = .OUT
pin.value = 0
print("\(pin.value)")
Thread.sleep(forTimeInterval: 10.0)
pin.value = 1
print("\(pin.value)")
}
It outputs
NONE
BOTH
0
0
0
gpioinfo returns this for the both pins I've used:
line 4: "GPIO4" unused input active-high
line 17: "GPIO17" "sysfs" input active-high [used]
The output pin stays high, when measured.