Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Illegal arguments for construction of _exports_Gpio in Node 4.2.3 using mraa 0.8.1 #380

Open
deadprogram opened this issue Dec 7, 2015 · 15 comments

Comments

@deadprogram
Copy link
Contributor

When trying to run the example program https://github.com/intel-iot-devkit/mraa/blob/master/examples/javascript/Blink-IO.js on an Edison with the latest release Yocto image 2.1 using mraa 0.8.1 under node.js 4.2.3, I received the error Illegal arguments for construction of _exports_Gpio

edison:~$ node -v        
v4.2.3
edison:~$ node mblink.js 
MRAA Version: v0.8.1
/home/cylon/mblink.js:28
var myLed = new m.Gpio(13); //LED hooked up to digital pin 13 (or built in pin on Galileo Gen1 & Gen2)
            ^

Error: Illegal arguments for construction of _exports_Gpio
    at Error (native)
    at Object.<anonymous> (/home/cylon/mblink.js:28:13)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:136:18)
    at node.js:963:3
@deadprogram
Copy link
Contributor Author

Did a little more research, the actually problem is a lack of permissions for that user (not running as root). Nothing to do with specific versions. I will close this, however, might I ask what would be an ideal udev rule to use on Edison to allow gpio & i2c permissions to a group named gpio?

@arfoll
Copy link
Contributor

arfoll commented Dec 7, 2015

Ah cool :) Had me confused.

Making nice udev rules is hard because you need to give permissions to created nodes. I've never tried it but this seems like it would be on the right tracks: http://raspberrypi.stackexchange.com/questions/23162/gpio-value-file-appears-with-wrong-permissions-momentarily

@deadprogram
Copy link
Contributor Author

Hi, @arfoll

I tried the followinig udev rule, and it did set the permissions as I expected, but still failing from code unless run as sudo:

SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 771 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio -R /sys%p /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/uevent /sys%p/value ; chmod 770 /sys%p /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/uevent /sys%p/value'"

Any suggestions? Seems pretty important to be able to run mraa code on Edison under other users accounts besides root

@deadprogram
Copy link
Contributor Author

I did some additional research, and even when setting the group to gpio to every file still getting same error. Is there a way to debug this from mraa side, so we can figure out what does not have the required permissions?

I modded my udev rules as follows:

SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport; chmod 771 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio -Rh /sys/class/gpio /sys/devices/pci0000:00/0000:00:0c.0/gpio; chmod -R 770 /sys/class/gpio /sys/devices/pci0000:00/0000:00:0c.0/gpio'"

Now I am seeing all files owned by gpio group.

edison:~$ ls -la /sys/class/gpio/
drwxrwx---    2 root     gpio             0 Dec  8 01:28 .
drwxr-xr-x   52 root     root             0 Dec  8 00:46 ..
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 export
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio124 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio124
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio125 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio125
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio126 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio126
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio127 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio127
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio128 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio128
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio129 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio129
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio130 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio130
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio131 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio131
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio132 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio132
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio133 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio133
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio134 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio134
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio207 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0020/gpio/gpio207
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:47 gpio214 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0020/gpio/gpio214
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpio215 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0020/gpio/gpio215
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:47 gpio243 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0022/gpio/gpio243
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:49 gpio261 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0023/gpio/gpio261
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:49 gpio40 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpio40
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpiochip0 -> ../../devices/pci0000:00/0000:00:0c.0/gpio/gpiochip0
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpiochip200 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0020/gpio/gpiochip200
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpiochip216 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0021/gpio/gpiochip216
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpiochip232 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0022/gpio/gpiochip232
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 gpiochip248 -> ../../devices/pci0000:00/0000:00:08.0/i2c-1/1-0023/gpio/gpiochip248
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 unexport

