Intermittent Failure on Serial Port
H J van Rooyen
mail at microcorp.co.za
Sat Jun 10 05:21:49 EDT 2006
Hi All,
I am writing a polling controller for an RS-485 line that has
several addressable devices connected.
It is a small access control system.
All is well- the code runs for anything from three hours to three days, then
sometimes when I get a comms error and have to send out a nak character, it
fails hard...
The traceback below pops up. - the first lines are just some debug prints.
and the four records show reader number, id number, name...
_______________start of Konsole Messages __________________
/dev/ttyS0 set to 9600 sane cread raw -echo
../logs/composite/rawlog
Pipe exists already
we get here - thread identity is: 1079298992
New Thread identity printed by new thread is: 1079298992
we get here too
5 0123456789012345 Sefie Sewenstein is in
2 DE0000085ABF8A01 Error record - catch her, catch him
2 8A00000870BEDE01 Bertus Bierdrinker is in
5 0123456789012345 Sefie Sewenstein is out
Traceback (most recent call last):
File "portofile.py", line 232, in ?
ret_val = main_routine(port, pollstruct, pfifo)
File "portofile.py", line 108, in main_routine
send_nak(port, timeout) # so bad luck - comms error
File "/home/hvr/Polling/lib/readerpoll.py", line 125, in send_nak
port.flush()
IOError: [Errno 29] Illegal seek
close failed: [Errno 29] Illegal seek
_______________end of Konsole Messages ___________________
The additional thread referred to is used to maintain a file of
people on the premises,- it is not relevant to this,
as it just writes out a global dictionary when
something has changed, and it works quite merrily...
Some of what I think are the relevant code snippets:
This one works all the time, as I send out an ack on the
succesful receipt of a message from one of the readers, and
I have not seen it fail yet:
def send_ack(port, timeout):
"""Routine to send out an ack on port"""
ack_string = ack # Ascii ack = '\x06'
s = ''
port.write(ack_string)
port.flush()
flush_out(port,timeout) # eat the echoed ack
This one is called after a comms error, and sometimes falls over in the above
manner...
def send_nak(port, timeout):
"""Routine to send out a nak on port"""
nak_string = nak # Ascii nak = '\x15'
s = ''
port.write(nak_string)
port.flush()
flush_out(port, timeout) # eat the echoed nak
# here we read to end, to flush a port buffer
def flush_out(file, time_out):
"""Reads the port till no more chars come in for a while"""
start_time = time.time()
s = ''
while (time.time() - start_time < time_out):
s, ret_val = read_char(file, s)
if ret_val == 0: # if there is input...
start_time = time.time()
# We make a function to read a char of file data
def read_char(file, s):
"""Reads file data returns string, ret_val is 0 on success, 1 for KbdInt, 2
no input."""
ret_val = 0 # No error yet
k = '' # Nothing read yet
try:
k = file.read(1) # read one char in as a string
except KeyboardInterrupt:
print "\n^C - Returning to Shell - Error is:", KeyboardInterrupt
ret_val = 1 # ^C while waiting for input
return k, ret_val # go out on error
except IOError:
ret_val = 2 # IOError on input - no record available
return s, ret_val # so no extra chars
if k == '': # empty string is nfg
ret_val = 2
return s, ret_val # so no extra chars
s = s + k # something to add in to passed buffer
return s, ret_val # ok exit no error
Note that the file is unblocked with some magic from fcntl module...
The file is the serial port /dev/ttyS0
There is hardware connected to the port that has the effect of a loopback - you
hear what you say..
Out of the box distribution - SuSe 10:
Python 2.4.1 (#1, Sep 13 2005, 00:39:20)
[GCC 4.0.2 20050901 (prerelease) (SUSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Where can I find out what the Errno 29 really means?
Is this Python, the OS or maybe hardware?
Any Ideas or suggestions will be appreciated
(I am doing this via email - so I am not on line all the time- so my responses
may be slow...)
- Hendrik van Rooyen
More information about the Python-list
mailing list