Is there a GPIO status register somewhere?

Hello!

On a Beagle Bone Black Rev C is there a digital GPIO status register where I can simply read the [digital] status of all the GPIOs?

or

Is there a way for two or more separate programs to read-only monitor the same digital GPIO pin at the exact same time?

I’ve looked through the PDF on the Sitara processor, every doc & book on the BBB I could find, and through this board, and I have had no luck finding reference to such an animal. I’m posting here since someone may have discovered an “undocumented feature” like this.

Back story:
I have a handful of GPIOs that I use to monitor dry contact switches via a Python program with the Adafruit GPIO library. As far as I can tell, once a GPIO pin is “assigned” (for lack of a better word) to a program like this it’s locked off from being read by any other source (like a Linux shell script that would also poll the same GPIO pin(s) for other purposes).

More specifically, my use case example is: independent programs A, B, and C each monitor a own GPIO and perform different actions upon the respective dry contact closure; in parallel a master program scans the status of all the GPIOs at once to do it’s own series of actions and reporting.

Help!

POSIX type operating systems in general, including GNU/Linux, everything is done by reading and/or writing to a file.

The GPIO “files” are in the “virtual” file system located at /sys/class/gpio.

An example for header pin P9.14, which is GPIO 50:

cat /sys/class/gpio/gpio50/value

at the command line will return either 0 or 1, indicating the current state.
Python and other languages have “system calls” which can do the same thing.
So you could create an array of the GPIOs you want to scan and loop through them and determine their current state.
Different processes (programs) can read the values independent of one another, so your “master” will be able to accomplish this.

Regards,
Greg

Greg, you nailed it!

Currently I’m only using pins P8-7 through P8-12 via Python/Adafruit Lib, and sure enough they are the only pin bindings appearing in /sys/class/gpio; and when I “cat /sys/class/gpio/value” it actually returns the pin value without appearing to affect anything else.

Many thanks to you!!!

On Thu, 1 Jun 2017 20:46:43 -0700 (PDT),
jhupcey@gmail.com declaimed the following:

Hello!

On a Beagle Bone Black Rev C is there a digital GPIO status register where
I can simply read the [digital] status of all the GPIOs?

  There is a register for each GPIO bank (actually, a slew of registers
for each bank), but "simply read" may not be the case. {Further info below}

Is there a way for two or more separate programs to read-only monitor the
same digital GPIO pin at the exact same time?

  The sys filesystem approach is to open/(read|write)/close the "file"
associated with each individual GPIO pin. I haven't experimented to see if
one can hold the "file" open and rewind (seek 0)/reread to get updates, or
must do the close/open stuff for each read. For a polling loop, that may be
a lot of OS overhead -- it may also be that for the duration the "file" is
open, others may be blocked (unless it can be opened in a shared read-only
mode without blocking the OS from updating the status).

  Last time I looked, this is the method used by the BBIO Python
libraries.

I've looked through the PDF on the Sitara processor, every doc & book on
the BBB I could find, and through this board, and I have had no luck
finding reference to such an animal. I'm posting here since someone may
have discovered an "undocumented feature" like this.

  Unless I have the wrong document (AM335x and AMIC110 Sitara™ Processors
Technical Reference Manual; Literature Number: SPRUH73P October
2011–Revised March 2017) what you are asking for is in Chapter 25. The
registers are listed in table 25.5 (as offsets -- I haven't found where the
banks are located yet). You probably want GPIO_DATAIN.

"""
25.4.1.17 GPIO_DATAIN Register (offset = 138h) [reset = 0h]

GPIO_DATAIN is shown in Figure 25-24 and described in Table 25-22.

The GPIO_DATAIN register is used to register the data that is read from the
GPIO pins. The GPIO_DATAIN register is a read-only register. The input data
is sampled synchronously with the interface clock and then captured in the
GPIO_DATAIN register synchronously with the interface clock. So, after
changing, GPIO pin levels are captured into this register after two
interface clock cycles (the required cycles to synchronize and to write the
data). When the AUTOIDLE bit in the system configuration register
(GPIO_SYSCONFIG) is set, the GPIO_DATAIN read command has a 3 OCP cycle
latency due to the data in sample gating mechanism. When the AUTOIDLE bit
is not set, the GPIO_DATAIN read command has a 2 OCP cycle latency.
"""

  Ah... Chapter 2 "Memory Map", with some digging, gives the base
addresses for the GPIO banks (GPIO0 is in a different table from the other
three -- as it is "wake-up" event capable).

  Getting access to the banks likely involves mmap operations, and that
may require running as root (granted, without doing some games to give user
accounts privileges in the sys filesystem, even the simple open/read/close
stuff requires root -- I believe work is being done to make GPIO, if not
the rest of the peripherals, accessible to user accounts).

  Of course, mapping bank/register/bit to each external GPIO is left as
an exercise...

Back story:

  <SNIP>

More specifically, my use case example is: independent programs A, B, and C
each monitor a own GPIO and perform different actions upon the respective
dry contact closure; in parallel a master program scans the status of all
the GPIOs at once to do it's own series of actions and reporting.

  Are A/B/C and M (master) truly independent?

  If A/B/C can be started by M via multiprocessing (if the processing is
simple enough, and most of the time is spent in I/O, even plain Python
threading may suffice) you could have M do the polling of the GPIO pins,
collect the states, and forward a single packet to each of A/B/C using a
(multiprocessing) Queue (one queue for each process).

  The only process that would need to read the pin states would thereby
be the master.

  You could also use one queue, shared by A/B/C, to return
acknowledgements to M -- thereby gaining an ability to detect if one of the
processes has died or hung up somewhere (by lack of an acknowledgement
message after some period of time).

Thanks, Dennis, for the detailed response!

[headsmack] to myself for missing the "GPIO_DATAIN Register" section
in the Sitara docs.

This is what has been concerning me about the file reading approach:

it may also be that for the duration the "file" is open, others may be blocked

But then again for my application I only need to poll the files'
status every 2-3 seconds or so -- nothing high bandwidth at all.

Are A/B/C and M (master) truly independent?

Yes -- they are all separate programs kicked off at boot time by their
own crontabs -- M is the only program that has to see all the pins --
A, B, and C don't need to know or care about each other.

Regarding the master program M, I still want to keep A, B, and C
independent and ignorant of each other, but I really like your idea of
a "status queue" + monitoring and ack mechanism for A, B, and C
themselves.

Great food for thought, and thanks again for the detailed post and
suggestions!!!

Joe