edison:~$ ls -la /sys/class/gpio/gpio128/
drwxrwx---    3 root     gpio             0 Dec  8 00:46 .
drwxrwx---   15 root     gpio             0 Dec  8 00:49 ..
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 active_low
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 device -> ../../../0000:00:0c.0
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 direction
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 edge
drwxrwx---    2 root     gpio             0 Dec  8 00:46 power
lrwxrwxrwx    1 root     gpio             0 Dec  8 00:46 subsystem -> ../../../../../class/gpio
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 uevent
-rwxrwx---    1 root     gpio          4096 Dec  8 00:46 value

I would strongly suggest that we collectively prioritize figuring this out, since no production deployment on Edison will want run as root correct?

@deadprogram
Copy link
Contributor Author

@arfoll any thoughts on how I might be able to track down the required permissions on Edison?

@tingleby
Copy link
Member

I havent got an edison to hand right now. Have you tried looking at the permissions of the linked file. "../../devices/pci0000:00/0000:00:0c.0/gpio/gpio127"

@deadprogram
Copy link
Contributor Author

Hi, @tingleby

Yes, and it would appear to also have to correct group ownership?

edison:~$ ls -la /sys/devices/pci0000:00/0000:00:0c.0/gpio/gpio127
drwxrwx---    3 root     gpio             0 Dec 11 17:33 .
drwxrwx---   15 root     gpio             0 Dec 11 17:54 ..
-rwxrwx---    1 root     gpio          4096 Dec 11 17:33 active_low
lrwxrwxrwx    1 root     gpio             0 Dec 11 17:33 device -> ../../../0000:00:0c.0
-rwxrwx---    1 root     gpio          4096 Dec 11 17:33 direction
-rwxrwx---    1 root     gpio          4096 Dec 11 17:33 edge
drwxrwx---    2 root     gpio             0 Dec 11 17:33 power
lrwxrwxrwx    1 root     gpio             0 Dec 11 17:33 subsystem -> ../../../../../class/gpio
-rwxrwx---    1 root     gpio          4096 Dec 11 17:33 uevent
-rwxrwx---    1 root     gpio          4096 Dec 11 17:33 value
@deadprogram
Copy link
Contributor Author

Likewise, I am certain on the correct group membership of current user:

edison:~$ whoami
cylon
edison:~$ groups cylon
sudo gpio cylon
@deadprogram
Copy link
Contributor Author

More info:

Here is the error as caught by my journal:

Dec 11 22:32:39 edison libmraa[347]: libmraa version v0.8.1 initialised by user 'cylon' with EUID 1000
Dec 11 22:32:39 edison libmraa[347]: edison: Failed to open SoC pinmode for opening
Dec 11 22:32:39 edison libmraa[347]: edison: Failed to open SoC pinmode for opening
Dec 11 22:32:39 edison libmraa[347]: edison: Failed to open SoC pinmode for opening
Dec 11 22:32:39 edison libmraa[347]: libmraa initialised for platform 'Intel Edison' of type 2
Dec 11 22:32:40 edison libmraa[347]: gpio: unable to setup muxes

That would appear to be this code here:
https://github.com/intel-iot-devkit/mraa/blob/v0.8.1/src/x86/intel_edison_fab_c.c#L111

I tried adding that path to the udev rule, and was able to chown to the gpio group as seen here:

root@edison:~# ls -la /sys/kernel/debug/gpio_debug/gpio127                                                                                                                    
drwxrwx---    2 root     gpio             0 Dec 11 22:32 .
drwxrwx---  194 root     gpio             0 Dec 11 22:32 ..
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_debounce
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_direction
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_irqtype
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_opendrain
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_override_indir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_override_inval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_override_outdir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_override_outval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_pinmux
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_pullmode
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_pullstrength
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_indir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_inval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_opendrain
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_outdir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_outval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_pullmode
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_standby_trigger
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 available_value
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 conf_reg
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_debounce
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_direction
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_irqtype
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_opendrain
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_override_indir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_override_inval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_override_outdir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_override_outval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_pinmux
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_pullmode
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_pullstrength
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_indir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_inval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_opendrain
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_outdir
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_outval
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_pullmode
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_standby_trigger
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 current_value
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 irq_count
-rwxrwx---    1 root     gpio             0 Dec 11 22:32 register_info

