GPIO sysfs interface is deprecated, and in the future it will be removed from the kernel. So in Fedora the kernel is compiled without such flag. As a consequence we don’t have the
/sys/class/gpio path. We have instead the
/dev/gpiochipN character device.
This means that the piles of examples you can find on the web are unuseful on Fedora in order to drive, for instance a LED from the command line (
echo 22 > /sys/class/gpio/export and stuff like this doesn’t work). This also means that many Python modules don’t work and that, probably, even kernel modules doen’t work anymore (
at least I was unable to use sensors based on the 1wire protocol).
Without going further into the question, after all I’m only a regular user, here you will find the steps to turn on an LED using such character interface, and to read the status of a button.
Disclaimer: this post comes from try and fail tasks, googling for info, observations, etc. I’m not an engineer nor a kernel developer. Pay attention when working with the GPIO pins and the electricity. I’m still alive and my RPi still works pretty well, but damages to your RPi coming from tasks here described cannot be attributed to me :-) As usual, forgive my English.
Install libgpiod CLI tools (and Python module)
Install the CLI tools needed to communicate to the device. And install the Python3 module as well.
sudo dnf install libgpiod-utils python3-libgpiod
List the devices and the pins
To list the GPIO chips that you can find on your hardware, use the
On the Raspberry Pi 3 you should get these devices:
gpiochip0 [pinctrl-bcm2835] (54 lines) gpiochip1 [raspberrypi-exp-gpio] (8 lines)
And we will be interested in gpiochip0
gpioinfo you will list all the GPIO pins (called lines, or somewhere else, offsets).
gpiochip0 - 54 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high ... line 50: unnamed unused input active-high line 51: unnamed unused input active-high line 52: unnamed unused input active-high line 53: unnamed unused input active-high
What? 53 lines? But aren’t there 40 pins on the RPi?
Don’t worry. As far as I can understand, these are the BCM numbers (well, the GPIO is a bit complex) and in fact, as we will see, you will address the pins with the BCM number and not the physical one. Not all these numbers (lines) have a corresponding physical pin and as a consequence, you need to pay attention on which number you will use.
At least these lines will cause a system hang or instability: 14, 15, 42, 43, from 48 up to 53
The usable lines (corresponding to the BCM numbers) are: 5, 6, 12, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
For the corresponding physical match, take a look here https://pinout.xyz
The “unnamed” value is due to the fact that there is not a description inside some device tree file (?).
Turning on an LED
Now connect an LED to the physical pin 40 (that is BCM 21): connect the short leg of the LED (the negative leg, called the cathode) to the GND, and the positive one (the anode) to the RPi pin. Please remember to place a resistor (220 or 330 ohm is ok) between the pin and the anode (or between the chatode and the ground).
And issue this command
sudo gpioset gpiochip0 21=1
You will see a very quick flash. In fact, with libgpiod “the new character device interface guarantees all allocated resources are freed after closing the device file descriptor“.
Using this command:
sudo gpioset --mode=wait gpiochip0 21=1
The LED will stay on until you hit CTRL+C
To turn on the LED for 4 seconds, use this command:
sudo gpioset -s 4 --mode=time gpiochip0 21=1
The -b option will detach from the terminal while the LED will stays on, and it will be switched off after 50 seconds
sudo gpioset --mode=time -s 50 -b gpiochip0 21=1
The “-l” option will set the line active state to low, and in practice you will have to use the value 0 in order to turn on the LED (inside foggy ideas I can imagine why but I’m unable to explain).
sudo gpioset --mode=wait -l gpiochip0 21=0
Driving a button
Connect a button to a pin (i.e. physical pin 39, that is BCM 20) following some example you can find on various sites.
To read the state of the pin:
sudo gpioget 0 20
As you can see, you can also use the number of the chip (0) instead of the name (gpiochip0). When you will push the button, the value should become 1, conversely when the button will be released, the value will be 0 (you can use the -l option here as well).
Monitor a pin state
You can also monitor the events using the command gpiomon
sudo gpiomon 0 20
When you push the button you will receive a RISING EDGE event
event: RISING EDGE offset: 20 timestamp: [1534429122.849170137]
When you release the button a you will get a FALLING EDGE event
event: FALLING EDGE offset: 20 timestamp: [1534429080.281903624]
As you can see you will receive also a timestamp. This could be useful to implement some sort of debouncing as some Python modules do underneath the hood for you in order do discard spurious state changes. In fact, sometimes, pushing the button you will get all these state changes, even if the button is pressed one time.
event: RISING EDGE offset: 20 timestamp: [1534429484.197105562] event: RISING EDGE offset: 20 timestamp: [1534429484.198478161] event: FALLING EDGE offset: 20 timestamp: [1534429484.198504046] event: FALLING EDGE offset: 20 timestamp: [1534429484.198543525] event: FALLING EDGE offset: 20 timestamp: [1534429484.198583786] event: RISING EDGE offset: 20 timestamp: [1534429484.199084669] event: FALLING EDGE offset: 20 timestamp: [1534429484.200216070] event: RISING EDGE offset: 20 timestamp: [1534429484.200242320]
Look here https://github.com/brgl/libgpiod/tree/master/bindings/python/examples for some examples made using the Python library.
sudo and how to use the gpiochip device as unprivileged user
As you can see, you need to use sudo in order to interact with the GPIO. These are the right on the device
ls -la /dev/gpiochip0 crw-------. 1 root root 254, 0 May 11 12:26 /dev/gpiochip0
You can use the GPIO as an unprivileged user creating for instance an UDEV rule.
Create a gpio group and assign your user to such group
groupadd gpio usermod -G gpio youruser
Create an udev rule:
echo 'KERNEL=="gpiochip0", SUBSYSTEM=="gpio", MODE="0660", GROUP="gpio"' > /etc/udev/rules.d/85-gpiochip.rules
udevadm control --reload-rules udevadm trigger --verbose
(Maybe perform a reboot in order to verify if all is ok). Log in as you user and you should be able to interact with the GPIO whitout using sudo.