Torizon container device (GPIO, I2C, SPI) access only working with --privileged=true

Hello,
I want to enable a container to access multiple GPIO chips, i2c, serial and spi.

Following "How to Use UART with Torizon Visual Studio Code Extension (Python)
"
I added the them in the devices list of the VS Code torizon configuration:

devices:
    common:
    - /dev/spidev3.0
    - /dev/i2c-0
    - /dev/i2c-1
    - /dev/gpiochip0
    - /dev/gpiochip1
    - /dev/gpiochip2
    - /dev/gpiochip3
    - /dev/gpiochip4
    - /dev/gpiochip5
    - /dev/gpiochip6
    - /sys/class/pwm/pwmchip0
    - /sys/class/pwm/pwmchip3
    - /sys/bus/iio/devices/iio:device0/in_voltage4_raw
    - /sys/bus/iio/devices/iio:device0/in_voltage5_raw
    - /sys/bus/iio/devices/iio:device0/in_voltage6_raw
    - /sys/bus/iio/devices/iio:device0/in_voltage7_raw
    - /dev/i2c-2

I also added

RUN usermod -a -G gpio,spidev,dialout,i2cdev,input  torizon

to buildcommands.

However I cannot access the devices from within the container (starting the container with --privileged=true does work). What am I missing? Thank you for your time and consideration.

config.Yaml

Another thing, I do not see i2c-2 which is available using the Yocto reference image. Do I have to use a custom .dbto to enable it in torizon?

manually starting the docker container with –device /dev/spidev3.0 etc. does work as intended.

Greetings @romnan,

This is strange. Could you share the code you’re using to test all these interfaces? I wanna see if I can reproduce with your setup on my side. Also can you elaborate on what you exactly mean by “doesn’t work” I assume it’s permission related errors. But I’d like to know the exact errors so I can look for them when I attempt to reproduce.

What happens if you’re trying to access 1 device/interface at a time, does it still not work then?

Finally in VS Code itself can you run Torizon: export docker command line. This should give the full docker run command that is being used to run your container. I just wanna make sure all your configuration changes are actually taking effect. I guess while we’re at it sharing your Dockerfile wouldn’t hurt either.

As for the i2c. The 3 default i2c interfaces on Colibri i.MX6 should be i2c0, i2c1, and i2c4. This should be the same on both the reference image and Torizon. The issue is that the exact i2cX can be inconsistent at times. Try running ls -l /dev/colibri-i2c, we symlinked the i2cs to more consistent names.

Best Regards,
Jeremias

The devices are not accessible/shown from within the container.

Outside container:

$ ls -l /dev
...
lrwxrwxrwx 1 root root         101 Mar  3 13:53 colibri-ain0 -> /sys/devices/soc0/soc/2100000.aips-bus/21a4000.i2c/i2c-0/0-0041/stmpe-adc/iio:device0/in_voltage4_raw
lrwxrwxrwx 1 root root         101 Mar  3 13:53 colibri-ain1 -> /sys/devices/soc0/soc/2100000.aips-bus/21a4000.i2c/i2c-0/0-0041/stmpe-adc/iio:device0/in_voltage5_raw
lrwxrwxrwx 1 root root         101 Mar  3 13:53 colibri-ain2 -> /sys/devices/soc0/soc/2100000.aips-bus/21a4000.i2c/i2c-0/0-0041/stmpe-adc/iio:device0/in_voltage6_raw
lrwxrwxrwx 1 root root         101 Mar  3 13:53 colibri-ain3 -> /sys/devices/soc0/soc/2100000.aips-bus/21a4000.i2c/i2c-0/0-0041/stmpe-adc/iio:device0/in_voltage7_raw
lrwxrwxrwx 1 root root           5 Mar  3 13:53 colibri-i2c -> i2c-1
lrwxrwxrwx 1 root root           5 Mar  3 13:53 colibri-i2c-on-module -> i2c-0
lrwxrwxrwx 1 root root           9 Mar  3 13:53 colibri-spi-cs0 -> spidev3.0
lrwxrwxrwx 1 root root           7 Mar  3 13:53 colibri-uarta -> ttymxc0
lrwxrwxrwx 1 root root           7 Mar  3 13:53 colibri-uartb -> ttymxc1
lrwxrwxrwx 1 root root           7 Mar  3 13:53 colibri-uartc -> ttymxc2
...

