how to access GPIO on Beaglebone AI via /dev/mem

Is it possible to access the GPIO on the Beaglebone AI via /dev/mem similar to how it is done in this stackoverflow question on the Beaglebone Black? If so, how would I find what the offsets are?

Hi John,

dynamic changes to the am57xx's pinmux registers and gpio values is a bad idea..

Figure out what you need and set them up in the device tree.

Regards,

Thanks Robert!

Can you clarify why it’s a bad idea on the am57xx when it seems to be the fastest way to do it on the am335x?

What is the fastest way to read/write to the GPIO on the am57xx?

Thanks Robert!

Can you clarify why it's a bad idea on the am57xx when it seems to be the fastest way to do it on the am335x?

I'm still waiting for an official Application Note from TI for the
am57xx, but the short answer, don't touch the pinmux registers from
linux.

What is the fastest way to read/write to the GPIO on the am57xx?

Define them in the device tree, toggle them from userspace, just like
the am335x, just don't TOUCH the pinmux...

Regards,

I’m happy to leave the pinmux alone, but if all I’m doing is reading or writing to the GPIO can I do so from /dev/mem?

According to this post, it’s about 1000x faster: http://chiragnagpal.com/examples.html

It’s also how hal_bb_gpio is implemented: https://github.com/machinekit/machinekit-hal/blob/master/src/hal/drivers/hal_bb_gpio/hal_bb_gpio.c

If necessary, it could be rewritten to use sysfs, but if it means being 1000x slower, that’s not ideal.

I’ve used /dev/mem to access(read, and write), registers on the BBB and I do agree. It is much faster.

The reason why it’s bad to use /dev/mem . . . is that there is no way for the kernel to know what state a given “device” is in. That is, without a physical read. Potentially, this could be bad. Especially if another driver or application has access to the given hardware register.

How bad is bad? That other driver/device has stale data? The chip gets fried? Somewhere in between?

If I’m certain that my application is the only user space application accessing a particular pin, can I safely use /dev/mem for the speed increase?

Hello Robert,

if I get this correctly, setting the direction of a gpio via the corresponding register (e.g. let’s say gpio4 base_addr + 0x134) should be avoided?

We use the BBB in combination with a carrier-board to have some industrial in- and outputs. Therefore, some pins enable some flipflops during initialization (the pins need to be outputs). These pins are later on used as inputs. The current implementation manages all this with an assembly program running on the pru and directly setting the right bits in the different registers of the gpios.
Now, I want to port this to the BB AI. Since direct access causes trouble, is there a better practise, than setting the direction/value of a gpio via /sys/class/gpio?

Regards,
Stephan

You my want to consider using libgpiod with the /dev/gpiochipN character device. You can get and set multiple lines in one syscall.

The libgpiod tools are installed on the Debian image.

More info:
https://www.cnx-software.com/2017/11/03/learn-more-about-linuxs-new-gpio-user-space-subsystem-libgpiod/

Dynamic pinmux changes on AM5x have issues specific to AM5x.

For GPIO, accessing via register writes in userspace (/dev/mem) has no more negative consequences than on AM3x or on any system running Linux for that matter. Standard caveats apply.

Ideally, we’d create a kernel module to avoid latency and keep kernel resource control. This doesn’t have to be that complicated. In short of that, the same old hacks will work fine on AM5x—just don’t touch the pinmux without doing a LOT more digging.

Dynamic pinmux changes on AM5x have issues specific to AM5x.

For GPIO, accessing via register writes in userspace (/dev/mem) has no more negative consequences than on AM3x or on any system running Linux for that matter. Standard caveats apply.

Ideally, we’d create a kernel module to avoid latency and keep kernel resource control. This doesn’t have to be that complicated. In short of that, the same old hacks will work fine on AM5x—just don’t touch the pinmux without doing a LOT more digging.

What is or how do I find the control register address for the AM5x? The system manual seems to list the offsets from the control register, but I’m unsure what that is.

You my want to consider using libgpiod with the /dev/gpiochipN character device. You can get and set multiple lines in one syscall.

The libgpiod tools are installed on the Debian image.

More info:
https://www.cnx-software.com/2017/11/03/learn-more-about-linuxs-new-gpio-user-space-subsystem-libgpiod/

Thanks Drew! I’ll give libgpiod a shot.

Probably in the TI technical reference manual SPRUHZ6L (
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwirrfuAk7voAhUOQK0KHbWUBAsQFjAAegQIBBAB&url=http%3A%2F%2Fwww.ti.com%2Flit%2Fug%2Fspruhz6l%2Fspruhz6l.pdf&usg=AOvVaw2uBbdusraPEVEasMDIT-r7
). Section 27.6 seems a candidate...

"""
27.6.1 General-Purpose Interface Instance Summary
Table 27-16 summarizes the general-purpose interface instance.
Table 27-16. Instance Summary
Module Name Module Base Address Size
GPIO7 0x4805 1000 408 Bytes
GPIO8 0x4805 3000 408 Bytes
GPIO2 0x4805 5000 408 Bytes
GPIO3 0x4805 7000 408 Bytes
GPIO4 0x4805 9000 408 Bytes
GPIO5 0x4805 B000 408 Bytes
GPIO6 0x4805 D000 408 Bytes
GPIO1 0x4AE1 0000 408 Bytes
"""

Here[1] are some notes I wrote for my students for accessing GPIO via /dev/mem on the BB Black. I’m not sure how much carries over to the AI.

–Mark

[1] https://elinux.org/EBC_Exercise_11b_gpio_via_mmap