很多内容来自互联网,可以在ipython中运行,加入了一些的异常处理.
#!/usr/bin/python
# -*- coding:utf-8 -*-
#from Crypto.Cipher import AES
import binascii
import sys
import re
import serial
import struct
import traceback
import IPython
from timeout import *
#reboot
s1 = '08 00 03 f0 00 00 01 00 11 22 33 44'
#test if run in ipython or not
def in_ipython():
try:
__IPYTHON__
except NameError:
return False
else:
return True
ser = serial.Serial()
#release the opened serial port
def relese_serial(obj):
if(obj.isOpen() == True):
obj.close()
#exception do when run script at shell
def my_excepthook(ex_cls, ex, tb):
global ser
relese_serial(ser)
msg = "Oops! There's an Error.\n"
print(msg)
with open("./ERR.txt", 'w') as a:
a.write(msg)
a.close()
#this function is very complex and still unkown now
def showtraceback(self):
traceback_lines = traceback.format_exception(*sys.exc_info())
del traceback_lines[1]
message = ''.join(traceback_lines)
sys.stderr.write(message)
global ser
if(ser.isOpen() == True):
ser.close()
print "over"
#capture error or excption when run script at ipython
def custom_exc(shell, etype, evalue, tb, tb_offset=None):
# shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset)
# ipshell()
global ser
relese_serial(ser)
print type(etype)
print etype
pass
if(in_ipython()):
print "run script in ipython!"
# IPython.core.interactiveshell.InteractiveShell.showtraceback = showtraceback
# get_ipython().set_custom_exc((Exception,), custom_exc)
get_ipython().set_custom_exc((Exception,), custom_exc)
else:
print "run script in shell!"
sys.excepthook = my_excepthook
def insert_blank(si):
len1 = len(si)
s3 = ''
# print len1
for i in range(len1):
if((i%2 == 0) and (i>0)):
s3+=' '
s3+=si[i]
return s3
def isset(v):
try:
type (eval(v))
except:
return False
else:
return True
if(isset('s1')==False):
print "no command"
sys.exit()
print s1
s1_1 = s1.replace(" ", "") #trip blank
#print s1_1
s2 = binascii.a2b_hex(s1_1)
#print binascii.b2a_hex(s2)
#sys.exit()
ser.baudrate = 57600
ser.port = "COM3"
ser.timeout=0.1
if(ser.isOpen() == False):
ser.open()
#ser = serial.Serial(2) # open first serial port
#print ser.portstr # check which port was really used
#ff
b_timeout = False
def functest(args):
global b_timeout
if(args == 0):
print "set b_timeout"
b_timeout = True
print '**timeout found**' , args #
else:
print '**timer stop event**' , args #
def recevie(obj, timeout):
global b_timeout
mytime=Pysettimer(functest, ('uuuuu' ,'vvvvv'), timeout=timeout) #register timer
print "start receive"
mytime.start()
rx_len = 0
index = 0
s0 = ''
b_timeout = False
print b_timeout
while(b_timeout == False):
if(obj.inWaiting()):
s0 += obj.read(1)
index += 1
if(index == 2 ):
t1 = struct.unpack("H", s0)
rx_len = t1[0]+4
# print rx_len
# break
# print index,rx_len
if((index > 4) and (index >= rx_len)):
break
print b_timeout
mytime.stop()
print "receive exit"
return s0
ser.write(s2) # write a string
s0_0 = recevie(ser, 1)
if(len(s0_0) < 8):
print "not receive"
ser.close()
sys.exit(1)
s0_1 = binascii.b2a_hex(s0_0)
print insert_blank(s0_1)
ser.timeout=2
s0_0 = recevie(ser, 5)
s0_1 = binascii.b2a_hex(s0_0)
if(len(s0_0) > 8):
t2 = struct.unpack("HHHB", s0_0[:7])
print insert_blank(s0_1)
if(t2[3] > 0):
print "operation fault(0x%02x)" %t2[3]
else:
print len(s0_0)
ser.close() # close port
if(in_ipython()):
print "run script in ipython!"
# IPython.core.interactiveshell.InteractiveShell.showtraceback = showtraceback
# get_ipython().set_custom_exc((Exception,), custom_exc)
get_ipython().set_custom_exc((None,), None)
超时异常处理的代码来自一位网友写的类,
具体来自 点击打开链接 http://blog.csdn.net/leos_blog/article/details/19251681
不过原作者对于是哪种方式结束线程没有区分,实际使用的使用是要区分的,主动停止和超时退出是不同的概念.
#!/usr/bin/python
# -*- coding:utf-8 -*-
import threading
import time
class Pysettimer(threading.Thread):
'''''
Pysettimer is simulate the C++ settimer ,
it need pass funciton pionter into the class ,
timeout and is_loop could be default , or customized
'''
def __init__(self, function, args=None,timeout=1,is_loop=False):
threading.Thread.__init__(self)
self.event=threading.Event()
# inherent the funciton and args
self.function=function
self.args=args # pass a tuple into the class
self.timeout=timeout
self.is_loop=is_loop
self.season = 0
def run(self):
while not self.event.is_set():
self.event.wait(self.timeout) # wait until the time eclipse
self.function(self.season)
if not self.is_loop:
# print "thread exit ###"
self.event.set()
# print "timer exit***"
def stop(self):
# print "timer stop!!!"
self.season = 1
self.event.set()
当然,串口处理还有需要改进的地方( 主要是效率的.),只是作为测试程序,也没什么大碍了.