Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Using GPIOs without Using sudo

404 views
Skip to first unread message

John Dammeyer

unread,
May 10, 2021, 1:09:37 PM5/10/21
to beagl...@googlegroups.com

That's the section heading on page 302 of Derek Molloy's second edition "Exploring Beaglebone"

 

I found the section lacking in information on exactly how to do this.  A web search showed up the following pages.

 

https://github.com/adafruit/adafruit-beaglebone-io-python/issues/137

 

https://linuxize.com/post/how-to-add-user-to-group-in-linux/

 

https://github.com/cnobile2012/RobotControl/tree/master/contrib

 

I'm still not sure of the actual process with this revision of the OS.

debian@ebb:~/lazarus$ uname -a

Linux ebb 4.14.108-ti-r136 #1stretch SMP PREEMPT Mon Jun 8 15:38:30 UTC 2020 armv7l GNU/Linux

 

Robert Nelson mentions 4.11+ as having support for "it" so is any of what is in the first link needed? 

"it's created after you export 0 (or 1) in the pwm system node. only v4.11.x+ has the udev patch for permissions. (didn't want to break older userspace, we still need to fix bonescript before i backport that patch to v4.4.x/v4.9.x)"

 

I don't have a

/etc/udev/rules.d/80-gpio-permissions.rules

 

So I'm thinking I do have to create that file with

KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/usr/local/bin/udev-gpio-permissions.sh"

 

And then create the shell script as outlined but with user debian in group gpio? 

Eg:

chown -R nick:digital /sys/devices/gpio

 

becomes

chown -R debian:gpio /sys/devices/gpio

 

 

That's where it starts to fall apart for me as far as instructions go.  There's an assumption of knowledge about something except I don't know what that is.

 

debian@ebb:~/lazarus$ ls -al  /etc/udev/rules.d/

total 84

drwxr-xr-x 2 root root 4096 Apr 24 17:05 .

drwxr-xr-x 4 root root 4096 Jul 14  2020 ..

-rw-r--r-- 1 root root  372 Jul 10  2020 10-of-symlink.rules

-rw-r--r-- 1 root root   48 Oct  7  2018 50-hidraw.rules

-rw-r--r-- 1 root root   44 Oct  7  2018 50-spi.rules

-rw-r--r-- 1 root root  142 Oct  7  2018 60-omap-tty.rules

-rw-r--r-- 1 root root  921 Jul 10  2020 80-eeprom-noroot.rules

-rw-r--r-- 1 root root  569 Feb 25 06:10 80-gpio-noroot.rules

-rw-r--r-- 1 root root  308 Feb 25 06:10 80-i2c-noroot.rules

-rw-r--r-- 1 root root 2113 Feb 25 06:10 81-pwm-noroot.rules

-rw-r--r-- 1 root root  339 Feb  1  2019 82-gpio-config-pin.rules

-rw-r--r-- 1 root root  359 Jul 10  2020 83-eqep-noroot.rules

-rw-r--r-- 1 root root  509 Aug 15  2018 84-gpio-noroot.rules

-rw-r--r-- 1 root root  188 Aug 15  2018 85-gpio-noroot.rules

-rw-r--r-- 1 root root 1414 Jul 10  2020 86-remoteproc-noroot.rules

-rw-r--r-- 1 root root  352 Jul 10  2020 86-rpmsg-noroot.rules

-rw-r--r-- 1 root root  218 Jul 10  2020 87-iio-noroot.rules

-rw-r--r-- 1 root root  308 Feb 25 06:10 88-leds-noroot.rules

-rw-r--r-- 1 root root  855 Oct  7  2018 beagle-tester.rules

-rw-r--r-- 1 root root   97 Oct  7  2018 tisdk.rules

-rw-r--r-- 1 root root  108 Oct  7  2018 uio.rules

debian@ebb:~/lazarus$

 

 

From

debian@ebb:~/lazarus$ more /etc/group

I get: 

gpio:x:999:debian,node-red,john

 

What else is required so I don't have to use sudo for C, Lazarus or python programs to access GPIO?  

 

debian@ebb:~/lazarus$ cat /etc/udev/rules.d/80-gpio-noroot.rules

# /etc/udev/rules.d/80-gpio-noroot.rules

#

# Stolen from Pi: https://github.com/RPi-Distro/raspberrypi-sys-mods/blob/master/etc.armhf/udev/rules.d/99-com.rules#L9-L14

#

SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660"

SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c '\

        chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio;\

        chown -R root:gpio /sys/class/gpio/*export && chmod -R 220 /sys/class/gpio/*export;\

        chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio;\

        chown -R root:gpio /sys$devpath && chmod -R 770 /sys$devpath\

'"

 

Or is it all as simple as this which is 7 years old:

https://github.com/cnobile2012/RobotControl/tree/master/contrib

Trouble with the read me here is that it doesn't show what the end result should look like and I already have the  80-gpio-noroot.rules file.

 

Very confused…

John

 

Dennis Lee Bieber

unread,
May 10, 2021, 3:31:34 PM5/10/21
to Beagleboard
On Mon, 10 May 2021 10:09:14 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

Suspect I'm not really going to be of much help -- but a few
comments...

>I'm still not sure of the actual process with this revision of the OS.
>debian@ebb:~/lazarus$ uname -a
>Linux ebb 4.14.108-ti-r136 #1stretch SMP PREEMPT Mon Jun 8 15:38:30 UTC 2020 armv7l GNU/Linux
>
Stretch is getting a bit long in the tooth -- is there some reason you
need to stay on it (Debian organization is in the midst of finalizing the
replacement for Buster!).

You also appear to have changed your Beagle's host name to match that
Malloy used for his -- the initials of "e/xploring b/eagleb/one". Just an
observation.

>
>And then create the shell script as outlined but with user debian in group gpio?
>Eg:
>chown -R nick:digital /sys/devices/gpio
>
>becomes
>chown -R debian:gpio /sys/devices/gpio
>
I'm somewhat surprised at that. My understanding is that adding the
"debian" user to the GROUP gpio should allow that user to access anything
that is part of the gpio group, using the group permissions rather than
owner permissions -- so should not need to be changed to debian as owner.

Unfortunately, I can't state anything specific. Buster doesn't seem to
have the same layout.

debian@beaglebone:~$ uname -a
Linux beaglebone 4.19.94-ti-r48 #1buster SMP PREEMPT Wed Aug 19 17:38:55
UTC 2020 armv7l GNU/Linux
debian@beaglebone:~$ ls /sys/devices
armv7_cortex_a8 kprobe soc0 system uprobe
breakpoint platform software tracepoint virtual
debian@beaglebone:~$

NOTE: NO /sys/devices/gpio!

debian@beaglebone:~$ ls -l /dev/gpiochip*
crw-rw---- 1 root gpio 254, 0 Apr 30 20:46 /dev/gpiochip0
crw-rw---- 1 root gpio 254, 1 Apr 30 20:46 /dev/gpiochip1
crw-rw---- 1 root gpio 254, 2 May 10 14:51 /dev/gpiochip2
crw-rw---- 1 root gpio 254, 3 May 10 14:51 /dev/gpiochip3
debian@beaglebone:~$


If I interpret the permissions, owner (root) and group (gpio) both have
R/W, so if debian is added to the group...

debian@beaglebone:~$ ls -l /sys/class/gpio
total 0
--w--w---- 1 root gpio 4096 Apr 30 20:46 export
lrwxrwxrwx 1 root gpio 0 Apr 30 20:46 gpio10 ->
../../devices/platform/ocp/44e07000.gpio/gpiochip0/gpio/gpio10
lrwxrwxrwx 1 root gpio 0 Apr 30 20:46 gpio11 ->
../../devices/platform/ocp/44e07000.gpio/gpiochip0/gpio/gpio11

... and those (links) are open to everyone, although...

debian@beaglebone:~$ ls -l
/sys/devices/platform/ocp/44e07000.gpio/gpiochip0/gpio/gpio10
total 0
-rwxrwx--- 1 root gpio 4096 Apr 30 20:46 active_low
lrwxrwxrwx 1 root gpio 0 Apr 30 20:46 device -> ../../../gpiochip0
-rwxrwx--- 1 root gpio 4096 Apr 30 20:46 direction
-rwxrwx--- 1 root gpio 4096 Apr 30 20:46 edge
-rwxrwx--- 1 root gpio 4096 Apr 30 20:46 label
drwxrwx--- 2 root gpio 0 Apr 30 20:46 power
lrwxrwxrwx 1 root gpio 0 Apr 30 20:46 subsystem ->
../../../../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 Apr 30 20:46 uevent
-rwxrwx--- 1 root gpio 4096 Apr 30 20:46 value
debian@beaglebone:~$

... what they link to is back to root:gpio without everyone.


--
Dennis L Bieber

John Dammeyer

unread,
May 10, 2021, 4:33:19 PM5/10/21
to beagl...@googlegroups.com
First of all thank you for responding. Comments below.
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> On Mon, 10 May 2021 10:09:14 -0700, in gmane.comp.hardware.beagleboard.user
> "John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:
>
> Suspect I'm not really going to be of much help -- but a few
> comments...
>
> >I'm still not sure of the actual process with this revision of the OS.
> >debian@ebb:~/lazarus$ uname -a
> >Linux ebb 4.14.108-ti-r136 #1stretch SMP PREEMPT Mon Jun 8 15:38:30 UTC 2020 armv7l GNU/Linux
> >
> Stretch is getting a bit long in the tooth -- is there some reason you
> need to stay on it (Debian organization is in the midst of finalizing the
> replacement for Buster!).
>
It's been a love/hate relationship with the Beagle. I have about 5 books that are useless because the OS changed so the experiments don't work. Regardless of how wonderful the newest revision of the BBB OS is, if changes don't match the documentation that's out there then the changes are useless. It's why I had to buy the second edition of Derek Molloy's book. No more $SLOTS.


> You also appear to have changed your Beagle's host name to match that
> Malloy used for his -- the initials of "e/xploring b/eagleb/one". Just an
> observation.

Good observation. After fighting the various books, web pages etc. I decided I'd start at page 1 and work my way through the second edition so that what was written matched what I was doing. So if he's using 4.14 so am I.
>
> >
> >And then create the shell script as outlined but with user debian in group gpio?
> >Eg:
> >chown -R nick:digital /sys/devices/gpio
> >
> >becomes
> >chown -R debian:gpio /sys/devices/gpio
> >
> I'm somewhat surprised at that. My understanding is that adding the
> "debian" user to the GROUP gpio should allow that user to access anything
> that is part of the gpio group, using the group permissions rather than
> owner permissions -- so should not need to be changed to debian as owner.
>
> Unfortunately, I can't state anything specific. Buster doesn't seem to
> have the same layout.

And now we run into the real problem. The web pages out there are in many cases useless because they might refer to older versions of the OS or newer versions.

What started this particular stream of discovery was that I jumped ahead a bit rather than continue page by page. My desire is to create the same library of C++ functions for Lazarus (Free Pascal) and ultimately update the sockets.pp code to support socketCAN which it currently doesn't.

I've written a few utilities already that use the CANUSB from Lawicel and the same source code compiled on each host runs on Windows, LinuxCNC, Pi3 and the Beagle talking to the CANUSB and an active CANopen project.

To deal with CAN bus on the Pi3/Pi4 requires access to the SPI bus for the MCP2515. On the Beagle it's the on chip CAN device. And if I want to talk to sensors like I2C or One-Wire plus inexpensive LCD displays I need access to the hardware.

So I installed the PXL library and that's where I ran into the next roadblock. First you can't, from within the IDE and debugging, work with SPI bus without running Lazarus as root. Or it just won't work with the /sys/class/gpio folders. And that's the reason for wanting to free up access to the gpio.

The SPI bus ADAfruit application for a 320x240 display written in Python runs properly rendering LENNA.JPG onto the LCD display. The key outputs are the DC and RESET which are on gpio48 and gpio60. An "ls" of the /sys/class/gpio folder shows on start up those two are not visible.

It's possible to use:
$ sudo echo 48 > /sys/class/gpio/export
to create the gpio48 folder and as super user the VXP library can do that but then it fails on the write to SPI.

=============================================================================
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/DisplaySPI$ sudo ./DisplaySPI
[sudo] password for debian:
An unhandled exception occurred at $00032BB0:
ESysfsSPITransfer: Cannot transfer <1> data byte(s) through SPI bus.
$00032BB0 TSYSFSSPI__TRANSFER, line 247 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas
$00032AC4 TSYSFSSPI__WRITE, line 228 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas
=============================================================================

I don't yet know the reason for this. The error happens here:
Res := fpioctl(FHandle, SPI_IOC_MESSAGE(1), @Data);

The fpioctl is in the Free Pascal interface library so that's not something to be dealt with in this forum.

I thought it best to solve the simple problem first which to not use sudo so I can run Lazarus from the debian user desktop and be able to debug with break points etc. The comment by Robert Nelson on 4.11+ suggests I'm fine with using 4.14. Or is Derek Molloy's second edition now also recycle material?

John



Dennis Lee Bieber

unread,
May 10, 2021, 10:26:06 PM5/10/21
to Beagleboard
On Mon, 10 May 2021 13:33:01 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

>To deal with CAN bus on the Pi3/Pi4 requires access to the SPI bus for the MCP2515. On the Beagle it's the on chip CAN device. And if I want to talk to sensors like I2C or One-Wire plus inexpensive LCD displays I need access to the hardware.
>
>So I installed the PXL library and that's where I ran into the next roadblock. First you can't, from within the IDE and debugging, work with SPI bus without running Lazarus as root. Or it just won't work with the /sys/class/gpio folders. And that's the reason for wanting to free up access to the gpio.
>
>The SPI bus ADAfruit application for a 320x240 display written in Python runs properly rendering LENNA.JPG onto the LCD display. The key outputs are the DC and RESET which are on gpio48 and gpio60. An "ls" of the /sys/class/gpio folder shows on start up those two are not visible.
>

SPI and I2C rely upon a different PINMUX configuration than GPIO...
GPIO is pretty much all "mode 7". SPI0 pins are "mode 0" and SPI1 pins are
"mode 3".
http://www.ofitselfso.com/BeagleNotes/BeagleboneBlackPinMuxModes.php

>It's possible to use:
>$ sudo echo 48 > /sys/class/gpio/export

Really?

debian@beaglebone:~$ sudo echo 48 > /sys/class/gpio/export
[sudo] password for debian:
echo: write error: Operation not permitted

To my knowledge, the redirection part is still done as the debian user,
only the echo is being done by sudo.

debian@beaglebone:~$ sudo su
root@beaglebone:/home/debian# echo 48 > /sys/class/gpio/export

>to create the gpio48 folder and as super user the VXP library can do that but then it fails on the write to SPI.
>

SPI0 appears on P9_17, _18, _21, and _22 (raw GPIO # 5, 4, 3, 2, aka
gpio0_5, ...). SPI1 are on P9_28, _29, _30, _31 (raw GPIO # 113, 111, 112,
110, aka gpio3_17, _15, _16, _14).

GPIO # 48 (gpio1_16) on P9_15 has no modes for SPI.


debian@beaglebone:~$ ls -l /sys/bus/spi/devices
total 0
lrwxrwxrwx 1 root root 0 Dec 31 1999 spi0.0 ->
../../../devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.0
lrwxrwxrwx 1 root root 0 Dec 31 1999 spi0.1 ->
../../../devices/platform/ocp/48030000.spi/spi_master/spi0/spi0.1
lrwxrwxrwx 1 root root 0 Dec 31 1999 spi1.0 ->
../../../devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.0
lrwxrwxrwx 1 root root 0 Dec 31 1999 spi1.1 ->
../../../devices/platform/ocp/481a0000.spi/spi_master/spi1/spi1.1
debian@beaglebone:~$

debian@beaglebone:~$ ls -l /sys/devices/platform/ocp/48030000.spi/
total 0
lrwxrwxrwx 1 root gpio 0 May 10 15:42 driver ->
../../../../bus/platform/drivers/omap2_mcspi
-rw-rw-r-- 1 root gpio 4096 May 10 15:42 driver_override
-r--r--r-- 1 root gpio 4096 May 10 15:42 modalias
lrwxrwxrwx 1 root gpio 0 May 10 15:42 of_node ->
../../../../firmware/devicetree/base/ocp/spi@48030000
drwxrwxr-x 2 root gpio 0 May 10 15:42 power
drwxrwxr-x 3 root gpio 0 May 10 15:42 spi_master
lrwxrwxrwx 1 root gpio 0 May 10 15:42 subsystem ->
../../../../bus/platform
-rw-rw-r-- 1 root gpio 4096 May 10 15:42 uevent
debian@beaglebone:~$

debian@beaglebone:~$ ls -l
/sys/devices/platform/ocp/48030000.spi/spi_master/spi0
total 0
lrwxrwxrwx 1 root gpio 0 May 10 15:42 device -> ../../../48030000.spi
lrwxrwxrwx 1 root gpio 0 May 10 15:42 of_node ->
../../../../../../firmware/devicetree/base/ocp/spi@48030000
drwxrwxr-x 2 root gpio 0 May 10 15:42 power
drwxrwxr-x 5 root gpio 0 May 10 15:42 spi0.0
drwxrwxr-x 5 root gpio 0 May 10 15:42 spi0.1
drwxrwxr-x 2 root gpio 0 May 10 15:42 statistics
lrwxrwxrwx 1 root gpio 0 May 10 15:42 subsystem ->
../../../../../../class/spi_master
-rw-rw-r-- 1 root gpio 4096 May 10 15:42 uevent
debian@beaglebone:~$



NOTE: there are two config-pin in Buster, maybe even Stretch. The one
you get if you just enter "config-pin" is a compiled executable with some
limitations (if there is no pinmux file found it objects). I'm using the
older PERL script version which has a few more capabilities.

debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -i
p9_15
Pin name: P9_15
Function if no cape loaded: gpio
Function if cape loaded: default gpio gpio_pu gpio_pd gpio_input pwm
Function information: gpio1_16 default gpio1_16 gpio1_16 gpio1_16 gpio1_16
ehrpwm1_tripzone_input
Kernel GPIO id: 48
PRU GPIO id: 80
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -i
p9_17
Pin name: P9_17
Function if no cape loaded: gpio
Function if cape loaded: default gpio gpio_pu gpio_pd gpio_input spi_cs i2c
pwm pru_uart
Function information: gpio0_5 default gpio0_5 gpio0_5 gpio0_5 gpio0_5
spi0_cs0 i2c1_scl ehrpwm0_synci pru_uart
Kernel GPIO id: 5
PRU GPIO id: 37
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -q
p9_15
P9_15 Mode: default Direction: in Value: 1
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -q
p9_17
P9_17 Mode: default Direction: in Value: 1
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -l
p9_15
default gpio gpio_pu gpio_pd gpio_input pwm
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -l
p9_17
default gpio gpio_pu gpio_pd gpio_input spi_cs i2c pwm pru_uart
debian@beaglebone:~$


>=============================================================================
>debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/DisplaySPI$ sudo ./DisplaySPI
>[sudo] password for debian:
>An unhandled exception occurred at $00032BB0:
> ESysfsSPITransfer: Cannot transfer <1> data byte(s) through SPI bus.
> $00032BB0 TSYSFSSPI__TRANSFER, line 247 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas
> $00032AC4 TSYSFSSPI__WRITE, line 228 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.SPI.pas
>=============================================================================
>
Since you haven't shown the code, I don't know what pins that call is
attempting to access. Especially as you earlier mention gpio 48 -- which
from what I can tell does not have SPI features. For the others, you may
need to pin-mux to activate SPI -- the default may be for them to be GPIO..

debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin p9_17
spi_cs
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin p9_18
spi
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin p9_22
spi_sclk
debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin -q
p9_18
P9_18 Mode: spi
debian@beaglebone:~$


Using the other SPI device is trickier -- I believe a device tree
overlay needs to be specified in /boot/uEnv.txt. Config-pin fails

debian@beaglebone:~$
/opt/source/bb.org-overlays/tools/beaglebone-universal-io/config-pin p9_31
spi_sclk
P9_31 pinmux file not found!
bash: /sys/devices/platform/ocp/ocp*P9_31_pinmux/state: No such file or
directory
Cannot write pinmux file: /sys/devices/platform/ocp/ocp*P9_31_pinmux/state

debian@beaglebone:~$ ls /opt/source/bb.org-overlays/src/arm/BB*SPI*
/opt/source/bb.org-overlays/src/arm/BBBLUE-GP0-SPI-00A0.dts
/opt/source/bb.org-overlays/src/arm/BB-LCD-ADAFRUIT-18-SPI1-00A0.dts
/opt/source/bb.org-overlays/src/arm/BB-SPI0-ADS8688-0A00.dts
/opt/source/bb.org-overlays/src/arm/BB-SPI0-AT86RF233-00A0.dts
/opt/source/bb.org-overlays/src/arm/BB-SPI0-MCP23S08-00A0.dts
/opt/source/bb.org-overlays/src/arm/BB-SPI0-MCP3008-00A0.dts
/opt/source/bb.org-overlays/src/arm/BB-SPIDEV0-00A0.dts
/opt/source/bb.org-overlays/src/arm/BB-SPIDEV1-00A0.dts


--
Dennis L Bieber

Alexander Zangerl

unread,
May 10, 2021, 10:33:42 PM5/10/21
to beagl...@googlegroups.com
On Mon, 10 May 2021 22:25:54 -0400, Dennis Lee Bieber writes:
>debian@beaglebone:~$ sudo echo 48 > /sys/class/gpio/export
>[sudo] password for debian:
>echo: write error: Operation not permitted
>
> To my knowledge, the redirection part is still done as the debian user,
>only the echo is being done by sudo.

you're absolutely correct, but there's more than one way to do that.
for example,
sudo sh -c "echo 48 > /sys/class/gpio/export"
would do all the stuff as root.

>debian@beaglebone:~$ sudo su
*shudder* *twitch*


--
Best Regards,
Alexander Zangerl
IT Engineer

BREATHE-SAFE intelligent cabin air filtration
Keeps your lungs and cabin dust free!
Head Office: 62 Mica Street, Carole Park QLD 4300 Australia
Western Australia: 169 Chisholm Crescent, Kewdale WA 6105
Tel: +61 7 3276 7833 M. +61 415 482 341 E. a...@breathe-safe.com

John Dammeyer

unread,
May 11, 2021, 1:29:23 AM5/11/21
to beagl...@googlegroups.com
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> "John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

> >The SPI bus ADAfruit application for a 320x240 display written in Python runs properly rendering LENNA.JPG onto the LCD display.

> The key outputs are the DC and RESET which are on gpio48 and gpio60. An "ls" of the /sys/class/gpio folder shows on start up those
> two are not visible.
> >
>
> SPI and I2C rely upon a different PINMUX configuration than GPIO...
> GPIO is pretty much all "mode 7". SPI0 pins are "mode 0" and SPI1 pins are
> "mode 3".
> http://www.ofitselfso.com/BeagleNotes/BeagleboneBlackPinMuxModes.php

Hi Dennis,
I think you missed the above line in my initial posting where the signals DC and RESET are used for controlling the LCD display. They have absolutely nothing to do with SPI.

>
> >to create the gpio48 folder and as super user the VXP library can do that but then it fails on the write to SPI.

In fact if I run the program without running it as super user the failure messages that occur happen because gpio48 and gpio60 cannot be created due to access rights.

The PXL library appears to be designed and tested with a BBB (based on the photos and wiring diagram) but because the library is older, the moving target (AKA BeagleBone OS) is likely the culprit for it not working.

Here's the constructor which shows I'm trying to get to spidev1.0 and the PinDC and PinRST are gpio48 and gpio60 respectively.

===================================================================================
constructor TApplication.Create;
begin
FGPIO := TSysfsGPIO.Create;
FDataPort := TSysfsSPI.Create('/dev/spidev1.0');

FDisplay := TDisplay.Create(TDisplay.OLED128x128, FGPIO, FDataPort, PinDC, PinRST);

FDisplaySize := (FDisplay as TDisplay).ScreenSize;

FDisplay.Initialize;
FDisplay.Clear;

LoadGraphics;
end;
===================================================================================

And then here's the python code that does work.

####################################################################################
from PIL import Image

import Adafruit_ILI9341 as TFT
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI

# BeagleBone Black configuration.
DC = 'P9_15'
RST = 'P9_12'
SPI_PORT = 1
SPI_DEVICE = 0

# Create TFT LCD display class.
disp = TFT.ILI9341(DC, rst=RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=64000000))
####################################################################################

In both cases SPI device 1.0. All I'm doing is compiling an example from the PXL library and the original subject line is still my primary interest. Likely this issue will be solved by the Lazarus group since it's likely a Linux on BBB problem.

So before we get too far off topic again do you know what to do to for setting up GPIO access without sudo?

Thanks
John

jmelson

unread,
May 11, 2021, 12:17:36 PM5/11/21
to BeagleBoard
OK, I am not using a current kernel, so can't really address the issues with group settings.  But, here's one thing that will work:
if you have a user program xyz, do :
sudo chown root:root xyz
sudo chmod u+s xyz

TYhis makes the program owned by rootm, and uses the privileges of root when that program is run.  You DO need root privileges to MAKE these settings, but then the program will run and be able to access the GPIO without the user needing the privileges.

Making the user a member of the right group should also make any program run by that user have the necessary privilege.  It depends on what is in the /etc/group file as to what group you need to be a member of.

Jon

John Dammeyer

unread,
May 11, 2021, 12:44:14 PM5/11/21
to beagl...@googlegroups.com

Thanks.

 

It's easy enough of course to sudo user_program and then enter password to run it but a pain.  Perhaps this will fix that issue

 

But the more important issue is whether I can get the Lazarus IDE along with the debugger (separate program I believe) to run elevated as super user. 

 

I need to be able to set break points and look at parameters before the system calls for sending data to the SPI port.  But since the code doesn't make it past the gpio48 and gpio60 control (due to permissions) I don't even get a chance to see if the parameters are correctly formed for the system call.

 

If the attached zip comes through you can see a simple program that just toggles gpio48 attached to an LED.  The memo component shows the results of the calls to the create/open/close links for the gpio access.  This small application is the test for reconfiguring the debian user to be part of the gpio group for access.  And once it runs from the command line or from the IDE without sudo then I know I've succeeded in that part.

 

It's likely the same issue is happening with access to the SPI1.0 although you'd think running the bigger program that does SPI access elevated with sudo wouldn't have that problem.

 

To try this program do sudo apt install lazarus.

 

John

 

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/12eed06d-2d12-402a-a82f-0ca2603d4a8fn%40googlegroups.com.

io_test.zip

Dennis Lee Bieber

unread,
May 11, 2021, 5:36:29 PM5/11/21
to Beagleboard
On Mon, 10 May 2021 22:29:01 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>I think you missed the above line in my initial posting where the signals DC and RESET are used for controlling the LCD display. They have absolutely nothing to do with SPI.
>

Okay... The following will be a bit of a rambling mess as I can't find
a clean way to separate all the file searching I'm doing... I tried to mark
what seem crucial points with

****************
the point
****************

>>
>> >to create the gpio48 folder and as super user the VXP library can do that but then it fails on the write to SPI.
>
>In fact if I run the program without running it as super user the failure messages that occur happen because gpio48 and gpio60 cannot be created due to access rights.
>
>The PXL library appears to be designed and tested with a BBB (based on the photos and wiring diagram) but because the library is older, the moving target (AKA BeagleBone OS) is likely the culprit for it not working.
>

I've downloaded the source https://asphyre.net/products/pxl , and can't
even find a mention of beagles (checked for "eagle", BBB, etc.). Whereas
the R-Pi has a dedicated module. {Side note: The MDI interface of Lazarus
is painful to me -- too many independent windows that have to be pulled
forward after every change from it to some other application}

PS C:\Users\Wulfraed\Desktop\pxl-v110\Source> Select-String -Pattern beagle
-Path *
PS C:\Users\Wulfraed\Desktop\pxl-v110\Source> Select-String -Pattern eagle
-Path *
PS C:\Users\Wulfraed\Desktop\pxl-v110\Source> Select-String -Pattern bone
-Path *

Jedi.Compilers.inc:1315:// Revision 1.30 2005/12/04 10:10:58 obones
Jedi.Compilers.inc:1318:// Revision 1.29 2005/11/01 20:46:20 obones


PS C:\Users\Wulfraed\Desktop\pxl-v110\Source> Select-String -Pattern bbb
-Path *

PXL.Linux.videodev2.pas:212:function V4L2_PIX_FMT_RGB444: Cardinal; inline;
{ 16 xxxxrrrr ggggbbbb }
PXL.Linux.videodev2.pas:289: xxxxrrrrrrrrrrxxxxgggggggggg
xxxxggggggggggxxxxbbbbbbbbbb... }

***********************************************************************
... But since you are specifying lower-level SysFS calls, it should be
generic.
***********************************************************************

>Here's the constructor which shows I'm trying to get to spidev1.0 and the PinDC and PinRST are gpio48 and gpio60 respectively.
>
>===================================================================================
>constructor TApplication.Create;
>begin
> FGPIO := TSysfsGPIO.Create;
> FDataPort := TSysfsSPI.Create('/dev/spidev1.0');
>
> FDisplay := TDisplay.Create(TDisplay.OLED128x128, FGPIO, FDataPort, PinDC, PinRST);
>
> FDisplaySize := (FDisplay as TDisplay).ScreenSize;
>
> FDisplay.Initialize;
> FDisplay.Clear;
>
> LoadGraphics;
>end;
>===================================================================================
>
>And then here's the python code that does work.
>
>####################################################################################
>from PIL import Image
>
>import Adafruit_ILI9341 as TFT
>import Adafruit_GPIO as GPIO

Unfortunately Adafruit_GPIO has been deprecated in favor of
CircuitPython libraries via the BLINKA interface package... <G> Makes
crawling through it problematic.

****************************************************
At the core, if it has to export the pin, it uses
****************************************************

"""
const char gpio_export[] = "/sys/class/gpio/export";

if ((fd = open(gpio_export, O_WRONLY)) < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_export(): %u couldn't open
\"%s\": %i-%s",
gpio, gpio_export, errno, strerror(errno));
ret = BBIO_SYSFS;
goto exit;
}

len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio);
if(write(fd, str_gpio, len) < 0) {
syslog(LOG_ERR, "Adafruit_BBIO: gpio_export: %u couldn't write
\"%s\": %i-%s",
gpio, gpio_export, errno, strerror(errno));
ret = BBIO_SYSFS;
goto exit;
}
"""

************************************************************************
It looks PXL display doesn't test/export GPIO pins -- it directly
accesses whatever was provided.
************************************************************************

"""
constructor TCustomDrivenDisplay.Create(const AGPIO: TCustomGPIO;
const ADataPort: TCustomDataPort; const APinDC: Integer;
const APinRST: Integer);
begin
FGPIO := AGPIO;
FDataPort := ADataPort;
FPinDC := APinDC;
FPinRST := APinRST;

inherited Create;

if FPinRST <> -1 then
FGPIO.PinMode[FPinRST] := TPinMode.Output;

if (FPinDC <> -1) and (FDataPort is TCustomPortSPI) then
FGPIO.PinMode[FPinDC] := TPinMode.Output;
end;
"""

**********************************************************************************
If those GPIOs have not been exported on your system, you may have to
manually invoke the export function before trying to create your display.
**********************************************************************************

Something like

FGPIO.ExportPin(PinDC);




debian@beaglebone:~$ ls -l /sys/class/gpio/e*
--w--w---- 1 root gpio 4096 May 10 22:26 /sys/class/gpio/export
debian@beaglebone:~$

which is writeable by group gpio members (on a Buster system)

debian@beaglebone:~$ groups debian
debian : debian adm kmem dialout cdrom floppy audio dip video plugdev users
systemd-journal input bluetooth netdev i2c gpio admin spi iio docker tisdk
weston-launch xenomai cloud9ide pwm eqep remoteproc
debian@beaglebone:~$

and debian user is a member of gpio, spi, i2c

>import Adafruit_GPIO.SPI as SPI
>
># BeagleBone Black configuration.
>DC = 'P9_15'
>RST = 'P9_12'
>SPI_PORT = 1
>SPI_DEVICE = 0
>
># Create TFT LCD display class.
>disp = TFT.ILI9341(DC, rst=RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=64000000))
>####################################################################################
>
>In both cases SPI device 1.0. All I'm doing is compiling an example from the PXL library and the original subject line is still my primary interest. Likely this issue will be solved by the Lazarus group since it's likely a Linux on BBB problem.
>

FYI: from the bottom of the C-language module for spidev one finds...

"""
>>> import Adafruit_GPIO as GPIO
>>> import Adafruit_GPIO.SPI as SPI
>>> spi = SPI.SpiDev(1, 0)
>>> spi2 = SPI.SpiDev(0,0)
>>>
>>> import spidev
>>> dir(spidev)
['SpiDev', '__doc__', '__file__', '__loader__', '__name__', '__package__',
'__spec__', '__version__']
>>> spidev.__file__
'/usr/local/lib/python3.7/dist-packages/spidev.cpython-37m-arm-linux-gnueabihf.so'
>>> print(spidev.__doc__)
This module defines an object type that allows SPI transactions
on hosts running the Linux kernel. The host kernel must have SPI
support and SPI device interface support.
All of these can be either built-in to the kernel, or loaded from
modules.

Because the SPI device interface is opened R/W, users of this
module usually must have root permissions.
"""

The question then becomes: what is different -- since the deprecated
Adafruit_GPIO.SPI seems to be able to touch them... (It imports the spidev
module).

The device open() call is just:

"""
if (snprintf(path, SPIDEV_MAXPATH, "/dev/spidev%d.%d", bus, device) >=
SPIDEV_MAXPATH) {
PyErr_SetString(PyExc_OverflowError,
"Bus and/or device number is invalid.");
return NULL;
}
if ((self->fd = open(path, O_RDWR, 0)) == -1) {
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
"""

And those devices are in the SPI group, so being a member of the group
should allow access to those devices.

*******************************************************************************
Not sure what happens if opening spidev1.x, since to my knowledge
spidev1.x is not active unless the appropriate device tree is loaded. It
seemed to open, but maybe will fail if I tried I/O on it.
*******************************************************************************

>So before we get too far off topic again do you know what to do to for setting up GPIO access without sudo?

Run a Buster edition? At the least (and given how cheap uSD cards are
becoming) install Buster on an 8-16GB uSD and see if it changes the
behavior. Most GPIOs are already exported/configured on my system by
default.

"""
debian@beaglebone:~$ ls -l `sudo find / -iname gpio48`
[sudo] password for debian:
lrwxrwxrwx 1 root gpio 0 May 10 22:26 /sys/class/gpio/gpio48 ->
../../devices/platform/ocp/4804c000.gpio/gpiochip1/gpio/gpio48

/sys/devices/platform/ocp/4804c000.gpio/gpiochip1/gpio/gpio48:
total 0
-rwxrwx--- 1 root gpio 4096 May 10 22:26 active_low
lrwxrwxrwx 1 root gpio 0 May 10 22:26 device -> ../../../gpiochip1
-rwxrwx--- 1 root gpio 4096 May 10 22:26 direction
-rwxrwx--- 1 root gpio 4096 May 10 22:26 edge
-rwxrwx--- 1 root gpio 4096 May 10 22:26 label
drwxrwx--- 2 root gpio 0 May 10 22:26 power
lrwxrwxrwx 1 root gpio 0 May 10 22:26 subsystem ->
../../../../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 May 10 22:26 uevent
-rwxrwx--- 1 root gpio 4096 May 10 22:26 value
debian@beaglebone:~$ ls -l `sudo find / -iname gpio60`
lrwxrwxrwx 1 root gpio 0 May 10 22:26 /sys/class/gpio/gpio60 ->
../../devices/platform/ocp/4804c000.gpio/gpiochip1/gpio/gpio60

/sys/devices/platform/ocp/4804c000.gpio/gpiochip1/gpio/gpio60:
total 0
-rwxrwx--- 1 root gpio 4096 May 10 22:26 active_low
lrwxrwxrwx 1 root gpio 0 May 10 22:26 device -> ../../../gpiochip1
-rwxrwx--- 1 root gpio 4096 May 10 22:26 direction
-rwxrwx--- 1 root gpio 4096 May 10 22:26 edge
-rwxrwx--- 1 root gpio 4096 May 10 22:26 label
drwxrwx--- 2 root gpio 0 May 10 22:26 power
lrwxrwxrwx 1 root gpio 0 May 10 22:26 subsystem ->
../../../../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 May 10 22:26 uevent
-rwxrwx--- 1 root gpio 4096 May 10 22:26 value
debian@beaglebone:~$
"""

"""
debian@beaglebone:~$ cat /sys/class/gpio/gpio48/value
1
debian@beaglebone:~$ cat /sys/class/gpio/gpio48/direction
in
debian@beaglebone:~$ cat /sys/class/gpio/gpio48/label
P9_15
debian@beaglebone:~$ echo out > /sys/class/gpio/gpio48/direction
debian@beaglebone:~$ cat /sys/class/gpio/gpio48/direction
out
debian@beaglebone:~$ echo 0 > /sys/class/gpio/gpio48/value
debian@beaglebone:~$ cat /sys/class/gpio/gpio48/value
0
debian@beaglebone:~$
"""

Not a "sudo" in sight! (I used sudo on the "find" operation just to
reduce the error messages for inaccessible files)

If you can't do those from the regular user shell, I don't think any
program will succeed. If you can, I'd put the blame on the library you are
trying to use. You mentioned it is a bit old -- it may be trying to
configure pins using the old capemgr /slots/ system. {Ignore that last
sentence -- obviously the source is just using SysFS I/O; the GPIO failure
may be due to lack of an export on Stretch}}



--
Dennis L Bieber

Dennis Lee Bieber

unread,
May 11, 2021, 8:30:13 PM5/11/21
to Beagleboard
On Tue, 11 May 2021 09:43:49 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>To try this program do sudo apt install lazarus.
>
I think not... Not for an experiment at least. No offence intended, but
it wants to install over 1GB of stuff -- which is a 33% increase in the
content of my uSD card!, and would require me to attach a keyboard and
display to work with the GUI.

Now, a simple command line only program would be a different matter
(does FPC support command line only? -- FPC may be small enough to justify
installing for testing via SSH, but not Lazarus... *** nope, just FPC is
most of the load, 900+MB)

An example using GNAT (Ada). There is no (or I don't know of one)
library for GPIO access in GNAT Ada, so everything is SysFS I/O. I had to
set the pin number to string as the simple integer'image(pin) was
generating leading spaces, which resulted in invalid file name. Everything
is in one (117 line) file -- no nasty forms, etc.

debian@beaglebone:~/BBB_IO$ ls
main.adb
debian@beaglebone:~/BBB_IO$ cat main.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Main is

Sysfs_Path : constant String := "/sys/class/gpio";
GPIO_Pin : constant String := "48";
Pin_Value : Integer;

procedure Export_Pin (Pin : in String) is

Export_File : File_Type;
Export_Path : constant String := Sysfs_Path & "/export";

begin
Put_Line ("Opening " & Export_Path);
Open (Export_File, Mode => Out_File, Name => Export_Path);

Put_Line ("Writing pin number: " & Pin);
Put (Export_File, Pin);

Put_Line ("Closing " & Export_Path);
Close (Export_File);

New_Line;

end Export_Pin;

procedure Set_Direction (Pin : in String; Direction : in String) is
Pin_File : File_Type;
Pin_Path : constant String := Sysfs_Path & "/gpio" & Pin &
"/direction";

begin
Put_Line ("Opening " & Pin_Path);
Open (Pin_File, Mode => Out_File, Name => Pin_Path);

Put_Line ("Writing direction: " & Direction);
Put (Pin_File, Direction);

Put_Line ("Closing " & Pin_Path);
Close (Pin_File);

New_Line;

end Set_Direction;

procedure Set_Value (Pin : in String; Value : in Integer) is

Pin_File : File_Type;
Pin_Path : constant String := Sysfs_Path & "/gpio" & Pin & "/value";

begin
Put_Line ("Opening " & Pin_Path);
Open (Pin_File, Mode => Out_File, Name => Pin_Path);

Put_Line ("Writing value: " & Integer'Image (Value));
Put (Pin_File, Value, Width => 1);

Put_Line ("Closing " & Pin_Path);
Close (Pin_File);

New_Line;

end Set_Value;

procedure Get_Value (Pin : in String; Value : out Integer) is

Pin_File : File_Type;
Pin_Path : constant String := Sysfs_Path & "/gpio" & Pin & "/value";
In_Value : String := " ";

begin
Put_Line ("Opening " & Pin_Path);
Open (Pin_File, Mode => In_File, Name => Pin_Path);

Put_Line ("Reading value");
Get (Pin_File, Value, Width => 0);

Put_Line ("Closing " & Pin_Path);
Close (Pin_File);

New_Line;

end Get_Value;

begin
-- Believe the pins are already exported in Buster
--Export_Pin (Gpio_Pin);

Get_Value (GPIO_Pin, Pin_Value);
Put_Line
("Current value of " & GPIO_Pin & " is " & Integer'Image (Pin_Value));
New_Line;

Set_Direction (GPIO_Pin, "out");

New_Line;

Get_Value (GPIO_Pin, Pin_Value);
Put_Line
("Current value of " & GPIO_Pin & " is " & Integer'Image (Pin_Value));

New_Line;

Set_Value (GPIO_Pin, 0);
Get_Value (GPIO_Pin, Pin_Value);
Put_Line
("Current value of " & GPIO_Pin & " is " & Integer'Image (Pin_Value));

New_Line;

Set_Value (GPIO_Pin, 1);
Get_Value (GPIO_Pin, Pin_Value);
Put_Line
("Current value of " & GPIO_Pin & " is " & Integer'Image (Pin_Value));

end Main;
debian@beaglebone:~/BBB_IO$

debian@beaglebone:~/BBB_IO$ gnatmake main
arm-linux-gnueabihf-gcc-8 -c main.adb
arm-linux-gnueabihf-gnatbind-8 -x main.ali
arm-linux-gnueabihf-gnatlink-8 main.ali
debian@beaglebone:~/BBB_IO$
debian@beaglebone:~/BBB_IO$ ls
main main.adb main.ali main.o
debian@beaglebone:~/BBB_IO$
debian@beaglebone:~/BBB_IO$ ./main
Opening /sys/class/gpio/gpio48/value
Reading value
Closing /sys/class/gpio/gpio48/value

Current value of 48 is 1

Opening /sys/class/gpio/gpio48/direction
Writing direction: out
Closing /sys/class/gpio/gpio48/direction


Opening /sys/class/gpio/gpio48/value
Reading value
Closing /sys/class/gpio/gpio48/value

Current value of 48 is 0

Opening /sys/class/gpio/gpio48/value
Writing value: 0
Closing /sys/class/gpio/gpio48/value

Opening /sys/class/gpio/gpio48/value
Reading value
Closing /sys/class/gpio/gpio48/value

Current value of 48 is 0

Opening /sys/class/gpio/gpio48/value
Writing value: 1
Closing /sys/class/gpio/gpio48/value

Opening /sys/class/gpio/gpio48/value
Reading value
Closing /sys/class/gpio/gpio48/value

Current value of 48 is 1
debian@beaglebone:~/BBB_IO$

Again, under a Buster IoT image (no X-Window overhead), NO SUDO NEEDED
FOR GPIO48 -- and it is already exported so I could even skip the export
call.

I'm not going to try to configure a SPI device for testing.


--
Dennis L Bieber

Dennis Lee Bieber

unread,
May 11, 2021, 8:47:51 PM5/11/21
to Beagleboard
On Tue, 11 May 2021 20:29:59 -0400, in gmane.comp.hardware.beagleboard.user
Dennis Lee Bieber <dennis.l.bieber-Re5...@public.gmane.org>
wrote:



> procedure Get_Value (Pin : in String; Value : out Integer) is
>
> Pin_File : File_Type;
> Pin_Path : constant String := Sysfs_Path & "/gpio" & Pin & "/value";
> In_Value : String := " ";

Whoops -- artifact from earlier attempts, In_Value is no longer needed.


--
Dennis L Bieber

John Dammeyer

unread,
May 11, 2021, 9:51:44 PM5/11/21
to beagl...@googlegroups.com
Actually I was suggesting the really simple way with apt install but there is another.

The fpupdeluxe is a windowing install application that allows you to create any version for any target on your PC. I did install it on my Beagle and yes, hours later it's done but that's because the beagle is a bit of a pig. Went much faster on a Pi3 and on both a LinuxCNC PC and WIN-7 PC lightning fast. And you can install which target you want to compile for.

The key here is that for the most part you write once, compile either anywhere or on the same machine for anywhere along with an IDE for much faster program development. The blinky.lpi project that I referred to is a command line program.

But I'm trying to keep this discussion pointed in the direction of the subject line. The problem with access to GPIO seems to exist in both the Pi and Beagle world. One posting mentioned how his software broke when the Pi OS was upgraded to 4.14.

The issues seem to be the same. Something with udev and creating the correct scripts and files.
https://stackoverflow.com/questions/41586162/access-gpio-on-beaglebone-as-non-root-user

The problem with the above link is that step 1 running 80-gpio-permissions.rules doesn't work for me because it doesn't exist on my system and the contents of that file aren't listed.

However they are in the reference but in that reference the revision of the kernel is 4.4.36
https://github.com/adafruit/adafruit-beaglebone-io-python/issues/137

My experience with changing Beagle versions is fraught with disaster where the change then breaks all sorts of stuff that was working. This is why I'm staying on 4.11 which is what the book uses and at least there's 1.25" of paper all pointing to the same OS.

So. Should I just blindly, in the command line way, type all that stuff with no idea of why I'm doing it, run it and if it works be happy?

As an example the second link uses:
chown -R nick:digital /sys/devices/gpio

The first link above uses
chown -R debian:root /sys/devices/gpio

I think debian:root is what I want to do but I don't understand why the nick:digital allows root access. Why not nick:root?

And the second link with nick's /usr/local/bin/udev-gpio-permissions.sh has a lot more lines in it.

As I said, this appears to have been an ongoing issue for more than 7 years. And perhaps the latest OS fixes it? But then I have to go through the process of rebuilding an entire system. Like going from WIN-7 to WIN-10. What a pain.

John



> -----Original Message-----
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/cr0m9g5jld35qrvviacghq4ut5o2aivj9q%404ax.com.

John Dammeyer

unread,
May 11, 2021, 10:20:12 PM5/11/21
to beagl...@googlegroups.com
Followed what this user reported step by step.
https://stackoverflow.com/questions/41586162/access-gpio-on-beaglebone-as-non-root-user

No matter. ./Blinky still requires sudo as explained in the comments at the start of the program.

So after creating the
80-gpio-permissions.rules
And creating the
udev-gpio-permissions.sh

And then going through the
udevadm control --reload-rules
and reboot

What should be done next?

Thanks
John




> -----Original Message-----
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/ic9m9g9v70473o3bpfomrtc5f83dngc104%404ax.com.
Blinky.lpr

Dennis Lee Bieber

unread,
May 12, 2021, 12:24:41 PM5/12/21
to Beagleboard
On Tue, 11 May 2021 18:51:22 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

>But I'm trying to keep this discussion pointed in the direction of the subject line. The problem with access to GPIO seems to exist in both the Pi and Beagle world. One posting mentioned how his software broke when the Pi OS was upgraded to 4.14.
>

pi@rpi3bplus-1:~/PI_GPIO$ uname -a
Linux rpi3bplus-1 5.10.17-v7+ #1403 SMP Mon Feb 22 11:29:51 GMT 2021 armv7l
GNU/Linux
pi@rpi3bplus-1:~/PI_GPIO$

If I interpret that, the current R-Pi is up to kernel 5.10 vs 4.18 for
BBB

debian@beaglebone:~$ uname -a
Linux beaglebone 4.19.94-ti-r48 #1buster SMP PREEMPT Wed Aug 19 17:38:55
UTC 2020 armv7l GNU/Linux
debian@beaglebone:~$


Well, there are some weird things on the R-Pi... My Ada program is able
to export a GPIO (they aren't exported by default, unlike the BBB). But it
fails when opening the direction file to change from "in" to "out". I even
tried changing from "out_file" to "append_file".

Turns out to be a timing issue -- the OS hasn't finished creating the
pin files by the time it tried to write the direction. {This is
Raspberry-Pi -- I didn't have that problem on BBB, but wasn't exporting in
code either}. Putting in a 1 second delay after closing the export file let
the program run. I also had to add an exception handler on the export
operation in case the pin had already been exported (along with adding an
Unexport function called at the end). Other than using GPIO 18, and using
export (with delay), unexport -- this is the same program that ran on the
BBB. In fact, I just built and ran it on the BBB (Using GPIO 18). (Changed
to GPIO 48 -- and first run had the same timing error -- since it took the
exception branch; subsequent runs no problem).

pi@rpi3bplus-1:~/PI_GPIO$ gnatmake main
arm-linux-gnueabihf-gcc-8 -c main.adb
arm-linux-gnueabihf-gnatbind-8 -x main.ali
arm-linux-gnueabihf-gnatlink-8 main.ali
pi@rpi3bplus-1:~/PI_GPIO$ ./main
Opening /sys/class/gpio/export
Writing pin number: 18
Closing /sys/class/gpio/export
Delaying to allow pin control files to be set up

Opening /sys/class/gpio/gpio18/value
Reading value
Closing /sys/class/gpio/gpio18/value

Current value of 18 is 1

Opening /sys/class/gpio/gpio18/direction
Writing direction: out
Closing /sys/class/gpio/gpio18/direction


Opening /sys/class/gpio/gpio18/value
Reading value
Closing /sys/class/gpio/gpio18/value

Current value of 18 is 0

Opening /sys/class/gpio/gpio18/value
Writing value: 0
Closing /sys/class/gpio/gpio18/value

Opening /sys/class/gpio/gpio18/value
Reading value
Closing /sys/class/gpio/gpio18/value

Current value of 18 is 0

Opening /sys/class/gpio/gpio18/value
Writing value: 1
Closing /sys/class/gpio/gpio18/value

Opening /sys/class/gpio/gpio18/value
Reading value
Closing /sys/class/gpio/gpio18/value

Current value of 18 is 1

Opening /sys/class/gpio/gpio18/direction
Writing direction: in
Closing /sys/class/gpio/gpio18/direction

Opening /sys/class/gpio/unexport
Writing pin number: 18
Closing /sys/class/gpio/unexport


>My experience with changing Beagle versions is fraught with disaster where the change then breaks all sorts of stuff that was working. This is why I'm staying on 4.11 which is what the book uses and at least there's 1.25" of paper all pointing to the same OS.
>

As I mentioned, uSD cards are getting cheap... Write a current OS image
and try it on a fresh 8+GB card (don't forget to resize the partition after
first boot). If it works, great. If it doesn't you still have your original
image to mess with. I'd suggest
https://elinux.org/Beagleboard:Latest-images-testing#Debian_10_.28Buster.29_LXQt
at a minimum, or
https://rcn-ee.net/rootfs/bb.org/testing/2021-04-19/buster-lxqt/ (to save
time bringing the image up-to-date -- note that the latter is Buster 10-9
while the shipping image https://beagleboard.org/latest-images is 10-3 and
a year out-of-date).

>So. Should I just blindly, in the command line way, type all that stuff with no idea of why I'm doing it, run it and if it works be happy?
>
>As an example the second link uses:
>chown -R nick:digital /sys/devices/gpio
>
>The first link above uses
>chown -R debian:root /sys/devices/gpio
>
>I think debian:root is what I want to do but I don't understand why the nick:digital allows root access. Why not nick:root?

It doesn't... It changes the OWNER of /sys/devices/gpio to BE the user
"nick" (note -- it isn't changing the files under that directory!), while
also putting them into a group called "digital". As owner, "nick" then has
full privileges to the file, and any user in the "digital" group has group
privileges.

The second, again, would change the OWNER to "debian" but put the file
into a group called "root". And, again, it doesn't change what is below
that directory. That's one reason for all those nasty udev rules -- the
sysfs is created at boot time, and the pin files are created when the pin
is exported. Those files would be created using whatever the kernel is
configured to use for permissions (likely root:root) unless over-written by
a udev rule.

In a proper system (current BBB and R-Pi), the GPIO should be
root:gpio, and the user "debian" ("pi") set as a member of the gpio group
-- owned by root, with access to any member of the "gpio" group, and group
permissions should be RWX

pi@rpi3bplus-1:~/PI_GPIO$ ls -l /sys/class/gpio
total 0
-rwxrwx--- 1 root gpio 4096 May 12 11:05 export
lrwxrwxrwx 1 root gpio 0 May 3 11:30 gpiochip0 ->
../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
lrwxrwxrwx 1 root gpio 0 May 3 11:30 gpiochip504 ->
../../devices/platform/soc/soc:firmware/soc:firmware:expgpio/gpio/gpiochip504
-rwxrwx--- 1 root gpio 4096 May 12 11:05 unexport

vs

debian@beaglebone:~/BBB_IO$ ls -l /sys/class/gpio
total 0
--w--w---- 1 root gpio 4096 May 12 11:20 export
lrwxrwxrwx 1 root gpio 0 May 11 20:40 gpio10 ->
../../devices/platform/ocp/44e07000.gpio/gpiochip0/gpio/gpio10
<SNIP>
lrwxrwxrwx 1 root gpio 0 May 11 20:40 gpiochip0 ->
../../devices/platform/ocp/44e07000.gpio/gpio/gpiochip0
lrwxrwxrwx 1 root gpio 0 May 11 20:40 gpiochip32 ->
../../devices/platform/ocp/4804c000.gpio/gpio/gpiochip32
lrwxrwxrwx 1 root gpio 0 May 11 20:40 gpiochip64 ->
../../devices/platform/ocp/481ac000.gpio/gpio/gpiochip64
lrwxrwxrwx 1 root gpio 0 May 11 20:40 gpiochip96 ->
../../devices/platform/ocp/481ae000.gpio/gpio/gpiochip96
--w--w---- 1 root gpio 4096 May 12 11:20 unexport


pi@rpi3bplus-1:~/PI_GPIO$ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev
spi i2c gpio lpadmin
pi@rpi3bplus-1:~/PI_GPIO$

... So, again... CAN you access GPIO 48 (from "debian", without using
sudo) from the SHELL itself?

-=-=-
debian@beaglebone:~/BBB_IO$ echo 48 > /sys/class/gpio/export
debian@beaglebone:~/BBB_IO$ cat /sys/class/gpio/gpio48/*
0 <<<<< active_low
cat: /sys/class/gpio/gpio48/device: Is a directory
in <<<<< direction
none <<<<< edge (trigger)
sysfs <<<<< label
cat: /sys/class/gpio/gpio48/power: Is a directory
cat: /sys/class/gpio/gpio48/subsystem: Is a directory
1 <<<<< value
debian@beaglebone:~/BBB_IO$ echo out > /sys/class/gpio/gpio48/direction
debian@beaglebone:~/BBB_IO$ cat /sys/class/gpio/gpio48/*
0
cat: /sys/class/gpio/gpio48/device: Is a directory
out
none
sysfs
cat: /sys/class/gpio/gpio48/power: Is a directory
cat: /sys/class/gpio/gpio48/subsystem: Is a directory
0
debian@beaglebone:~/BBB_IO$ echo 1 > /sys/class/gpio/gpio48/value
debian@beaglebone:~/BBB_IO$ cat /sys/class/gpio/gpio48/*
0
cat: /sys/class/gpio/gpio48/device: Is a directory
out
none
sysfs
cat: /sys/class/gpio/gpio48/power: Is a directory
cat: /sys/class/gpio/gpio48/subsystem: Is a directory
1
debian@beaglebone:~/BBB_IO$ echo 0 > /sys/class/gpio/gpio48/value
debian@beaglebone:~/BBB_IO$ cat /sys/class/gpio/gpio48/*
0
cat: /sys/class/gpio/gpio48/device: Is a directory
out
none
sysfs
cat: /sys/class/gpio/gpio48/power: Is a directory
cat: /sys/class/gpio/gpio48/subsystem: Is a directory
0
debian@beaglebone:~/BBB_IO$
-=-=-

If you can do that, you do NOT have a permission problem for GPIO (SPI
is another matter) -- and the problem is either in PXL library or your
code. As I mentioned previously, your code may need to EXPORT the GPIOs
before you can pass the pins to your display driver call. PXL appears to
assume the two GPIOs are already exported with direction set to OUT.


*************************************

I would also like to point out that
https://beagleboard.org/Support/bone101 indicates that SPI1 (pins P9_28,
P9_29, P9_31) are used by the HDMI system -- in order to gain use of SPI1
you may have to disable the HDMI device tree overlay (besides maybe needing
to add a SPI1 overlay) in /boot/uEnv.txt... say goodbye to using a direct
monitor/keyboard/mouse on the BBB; you'd have to export the display to some
external X-server and use its monitor/keyboard/mouse.

###Additional custom capes
#uboot_overlay_addr4=/lib/firmware/<file4>.dtbo <<<<<<
#uboot_overlay_addr5=/lib/firmware/<file5>.dtbo
#uboot_overlay_addr6=/lib/firmware/<file6>.dtbo
#uboot_overlay_addr7=/lib/firmware/<file7>.dtbo
###
###Custom Cape
#dtb_overlay=/lib/firmware/<file8>.dtbo
###
###Disable auto loading of virtual capes (emmc/video/wireless/adc)
#disable_uboot_overlay_emmc=1
#disable_uboot_overlay_video=1 <<<<<<<
#disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1
#disable_uboot_overlay_adc=1
###

debian@beaglebone:~/BBB_IO$ ls /lib/firmware/*SPI1*
/lib/firmware/ADAFRUIT-SPI1-00A0.dtbo ???????????
/lib/firmware/PB-SPI1-ETH-WIZ-CLICK.dtbo
/lib/firmware/BB-LCD-ADAFRUIT-18-SPI1-00A0.dtbo
/lib/firmware/PB-SPI1-MICROSD-CLICK.dtbo
/lib/firmware/BB-LCD-ADAFRUIT-24-SPI1-00A0.dtbo
/lib/firmware/PB-SPI1-OLEDB-CLICK.dtbo
/lib/firmware/BB-SPI1-LTC2947-00A0.dtbo
/lib/firmware/PB-SPI1-OLEDC-CLICK.dtbo
/lib/firmware/PB-MCP2515-SPI1.dtbo /lib/firmware/PB-SPI1-RTC-5-CLICK.dtbo
/lib/firmware/PB-SPI1-7SEG-TECHLAB-CAPE.dtbo
/lib/firmware/PB-SPI1-THUNDER-CLICK.dtbo
/lib/firmware/PB-SPI1-ETH-CLICK.dtbo
debian@beaglebone:~/BBB_IO$

Could be that just disabling the HDMI overlay will make SPI1 available.


--
Dennis L Bieber

John Dammeyer

unread,
May 12, 2021, 1:54:39 PM5/12/21
to beagl...@googlegroups.com
Hi Dennis,
As you described below I have the permissions sets as below for both gpio48 and gpio60.

debian@ebb:/sys/class/gpio$ echo 48 > export
debian@ebb:/sys/class/gpio$ ls -l gpio48
lrwxrwxrwx 1 root gpio 0 May 12 10:22 gpio48 -> ../../devices/platform/ocp/4804c000.gpio/gpiochip1/gpio/gpio48
debian@ebb:/sys/class/gpio$

And user debian has belongs to these groups including 'gpio'

debian@ebb:/sys/class/gpio$ groups debian
debian : debian adm kmem dialout cdrom floppy sudo audio dip video plugdev users systemd-journal i2c bluetooth netdev cloud9ide gpio pwm eqep admin spi tisdk weston-launch xenomai
debian@ebb:/sys/class/gpio$

So now let's play with gpio48 which has an LED attached to it.

debian@ebb:/sys/class/gpio/gpio48$ ls
active_low device direction edge label power subsystem uevent value
debian@ebb:/sys/class/gpio/gpio48$ cat direction
in
debian@ebb:/sys/class/gpio/gpio48$ echo out > direction
debian@ebb:/sys/class/gpio/gpio48$ cat direction
out
debian@ebb:/sys/class/gpio/gpio48$ cat value
0

LED is currently OFF

debian@ebb:/sys/class/gpio/gpio48$ echo 1 > value
debian@ebb:/sys/class/gpio/gpio48$ cat value
1
debian@ebb:/sys/class/gpio/gpio48$

LED is ON.
No "sudo" required.

Now let's look at groups.
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ls -l Blinky
-rwxr-xr-x 1 debian debian 270880 May 11 15:08 Blinky

Hmmm. Not part of the gpio group

debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ./Blinky
An unhandled exception occurred at $000282E0:
ESysfsFileOpenWrite: Cannot open file </sys/class/gpio/gpio48/direction> for writing.
$000282E0 WRITETEXTTOFILE, line 68 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.Types.pas
$00021CB4 TSYSFSGPIO__SETPINMODE, line 200 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.GPIO.pas

So let’s add it to the gpio group:
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ chgrp gpio Blinky
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ls -l Blinky
-rwxr-xr-x 1 debian gpio 270880 May 11 15:08 Blinky


debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ./Blinky
An unhandled exception occurred at $000282E0:
ESysfsFileOpenWrite: Cannot open file </sys/class/gpio/gpio48/direction> for writing.
$000282E0 WRITETEXTTOFILE, line 68 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.Types.pas
$00021CB4 TSYSFSGPIO__SETPINMODE, line 200 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.GPIO.pas

So at the command line level I can work with gpio48 turning on and off the output (and the LED).

From the program I cannot since I don't have permission without using sudo to write to ...gpio48/direction

After every compile I could run the application from the command line with a sudo but that's not the solution I need. Nor to each time change the permissions at the command line level. If we can figure out what the attributes of the program are supposed to be so it runs without the sudo then I can potentially change something with the Lazarus IDE or Free Pascal Compiler to properly configure the executable. But at the moment I can't get the executable to run.

I recall reading that permissions of the gpio48 folder aren't enough. That the links may be a problem but each of the entries in gpio48 are also in the gpio group.

debian@ebb:/sys/class/gpio/gpio48$ ls -l
total 0
-rwxrwx--- 1 root gpio 4096 May 12 10:47 active_low
lrwxrwxrwx 1 root gpio 0 May 12 10:47 device -> ../../../gpiochip1
-rwxrwx--- 1 root gpio 4096 May 12 10:47 direction
-rwxrwx--- 1 root gpio 4096 May 12 10:47 edge
-rwxrwx--- 1 root gpio 4096 May 12 10:47 label
drwxrwx--- 2 root gpio 0 May 12 10:47 power
lrwxrwxrwx 1 root gpio 0 May 12 10:47 subsystem -> ../../../../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 May 12 10:47 uevent
-rwxrwx--- 1 root gpio 4096 May 12 10:47 value
debian@ebb:/sys/class/gpio/gpio48$

So still basically lost. What sort of permissions does the executable "Blinky" need in order to be able to write to .../gpio/gpio48/direction?

Thanks
John

Oh, and one other thing with respect to the SPI. Here's another weird thing about the Beagle. Notice how the numbering is shifted from 0 relative to 1 relative. So I believe when the program tries to open spidev1.0 it's really still going for the physical spi0 port. But I could be wrong.

debian@ebb:/sys/class/gpio/gpio48$ ls /dev/spi*
/dev/spidev1.0 /dev/spidev1.1 /dev/spidev2.0 /dev/spidev2.1

/dev/spi:
0.0 0.1 1.0 1.1



> -----Original Message-----
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> Sent: May-12-21 9:24 AM
> To: Beagleboard
> Subject: [beagleboard] Re: Using GPIOs without Using sudo
>
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/k8on9gd9tbk7v4t3qd2rdbhi4h3ih81bi5%404ax.com.

Dennis Lee Bieber

unread,
May 12, 2021, 5:22:16 PM5/12/21
to Beagleboard
On Wed, 12 May 2021 10:54:12 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>Now let's look at groups.
>debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ls -l Blinky
>-rwxr-xr-x 1 debian debian 270880 May 11 15:08 Blinky
>
>Hmmm. Not part of the gpio group
>
It shouldn't be... That line says the file "Blinky" is owned by user
"debian" and is part of the group "debian"... And group/other have
read/execute permission on the file.

You /run/ the file from your account, and your account is a member of
"gpio" group.

>debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ./Blinky
>An unhandled exception occurred at $000282E0:
> ESysfsFileOpenWrite: Cannot open file </sys/class/gpio/gpio48/direction> for writing.
> $000282E0 WRITETEXTTOFILE, line 68 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.Types.pas
> $00021CB4 TSYSFSGPIO__SETPINMODE, line 200 of /home/debian/lazarus/pxl/Source/PXL.Sysfs.GPIO.pas
>
>So let’s add it to the gpio group:
> debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ chgrp gpio Blinky

Which only means users with group "gpio" membership now have access to
the file. It does nothing for what permissions the file itself is running
under -- those are defined by the user group membership.

Unfortunately, the PXL source doesn't return the actual error code
which fpGetErrno would report; it raises that exception for any error code
(the help systems says "negative value if there was an error" whereas
fpwrite explicitly says -1 for an error; in either case, having fpgeterrno
value could help pin down what the real problem is).

Handle := fpopen(FileName, O_WRONLY);
if Handle < 0 then
raise ESysfsFileOpenWrite.Create(Format(SCannotOpenFileForWriting,
[FileName]));

I see that setpinmode does do an export of the pin if it is not already
exported... As my tests with Ada program show, I needed a delay (used one
second I believe) after doing an export or I'd get a similar problem with
opening the pin's files. However -- "not already exported" is PXL's
concept, not reality. PXL maintains a bit-map of "exported" pins, meaning
pins IT has done an export for...

function TSysfsGPIO.IsPinExported(const Pin: TPinIdentifier): Boolean;
begin
Result := IsPinBitSet(Pin, ExportedBitmask);
end;

This means the every time you run the program, it starts with the
assumption that the pin is NOT exported, and issues an export operation. I
suspect -- based on my timing issues -- that

procedure TSysfsGPIO.ExportPin(const Pin: TPinIdentifier);
begin
TryWriteTextToFile(FExportFileName, IntToStr(Pin));
SetPinBit(Pin, ExportedBitmask);
end;

needs to have some sleep/delay placed in it before it returns... say

Sleep(1000);

for a 1 second delay (if that runs you could try fine-tuning downwards
until it fails, then add a safety margin to the last working value).
>After every compile I could run the application from the command line with a sudo but that's not the solution I need. Nor to each time change the permissions at the command line level. If we can figure out what the attributes of the program are supposed to be so it runs without the sudo then I can potentially change something with the Lazarus IDE or Free Pascal Compiler to properly configure the executable. But at the moment I can't get the executable to run.

The program attributes should only be a need to have eXecute permission
on thre file. Everything else should be defined by the /user account/
membership and the permissions of the target files.

I don't know why "sudo" doesn't have the problem, unless, again, it is
a timing matter -- and immediately after the export the direction file
starts with root:root and needs time to be changed to root:gpio. If so,
then sudo would be owner of root and not tied to the group access... and if
so, adding a delay immediately after the export write in PXL may suffice.
After all, the program, as I understand the calling sequences and tests, IS
WRITING TO /sys/class/gpio/export without a problem.


>debian@ebb:/sys/class/gpio/gpio48$ ls /dev/spi*
>/dev/spidev1.0 /dev/spidev1.1 /dev/spidev2.0 /dev/spidev2.1
>
>/dev/spi:
>0.0 0.1 1.0 1.1
>

Try ls -l This appears to be another change as mine map 1:1
(another reason to create an current Debian 10/buster uSD card). I wouldn't
be surprised if Stretch maps 0.0 to spidev2.0, while 1.0 goes to spidev1.0.

debian@beaglebone:~$ ls -l /dev/spi*
crw-rw---- 1 root spi 153, 0 May 12 12:46 /dev/spidev0.0
crw-rw---- 1 root spi 153, 1 May 12 12:46 /dev/spidev0.1
crw-rw---- 1 root spi 153, 2 May 12 15:58 /dev/spidev1.0
crw-rw---- 1 root spi 153, 3 May 12 15:58 /dev/spidev1.1

/dev/spi:
total 0
lrwxrwxrwx 1 root root 12 May 12 12:46 0.0 -> ../spidev0.0
lrwxrwxrwx 1 root root 12 May 12 12:46 0.1 -> ../spidev0.1
lrwxrwxrwx 1 root root 12 May 12 15:58 1.0 -> ../spidev1.0
lrwxrwxrwx 1 root root 12 May 12 15:58 1.1 -> ../spidev1.1
debian@beaglebone:~$

A year old, so might be based on Stretch is
https://arcanesciencelab.wordpress.com/2020/01/14/the-correct-way-to-enable-spi-ports-on-the-beaglebone-black/

On that page they state
"""
# For SPI1, /dev/spidev1.#
#
config-pin p9_17 spi_cs
config-pin p9_18 spi
config-pin p9_21 spi
config-pin p9_22 spi_sclk

# For SPI0, /dev/spidev2.#
#
config-pin p9_28 spi_cs
config-pin p9_29 spi
config-pin p9_30 spi
config-pin p9_31 spi_sclk
"""

Note the cross -- spidev2 is SPI0. Hmmm, and Molloy states that SPI0 is the
one not available normally...

Confusingly https://beagleboard.org/Support/bone101 shows SPI0 on pins
17/18/21/22, and SPI1 is on 19/20/28/29/30/31/42 -- chart may be a bit in
error as it shows two SPI1_CS0 and two _CS1 (19 and 20 seem the anomaly --
they are only assigned to I2C, SPI, and UART, otherwise blank) Maybe
https://microcontrollerslab.com/beaglebone-black-pinout-pin-configuration-features-applications/
is more trustworthy. Note that it puts SPI0 on 17-22, and SPI1 on 28-31



--
Dennis L Bieber

Dennis Lee Bieber

unread,
May 13, 2021, 12:04:46 PM5/13/21
to Beagleboard
o/~ Talking to myself in public... o/~

On Wed, 12 May 2021 17:22:04 -0400, in gmane.comp.hardware.beagleboard.user
Dennis Lee Bieber <dennis.l.bieber-Re5...@public.gmane.org>
wrote:

I'd strongly recommend editing this and doing whatever needs to be done
to rebuild the PXL library (if it doesn't just compile from sources
everytime) OR...

>procedure TSysfsGPIO.ExportPin(const Pin: TPinIdentifier);
>begin
> TryWriteTextToFile(FExportFileName, IntToStr(Pin));

Sleep(1000); <<<<<

> SetPinBit(Pin, ExportedBitmask);
>end;

... modifying the source program (for test: Blinky) to explicitly export
pins and delay before trying to do anything with them...

"""
begin
GPIO := TSysfsGPIO.Create;

GPIO.ExportPin(PinLED); <<<<<<<<
Sleep(1000); <<<<<<<<

try
// Switch LED pin for output.
GPIO.PinMode[PinLED] := TPinMode.Output;

WriteLn('Blinking LED, press any key to exit...');
"""

Modifying the library (and fine-tuning the sleep duration to the
minimum that is reliable) should ensure that any implicit pin export works
safely. Modifying the application source, OTOH, means if one exports ALL
NEEDED pins at the start, only one sleep would suffice for the batch,
rather than getting a sleep on each implicit export.

*** WORRY ABOUT SPI AFTER THE GPIO PROBLEM IS SOLVED ***



--
Dennis L Bieber

John Dammeyer

unread,
May 13, 2021, 1:06:11 PM5/13/21
to beagl...@googlegroups.com
Hi Dennis,
I've been playing with that yesterday.
I think the library needs to be changed in a couple of places. As you pointed out, it doesn't really know if the GPIO pin was already exported until it tries to do it and then flags that it's exported in the flags variable.

The problem is if the export fails it then not only checks an invalid flag setting and does the unexport but that ends up removing an exported pin that was already there when the program stops. I don't like that behaviour. I thought I saw that it only changes it to input from output but yet it's gone when the program finishes so that will take some more investigation.

What I found yesterday is by adding the delay you suggested down in the library after the TryWriteTextToFile() that I now get run from command line performance. Most of yesterday was a bit of a write-off dealing with a missing SIM card for my wife's new iPhone 12 and some running around to get other problems solved.

From puTTY I reliably get this now.
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ./Blinky
Blinking LED, press any key to exit...
debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$

Today I want to change that low level code to:
1. Not set the exported flag if the pin is already there so it won't be unexported at the end but only set to what it was before the program ran. This means we also won't try to export it at the start.
2. If it was found to not be there then add the delay but within a repeat until with shorter sleep times and a loop counter.

I'll report back when it's done.

John




> -----Original Message-----
> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber
> Sent: May-13-21 9:04 AM
> To: Beagleboard
> Subject: [beagleboard] Re: Using GPIOs without Using sudo
>
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/nriq9ghfakl67f0tdb9mm6qdqriiiundg6%404ax.com.

Dennis Lee Bieber

unread,
May 13, 2021, 2:35:17 PM5/13/21
to Beagleboard
On Thu, 13 May 2021 10:05:24 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:

>I've been playing with that yesterday.
>I think the library needs to be changed in a couple of places. As you pointed out, it doesn't really know if the GPIO pin was already exported until it tries to do it and then flags that it's exported in the flags variable.
>
On further scanning of the source -- it will all come down to the
library. I think the Export method is declared as private, so your
application couldn't call it directly without modifying the library spec.
And if one is modifying the library, might as well fix it all within the
library instead of still requiring applications to change also.

>The problem is if the export fails it then not only checks an invalid flag setting and does the unexport but that ends up removing an exported pin that was already there when the program stops. I don't like that behaviour. I thought I saw that it only changes it to input from output but yet it's gone when the program finishes so that will take some more investigation.
>
The change from in to out might be linked to the re-export if the
kernel tears down the pin configuration and rebuilds it (or -- it might
have been built into some overhead library operation, forgive me for not
doing a scan of the sources again).

>What I found yesterday is by adding the delay you suggested down in the library after the TryWriteTextToFile() that I now get run from command line performance. Most of yesterday was a bit of a write-off dealing with a missing SIM card for my wife's new iPhone 12 and some running around to get other problems solved.
>
>From puTTY I reliably get this now.
>debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$ ./Blinky
>Blinking LED, press any key to exit...
>debian@ebb:~/lazarus/pxl/Samples/FreePascal/SingleBoard/Generic/Blinky$
>
Progress... <G>

>Today I want to change that low level code to:
>1. Not set the exported flag if the pin is already there so it won't be unexported at the end but only set to what it was before the program ran. This means we also won't try to export it at the start.

That might add a bit more overhead than you want -- if you are talking
about adding a test to see if the .../gpioXX directory (or a file within
the directory) exists and is accessible. After all, it appears that every
access of a pin includes the test for is-pin-exported. You might want to
add a parallel bitmap similar to the one currently used in which you record
pins that were found to be externally exported.

That would make the is-pin-exported something like

<current pin bitmap test> OR <new bitmap test>

That way you only invoke the export function if the pin is in neither
bitmap. Export function could then be something like

if <.../gpioXX directory exists> then
update new bitmap
else
write the export command
sleep
update old bitmap




--
Dennis L Bieber

John Dammeyer

unread,
May 17, 2021, 11:37:57 PM5/17/21
to beagl...@googlegroups.com, Dennis Lee Bieber

Hi Dennis,

 

I've got a pretty stable pxl gpio library working now.

 

Here is the original ExportPin function with the problem you identified where the OS needs time to create the files but fails when it tries to write out.

 

procedure TSysfsGPIO.ExportPin(const Pin: TPinIdentifier);
begin


  TryWriteTextToFile(FExportFileName, IntToStr(Pin));
  SetPinBit(Pin, ExportedBitmask);
end;


A bit of a mystery in how it works other than it creates an OS fault to signal issues.  My new function is more complicated:

{
    The ExportPin procedure has been expanded to test to see if it is already
    exported.  If it was already there then a new bit flag is set so that when
    the application calls to unexport pins, the ones that were there are left alone.
}

procedure TSysfsGPIO.ExportPin(const Pin: TPinIdentifier);
var val : StdChar;
begin
 
// First check to see if we already exported this pin inside this application.
  if (not IsPinBitSet(Pin, ExportedBitmask)) then begin
   
// Check to see if the pin was set before program started by reading from it.
    // If the read fails then the /sys/class/gpio/gpio__ folder does not exist.
    if (TryReadCharFromFile(FAccessFileName + IntToStr(Pin) + '/direction',val)) then begin
     
// It's already exported and folder exists so don't bother trying again.
      SetPinBit(Pin, ExportDefinedBitmask);   // Set that it was already exported on start
      SetPinBit(Pin, ExportedBitmask);        // and that it's exported.
    end
   
else begin // File didn't exist
      // Wasn't exported when program started so now let's export it.
      if TryWriteTextToFile(FExportFileName, IntToStr(Pin)) then
         SetPinBit(Pin, ExportedBitmask);
   
end;
 
end;
end;

The only problem with the above procedure is that it's not a function that returns a successful or not successful export.  So we don't know if the pin was actually exported yet.

 

So where does the delay suggestion you made come in?  When we try and set the direction of the pin!  Which is done in the user application. 

// Switch LED pin for output.
GPIO.PinMode[PinLED] := TPinMode.Output;

 

The delay is not done in the original but should come after the call to export it or ExportPin needs to be changed to a function and the delay done there.  Here's the original.

 

procedure TSysfsGPIO.SetPinMode(const Pin: TPinIdentifier; const Mode: TPinMode);
begin
 
if Pin > MaximumSupportedPins then
   
raise EGPIOInvalidPin.Create(Format(SGPIOSpecifiedPinInvalid, [Pin]));

 
if not IsPinExported(Pin) then
    ExportPin(Pin);

 
if Mode = TPinMode.Input then
 
begin
    WriteTextToFile(FAccessFileName
+ IntToStr(Pin) + '/direction', 'in');
    ClearPinBit(Pin, DirectionBitmask);
 
end
 
else
 
begin
    WriteTextToFile(FAccessFileName
+ IntToStr(Pin) + '/direction', 'out');
    SetPinBit(Pin, DirectionBitmask);
 
end;

  SetPinBit(Pin, DirectionDefinedBitmask);
end;

 

Instead I've done as you suggested but let the program try with short intervals.

 

{
    When we try and set the pin mode we first test to see if the pin was exported.
    When the program first runs we don't know yet if it existed as exported but after
    that even if the pin mode is set again we will know because of the new alreadyexportedflag
    and the exported flag.
}

procedure TSysfsGPIO.SetPinMode(const Pin: TPinIdentifier; const Mode: TPinMode);
var
  escapeCounter : integer;
begin
 
if Pin > MaximumSupportedPins then
   
raise EGPIOInvalidPin.Create(Format(SGPIOSpecifiedPinInvalid, [Pin]));

 
if not IsPinExported(Pin) then begin  // First time we don't know if the pin was already exported.
    ExportPin(Pin);  // So we have to try which will set the proper flags.
    if not IsPinAlreadyExported(Pin) then begin  // If it wasn't already exported then wait to see if it now is.
        escapeCounter := 10;    // Wait 5 seconds max for OS to create file structure.
        repeat
          Sleep(
500);  // Let the OS have time to create the files.
          if (TryReadCharFromFile(FAccessFileName + IntToStr(Pin) + '/direction',val)) then
            escapeCounter
:= 0
         
else
            dec(escapeCounter);
       
until escapeCounter <= 0;
   
end;
 
end;
 
// Finally set the direction.
  if Mode = TPinMode.Input then
 
begin
    WriteTextToFile(FAccessFileName
+ IntToStr(Pin) + '/direction', 'in');
    ClearPinBit(Pin, DirectionBitmask);
 
end
 
else
 
begin
    WriteTextToFile(FAccessFileName
+ IntToStr(Pin) + '/direction', 'out');
    SetPinBit(Pin, DirectionBitmask);
 
end;

  SetPinBit(Pin, DirectionDefinedBitmask);
end;

The only issue I've run into is the repeat until loop.  Seems like the file is readable in about 100mS but fails with the write unless the delay is 500mS.

 

John

 

 

> -----Original Message-----

> From: beagl...@googlegroups.com [mailto:beagl...@googlegroups.com] On Behalf Of Dennis Lee Bieber

> Sent: May-12-21 9:24 AM

> To: Beagleboard

> Subject: [beagleboard] Re: Using GPIOs without Using sudo

>

> On Tue, 11 May 2021 18:51:22 -0700, in gmane.comp.hardware.beagleboard.user

> --

> For more options, visit http://beagleboard.org/discuss

> ---

> You received this message because you are subscribed to the Google Groups "BeagleBoard" group.

> To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.

> To view this discussion on the web visit

Dennis Lee Bieber

unread,
May 18, 2021, 7:51:45 AM5/18/21
to Beagleboard
On Mon, 17 May 2021 20:37:36 -0700, in gmane.comp.hardware.beagleboard.user
"John Dammeyer" <johnd-5o6dItLo...@public.gmane.org> wrote:


>A bit of a mystery in how it works other than it creates an OS fault to signal issues. My new function is more complicated:
>{
> The ExportPin procedure has been expanded to test to see if it is already
> exported. If it was already there then a new bit flag is set so that when
> the application calls to unexport pins, the ones that were there are left alone.
>}
>procedure TSysfsGPIO.ExportPin(const Pin: TPinIdentifier);
>var val : StdChar;
>begin
> // First check to see if we already exported this pin inside this application.
> if (not IsPinBitSet(Pin, ExportedBitmask)) then begin

Suggest

if (not (IsPinBitSet(Pin, ExportedBitmask)
or IsPinBitSet(Pin, ExportDefinedBitmask)) then begin

That way you don't waste time with the TryReadCharFromFile() if you already
know it was externally exported.
>
>So where does the delay suggestion you made come in? When we try and set the direction of the pin! Which is done in the user application.
>// Switch LED pin for output.
>GPIO.PinMode[PinLED] := TPinMode.Output;
>
I'd put the delay immediately after

// Wasn't exported when program started so now let's export it.
if TryWriteTextToFile(FExportFileName, IntToStr(Pin)) then
begin
SetPinBit(Pin, ExportedBitmask);
*** put delay statement here ***;
end;


>
>
>The only issue I've run into is the repeat until loop. Seems like the file is readable in about 100mS but fails with the write unless the delay is 500mS.
>

Which "file" (there are so many created under each exported pin) <G>

It may be that the OS default for those files permits reading -- but
the group hasn't been changed yet so only root can write. Sometime after
the creation, the logic that sets up special groups runs and changes the
file to a group that allows you to write.


--
Dennis L Bieber

John Dammeyer

unread,
May 18, 2021, 1:42:27 PM5/18/21
to beagl...@googlegroups.com
Hi Dennis,
> Suggest
>
> if (not (IsPinBitSet(Pin, ExportedBitmask)
> or IsPinBitSet(Pin, ExportDefinedBitmask)) then begin
>
> That way you don't waste time with the TryReadCharFromFile() if you already
> know it was externally exported.

The ExportDefinedBitmask I created is the only extra bit available in that array of bytes indexed by pin number. But like the ExportedBitmask it's unknown until the system tries to read from it at which point it's defined. I added it because I didn't think any application has the right to unexport a pin that was already exported on start up.

Even with just the 1/2 second delay, you can see the difference in speed of the test application when the pin is already exported compared to when it's not.


> >
> >
> I'd put the delay immediately after
>
> // Wasn't exported when program started so now let's export it.
> if TryWriteTextToFile(FExportFileName, IntToStr(Pin)) then
> begin
> SetPinBit(Pin, ExportedBitmask);
> *** put delay statement here ***;
> end;
>
Yes. Could be put there too. I'll take a closer look to see if that introduces a side effect. I had a reason for not doing it in the export procedure. Just don't remember why...

>
> >
> >
> >The only issue I've run into is the repeat until loop. Seems like the file is readable in about 100mS but fails with the write unless the
> delay is 500mS.
> >
>
> Which "file" (there are so many created under each exported pin) <G>

The initial usage of the pin must be to set the direction which then does the export so that's the file I try and read from. Trying to get pin value before setting direction results in a fault.


>
> It may be that the OS default for those files permits reading -- but
> the group hasn't been changed yet so only root can write. Sometime after
> the creation, the logic that sets up special groups runs and changes the
> file to a group that allows you to write.

Hmm. Maybe it's better to try and get the file attributes and then it would execute the loop decrement section instead. At the moment it never executes that part of the code.

In either case I just need to test that code on the Pi3 and Pi4 to make sure Blinky blinks. On the Beagle the code now makes it through the Reset and DIR select for the SPI bus test code but dies on the IOCTL call.

The simple C code in the \\BEAGLEBONE\debian\exploringBB\chp08\spi\spidev_test does work so the question is what's broken in the pxl library?

And now that I have the Mikroe Click board rewired I have two beagles with CAN bus drivers in the kennel.

I have a Click board with a SPI based RAM chip which will be the easiest to interface with rather than a breadboard with an SPI 320x240 LCD SPI controlled display.

Baby steps eh?
John

>
>
> --
> Dennis L Bieber
>
> --
> For more options, visit http://beagleboard.org/discuss
> ---
> You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/beagleboard/40a7ag9gv2635mshemm4euqic4370aodfr%404ax.com.

John Dammeyer

unread,
May 18, 2021, 6:12:15 PM5/18/21
to beagl...@googlegroups.com
BTW, caught this posting
https://forum.beagleboard.org/t/gpio-export-problem/29737

Apparently exporting twice to the same pin will cause it to go away. If I understand the issue correctly. All the more reason to test to see if it's already there and then not export if so.

John
> https://groups.google.com/d/msgid/beagleboard/011e01d74c0c%24e13144e0%24a393cea0%24%40autoartisans.com.

Reply all
Reply to author
Forward
0 new messages