This post describes a workaround to an issue in Adafruit BeagleBone IO library where non-root user cannot start PWM on BeagleBone Black.
Problem with a Sysfs File
Consider below simple PWM code with Adafruit BBIO Python library in Ubuntu 16.04 (kernel 4.4).
1 2 3 4 5 6 7 8 9 10 11 12 | #!/bin/env python from Adafruit_BBIO import PWM import time PWM.start("P9_21", 50, 200) PWM.start("P9_22", 0, 200) time.sleep(1) PWM.stop("P9_21") PWM.stop("P9_22") PWM.cleanup() |
On some BeagleBone images, above code – PWM.start()
line – throws an error. However, same script executes fine sudo
.
1 2 3 4 5 6 | # python test_bbio_pwm.py Traceback (most recent call last): File "test_bbio_pwm.py", line 6, in <module> PWM.start("P9_21", 50, 200) RuntimeError: Problem with a sysfs file |
Obviously, this post is not relevant to you if above error is not encountered. Latest BeagleBone images may have a proper fix.
The Reason
PWM.start()
method tries to access corresponding device file period
(and others) when setting up PWM. The device files like period
, duty_cycle
and polarity
are visible only when pwm is setup. This is done by writing 1 (pwm1) or 0 (pwm0) to /sys/devices/platform/ocp/*.epwmss/*.pwm/pwm/pwmchip*/export
.
However, when pwm1/0 and device files created under it are owned by user root
and group root
. So a non-root user do not have permissions to write to the device files. This is a bug, that may have got fixed in latest BeagleBone images.
1 2 3 4 5 6 7 8 9 10 11 12 | $ ls -la /sys/devices/platform/ocp/*.epwmss/*.pwm/pwm/pwmchip*/pwm* total 0 drwxr-xr-x 3 root root 0 Dec 31 19:25 . drwxrwxr-x 4 root pwm 0 Dec 31 19:06 .. -rw-r--r-- 1 root root 4096 Dec 31 19:25 duty_cycle -rw-r--r-- 1 root root 4096 Dec 31 19:25 enable -rw-r--r-- 1 root root 4096 Dec 31 19:06 period -rw-r--r-- 1 root root 4096 Dec 31 19:25 polarity drwxr-xr-x 2 root root 0 Dec 31 19:25 power -rw-r--r-- 1 root root 4096 Dec 31 19:25 uevent |
The Workaround
Udev rules allow non-root users to access PWM devices if that user is part of pwm
unix group. Check that by typing groups
command on your BeagleBone terminal.
As you might have guessed, for all PWM device files, the trick is to change the group from root
to pwm
and let all user of group pwm
have write permissions. Once this is done, you will be able to do execute PWM Python scripts without the need for sudo
.
Below is my script that changes group for all PWM devices on BeagleBone Black. Remember to execute this script with sudo
– for one last time!
1 2 3 4 5 6 7 8 9 10 | #!/usr/bin/env sh # NOTE: Run this script as sudo for dir in /sys/devices/platform/ocp/*.epwmss/*.pwm/pwm/pwmchip*/ ; do echo '0' > "$dir"/export echo '1' > "$dir"/export done find /sys/devices/platform/ocp/ -type f |grep /sys/devices/platform/ocp/ |grep pwmchip |egrep '(duty_cycle|enable|period|polarity)$' |xargs sudo chgrp pwm find /sys/devices/platform/ocp/ -type f |grep /sys/devices/platform/ocp/ |grep pwmchip |egrep '(duty_cycle|enable|period|polarity)$' |xargs sudo chmod g+w |