GPIO in C/C++ on the Beaglebone Black?

You don’t have to use the sysfs interface. It’s a simple user friendly, low performance, way to sparingly interact with the gpio. Absolutely great for clicking a relay or turning on an led. I think it’s silly to use it in a program as it was meant more for command line operations like “cat” and “echo”.

You can use the linux gpio interface: https://www.kernel.org/doc/Documentation/gpio.txt

Or, you can get near bare metal with direct memory manipulation for highest performance (> 4MHz, compared to the few hundred kHz of the sysfs interface), where you can twiddle bits of the gpio registers: http://stackoverflow.com/questions/13124271/driving-beaglebone-gpio-through-dev-mem

Or, you can use one of the many performance minded gpio libraries that makes gpio manipulation as simple as calling an existing function.

Or, write an asm program and load it on one of the PRU co-processors for your deterministic GPIO needs.

This is Linux, a seemingly random and uncoordinated mixture of interfaces and libraries (many duplicated several times over), so there’s are always many ways to do any one thing. :smiley:

You need to read “kernels - their care, feeding and cure”. On all the processors you mention you were working on the bare metal, which as you say has advantages for simplicity and speed. However, kernels are useful (among other things) for allocating resources such as memory and disk space, and to do that they have to restrict memory access - to write to a port, you need to go through the kernel. (As a general rule - CP/M was a perfectly good 8-bit OS, but it had no memory management, so if you were sufficiently irritated you could hit the controller registers directly.)

You could program the BBB without using an OS, but it would be pretty painful; better to use the PRUSS cores if you want speed, or the Xenomai near-realtime Linux kernel patches. The Linux used on the BBB has a wide variety of approaches to I/O, some slow and convenient, some fast and tricky. You should be able to find one that suits your project.

Good luck - Will

The mmap example at stackoverflow works on the BBB with 3.8 Angstrom kernel?

The only way to modify the physical gpio hardware is through the gpio registers, some of them pointed to by that mmap example. There’s nothing in the 3.8 Kernel that prevents you from getting an mmap to that memory space.

The pad control/pin mux stuffs changed in 3.8, but that’s completely separate from the gpio. You tell the pad control registers to connect the physical pin to the internal gpio circuitry (though the pin mux mode bits), but the gpio blocks exist separately. Pad control registers have never been controllable through mmap since it requires privileged (kernel) access.

This - like several solutions - tries to open /dev/mem for read and write. On my Rev C debian BBB, this operation fails, I suspect due to access rights as it seems like it may need root access privilege? (Similarly for the sysfs method, you can’t write to sys/class/gpio/export unless you’re root, making it easy from a shell using sudo, and a PITA from C++). Is that correct?

As /dev/mem gives you uncontrolled access to the entire memory, you
need administrative rights to open the device. If you are concerned
about security, it should possible to drop privileges after opening
the device; However, the program has to be started as root, either
from root account, or as suid root.

j.

CEB,
On which platform you tested this?Did you get any issue?Set/Reset of any GPIO works fine on any kernel?4.x+?
Rp

I modified the app a bit and tried running this code on the BBB under sudo mode :

gpio_export(gpio);
// gpio_set_dir(gpio, 0);
gpio_set_dir(gpio, 1);
gpio_set_edge(gpio, “rising”);
gpio_fd = gpio_fd_open(gpio);
printf(“debug_1 \n”);
gpio_set_value(gpio,1);
sleep(1000);
gpio_set_value(gpio,0);
printf(“debug_2 \n”);

but I see App stuck @debug_1 and getting this error :
gpio-49(sysfs):_gpiod_direction_output_raw:tried to set a GPIO tied to an IRQ as output.

I even tried this :

gpio_set_dir(gpio, 0);
// gpio_set_dir(gpio, 1);

in this I don’t get the error but again the App hangs at the same point.

What I am doign wrong here?My intent is to Set -reset the GPIO1_17 ( that is p9 header pin P9_23) that is GPIO 17 of 32 (0–31) on the second GPIO chip of four (0–3).
Am I choosing the wrong GPIO.?

Read the Kernel docs to learn how to do this correctly. If you have the kernel source, the docs are under /Documentation/gpio. The board.txt file will explain how to access the DTS definitions for the GPIO. In the DTS, you will define which GPIO are allocated to your driver. The driver.txt file will explain how to use the generic gpio library to set gpio direction and how to read/write from/to the gpio defined in the DTS.

Look at /driver/gpio/gpiolib to learn about the generic gpio interface. Also look at /driver/gpio/gpio-omap to see how the generic interface is implemented on the AM335x. Specifically, the gpio_bank and gpio_chip are the two structures that do everything you need.

Regards,
John