After exporting PWM udev will trigger and if rules are set up correctly non-root permissions will be applied.
This process isn't synchronous, i.e. it will take some time after export until the sysfs node can be used by non-root users.
pwm.py however does not. The following test case shows this
from periphery import PWM
import time
# Exports the PWM, this succeeds because udev set permissions correctly.
pwm = PWM(0, 0)
# Tries to write to /sys/class/pwm/pwmchip0/pwm0/period
# This fails with:
# "PermissionError: [Errno 13] Permission denied: '/sys/class/pwm/pwmchip0/pwm0/period'"
# even if udev have set permissions correctly.
try:
pwm.frequency = 1e3
print('test1: frequency set')
except Exception as e:
print('test1: failed to set frequency', e)
pwm.close()
# Now add a small delay and try again.
pwm = PWM(0, 0)
time.sleep(0.1)
pwm.frequency = 1e3
print('test2: frequency set')
time.sleep(5)
pwm.close()
Output as non-root:
test1: failed to set frequency [Errno 13] Permission denied: '/sys/class/pwm/pwmchip0/pwm0/period'
test2: frequency set
With suggested fix:
test1: frequency set
test2: frequency set
If, with the suggested fix, there's a real issue with permissions the following is raised in PWM._open:
After exporting PWM udev will trigger and if rules are set up correctly non-root permissions will be applied. This process isn't synchronous, i.e. it will take some time after export until the sysfs node can be used by non-root users.
gpio.py has retry logic to account for this: https://github.com/vsergeev/python-periphery/blob/master/periphery/gpio.py#L723
pwm.py however does not. The following test case shows this
Output as non-root:
With suggested fix:
If, with the suggested fix, there's a real issue with permissions the following is raised in PWM._open: