iot: GpioController is not correctly identifying Raspberry Pi after latest Raspbian kernel updates

Describe the bug

After running apt-get upgrade on a Raspberry Pi 4B, I couldn’t set pinmodes to pullup or pulldown anymore. Instead, I was getting an error: Unhandled exception. System.InvalidOperationException: The pin does not support the selected mode.

After checking the System.Device.Gpio project I found that GpioController is trying to know if it’s running on a Raspberry Pi via /proc/cpuinfo. There’s a field in there called Hardware and it returns the processor type. Apparently in older Raspbian kernels it was returning the wrong value, since even on a Raspberry Pi 4 it would return “BCM2835”. This is the value that GpioController is comparing against.

Since the kernel update however it seems to be returning the correct value, which for a Raspberry Pi 4 is “BCM2711”.

In fact, BCM2835 is only correct for the first Raspberry Pi, the other models are listed here: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md

Current workaround is to manually specify a GpioDriver and pass it to the GpioController constructor:

GpioDriver driver = new RaspberryPi3Driver();
Controller = new GpioController(PinNumberingScheme.Logical, driver);

Steps to reproduce

Update Raspbian on Raspberry Pi 4b to latest kernel via:

sudo apt-get update sudo apt-get upgrade

and reboot the Pi. Then the following code will fail:

Controller = new GpioController();
Controller.OpenPin(26, PinMode.InputPullUp);

Expected behavior

The pin would be opened and the internal pullup resistor turned on.

Actual behavior

Exception is raised: System.InvalidOperationException: The pin does not support the selected mode.

Versions used Target framework: netcoreapp3.1 System.Device.Gpio version: 1.1.0-prerelease.20276.1

Running self-contained on Raspberry Pi 4b, with kernel version 5.4.51-v7l+ (before the update it was 4.19.118-v7l+)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (17 by maintainers)

Most upvoted comments

@pgrawehr I’m fine with that PR but I do not want any new APIs in SDG as part of it, I’d prefer we’ve split SDG into abstraction and implementation. We’re currently brainstorming about how to align board abstraction with other repos and we already have some idea what we could possibly do

Two observations from my side:

  • The RaspberryPi3Driver works fine on the Pi4. I’ve always used that one and it has never had any problems (except for the pull up/pull down stuff, but that’s fixed since long). So the register address detection works.
  • When (due to the bug in our detection routine) the LibgpiodDriver is used instead of the Raspi driver, everything should be fine as well, since with the current build, that one also supports the pulls.

I just did a bit more digging here and found that actually looks like it is good that our detection logic is not picking the RaspberryPi3Driver, since that one works directly with the registers and those addresses have changed now according to the Datasheets. RPi3 uses BCM2835 which has the base address for GPIO at 0x7E20_0000 whereas Rpi4 uses BCM2711 which has the base address shifted to 0x7E21_5000. I need to test whether or not the logic we have on the Rpi Linux driver with both /dev/gpiomem and to get the base address when using /dev/mem still works in these cases.