Intermittent Failure on Serial Port



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

.



Relevant Pages

  • Re: How to ping in Python?
    ... > # Changed the struct.packcalls to pack the checksum and ID as ... > def receiveOnePing(mySocket, ID, timeout): ... > # Returns either the delay or none on timeout. ...
    (comp.lang.python)
  • [suggestion+code] timed deq for the Queue class?
    ... class TimedReadQueue < Queue ... # problem with using Timeout and Queue together to achieve ... kill it and restart the main thread. ... def __arnold ...
    (comp.lang.ruby)
  • Re: Rogue threads found! The plot thickens....
    ... Somewhere around here I have a stream implementation for it. ... def read(stream, timeout) ... def initialize ... def pop(sec = nil) ...
    (comp.lang.ruby)
  • Re: Function decorator that caches function results
    ... Lasse Vågsæther Karlsen wrote: ... arg_names = inspect.getargspecdef cached_result: # Update named arguments with positional argument values ... added timeout, results will be recalculated when it expires ... PGP KeyID: 0x2A42A1C2. ...
    (comp.lang.python)