I was getting the following exceptions sometimes:
File "/home/pi/RWPi/PDALib.py", line 324, in writeDio
r = spi.xfer([0x40,reg,val&255,val>>8])
IOError: [Errno 9] Bad file descriptor
The fix seems to make digitalWrite() a critical section so that no other thread will use it:
- Code: Select all
import threading
dio_lock = threading.Lock()
...
def digitalWrite(pin,val):
with dio_lock: # Critical Section - only one thread # ALAN
if pin < 0:
return -1
if pin < 8:
return pi.write(servopin[pin],val)
if pin < 24:
if val:
return setDioBit(DIO_OLAT,pin-8)
else:
return clearDioBit(DIO_OLAT,pin-8)
return -1
Without this, I could only go three or four times through my robot loop before an exception. With this change to PDALib.v93.py, I have gone through the loop over 60 times, before getting an exception....
This time in readDIo().
PDALib.digitalWrite(Motors.M1DirB,0) #set to off/coast
File "/home/pi/RWPi/PDALib.py", line 193, in digitalWrite
return clearDioBit(DIO_OLAT,pin-8)
File "/home/pi/RWPi/PDALib.py", line 356, in clearDioBit
t = readDio(reg)
File "/home/pi/RWPi/PDALib.py", line 319, in readDio
r = spi.xfer([0x41,reg,0,0])
IOError: [Errno 9] Bad file descriptor
So the solution looks to be to add the following at the start of PDALib.93.py:
- Code: Select all
...
import threading
...
dio_lock = threading.Lock()
and add the line:
- Code: Select all
with dio_lock: # critical section #ALAN
to:
pinMode()
digitalRead()
digitalWrite()
analogRead()
analogWrite()
servoWrite()
I have not had an exception this evening. This was a shotgun approach rather than knowlege, so perhaps I over did it. I was getting tired of typing the: ps -ef | grep python, kill -9 xxxx
I would have to write a test program that launched threads to bang each PDALib public function repeatedly to be sure PDALib is now thread-safe, but not right now.