GPIO.add_event_detect no longer works with the new kernel 6.60
Describe the bug
Since the update to the following kernel, the "add_event_detect" function from the RPi.GPIO library no longer works.
Linux outdoor enclosurePi 6.6.20+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.20-1+rpt1 (2024-03-07) aarch64 GNU/Linux
The program crashes with the following error.
Traceback (most recent call last):
File "/home/pi/scripts/test/./door_limit_switch_states.py", line 48, in <module>
GPIO.add_event_detect(door_limit_switch_top, GPIO.BOTH, callback=all, bouncetime = 20)
RuntimeError: Failed to add edge detection
I use the following Raspberry
Raspberry Pi 4 Model B Rev 1.5
Steps to reproduce the behaviour
Update to the actual kernel and try the RPi.GPIO library function "add_event_detect"
Device (s)
Raspberry Pi 4 Mod. B
System
Raspberry Pi reference 2023-10-10 Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, fb56ad562991cf3ae5c96ab50983e1deeaefc7b6, stage2
Feb 29 2024 12:24:53 Copyright (c) 2012 Broadcom version f4e2138c2adc8f3a92a3a65939e458f11d7298ba (clean) (release) (start)
Logs
No response
Additional context
No response
I suspect this is because the rpi-6.6.y kernel no longer overrides an upstream kernel decision to force the base number of the main GPIO controller to be global GPIO 0. Running cat /sys/kernel/debug/gpio will show that GPIO0 (named ID_SDA) is allocated global GPIO number 512. It is going to be painful until the 3rd party libraries are updated, but the choice to stop swimming against the tide was intentional.
Okay, if that was the intention, then I know. Since many tutorials on the internet still use the RPi.GPIO library, this will definitely be painful for users.
I also don't think that the RPi.GPIO library will receive an update or be adapted, as it has not received an update for the Raspberry Pi 5 either.
What sensible alternative should users use? Especially with a trigger for events?
Old Kernel on a other RPI:
gpiochip0: GPIOs 0-53, parent: platform/3f200000.gpio, pinctrl-bcm2835:
gpio-0 (ID_SDA )
gpio-1 (ID_SCL )
gpio-2 (SDA1 )
gpio-3 (SCL1 )
gpio-4 (GPIO_GCLK )
gpio-5 (GPIO5 )
gpio-6 (GPIO6 )
gpio-7 (SPI_CE1_N )
gpio-8 (SPI_CE0_N )
gpio-9 (SPI_MISO )
gpio-10 (SPI_MOSI )
gpio-11 (SPI_SCLK )
gpio-12 (GPIO12 )
gpio-13 (GPIO13 |sysfs ) in lo IRQ
gpio-14 (TXD1 )
gpio-15 (RXD1 )
gpio-16 (GPIO16 )
gpio-17 (GPIO17 )
gpio-18 (GPIO18 |sysfs ) in lo IRQ
gpio-19 (GPIO19 |sysfs ) in lo IRQ
gpio-20 (GPIO20 )
gpio-21 (GPIO21 )
gpio-22 (GPIO22 |sysfs ) in lo IRQ
gpio-23 (GPIO23 )
gpio-24 (GPIO24 )
gpio-25 (GPIO25 |sysfs ) in lo IRQ
gpio-26 (GPIO26 |sysfs ) in lo IRQ
gpio-27 (GPIO27 |sysfs ) in lo IRQ
gpio-28 (NC )
gpio-29 (LAN_RUN_BOOT )
gpio-30 (CTS0 )
gpio-31 (RTS0 )
gpio-32 (TXD0 )
gpio-33 (RXD0 )
gpio-34 (SD1_CLK )
gpio-35 (SD1_CMD )
gpio-36 (SD1_DATA0 )
gpio-37 (SD1_DATA1 )
gpio-38 (SD1_DATA2 )
gpio-39 (SD1_DATA3 )
gpio-40 (PWM0_OUT )
gpio-41 (PWM1_OUT )
gpio-42 (ETH_CLK )
gpio-43 (WIFI_CLK )
gpio-44 (SDA0 )
gpio-45 (SCL0 )
gpio-46 (SMPS_SCL )
gpio-47 (SMPS_SDA )
gpio-48 (SD_CLK_R )
gpio-49 (SD_CMD_R )
gpio-50 (SD_DATA0_R )
gpio-51 (SD_DATA1_R )
gpio-52 (SD_DATA2_R )
gpio-53 (SD_DATA3_R )
gpiochip1: GPIOs 100-101, brcmvirt-gpio, can sleep:
gpio-100 ( |ACT ) out lo
gpiochip3: GPIOs 500-503, parent: usb/1-1.2:1.0, ftdi-cbus, can sleep:
gpiochip2: GPIOs 504-511, parent: platform/soc:firmware:expgpio, raspberrypi-exp-gpio, can sleep:
gpio-504 (BT_ON |shutdown ) out hi
gpio-505 (WL_ON )
gpio-506 (STATUS_LED )
gpio-507 (LAN_RUN )
gpio-508 (HDMI_HPD_N |hpd ) in lo ACTIVE LOW
gpio-509 (CAM_GPIO0 |cam1_regulator ) out lo
gpio-510 (CAM_GPIO1 )
gpio-511 (PWR_LOW_N |PWR ) in hi
New Kernel on the RPI 4:
gpiochip0: GPIOs 512-569, parent: platform/fe200000.gpio, pinctrl-bcm2711:
gpio-512 (ID_SDA )
gpio-513 (ID_SCL )
gpio-514 (GPIO2 )
gpio-515 (GPIO3 )
gpio-516 (GPIO4 |onewire@4 ) out hi
gpio-517 (GPIO5 )
gpio-518 (GPIO6 )
gpio-519 (GPIO7 |lg ) in lo IRQ
gpio-520 (GPIO8 )
gpio-521 (GPIO9 )
gpio-522 (GPIO10 )
gpio-523 (GPIO11 )
gpio-524 (GPIO12 )
gpio-525 (GPIO13 )
gpio-526 (GPIO14 )
gpio-527 (GPIO15 )
gpio-528 (GPIO16 )
gpio-529 (GPIO17 )
gpio-530 (GPIO18 |ir-receiver@12 ) in hi IRQ ACTIVE LOW
gpio-531 (GPIO19 )
gpio-532 (GPIO20 )
gpio-533 (GPIO21 )
gpio-534 (GPIO22 )
gpio-535 (GPIO23 )
gpio-536 (GPIO24 |lg ) in lo IRQ
gpio-537 (GPIO25 )
gpio-538 (GPIO26 )
gpio-539 (GPIO27 )
gpio-540 (RGMII_MDIO )
gpio-541 (RGMIO_MDC )
gpio-542 (CTS0 )
gpio-543 (RTS0 )
gpio-544 (TXD0 )
gpio-545 (RXD0 )
gpio-546 (SD1_CLK )
gpio-547 (SD1_CMD )
gpio-548 (SD1_DATA0 )
gpio-549 (SD1_DATA1 )
gpio-550 (SD1_DATA2 )
gpio-551 (SD1_DATA3 )
gpio-552 (PWM0_MISO )
gpio-553 (PWM1_MOSI )
gpio-554 (STATUS_LED_G_CLK |ACT ) out lo
gpio-555 (SPIFLASH_CE_N )
gpio-556 (SDA0 )
gpio-557 (SCL0 )
gpio-558 (RGMII_RXCLK )
gpio-559 (RGMII_RXCTL )
gpio-560 (RGMII_RXD0 )
gpio-561 (RGMII_RXD1 )
gpio-562 (RGMII_RXD2 )
gpio-563 (RGMII_RXD3 )
gpio-564 (RGMII_TXCLK )
gpio-565 (RGMII_TXCTL )
gpio-566 (RGMII_TXD0 )
gpio-567 (RGMII_TXD1 )
gpio-568 (RGMII_TXD2 )
gpio-569 (RGMII_TXD3 )
gpiochip1: GPIOs 570-577, parent: platform/soc:firmware:gpio, raspberrypi-exp-gpio, can sl eep:
gpio-570 (BT_ON )
gpio-571 (WL_ON )
gpio-572 (PWR_LED_OFF |PWR ) out lo ACTIVE LOW
gpio-573 (GLOBAL_RESET )
gpio-574 (VDD_SD_IO_SEL |vdd-sd-io ) out lo
gpio-575 (CAM_GPIO |cam1_regulator ) out lo
gpio-576 (SD_PWR_ON |regulator-sd-vcc ) out lo
gpio-577 (SD_OC_N )
I suspect this is because the rpi-6.6.y kernel no longer overrides an upstream kernel decision to force the base number of the main GPIO controller to be global GPIO 0. Running
cat /sys/kernel/debug/gpiowill show that GPIO0 (named ID_SDA) is allocated global GPIO number 512. It is going to be painful until the 3rd party libraries are updated, but the choice to stop swimming against the tide was intentional.
Ok, what is the fix? Sorry for the basic question. Newbie at Rpi
The fix is for someone to patch RPi.GPIO to locate the global GPIO number for GPIO0, and add that as an offset to the requested GPIO number. In this case it is likely to be 512.
Thanks Phil. I guess I'll have to wait for 'someone'. Although I'd be willing to do such a fix, I have zero experience in RPi for the time being.
Saludos, Greetings Jean-Robert STRELE COL: +57.321.414.6328 USA: +1.925.922.4231 @.***
ᐧ
On Thu, 14 Mar 2024 at 11:23, Phil Elwell @.***> wrote:
The fix is for someone to patch RPi.GPIO to locate the global GPIO number for GPIO0, and add that as an offset to the requested GPIO number. In this case it is likely to be 512.
— Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/6037#issuecomment-1997842569, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFQXPNRQQNV5XGCAMIPMWXDYYHFHTAVCNFSM6AAAAABEUTY3D2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOJXHA2DENJWHE . You are receiving this because you commented.Message ID: @.***>
Ubuntu have already been down this path (GPIO via sysfs has totally gone there), and Dave Jones has written an RPi.GPIO shim on top of lgpio https://waldorf.waveform.org.uk/2022/the-one-where-dave-breaks-stuff.html https://rpi-lgpio.readthedocs.io/en/release-0.4/#
I thought we'd pulled that shim into Raspberry Pi OS, but we only appear to have python3-rpi.gpio and not python3-rpi-gpio. @XECDesign am I wrong on this one?
On Pi 5
gpiochip0: GPIOs 512-543, parent: platform/107d508500.gpio, gpio-brcmstb@107d508500:
gpio-512 (- )
gpio-513 (2712_BOOT_CS_N |spi10 CS0 ) out hi ACTIVE LOW
gpio-514 (2712_BOOT_MISO )
gpio-515 (2712_BOOT_MOSI )
gpio-516 (2712_BOOT_SCLK )
gpio-517 (- )
gpio-518 (- )
gpio-519 (- )
gpio-520 (- )
gpio-521 (- )
gpio-522 (- )
gpio-523 (- )
gpio-524 (- )
gpio-525 (- )
gpio-526 (PCIE_SDA )
gpio-527 (PCIE_SCL )
gpio-528 (- )
gpio-529 (- )
gpio-530 (- )
gpio-531 (- )
gpio-532 (PWR_GPIO |pwr_button ) in hi ACTIVE LOW
gpio-533 (2712_G21_FS )
gpio-534 (- )
gpio-535 (- )
gpio-536 (BT_RTS )
gpio-537 (BT_CTS )
gpio-538 (BT_TXD )
gpio-539 (BT_RXD )
gpio-540 (WL_ON |wl_on_reg ) out hi
gpio-541 (BT_ON |shutdown ) out hi
gpio-542 (WIFI_SDIO_CLK )
gpio-543 (WIFI_SDIO_CMD )
gpiochip1: GPIOs 544-547, parent: platform/107d508500.gpio, gpio-brcmstb@107d508520:
gpio-544 (WIFI_SDIO_D0 )
gpio-545 (WIFI_SDIO_D1 )
gpio-546 (WIFI_SDIO_D2 )
gpio-547 (WIFI_SDIO_D3 )
gpiochip2: GPIOs 548-564, parent: platform/107d517c00.gpio, gpio-brcmstb@107d517c00:
gpio-548 (RP1_SDA )
gpio-549 (RP1_SCL )
gpio-550 (RP1_RUN |RP1 RUN pin ) out hi
gpio-551 (SD_IOVDD_SEL |vdd-sd-io ) out hi
gpio-552 (SD_PWR_ON |sd_vcc_reg ) out hi
gpio-553 (SD_CDET_N |cd ) in lo ACTIVE LOW
gpio-554 (SD_FLG_N )
gpio-555 (- )
gpio-556 (2712_WAKE )
gpio-557 (2712_STAT_LED |ACT ) out hi ACTIVE LOW
gpio-558 (- )
gpio-559 (- )
gpio-560 (PMIC_INT )
gpio-561 (UART_TX_FS )
gpio-562 (UART_RX_FS )
gpio-563 (- )
gpio-564 (- )
gpiochip3: GPIOs 565-570, parent: platform/107d517c00.gpio, gpio-brcmstb@107d517c20:
gpio-565 (HDMI0_SCL )
gpio-566 (HDMI0_SDA )
gpio-567 (HDMI1_SCL )
gpio-568 (HDMI1_SDA )
gpio-569 (PMIC_SCL )
gpio-570 (PMIC_SDA )
gpiochip4: GPIOs 571-624, parent: platform/1f000d0000.gpio, pinctrl-rp1:
gpio-571 (ID_SDA )
gpio-572 (ID_SCL )
gpio-573 (GPIO2 )
gpio-574 (GPIO3 )
gpio-575 (GPIO4 |sysfs ) out lo
gpio-576 (GPIO5 |sysfs ) in hi IRQ
gpio-577 (GPIO6 |sysfs ) in hi IRQ
gpio-578 (GPIO7 )
gpio-579 (GPIO8 |sysfs ) in hi IRQ
gpio-580 (GPIO9 )
gpio-581 (GPIO10 )
gpio-582 (GPIO11 |sysfs ) out lo
gpio-583 (GPIO12 )
gpio-584 (GPIO13 )
gpio-585 (GPIO14 )
gpio-586 (GPIO15 )
gpio-587 (GPIO16 |sysfs ) in hi IRQ
gpio-588 (GPIO17 )
gpio-589 (GPIO18 |sysfs ) out lo
gpio-590 (GPIO19 )
gpio-591 (GPIO20 )
gpio-592 (GPIO21 |sysfs ) in hi IRQ
gpio-593 (GPIO22 )
gpio-594 (GPIO23 |sysfs ) out lo
gpio-595 (GPIO24 )
gpio-596 (GPIO25 |sysfs ) out lo
gpio-597 (GPIO26 )
gpio-598 (GPIO27 )
gpio-599 (PCIE_RP1_WAKE )
gpio-600 (FAN_TACH )
gpio-601 (HOST_SDA )
gpio-602 (HOST_SCL )
gpio-603 (ETH_RST_N |phy-reset ) out hi ACTIVE LOW
gpio-604 (- )
gpio-605 (CD0_IO0_MICCLK |cam0_reg ) out lo
gpio-606 (CD0_IO0_MICDAT0 )
gpio-607 (RP1_PCIE_CLKREQ_N )
gpio-608 (- )
gpio-609 (CD0_SDA )
gpio-610 (CD0_SCL )
gpio-611 (CD1_SDA )
gpio-612 (CD1_SCL )
gpio-613 (USB_VBUS_EN )
gpio-614 (USB_OC_N )
gpio-615 (RP1_STAT_LED |PWR ) out hi ACTIVE LOW
gpio-616 (FAN_PWM )
gpio-617 (CD1_IO0_MICCLK |cam1_reg ) out lo
gpio-618 (2712_WAKE )
gpio-619 (CD1_IO1_MICDAT1 )
gpio-620 (EN_MAX_USB_CUR )
gpio-621 (- )
gpio-622 (- )
gpio-623 (- )
gpio-624 (- )
/boot/firmware/config.txt worked with
gpio=5,6,7,8,16,17,20,21,22,26,27=pu
gpio=9,10,11,12,18,19,23,24,25=op
In the past, now only first 5 values take effect for each line.... (Values adjusted for sure)
Now you are really crossing the streams. The config.txt lines are interpreted by the firmware, which should then set default pull-ups on some pins and make others outputs. These changes may persist once the kernel has booted, but they may also be overwritten.
-
Are you saying that this changed with the switch to the 6.6 kernel?
-
Can you point out some parts of the
/sys/kernel/debug/gpiooutput that show the problem?
I thought we'd pulled that shim into Raspberry Pi OS, but we only appear to have python3-rpi.gpio and not python3-rpi-gpio. @XECDesign am I wrong on this one?
Off the top of my head, I'm not sure. Last time I looked at GPIO libraries, there was some uncertainty about what the right way forward is and what to focus on. I'll revisit when I'm back in April.
@pelwell we can separate that, sure. Wasn't sure if it's also related here. But yes, it's new since the switch on 6.6. not sure what's the cause, kernel or other firmware/OS related changes.
To me it looks like there's also a difference on the GPIO mapping (gpio 3 on Pi 4 on 515, Pi 5 on 574), is that true in general or depends on the kernel Version? Linux 6.6.20+rpt-rpi-2712 aarch64 is installed. Can post more information in April, don't get hands on my Pi next 2 weeks...
597,598 and 595 are ignored.
The firmware still expects the GPIOs to be numbered from 0 (the firmware and kernel are completely different worlds), so:
gpio=5,6,7,8,16,17,20,21,22,26,27=pu
gpio=9,10,11,12,18,19,23,24,25=op
was correct.
Hello,
If I understand the conversation correctly we are looking for a solution sometime in April, correct?
Just so I can plan my project around this.
Have a good weekend
Saludos, Regards,
Jean-Robert STRELE COL +57.321.414.6328 USA +1.925.922.4231 @.***
On Fri, Mar 15, 2024, 09:26 Phil Elwell @.***> wrote:
The firmware still expects the GPIOs to be numbered from 0 (the firmware and kernel are completely different worlds), so:
gpio=5,6,7,8,16,17,20,21,22,26,27=pu gpio=9,10,11,12,18,19,23,24,25=op
was correct.
— Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/6037#issuecomment-1999782439, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFQXPNSX64HXMA25HRHBWSLYYMAIZAVCNFSM6AAAAABEUTY3D2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOJZG44DENBTHE . You are receiving this because you commented.Message ID: @.***>
we are looking for a solution sometime in April, correct?
You probably won't get an answer before April, but there is no timeframe for a solution.
So we can understand your situation a bit better:
- Are you building RPi.GPIO yourself?
- Are you shipping/going to ship it to your customers (if there are customers)?
- In other words, would a locally modified version of RPi.GPIO be a workable solution?
This is a local project for my pool chemistry. One time solution.
I don't have the knowledge to build/modify my own RPi.gpio.
So, yes, a local solution would be acceptable to me as an interim solution, until a stock solution is available...
Keep in mind, I'm a newbie at RPi...
Thanks!
On Fri, Mar 15, 2024, 12:50 Phil Elwell @.***> wrote:
we are looking for a solution sometime in April, correct?
You probably won't get an answer before April, but there is no timeframe for a solution.
So we can understand your situation a bit better:
- Are you building RPi.GPIO yourself?
- Are you shipping/going to ship it to your customers (if there are customers)?
- In other words, would a locally modified version of RPi.GPIO be a workable solution?
— Reply to this email directly, view it on GitHub https://github.com/raspberrypi/linux/issues/6037#issuecomment-2000157674, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFQXPNSHM26OUXSW3M2WH4TYYMYHJAVCNFSM6AAAAABEUTY3D2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBQGE2TONRXGQ . You are receiving this because you commented.Message ID: @.***>
First of all, I just wanted to thank you for your great work over the last few years.
But now to the topic. In my humble opinion, letting die the RPi.GPIO library is one of the biggest mistakes of the Raspberry Pi Foundation. In my humble opinion, this has the following reasons:
-
there are millions of projects running with this library and probably not anymore. Backwards compatibility was always the argument in favor of the Raspberry Pi and against alternatives
-
the GPIOZERO library is not an equivalent replacement. First of all, GPIOS cannot be accessed with several programs at the same time. The new library may be suitable for beginners, but if you are an advanced beginner, this is no longer the case. Not everyone is familiar with sockets or named pipes. The leap is simply too big for many beginners. RPi.GPIO could do this without any problems.
-
if you terminate a program that uses the GPIOZERO library, the current state of the GPIO is not retained after termination. This means that no script can be programmed that changes the state of the pin and is then terminated. Beginners in the web area will find this particularly difficult.
Therefore, in my humble opinion, the library should be adapted for all models, even if the original developer no longer does this, the maintenance could be continued by the Raspberry Pi Foundation.
There is a related discussion/ticket at https://sourceforge.net/p/raspberry-gpio-python/tickets/210/ It seems that especially for event detection the RPi.GPIO library is outdated.
I have been struggling with this issue for a couple of days and have just come across this thread.
I have several clients who are using RPi4s who will have to stay on the Bullseye OS until a solution is found. To date RPi.GPIO has worked well
It would be really helpful if the documentation https://www.raspberrypi.com/documentation/computers/os.html could be updated to cover the issues raised by @Blackbox-git .
rpi-lgpio seems to work well on RPi5s running Bookworm. Perhaps this could be extended to provide at least an interim solution for RPi4s.
Perhaps this could be extended to provide at least an interim solution for RPi4s.
Does it not work on all Pis?
@pelwell , Unfortunately I don't think so. On RPi4s rpi-lgpio seems to mimic the behaviour of RPi.GPIO. Perhaps somebody has found a way to make it work.
@TimW55 and @pelwell
I use a workaround now
I use gpiozero for the previous "Event_detect". The rest of the pin control still runs via RPi.GPIO. FOR EXAMPLE:
import gpiozero
gpio_pin_input = gpiozero.DigitalInputDevice("MY_PIN_NUMBER", pull_up = None, active_state = True)
# Function for event
def event():
time.sleep(0.1)
state = MY_PIN_NUMBER.value
print("The current state of the PIN is: ", str(state))
gpio_pin_input.when_activated = event
gpio_pin_input.when_deactivated = event
while True:
time.sleep(1)
This makes it possible to use the GPIO-PIN once with an event listener in program 1. In program 2 you can still read the state of the GPIO-PIN via the RPi.GPIO libary with the command GPIO.input("MY_PIN_NUMBER") without getting a "GPIO is busy" warning.
@pelwell , Unfortunately I don't think so. On RPi4s rpi-lgpio seems to mimic the behaviour of RPi.GPIO. Perhaps somebody has found a way to make it work.
I'm confused. It's meant to mimic the behaviour of RPi.GPIO.
Running on a Pi4 with Bookworm here, rpi-lgpio installed via pip3, and interactively doing
>>> import RPi.GPIO as GPIO
>>> GPIO.setmode(GPIO.BCM)
>>> GPIO.setwarnings(False)
>>> led = 4
>>> #Initialize your pin
>>> GPIO.setup(led,GPIO.OUT)
>>> GPIO.output(led,1)
>>> GPIO.output(led,0)
has just done the expected when each step was checked via pinctrl get 4.
Quit, and GPIO 4 is left as an output with the current state.
I've not looked specifically at the add_event_detect hook.
It is true that 2 different processes can not access the same GPIO as libgpiod enforces ownership, but different processes can access different GPIOs.
@pelwell, yes, you are right but I was specifically looking at add_event_detect which I haven't been able to get working.
Can you post a small sample program so we can take a look?
If it's more than a page you could put it in a gist (see the + Create New button at the top of the page).
@pelwell, Ooopps. My apologies there was an issue in my environment affecting RPi4s. It is working exactly as expected now! I wasn't seeing the wood for the trees.
@pelwell who should post a sample program?
@6by9 this works normal. but "add_event_detect" is broken
@Blackbox-git , "add_event_detect works" as expected on RPi4s running Bookworm when using the rpi-lgpio package
Well, at least it doesn't crash.
@Blackbox-git , "add_event_detect works" as expected on RPi4s running Bookworm when using the rpi-lgpio package
Yes. But you cant access from another programm the gpio with this libary.