Closed mroach closed 5 years ago
The reason why it creates entries in /sys/class/gpio
is that Circuits
still uses the old way of accessing GPIOs. Python recently switched over to the new method of using libgpiod
instead of sysfs
. We plan on doing the same, but haven't done it yet.
I'm not sure why you got accessed denied, but I've been only using Circuits in Nerves recently. Maybe someone else can comment, or if not, I should eventually get a chance to try it out again in Raspbian.
Ah, makes sense with the different behaviour and permission requirements then.
Note to self: try this solution: https://stackoverflow.com/a/50650398/642978 If it works, I'll open a PR to update the README for Pi users to work around the permission issue.
@mroach Thanks!
@mattludwigs How's your libgpiod
code coming? Maybe @mroach can try it out from a branch to see if it fixes the permissions issue.
Most of my work still in some bare-bones C code used for experimentation. I can start a branch that starts to pull that work into circuits_gpio
.
I ran the permission modification via:
sudo /bin/sh -c 'find -L /sys/class/gpio/ -maxdepth 2 -exec chown root:gpio {} \; -exec chmod 770 {} \; || true'
Now the problem is different. The first time I run GPIO.open/2
I get {:error, :access_denied}
again, but the sysfs link is created. So then if I run open
a second time with the same arguments, it works! So it seems like maybe a race condition or bad feedback from sysfs?
@mattludwigs If you're looking for someone to guinea pig your branch, count me in! C is not my forte but I'll help if I'm able.
Yep, that's a race condition. Circuits.GPIO
needs to wait for udev
to fix permissions before trying to open the GPIO file.
Could you try changing this line:
https://github.com/elixir-circuits/circuits_gpio/blob/master/src/hal_sysfs.c#L177
to
pin->fd = retry_open(value_path, O_RDWR, 1000);
That works great for opening the pins!
I also figured out that the nif wasn't being compiled with TARGET_RPI
which explains why I couldn't set the the pull_mode
. My hacky workaround to trigger a recompile with detecting bcm_host.h
:
rm -rf _build/dev/lib/circuits_gpio
CPATH=/opt/vc/include iex -S mix
Awesome! I will work on getting some of the code ready and into a branch.
Right now it's just the linux/gpio
C calls, so I will need to translate the code into the nif. I will probably get things in iteratively, so we can try to exercise the code as we develop it as we will want to make sure we are testing it well.
I can ping you via mention once I a branch going.
refs: #16
@fhunleth Is the race condition unique to the Raspberry Pi? If so I'm happy to open a PR that uses the TARGET_RPI
directive to use retry_open
I think it's fine to always call retry_open
. I'd expect other platforms that use udev to fix the permissions to hit it as well.
Fixed in 93ca09c9ae07ecb6ae9208e317847f57dce5bfdb and the Raspbian build issue referred to above is fixed in ddea948fe00843a6c4232976cf31100da4d0d4b1.
Porting to the new "libgpiod" way of accessing GPIOs is in #16.
I setup a brand new project on my Raspberry Pi 3 B. I fired-up
iex -S mix
and tried:Strange. So I tried the same thing in Python3 using the standard
RPi.GPIO
and it worked fine. I tried in Elixir again, same problem. Then I ransudo iex -S mix
to see if this were a device permission error, and then it worked fine!So I switched back to running
iex
aspi
, and opening the pin worked! Then I tried opening a different pin, and got{:error, :access_denied}
again. Strange. I found that if I first open a pin asroot
, then I am able to use it aspi
. I also found after every time I opened a pin, a new entry was added to/sys/class/gpio
Of course my
pi
user is a member ofgpio
so should have access to the devices.So the question is, what's going on here? Is this supposed to work as the
pi
user? And why does Circuits create entries in/sys/class/gpio
whenRPi.GPIO
doesn't? (Not that I mind at all, just curious).