Map Raspberry hardware GPIO pins to gpiod chip line numbers - gpio

I was playing with my Raspberry Pi over the weekend. I used a tutorial from Freenove that I followed to realize a few simple circuits that are controlled by the GPIO pins on the raspberry.
The Freenove tutorial is using a deprecated library named WiringPi. Besides the fact, that its deprecated, my understanding is that WiringPi adds additional abstractions and simplifications to allow users to focus on their circuits and less on writing boilerplate code to integrate low-level (C) libraries.
Now I want to gain a better understanding about how user space applications interface with the hardware GPIO pins and I am not worried about writing boilerplate code. So I started to play with libgpiod, which has a C API that can be used to read and set GPIO pins and that works well.
One thing that is not clear to me is how I can map the physical hardware GPIO pins on the 40pin connector (which are numbered from 1 to 40) to one of the 54 internal line numbers that gpiod reports when I use the gpioinfo command.
On my Raspberry 3b+ with Raspbian 10 the gpioinfo command prints the following, with all line names showing as unnamed. The list goes on like this but I truncated it at 10 lines.
gpiochip0 - 54 lines:
line 0: unnamed unused output active-high
line 1: unnamed unused output active-high
line 2: unnamed unused output active-high
line 3: unnamed unused output active-high
line 4: unnamed unused output active-high
line 5: unnamed unused output active-high
line 6: unnamed unused output active-high
line 7: unnamed unused output active-high
line 8: unnamed unused output active-high
line 9: unnamed unused input active-high
line 10: unnamed unused input active-high
[...]
I found an issue about missing GPIO line names which discusses this problem but I do not understand the answer or why it was closed.
How am I supposed to lookup the line numbers of the chip based on a pin name such as GPIO17? I found by trial and error that GPIO17 maps to line 17, but for example CE0 maps to line 8 and SCL1 maps to line 3, which I learned by trial and error using gpioset.
I am not sure if its a good idea to hard-code this mapping into my application, or if I somehow should discover these values programmatically to make the program more portable?
I tried to use gpiod_ctxless_find_line:
gpiod_ctxless_find_line ("SCL1", configuration->chipname, configuration->chipname_length, &offset);
but even while that returns a value of 0 (OK) the resulting offset is 66796 which is not the correct value. I assume it does not return anything, because gpioinfo has no names for the lines.
If I write a C program using libgpiod, can (should?) I discover these mappings at runtime, or is it ok to simply hard-code them? Is is possible that on a future Raspberry the SCL1 will not be at physical pin 5 or map to line 3?

While I was writing this question, I found that the official Raspberry GPIO documentation has these pictures, which show the mapping, and then I realized that the yellow GPIO numbers from the second picture correspond to the libgpiod line numbers. So there is a one-to-one mapping between GPIOxx and line number:
I guess there were two confusing parts in my the learning process. The first was that WiringPi uses different GPIO terms than the Raspberry. For example, WiringPi has two blocks of GPIOs numbered as GPIO0 (wiringPi) to GPIO7 (wiringPi) followed by a gap for the special pins like SDA1 and another block numbered as GPIO21 (wiringPi) to GPIO29 (wiringPi). So the GPIO29 (wiringPi) is actually GPIO21 (raspberry) on the Raspberry.
The second part is that my breakout board shows only the semantic names for some GPIOs rather than the actual GPIO number (for example instead of GPIO 2 (SDA) it only shows SDA).
Using the pinout command one can see the official mapping of the Raspberry Pi which maps GPIOs to physical pins. The same information is present in the gpio readall command in the BMC column, but the name column shows the wiringPi GPIO names not the Raspberry pi GPIO names from the image above.

The issue you referenced about missing GPIO line names was resuscitated recently, and AFAIK has finally been resolved. The issue was that the device tree did not have gpio-line-names defined. This was corrected in the RPi 4B a while ago, but for some reason the older platforms were overlooked. I think all of the source files have been updated now - though you may still need an rpi-update for a while until the firmware is released for apt updates.
FWIW, I elected to add the gpio-line-names to my RPi 3B+ with a device tree overlay. I did this strictly as a learning exercise, but I'm not sure I learned much as device tree code seems arcane to me. Nevertheless, having finished the overlay project I do like the idea of having an overlay as it allows me to easily change the gpio-line-names to suit my preferences.

Related

Beaglebone black GPIO registers not changing voltage on value change

I'm trying to turn on and off the GPIO headers on the beaglebone, but i'm unable to get the physical pins to switch from high to low and vice versa. Ive written some code within my application to do this but even when I change the values in the command line I have the same issues.
Firstly, all of the pins I want to use have been correctly exported. For this example lets focus on GPIO 117. I'm able to change into /sys/class/gpio/gpio117 and when I run cat value, its in line with what I expected from my program. When I run echo 0 > value it changes to a zero and when I run echo 1 > value its a 1. Everything as expected. When I go to measure the voltage on that pin, it is always high, independent of the value.
Am I missing something here?
GPIO 117 is gpio3_21 on the "MCSAP0_AHCLKX" pin. So it is probably used by some audio device, probably HDMI. You can disable that by adding disable_uboot_overlay_audio=1 to your /boot/uEnv.txt file, see https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Disable_on-board_devices

device driver documentation for linux

