Accessing SPI in userspace (spidev permission errors)

Hello,

I’m upgrading a Beaglebone Green from a Debian 9 image to Debian 12 image. I am mainly concerned with SPI0 /dev/spidev0.0 on Debian 12. The Debian 9 version seemed to have no issue accessing SPI. I’m not sure how this initial configuration was created, if it was out of the box or not, but the permissions are below:

crw-rw---- 1 root spi 153, 1 Feb 26 20:00 /dev/spidev1.0
crw-rw---- 1 root spi 153, 0 Feb 26 20:00 /dev/spidev1.1
crw-rw---- 1 root spi 153, 3 Feb 26 20:00 /dev/spidev2.0
crw-rw---- 1 root spi 153, 2 Feb 26 20:00 /dev/spidev2.1

In particular, the group is spi and permissions for the group are read and write, and this is what appears on boot without running extra commands. I have no issue using the python spidev library to write or read bytes through SPI0.

As for SPI0 on Debian 12, or rather any of the SPI bus/devices, I’m having permission errors in userspace. I have not applied any device tree overlays other than the default, and my kernel and u-boot are the default as well, from the 12.2 Debian image. Upon initial boot, the permissions are:

crw------- 1 root root 153, 0 Oct  7 20:10 /dev/spidev0.0
crw------- 1 root root 153, 1 Oct  7 20:10 /dev/spidev0.1
crw------- 1 root root 153, 2 Oct  7 20:10 /dev/spidev1.0
crw------- 1 root root 153, 3 Oct  7 20:10 /dev/spidev1.1

I can successfully read and write on SPI0 (spidev0.0) if I perform these commands:

sudo groupadd spi
sudo adduser debian spi
sudo chgrp spi /dev/spidev0.0
sudo chmod 660 /dev/spidev0.0

and get

crw-rw---- 1 root spi 153, 0 Oct  7 20:10 /dev/spidev0.0

However, upon reboot, the permissions revert back to the root group without read/write in userspace.

Is there a way to make these userspace permissions stick without using something like a service that would trigger on boot to run the commands above? Is there some kernel config (CONFIG_*) option(s) I can recompile the kernel with in order to enable SPI0 reads and writes in userspace?

Thanks for the help.

we had a udev rule years ago for spidev, can’t seem to find it anymore…

Edit try:

cat /etc/udev/rules.d/50-spi.rules

KERNEL=="spidev", GROUP="gpio", MODE="0660"

edit, you might not have gpio group

cat /etc/group | grep ^gpio || groupadd -r gpio || true

gpio is used as our generic “group” for all random udev rules…

Regards,

1 Like

Thank you, Robert! I will try this.

Hi, Robert.

So I did already have gpio group:

debian@BeagleBone:~$ cat /etc/group | grep ^gpio
gpio:x:996:node-red,debian

I tried adding that line to 50-spi.rules exactly as you said:

debian@BeagleBone:~$ cat /etc/udev/rules.d/50-spi.rules
KERNEL=="spidev", GROUP="gpio", MODE="0660"

But now none of the /dev/spidev* files are showing up.

debian@BeagleBone:~$ ls -al /dev/spidev*
ls: cannot access '/dev/spidev*': No such file or directory

In case it helps, here’s the U-Boot output:

U-Boot 2022.04-ge0d31da5 (Aug 04 2023 - 18:48:26 +0000)

CPU  : AM335X-GP rev 2.1
Model: TI AM335x BeagleBone Black
DRAM:  512 MiB
Reset Source: Global warm SW reset has occurred.
Reset Source: Power-on reset has occurred.
RTC 32KCLK Source: External.
Core:  150 devices, 14 uclasses, devicetree: separate
WDT:   Started wdt@44e35000 with servicing (60s timeout)
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
Loading Environment from EXT4... ** File not found /boot/uboot.env **