Despite that, still same problem... 😿

@tingleby
Copy link
Member

So Ive had a play this afternoon, Ive gotten most of the way but still I get some issues. Mostly I think with muxes.
Ive posted them to so we can modify them,
https://github.com/intel-iot-devkit/mraa/wiki/Edison-Udev-rules

@alext-mkrs
Copy link
Contributor

FWIW, it looks good and indeed @deadprogram's problems mostly look like some permissions still not accounted for. If you need a hand with e.g. testing those rules you've come up with - let me know. I have Edison and both Arduino & mini-breakout boards.

@mogar
Copy link

mogar commented Sep 7, 2016

I'm trying to use these udev rules to allow non-root users access to GPIO and the SPI bus through mraa. I've adapted the rules a for spi:

$ cat /etc/udev/rules.d/edison.rules
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport; chmod 771 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio -Rh /sys/class/gpio /sys/devices/pci0000:00/0000:00:0c.0/gpio /sys/devices/pci0000:00/0000:00:08.0/i2c-1 /sys/devices/pci0000:00/0000:00:07.0/spi_master /sys/kernel/debug/gpio_debug; chmod -R 770 /sys/class/gpio /sys/devices/pci0000:00/0000:00:0c.0/gpio /sys/devices/pci0000:00/0000:00:08.0/i2c-1 /sys/devices/pci0000:00/0000:00:07.0/spi_master /sys/kernel/debug/gpio_debug; chmod a+rx /sys/kernel/debug'"

Now when I try to use mraa with gpio, I don't get any errors but I also can't control the GPIO. I think writing to the gpio is failing.

I'm also having issues with the spi bus:

$ python ExplorerCtl.py
Traceback (most recent call last):
  File "ExplorerCtl.py", line 5, in <module>
    ss = spi_serial.SpiSerial()
  File "/usr/lib/python2.7/site-packages/spi_serial-0.0-py2.7.egg/spi_serial/spi_serial.py", line 14, in __init__
    self.dev = m.spiFromDesc("spi-raw-5-1")
  File "/usr/lib/python2.7/site-packages/mraa.py", line 880, in spiFromDesc
    return _mraa.spiFromDesc(desc)
ValueError: Invalid SPI context

Could you please give me some pointers for what the udev rules should be to get these working?

@deadprogram
Copy link
Contributor Author

Hi @mogar as far as I know, still no one has actually been able to access GPIO etc. under a non-root user on Edison. :(

If so, they have not chimed in here.

@sgentle
Copy link

sgentle commented Feb 3, 2017

I was able to control both I2C and GPIO successfully using nodejs on an Edison running Jubilinux. I believe the process should be the same for other variants. @mogar's udev rules worked, though I also had to add the following rule:

KERNEL=="i2c-*", GROUP="gpio", MODE="660"

For debugging, I found this command useful (you can replace node index.js with any command that uses mraa):

strace node index.js 2>&1 | grep Permission

Which gives you output like this to tell you which files are the issue:

open("/dev/i2c-1", O_RDWR|O_LARGEFILE)  = -1 EACCES (Permission denied)

It seems that there is an issue caused by the GPIOs being added while the program is running. The first time I run it I see this:

open("/sys/class/gpio/gpio12/direction", O_RDWR|O_LARGEFILE) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio12/value", O_RDWR|O_LARGEFILE) = -1 EACCES (Permission denied)

And the GPIO doesn't work, probably because the device path has just been created and udev hasn't had time to change its permissions yet. The second time I run it, the device is already there, and it works fine. Maybe mraa needs to wait a bit before accessing those paths after setting the GPIO up?

@arfoll
Copy link
Contributor

arfoll commented Feb 6, 2017

So the solution I made but haven't quite finished is using imraa to do exactly this, open the gpios you want and then not release them. You can use this configuration file as the basis:
https://raw.githubusercontent.com/intel-iot-devkit/mraa/edison-perms/imraa/imraa.io.edison.conf

and then at the top of the file define the I/O you want to use under which user, and the rest should just work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment