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: [email protected] [mailto:[email protected]] 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
> "John Dammeyer" < <mailto:[email protected]>
> [email protected]> 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>
>
> 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/>
> 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>
> 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>
> 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
>
> --
> For more options, visit <http://beagleboard.org/discuss>
> 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 <mailto:[email protected]>
> [email protected].
> To view this discussion on the web visit
>
> <https://groups.google.com/d/msgid/beagleboard/k8on9gd9tbk7v4t3qd2rdbhi4h3ih81bi5%404ax.com>
>
> https://groups.google.com/d/msgid/beagleboard/k8on9gd9tbk7v4t3qd2rdbhi4h3ih81bi5%404ax.com.
--
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/00b501d74b97%24260fe600%24722fb200%24%40autoartisans.com.