-
Notifications
You must be signed in to change notification settings - Fork 220
Description
Hi Adafruit team,
It seems like there is a problem with file descriptor leaks in the PWM module.
enable_fd is opened every time pwm_setup
is called, but never closed on pwm_disable
, or if pwm_setup
otherwise fails. The PWM is removed from the exported_pwm
list, so a new enable_fd
is created the next time PWM.start
is called
Eventually the python process runs out of file descriptors and so all calls to PWM.start
raises
RuntimeError: problem with sysfs file.
Could I suggest that PWMs aren't removed from exported_pwms
on PWM.stop
until they are actually unexported (ie stop writes enable=0 but does not call disable_pwm
), and file descriptors for frequency, duty cycle, polarity and enable are kept open as long as the pwm is exported? This may require PWM.setup
and PWM.disable
methods to be exported to python so eventually they could be closed, but would have more predictable behaviour. Otherwise, at least closing enable_fd in pwm_disable
will stop the leak, but adds overhead in setup and teardown event time start
/stop
is called.
This occurs on Beaglebone Black running Adafruit_BBIO 1.0.7 (and other earlier versions i've used as well)
uname -a
cat /etc/dogtag
cat /etc/debian_version
Linux keyhound 4.4.9-ti-r25 #1 SMP Thu May 5 23:08:13 UTC 2016 armv7l GNU/Linux
BeagleBoard.org Debian Image 2016-05-13
8.8
to reproduce
test file:
import Adafruit_BBIO.PWM as PWM
for i in range(20,20000): # could just be an infinite loop, will eventually crash with any open file limit
PWM.start('P8_19',5,i)
PWM.stop('P8_19')
set open file limit to 1000, for example, then run test script
ulimit -n 1000
python pwmtest.py
Traceback (most recent call last):
File "./pwmtest.py", line 9, in
PWM.start('P8_19',5,i)
RuntimeError: Problem with a sysfs file
You can also check lsof --pid and see that enable_fd is not closed.
Workaround
only call start/stop on each pwm once. rather than disabling, set duty cycle to zero. This isn't ideal as the peripheral is still in use and can cause glitches when changing frequency, as duty cycle is actually stored in sysfs as the on time, not the duty cycle. changing frequency using sysfs doesn't maintain duty cycle. it maintains on time.