20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 #You should have received a copy of the GNU General Public |
22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from threading import Timer, Thread, Lock |
|
26 import ctypes, os, commands, types, sys |
25 import ctypes, os, commands, types, sys |
27 import traceback |
|
28 from LPCProto import * |
26 from LPCProto import * |
29 |
27 |
30 class LPCObject(): |
28 class LPCObject(): |
31 def __init__(self,pluginsroot): |
29 def __init__(self,pluginsroot, location): |
32 self.PLCStatus = "Stopped" |
30 self.PLCStatus = "Disconnected" |
33 self.pluginsroot = pluginsroot |
31 self.pluginsroot = pluginsroot |
34 self.PLCprint = pluginsroot.logger.write |
32 self.PLCprint = pluginsroot.logger.write |
35 self.SerialConnection = None |
|
36 self.StorageConnection = None |
|
37 self._Idxs = [] |
33 self._Idxs = [] |
38 |
34 self.UpdateLocation(location) |
39 def HandleSerialTransaction(self, transaction): |
35 |
40 if self.SerialConnection is None: |
36 def UpdateLocation(self, location): |
|
37 # Is that a comport ? |
|
38 if len(location) == 5 and\ |
|
39 location.startswith("COM") and \ |
|
40 location[3].isdigit() and \ |
|
41 location[4]==":" : |
|
42 self.StorageConnection = None |
41 try: |
43 try: |
42 self.SerialConnection = LPCProto(6,115200,2) |
44 comport = int(location[3]) - 1 |
|
45 self.SerialConnection = LPCProto(comport,#number |
|
46 115200, #speed |
|
47 2) #timeout |
|
48 # This will update status |
|
49 self.HandleSerialTransaction(IDLETransaction()) |
43 except Exception,e: |
50 except Exception,e: |
44 self.pluginsroot.logger.write_error(str(e)+"\n") |
51 self.pluginsroot.logger.write_error(str(e)+"\n") |
45 self.SerialConnection = None |
52 self.SerialConnection = None |
46 return "Disconnected", res |
53 self.PLCStatus = "Disconnected" |
47 try: |
54 # or a drive unit ? |
48 return self.SerialConnection.HandleTransaction(transaction) |
55 elif len(location)==2 and \ |
49 except LPCError,e: |
56 location[0].isalpha() and \ |
50 #pluginsroot.logger.write_error(traceback.format_exc()) |
57 location[1] == ':' : |
51 self.pluginsroot.logger.write_error(str(e)+"\n") |
|
52 self.SerialConnection = None |
58 self.SerialConnection = None |
53 return "Disconnected", res |
59 if os.path.exist(location): |
|
60 self.StorageConnection = location |
|
61 self.PLCStatus = "Stopped" |
|
62 else: |
|
63 self.pluginsroot.logger.write_error("Drive "+ |
|
64 location+ |
|
65 " do not exist !\n") |
|
66 self.StorageConnection = None |
|
67 self.PLCStatus = "Disconnected" |
|
68 |
|
69 def HandleSerialTransaction(self, transaction): |
|
70 if self.SerialConnection is not None: |
|
71 try: |
|
72 self.PLCStatus, res = self.SerialConnection.HandleTransaction(transaction) |
|
73 return res |
|
74 except LPCError,e: |
|
75 self.pluginsroot.logger.write_error(str(e)+"\n") |
|
76 self.SerialConnection = None |
|
77 self.PLCStatus = "Disconnected" |
|
78 return None |
54 |
79 |
55 def StartPLC(self, debug=False): |
80 def StartPLC(self, debug=False): |
56 PLCprint("StartPLC") |
81 PLCprint("StartPLC") |
57 self.HandleSerialTransaction(STARTTransaction()) |
82 self.HandleSerialTransaction(STARTTransaction()) |
58 |
83 |
62 |
87 |
63 def ForceReload(self): |
88 def ForceReload(self): |
64 pass |
89 pass |
65 |
90 |
66 def GetPLCstatus(self): |
91 def GetPLCstatus(self): |
67 status,data = self.HandleSerialTransaction(IDLETransaction()) |
92 self.HandleSerialTransaction(IDLETransaction()) |
68 return status |
93 return self.PLCStatus |
69 |
94 |
70 def NewPLC(self, md5sum, data, extrafiles): |
95 def NewPLC(self, md5sum, data, extrafiles): |
71 pass |
96 pass |
72 |
97 |
73 def MatchMD5(self, MD5): |
98 def MatchMD5(self, MD5): |
74 status,data = self.HandleSerialTransaction(PLCIDTransaction()) |
99 data = self.HandleSerialTransaction(PLCIDTransaction()) |
75 return data == MD5 |
100 return data == MD5 |
76 |
101 |
77 class IEC_STRING(ctypes.Structure): |
102 class IEC_STRING(ctypes.Structure): |
78 """ |
103 """ |
79 Must be changed according to changes in iec_types.h |
104 Must be changed according to changes in iec_types.h |
102 "REAL" : (ctypes.c_float, lambda x:x.value, lambda t,x:t(x)), |
127 "REAL" : (ctypes.c_float, lambda x:x.value, lambda t,x:t(x)), |
103 "LREAL" : (ctypes.c_double, lambda x:x.value, lambda t,x:t(x)), |
128 "LREAL" : (ctypes.c_double, lambda x:x.value, lambda t,x:t(x)), |
104 } |
129 } |
105 |
130 |
106 def SetTraceVariablesList(self, idxs): |
131 def SetTraceVariablesList(self, idxs): |
107 self._Idxs = idxs[:] |
|
108 status,data = self.HandleSerialTransaction( |
|
109 SET_TRACE_VARIABLETransaction( |
|
110 ''.join(map(chr,idx)))) |
|
111 |
|
112 def SetTraceVariablesList(self, idxs): |
|
113 """ |
132 """ |
114 Call ctype imported function to append |
133 Call ctype imported function to append |
115 these indexes to registred variables in PLC debugger |
134 these indexes to registred variables in PLC debugger |
116 """ |
135 """ |
117 if idxs: |
136 if idxs: |
130 pack_func(c_type,force)), |
149 pack_func(c_type,force)), |
131 forced_type_size) |
150 forced_type_size) |
132 buff += idxstr + forced_type_size_str + forcestr |
151 buff += idxstr + forced_type_size_str + forcestr |
133 else: |
152 else: |
134 buff += idxstr + chr(0) |
153 buff += idxstr + chr(0) |
135 status,data = self.HandleSerialTransaction( |
154 data = self.HandleSerialTransaction( |
136 SET_TRACE_VARIABLETransaction(buff)) |
155 SET_TRACE_VARIABLETransaction(buff)) |
137 else: |
156 else: |
138 self._Idxs = [] |
157 self._Idxs = [] |
139 |
158 |
140 def GetTraceVariables(self): |
159 def GetTraceVariables(self): |
141 """ |
160 """ |
142 Return a list of variables, corresponding to the list of required idx |
161 Return a list of variables, corresponding to the list of required idx |
143 """ |
162 """ |
144 if self.PLCStatus == "Started": |
163 offset = 0 |
145 res=[] |
164 strbuf = self.HandleSerialTransaction( |
146 tick = ctypes.c_uint32() |
165 GET_TRACE_VARIABLETransaction()) |
147 size = ctypes.c_uint32() |
166 size = len(strbuf) - 4 |
148 buffer = ctypes.c_void_p() |
167 if size > 0 and self.PLCStatus == "Started": |
149 offset = 0 |
168 tick = ctypes.cast( |
150 if self.PLClibraryLock.acquire(False) and \ |
169 ctypes.c_char_p(strbuf[:4]), |
151 self._GetDebugData(ctypes.byref(tick),ctypes.byref(size),ctypes.byref(buffer)) == 0 : |
170 ctypes.POINTER(ctypes.c_int)).contents |
152 if size.value: |
171 buffer = ctypes.cast( |
153 for idx, iectype, forced in self._Idxs: |
172 ctypes.c_char_p(strbuf[4:]), |
154 cursor = ctypes.c_void_p(buffer.value + offset) |
173 ctypes.c_void_p) |
155 c_type,unpack_func, pack_func = self.TypeTranslator.get(iectype, (None,None,None)) |
174 for idx, iectype, forced in self._Idxs: |
156 if c_type is not None and offset < size: |
175 cursor = ctypes.c_void_p(buffer.value + offset) |
157 res.append(unpack_func(ctypes.cast(cursor, |
176 c_type,unpack_func, pack_func = self.TypeTranslator.get(iectype, (None,None,None)) |
158 ctypes.POINTER(c_type)).contents)) |
177 if c_type is not None and offset < size: |
159 offset += ctypes.sizeof(c_type) |
178 res.append(unpack_func(ctypes.cast(cursor, |
160 else: |
179 ctypes.POINTER(c_type)).contents)) |
161 if c_type is None: |
180 offset += ctypes.sizeof(c_type) |
162 PLCprint("Debug error - " + iectype + " not supported !") |
181 else: |
163 if offset >= size: |
182 if c_type is None: |
164 PLCprint("Debug error - buffer too small !") |
183 PLCprint("Debug error - " + iectype + " not supported !") |
165 break |
184 if offset >= size: |
166 self._FreeDebugData() |
185 PLCprint("Debug error - buffer too small !") |
167 self.PLClibraryLock.release() |
186 break |
168 if offset and offset == size.value: |
187 if offset and offset == size: |
169 return self.PLCStatus, tick.value, res |
188 return self.PLCStatus, tick.value, res |
170 elif size.value: |
189 PLCprint("Debug error - wrong buffer unpack !") |
171 PLCprint("Debug error - wrong buffer unpack !") |
|
172 return self.PLCStatus, None, None |
190 return self.PLCStatus, None, None |
173 |
191 |