Skip to content

Conversation

@hfxbse
Copy link
Contributor

@hfxbse hfxbse commented Mar 26, 2025

Currently, flutter_gpiod assumes the GPIO numbers to be a sequence and therefore reconstructs the file descriptor paths accordingly

for (var i = 0; i < numChips; i++) {
    final pathPtr = '/dev/gpiochip$i'.toNativeUtf8();
    // ...
}

On more recent images of the Raspberry Pi OS, the GPIO chip numbers are no longer a sequence, causing any app using flutter_gpiod to crash during the initialization process. In particular, /dev/gpiochip3 does not exists but /dev/gpiochip4, which seems to also map the chip bcm2835 in my case. Apparently this is related to changes introduced for the Raspberry Pi 5.

pi@raspberry:~ $ ls /dev/ | grep gpio
gpiochip0
gpiochip1
gpiochip2
gpiochip4
gpiomem

pi@raspberry:~ $ gpiodetect
gpiochip0 [pinctrl-bcm2835] (54 lines)
gpiochip1 [brcmvirt-gpio] (2 lines)
gpiochip2 [raspberrypi-exp-gpio] (8 lines)
gpiochip0 [pinctrl-bcm2835] (54 lines)

I propose to not rely on the reconstruction of the device file paths, but use the paths already queried to solve this issue. The implementation in this PR worked for me and but does not garantuar that the index in the list FlutterGpiod.instance.chips matches the chip number as the following comment states:

class GpioChip {
  /// The index of the GPIO chip in the [FlutterGpiod.chips] list,
  /// and at the same time, the numerical suffix of [name].
  final int index;

  // ...
}

Also, this example

final chip = chips.singleWhere(
  (chip) => chip.label == 'pinctrl-bcm2711',
  orElse: () => chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835'),
);

fails as their are now two entries with the same chip label. Using firstWhere instead of singleWhere still works. I suppose this does not need any changes to the library itself but in the documentation, as this affects specifically Raspberry Pi devices.

Using a map instead of a list for FlutterGpiod.instance.chips seems the most fitting to me right now, but I am not sure. It looks like a breaking change is unavoidable in order to fix this issue. Let me know your thoughts on this.

…and thank you for this handy library :)

@hfxbse hfxbse marked this pull request as draft March 26, 2025 23:21
@hfxbse hfxbse changed the title Consider cases in which the chip numbers are not a sequence Support cases in which the GPIO chip numbers are not a sequence Mar 26, 2025
@MatthewJones517
Copy link

I am having an issue right now that I think is related to this. I can't run my app at all because of a FileSystem error stating that gpiochip2 can't be found. I think this would resolve the issue.

@ardera
Copy link
Owner

ardera commented Apr 11, 2025

Sorry, was on vacation for the past 2 weeks. Thanks for the fix!

@ardera
Copy link
Owner

ardera commented Apr 11, 2025

You're right it is a bit problematic, making the elements nullable would mean people would have to add null-safety assertions everywhere. Making it a Map would break easy iteration over the elements. A sparse list would be good but that also breaks if people do old-school for (int i = 0; i < chips.length; i++) { /* ... */ } iteration

I think I'd go with the Map, it is a breaking change and I'll have to increase major versions, but there's no other way around AFAICT

@ardera ardera linked an issue Apr 11, 2025 that may be closed by this pull request
Copy link
Owner

@ardera ardera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rest of the code looks good to me though 👍

@hfxbse hfxbse force-pushed the main branch 2 times, most recently from 5546891 to 8a64485 Compare April 13, 2025 12:50
@hfxbse hfxbse marked this pull request as ready for review April 13, 2025 12:53
@hfxbse
Copy link
Contributor Author

hfxbse commented Apr 13, 2025

I went ahead and changed it to map as discussed, and hopefully caught every reference to the list in comments, examples, and the documentation.

As a heads-up, while I adjusted the integration tests accordingly, it is beyond me on how to actually execute them with my current setup. While a quick manual check seems to work as expected, you probably still want to run them :)

@ardera
Copy link
Owner

ardera commented Apr 14, 2025

Looks good. Thanks a lot for the fix!

Btw, it could be that we need to be even more conservative in the future. I just checked how gpiodetect from libgpiod enumerates GPIO devices, and it just lists all devices in /dev/ and checks for some criteria:
https://github.com/brgl/libgpiod/blob/9f0eca2d7260de1ae22fed3795280bdb14b62e57/examples/find_line_by_name.c#L14-L64

And gpiod_check_gpiochip_device looks up some paths in /sys using major & minor device numbers to check if a path is a GPIO device:
https://github.com/brgl/libgpiod/blob/9f0eca2d7260de1ae22fed3795280bdb14b62e57/lib/internal.c#L18-L83

Doesn't even have the concept of a chip index. AFAICT the only thing that can be reliably used as an identifier is the chip name, which is a string.

But changing that would be a pretty big change, so I think it can be delayed for now. Maybe it can be done in combination with the support for the GPIOD v2 ABI.

@hfxbse hfxbse changed the title Support cases in which the GPIO chip numbers are not a sequence fix(flutter_gpiod)!: Support cases in which the GPIO chip numbers are not a sequence Apr 14, 2025
@ardera ardera merged commit b09aa74 into ardera:main Apr 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Package Broken on Newer Versions of Rapberry Pi OS

3 participants