** Unable to read "/boot/uboot.env" from mmc0:1 **
Board: BeagleBone Black
<ethaddr> not set. Validating first E-fuse MAC
BeagleBone Black:
Model: SeeedStudio BeagleBone Green:
BeagleBone Cape EEPROM: no EEPROM at address: 0x54
BeagleBone Cape EEPROM: no EEPROM at address: 0x55
BeagleBone Cape EEPROM: no EEPROM at address: 0x56
BeagleBone Cape EEPROM: no EEPROM at address: 0x57
Net:   eth2: ethernet@4a100000, eth3: usb_ether
Press SPACE to abort autoboot in 0 seconds
board_name=[BBG1] ...
switch to partitions #0, OK
mmc0 is current device
SD/MMC found on device 0
Couldn't find partition 0:2 0x82000000
Can't set block device
Couldn't find partition 0:2 0x82000000
Can't set block device
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk mmc@48060000.blk...
Scanning disk mmc@481d8000.blk...
Found 3 disks
No EFI system partition
BootOrder not defined
EFI boot manager: Cannot load any image
gpio: pin 56 (gpio 56) value is 0
gpio: pin 55 (gpio 55) value is 0
gpio: pin 54 (gpio 54) value is 0
gpio: pin 53 (gpio 53) value is 1
switch to partitions #0, OK
mmc0 is current device
gpio: pin 54 (gpio 54) value is 1
Checking for: /uEnv.txt ...
Checking for: /boot/uEnv.txt ...
gpio: pin 55 (gpio 55) value is 1
1713 bytes read in 4 ms (418 KiB/s)
Loaded environment from /boot/uEnv.txt
Checking if uname_r is set in /boot/uEnv.txt...
gpio: pin 56 (gpio 56) value is 1
Running uname_boot ...
loading /boot/vmlinuz-5.10.168-ti-r77 ...
11366912 bytes read in 718 ms (15.1 MiB/s)
debug: [enable_uboot_overlays=1] ...
debug: [enable_uboot_cape_universal=1] ...
debug: [uboot_base_dtb_univ=am335x-boneblack-uboot-univ.dtb] ...
uboot_overlays: [uboot_base_dtb=am335x-boneblack-uboot-univ.dtb] ...
uboot_overlays: Switching too: dtb=am335x-boneblack-uboot-univ.dtb ...
loading /boot/dtbs/5.10.168-ti-r77/am335x-boneblack-uboot-univ.dtb ...
210706 bytes read in 19 ms (10.6 MiB/s)
Found 0 extension board(s).
uboot_overlays: [fdt_buffer=0x60000] ...
uboot_overlays: loading /boot/dtbs/5.10.168-ti-r77/overlays/M-BB-BBG-00A0.dtbo ...
418 bytes read in 9 ms (44.9 KiB/s)
uboot_overlays: loading /boot/dtbs/5.10.168-ti-r77/overlays/BB-ADC-00A0.dtbo ...
645 bytes read in 9 ms (69.3 KiB/s)
uboot_overlays: loading /boot/dtbs/5.10.168-ti-r77/overlays/BB-BONE-eMMC1-01-00A0.dtbo ...
1605 bytes read in 9 ms (173.8 KiB/s)
loading /boot/initrd.img-5.10.168-ti-r77 ...
8081270 bytes read in 517 ms (14.9 MiB/s)
debug: [console=ttyS0,115200n8 bone_capemgr.uboot_capemgr_enabled=1 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet] ...
debug: [bootz 0x82000000 0x88080000:7b4f76 88000000] ...
Kernel image @ 0x82000000 [ 0x000000 - 0xad7200 ]
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
   Loading Ramdisk to 8f84b000, end 8fffff76 ... OK
   Loading Device Tree to 8f7b4000, end 8f84afff ... OK

Starting kernel ...

[    0.167581] l3-aon-clkctrl:0000:0: failed to disable
[   12.626826] debugfs: Directory '49000000.dma' with parent 'dmaengine' already present!
[   12.671910] gpio-of-helper ocp:cape-universal: Failed to get gpio property of 'P8_03'
[   12.671939] gpio-of-helper ocp:cape-universal: Failed to create gpio entry
[   13.430295] omap_voltage_late_init: Voltage driver support not added
rootfs: recovering journal
rootfs: Clearing orphaned inode 23111 (uid=0, gid=0, mode=0100644, size=83886080)
rootfs: clean, 62978/944384 files, 653003/3888507 blocks
trap: EXIT: bad trap

Debian GNU/Linux 12 BeagleBone ttyS0

Try mod probing spidev, lately it’s been causing users issues…

Regards,

That did work to load the module, but the permissions are still root only:

debian@BeagleBone:~$ ls /dev/spi*
ls: cannot access '/dev/spi*': No such file or directory
debian@BeagleBone:~$ sudo modprobe spidev
[sudo] password for debian:
debian@BeagleBone:~$ ls /dev/spi* -al
crw------- 1 root root 153, 0 Mar 14 16:44 /dev/spidev0.0
crw------- 1 root root 153, 1 Mar 14 16:44 /dev/spidev0.1
crw------- 1 root root 153, 2 Mar 14 16:44 /dev/spidev1.0
crw------- 1 root root 153, 3 Mar 14 16:44 /dev/spidev1.1

Any other thoughts? Thanks for the help so far.

I was able to fix it.

First of all, something I didn’t mention that I believe is needed is using the SPIDEV0 overlay. So in uEnv.txt I have:

uboot_overlay_addr5=BB-SPIDEV0-00A0.dtbo

Once rebooted, I modprobe’d spidev as Robert suggested. This oneliner checks if spidev module is loaded, and if not, it loads it:

lsmod | grep ^spidev || sudo modprobe spidev || true

Then to fix the permissions:

sudo chgrp gpio /dev/spidev*
sudo chmod 660 /dev/spidev*

Now I can successfully run spidev_test in /opt/source/spidev_test. My SPI0 pins show up like so:

debian@BeagleBone:~$ show-pins | sort | grep spi
P9.17 / spi boot cs               87 fast rx      0 spi 0 cs 0       spi@48030000 (pinmux_bb_spi0_pins)
P9.18 / spi boot out              86 fast rx      0 spi 0 d1 mosi    spi@48030000 (pinmux_bb_spi0_pins)
P9.21 / spi boot in               85 fast rx      0 spi 0 d0 miso    spi@48030000 (pinmux_bb_spi0_pins)
P9.22 / spi boot clk              84 fast rx      0 spi 0 clk        spi@48030000 (pinmux_bb_spi0_pins)
1 Like