in the book 2017 " UNIX and Linux System Administration " i've read the article below :
Modern systems manage their device files automatically. However, a few rare corner
cases may still require you to create devices manually with the mknod command.
So here’s how to do it:
mknod filename type major minor
Here, filename is the device file to be created, type is c for a character device or b
for a block device, and major and minor are the major and minor device numbers.
If you are creating a device file that refers to a driver that’s already present in your
kernel, check the documentation for the driver to find the appropriate major and
minor device numbers.
where can i find this doc and how to find Major & Minor for a device driver ???
The command cat /proc/devices shows the character and block major device numbers in use by drivers in the currently running Linux kernel, but provides no information about minor device numbers.
There is a list of pre-assigned (reserved) device numbers in the Linux kernel user's and administrator's guide: Linux allocated devices (4.x+ version). (The same list also appears in "Documentation/admin-guide/devices.txt" in the Linux kernel sources.) The list shows how minor device numbers are interpreted for each pre-assigned character and block major device number.
Some major device numbers are reserved for local or experimental use, or for dynamic assignment:
60-63 char LOCAL/EXPERIMENTAL USE
60-63 block LOCAL/EXPERIMENTAL USE
Allocated for local/experimental use. For devices not
assigned official numbers, these ranges should be
used in order to avoid conflicting with future assignments.
120-127 char LOCAL/EXPERIMENTAL USE
120-127 block LOCAL/EXPERIMENTAL USE
Allocated for local/experimental use. For devices not
assigned official numbers, these ranges should be
used in order to avoid conflicting with future assignments.
234-254 char RESERVED FOR DYNAMIC ASSIGNMENT
Character devices that request a dynamic allocation of major number will
take numbers starting from 254 and downward.
240-254 block LOCAL/EXPERIMENTAL USE
Allocated for local/experimental use. For devices not
assigned official numbers, these ranges should be
used in order to avoid conflicting with future assignments.
384-511 char RESERVED FOR DYNAMIC ASSIGNMENT
Character devices that request a dynamic allocation of major
number will take numbers starting from 511 and downward,
once the 234-254 range is full.
Character device drivers that call alloc_chrdev_region() to register a range of character device numbers will be assigned an unused major device number from the dynamic range. The same is true for character device drivers that call __register_chrdev() with the first argument (major) set to 0.
Some external ("out-of-tree") Linux kernel modules have a module parameter to allow their default major device number to be specified at module load time. That is useful for drivers that do not create their "/dev" entries dynamically, but want some flexibility for the system administrator to choose a major device number when creating device files manually with mknod.
docs:
https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch03s02.html
https://tldp.org/LDP/tlk/dd/drivers.html
how to find the appropriate minor & major number for a device number:
ls -l /dev/
cat /proc/devices shows the same as lsblk

How can I blink LEDs in a Linux kernel module?

I have a laptop with Linux Mint and 4.4.0-78-generic kernel.
Also, I have some LEDs there in the /sys/class/leds directory, and I can turn them on and off in the userspace by executing "echo 255 > brightness" in Bash.
However, I want to switch them in my kernel module. Let’s say, that this module will listen a UDP socket and switch LED based on incoming packet data.
I have googled and found kernel source files called "leds-base.c", "leds-class.c" which contains functions to control LEDs. However, this functions require "struct led_classdev" to be passed, and I don't know where do I should get it.
How can I set LED brightness using its name from /sys/class/leds directory in a kernel module?
PS. I have seen a similar question, but it's about keyboard LEDs only, the LED I want to control is not a keyboard one, and can not be controlled by code in question mentioned before.
Implement an led_trigger class and call
led_trigger_event(led, LED_FULL);
and friends in your driver. You can bind your trigger to any LED by
echo my-trigger-name > /sys/class/leds/.../trigger

How do you find the major and minor numbers for devices in linux

Trying to get access to a partially rooted Galaxy S2 external sd card.
The problem is that /dev/block/mmcblk1p1 does not exist on the phone. This is the device name that should allow me to put the "recovery" image onto the sdcard so that the unit will be a phone again.
Problem is, I don't know where to find the magic Major and Minor numbers for this device and I'm trying to figure out where in the kernel source I should be looking for them.
Could someone point me at the right kernel files to find this information?
Standard devices use predefined major numbers and minor numbers starting from 0 for the first instance and upward depending on how many instances there are going to be.
Look at the Linux Documentation file(devices.txt) to see the full list but the section of interest to you is:
179 block MMC block devices
0 = /dev/mmcblk0 First SD/MMC card
1 = /dev/mmcblk0p1 First partition on first MMC card
8 = /dev/mmcblk1 Second SD/MMC card
...
The start of next SD/MMC card can be configured with
CONFIG_MMC_BLOCK_MINORS, or overridden at boot/modprobe
time using the mmcblk.perdev_minors option. That would
bump the offset between each card to be the configured
value instead of the default 8.
So /dev/block/mmcblk1p1 would be major 179, minor 9.
According to hotplug.txt
Entries for block devices are found at the following locations:
/sys/block/*/dev
/sys/block/*/*/dev
So try looking in /sys/block/mmcblk1p1/dev.
EDIT:
Looking at it again I actually think that it will be in /sys/block/mmcblk1/mmcblk1p1/dev

ARM LPC1751 pins configured as I/O

How can I configure one pin for input and another for the output?
If I am not wrong this could be done with GPIO registers that controlls device pins that are not connected to peripherical functions.
Look in UM10360.PDF, Chapter 9: GPIO. There you can find the description for the FIOxDIR direction registers, as well as the reigisters for querying, setting and clearing GPIO pins.
I also strongly recommend looking at the CMSIS Standard Peripherial Driver Library that NXP offers for 175x/176x, look in microcontroller support documents. Edit: There are lots of sample code in this Library.
https://github.com/dwelch67
I have a number of lpc based examples. You are looking for the IODIR register, depending on the port and flavor of LPC, there are now what they call fast I/O registers. a one in a bit location means that pin is an output, a zero an input.

Resources