From within the container:

colibri-imx6-10713580:~$ docker run -it testio_arm32v7-debian-python3_bullseye_release_a2144247-4b22-4424-a4fb-44b1d29293e0 /bin/sh
$ ls -l /dev
total 0
crw--w---- 1 torizon tty  136, 0 Mar  5 12:18 console
lrwxrwxrwx 1 root    root     13 Mar  5 12:18 fd -> /proc/self/fd
crw-rw-rw- 1 root    root   1, 7 Mar  5 12:18 full
drwxrwxrwt 2 root    root     40 Mar  5 12:18 mqueue
crw-rw-rw- 1 root    root   1, 3 Mar  5 12:18 null
lrwxrwxrwx 1 root    root      8 Mar  5 12:18 ptmx -> pts/ptmx
drwxr-xr-x 2 root    root      0 Mar  5 12:18 pts
crw-rw-rw- 1 root    root   1, 8 Mar  5 12:18 random
drwxrwxrwt 2 root    root     40 Mar  5 12:18 shm
lrwxrwxrwx 1 root    root     15 Mar  5 12:18 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root    root     15 Mar  5 12:18 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root    root     15 Mar  5 12:18 stdout -> /proc/self/fd/1
crw-rw-rw- 1 root    root   5, 0 Mar  5 12:18 tty
crw-rw-rw- 1 root    root   1, 9 Mar  5 12:18 urandom
crw-rw-rw- 1 root    root   1, 5 Mar  5 12:18 zero

So the exact error is:

$ ls -l /dev/colibri-i2c
ls: cannot access '/dev/colibri-i2c': No such file or directory

Docker command line:

docker run --device /dev/spidev3.0:/dev/spidev3.0 --device /dev/i2c-0:/dev/i2c-0 --device /dev/i2c-1:/dev/i2c-1 --device /dev/gpiochip0:/dev/gpiochip0 --device /dev/gpiochip1:/dev/gpiochip1 --device /dev/gpiochip2:/dev/gpiochip2 --device /dev/gpiochip3:/dev/gpiochip3 --device /dev/gpiochip4:/dev/gpiochip4 --device /dev/gpiochip5:/dev/gpiochip5 --device /dev/gpiochip6:/dev/gpiochip6 --device /sys/class/pwm/pwmchip0:/sys/class/pwm/pwmchip0 --device /sys/class/pwm/pwmchip3:/sys/class/pwm/pwmchip3 --device /sys/bus/iio/devices/iio:device0/in_voltage4_raw:/sys/bus/iio/devices/iio:device0/in_voltage4_raw --device /sys/bus/iio/devices/iio:device0/in_voltage5_raw:/sys/bus/iio/devices/iio:device0/in_voltage5_raw --device /sys/bus/iio/devices/iio:device0/in_voltage6_raw:/sys/bus/iio/devices/iio:device0/in_voltage6_raw --device /sys/bus/iio/devices/iio:device0/in_voltage7_raw:/sys/bus/iio/devices/iio:device0/in_voltage7_raw --device /dev/i2c-2:/dev/i2c-2 testio_arm32v7-debian-python3_bullseye_release_a2144247-4b22-4424-a4fb-44b1d29293e0

docker release file

I did some testing on my side and I don’t seem to have any issues, similar to your setup.

Some observations however. First of all your dockerfile is missing RUN usermod -a -G gpio,spidev,dialout,i2cdev,input torizon, for some reason.

Also the devices config option is really only meant for devices/files in /dev for things in /sys you want to bindmount them into the container via the volumes config option.

Here’s the details of my setup to compare:

Container run command:

docker run --volume /sys:/sys --device /dev/spidev3.0:/dev/spidev3.0 --device /dev/i2c-0:/dev/i2c-0 --device /dev/i2c-1:/dev/i2c-1 --device /dev/i2c-4:/dev/i2c-4 --device /dev/gpiochip0:/dev/gpiochip0 --device /dev/gpiochip1:/dev/gpiochip1 --device /dev/gpiochip2:/dev/gpiochip2 --device /dev/gpiochip3:/dev/gpiochip3 --device /dev/gpiochip4:/dev/gpiochip4 --device /dev/gpiochip5:/dev/gpiochip5 --device /dev/gpiochip6:/dev/gpiochip6 test_arm32v7-debian-python3_bullseye_release_67274fc6-177a-4f59-9c08-f0a210813d55

Inside the container:

torizon@8765e7faf8b6:/test$ ls -l /dev/
total 0
lrwxrwxrwx 1 root root       13 Mar  5 19:05 fd -> /proc/self/fd
crw-rw-rw- 1 root root     1, 7 Mar  5 19:05 full
crw-rw-r-- 1 root gpio   254, 0 Mar  5 19:05 gpiochip0
crw-rw-r-- 1 root gpio   254, 1 Mar  5 19:05 gpiochip1
crw-rw-r-- 1 root gpio   254, 2 Mar  5 19:05 gpiochip2
crw-rw-r-- 1 root gpio   254, 3 Mar  5 19:05 gpiochip3
crw-rw-r-- 1 root gpio   254, 4 Mar  5 19:05 gpiochip4
crw-rw-r-- 1 root gpio   254, 5 Mar  5 19:05 gpiochip5
crw-rw-r-- 1 root gpio   254, 6 Mar  5 19:05 gpiochip6
crw-rw-r-- 1 root i2cdev  89, 0 Mar  5 19:05 i2c-0
crw-rw-r-- 1 root i2cdev  89, 1 Mar  5 19:05 i2c-1
crw-rw-r-- 1 root i2cdev  89, 4 Mar  5 19:05 i2c-4
drwxrwxrwt 2 root root       40 Mar  5 19:05 mqueue
crw-rw-rw- 1 root root     1, 3 Mar  5 19:05 null
lrwxrwxrwx 1 root root        8 Mar  5 19:05 ptmx -> pts/ptmx
drwxr-xr-x 2 root root        0 Mar  5 19:05 pts
crw-rw-rw- 1 root root     1, 8 Mar  5 19:05 random
drwxrwxrwt 2 root root       40 Mar  5 19:05 shm
crw-rw-r-- 1 root spidev 153, 0 Mar  5 19:05 spidev3.0
lrwxrwxrwx 1 root root       15 Mar  5 19:05 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root       15 Mar  5 19:05 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root       15 Mar  5 19:05 stdout -> /proc/self/fd/1
crw-rw-rw- 1 root root     5, 0 Mar  5 19:05 tty
crw-rw-rw- 1 root root     1, 9 Mar  5 19:05 urandom
crw-rw-rw- 1 root root     1, 5 Mar  5 19:05 zero

config.yaml and docker release file

I’d suggest quickly redoing everything cause something must be amiss here. Also make sure you’re not directly editing config.yaml. This file isn’t meant to be edited directly.

Best Regards,
Jeremias

Hi @jeremias.tx,

Isn’t the Dockerfile autogenerated by the torizon plugin and editing not allowed?

Can we modify the Dockerfile? As far as I remember while debugging changes in the debug dockerfile were overwritten?

Regards,
Gaurav

Hello Jeremias,

thank you for answering, I did miss, that when starting the container manually, I also have to use the full docker command (incl. all the --devices options).

You are correct this file is auto-generated by the plugin. Any changes/additions need to be included by modifying the correct options in the configuration view. I was observing that “romnan”, modified the buildcommands config option but their modifications weren’t added to the Dockerfile as expected.

So are you still having issues or were you able to access all the peripherals as shown in my setup?

Hi, I am having similar issues. It would be great if I can configure VS to autogenerate a container with the right permissions to allow me to access I2C, and GPIO. Have you managed to achieve? If not, do you have to build to a output file and then copy that file into a container with the correct device permissions , manually?
Cheers

Richard

@FatLinux we have an article here on how to use GPIO with VS: https://developer.toradex.com/gpio-visual-studio-plugin

For I2C the process is basically the same.