# HG changeset patch # User Edouard Tisserant # Date 1359436861 -39600 # Node ID ffa24427396a85d411a77e03038f3972ebe13186 # Parent f6d06bdd31e8e516ecfd4551620bb5f0930251c5 Log redirected to console, dump of all available log to console when connecting to PLC diff -r f6d06bdd31e8 -r ffa24427396a ProjectController.py --- a/ProjectController.py Thu Jan 24 17:44:44 2013 +1100 +++ b/ProjectController.py Tue Jan 29 16:21:01 2013 +1100 @@ -113,7 +113,7 @@ self.DebugThread = None self.debug_break = False self.previous_plcstate = None - self.previous_log_count = -1 + self.previous_log_count = None # copy ConfNodeMethods so that it can be later customized self.StatusMethods = [dic.copy() for dic in self.StatusMethods] @@ -1077,11 +1077,26 @@ self._builder = None self.CompareLocalAndRemotePLC() - ############# Real PLC object access ############# + def UpdatePLCLog(self, log_count): + if log_count and self.previous_log_count != log_count: + #self.logger.write("Now log count is "+repr(log_count)+"\n") + to_console = [''] + for msgidx in xrange(log_count-1, self.previous_log_count - 1 if self.previous_log_count is not None else 0,-1): + msg = self._connector.GetLogMessage(msgidx) + if msg is not None : + to_console.insert(0, '#' + repr(msgidx) + ": " + msg) + else: + #self.logger.write(repr(msgidx) + " : GetLogMessage returned None\n") + to_console.insert(0, 'No log before #'+repr(msgidx)) + break; + self.logger.write("\n".join(to_console)) + self.previous_log_count = log_count + def UpdateMethodsFromPLCStatus(self): status = None if self._connector is not None: status, log_count = self._connector.GetPLCstatus() + self.UpdatePLCLog(log_count) if status is None: self._connector = None status = "Disconnected" @@ -1103,9 +1118,6 @@ self.ShowMethod(*args) self.previous_plcstate = status return True - if(self.previous_log_count != log_count): - self.logger.write("Now log count is %d"%log_count) - self.previous_log_count = log_count return False def PullPLCStatusProc(self, event): diff -r f6d06bdd31e8 -r ffa24427396a runtime/PLCObject.py --- a/runtime/PLCObject.py Thu Jan 24 17:44:44 2013 +1100 +++ b/runtime/PLCObject.py Tue Jan 29 16:21:01 2013 +1100 @@ -79,6 +79,23 @@ if self.statuschange is not None: self.statuschange(self.PLCStatus) + def LogMessage(self, msg): + return self._LogMessage(msg, len(msg)) + + + def GetLogCount(self): + if self._GetLogCount is not None : + return int(self._GetLogCount()) + + def GetLogMessage(self, msgid): + maxsz = len(self._log_read_buffer)-1 + sz = self._GetLogMessage(msgid, self._log_read_buffer, maxsz) + if sz and sz <= maxsz: + self._log_read_buffer[sz] = '\x00' + return self._log_read_buffer.value + else : + return None + def _GetMD5FileName(self): return os.path.join(self.workingdir, "lasttransferedPLC.md5") @@ -149,6 +166,15 @@ self._GetLogCount = self.PLClibraryHandle.GetLogCount self._GetLogCount.restype = ctypes.c_uint32 + self._LogMessage = self.PLClibraryHandle.LogMessage + self._LogMessage.restype = ctypes.c_int + self._LogMessage.argtypes = [ctypes.c_char_p, ctypes.c_uint32] + + self._log_read_buffer = ctypes.create_string_buffer(1<<14) #16K + self._GetLogMessage = self.PLClibraryHandle.GetLogMessage + self._GetLogMessage.restype = ctypes.c_uint32 + self._GetLogMessage.argtypes = [ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32] + return True except: PLCprint(traceback.format_exc()) @@ -171,7 +197,9 @@ self._suspendDebug = lambda x:-1 self._resumeDebug = lambda:None self._PythonIterator = lambda:"" - self._GetLogCount = lambda:-1 + self._GetLogCount = None + self._LogMessage = lambda m,s:PLCprint("OFF LOG :"+m) + self._GetLogMessage = lambda i,b,s:None self.PLClibraryHandle = None # Unload library explicitely if getattr(self,"_PLClibraryHandle",None) is not None: @@ -258,6 +286,7 @@ def StartPLC(self): PLCprint("StartPLC") + self.LogMessage("Hello Log") if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": c_argv = ctypes.c_char_p * len(self.argv) error = None @@ -293,7 +322,7 @@ return True def GetPLCstatus(self): - return self.PLCStatus, self._GetLogCount() + return self.PLCStatus, self.GetLogCount() def NewPLC(self, md5sum, data, extrafiles): PLCprint("NewPLC (%s)"%md5sum) @@ -414,10 +443,10 @@ self._FreeDebugData() self.PLClibraryLock.release() if offset and offset == size.value: - return self.PLCStatus, self._GetLogCount(), tick.value, res + return self.PLCStatus, self.GetLogCount(), tick.value, res #elif size.value: #PLCprint("Debug error - wrong buffer unpack ! %d != %d"%(offset, size.value)) - return self.PLCStatus, self._GetLogCount(), None, [] + return self.PLCStatus, self.GetLogCount(), None, [] def RemoteExec(self, script, **kwargs): try: diff -r f6d06bdd31e8 -r ffa24427396a targets/plc_debug.c --- a/targets/plc_debug.c Thu Jan 24 17:44:44 2013 +1100 +++ b/targets/plc_debug.c Tue Jan 29 16:21:01 2013 +1100 @@ -322,7 +322,7 @@ if(buffpos + size < LOG_BUFFER_SIZE){ memcpy(buf, &LogBuff[buffpos], size); }else{ - uint32_t remaining = LOG_BUFFER_SIZE - buffpos - 1; + uint32_t remaining = LOG_BUFFER_SIZE - buffpos; memcpy(buf, &LogBuff[buffpos], remaining); memcpy(buf + remaining, LogBuff, size - remaining); } @@ -387,27 +387,24 @@ uint32_t GetLogMessage(uint32_t msgidx, char* buf, uint32_t max_size){ uint64_t cursor = LogCursor; if(cursor){ - /* feeding cursor values */ - uint32_t curbuffpos = (uint32_t)cursor; - uint32_t curmsgidx = (cursor >> 32); - /* seach cursor */ - uint32_t stailpos = (curbuffpos - sizeof(mTail)) & LOG_BUFFER_MASK; + uint32_t stailpos = (uint32_t)cursor; uint32_t smsgidx; mTail tail; - tail.msgidx = curmsgidx; + tail.msgidx = cursor >> 32; + tail.msgsize = 0; /* Message search loop */ do { smsgidx = tail.msgidx; + stailpos = (stailpos - sizeof(mTail) - tail.msgsize ) & LOG_BUFFER_MASK; copy_from_log(stailpos, &tail, sizeof(mTail)); - stailpos = (stailpos - sizeof(mTail) - tail.msgsize ) & LOG_BUFFER_MASK; - }while(tail.msgidx == smsgidx - 1 && tail.msgidx > msgidx); + }while((tail.msgidx == smsgidx - 1) && (tail.msgidx > msgidx)); if(tail.msgidx == msgidx){ uint32_t sbuffpos = (stailpos - tail.msgsize ) & LOG_BUFFER_MASK; - uint32_t totalsize = tail.msgsize + sizeof(mTail); - copy_from_log(stailpos, &tail, totalsize > max_size ? max_size : totalsize); + uint32_t totalsize = tail.msgsize; /*sizeof(mTail);*/ + copy_from_log(sbuffpos, buf, totalsize > max_size ? max_size : totalsize); return totalsize; } } diff -r f6d06bdd31e8 -r ffa24427396a tests/logging/beremiz.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/logging/beremiz.xml Tue Jan 29 16:21:01 2013 +1100 @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<BeremizRoot URI_location="PYRO://127.0.0.1:3000"> + <TargetType/> +</BeremizRoot> diff -r f6d06bdd31e8 -r ffa24427396a tests/logging/plc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/logging/plc.xml Tue Jan 29 16:21:01 2013 +1100 @@ -0,0 +1,311 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.plcopen.org/xml/tc6.xsd" + xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xhtml="http://www.w3.org/1999/xhtml"> + <fileHeader companyName="Unknown" + productName="Unnamed" + productVersion="1" + creationDateTime="2013-01-29T14:01:00"/> + <contentHeader name="Unnamed" + modificationDateTime="2013-01-29T15:56:10"> + <coordinateInfo> + <fbd> + <scaling x="0" y="0"/> + </fbd> + <ld> + <scaling x="0" y="0"/> + </ld> + <sfc> + <scaling x="0" y="0"/> + </sfc> + </coordinateInfo> + </contentHeader> + <types> + <dataTypes/> + <pous> + <pou name="LOGGER" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="TRIG"> + <type> + <BOOL/> + </type> + </variable> + <variable name="MSG"> + <type> + <string/> + </type> + </variable> + </inputVars> + <localVars> + <variable name="TRIG0"> + <type> + <BOOL/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> +<![CDATA[IF TRIG AND NOT TRIG0 THEN +{{ + LogMessage(GetFbVar(MSG, .body),GetFbVar(MSG, .len)); +}} +END_IF; +TRIG0:=TRIG; +]]> + </ST> + </body> + </pou> + <pou name="program0" pouType="program"> + <interface> + <localVars> + <variable name="LOGGER0"> + <type> + <derived name="LOGGER"/> + </type> + </variable> + <variable name="beat"> + <type> + <BOOL/> + </type> + </variable> + <variable name="count"> + <type> + <INT/> + </type> + </variable> + </localVars> + </interface> + <body> + <FBD> + <block localId="1" width="65" height="71" typeName="LOGGER" instanceName="LOGGER0"> + <position x="1008" y="64"/> + <inputVariables> + <variable formalParameter="TRIG"> + <connectionPointIn> + <relPosition x="0" y="32"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="1008" y="96"/> + <position x="640" y="96"/> + <position x="640" y="94"/> + <position x="272" y="94"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="MSG"> + <connectionPointIn> + <relPosition x="0" y="57"/> + <connection refLocalId="8" formalParameter="OUT"> + <position x="1008" y="121"/> + <position x="970" y="121"/> + <position x="970" y="204"/> + <position x="935" y="204"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables/> + </block> + <inVariable localId="2" height="27" width="85"> + <position x="732" y="188"/> + <connectionPointOut> + <relPosition x="85" y="13"/> + </connectionPointOut> + <expression>'Moooooo'</expression> + </inVariable> + <block localId="3" width="59" height="40" typeName="NOT"> + <position x="213" y="64"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="4"> + <position x="213" y="94"/> + <position x="179" y="94"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="59" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inOutVariable localId="4" height="27" width="41"> + <position x="138" y="81"/> + <connectionPointIn> + <relPosition x="0" y="13"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="138" y="94"/> + <position x="123" y="94"/> + <position x="123" y="124"/> + <position x="282" y="124"/> + <position x="282" y="94"/> + <position x="272" y="94"/> + </connection> + </connectionPointIn> + <connectionPointOut> + <relPosition x="41" y="13"/> + </connectionPointOut> + <expression>beat</expression> + </inOutVariable> + <block localId="5" width="68" height="80" typeName="ADD"> + <position x="482" y="209"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="35"/> + <connection refLocalId="10" formalParameter="OUT"> + <position x="482" y="244"/> + <position x="459" y="244"/> + <position x="459" y="230"/> + <position x="449" y="230"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="65"/> + <connection refLocalId="6"> + <position x="482" y="274"/> + <position x="397" y="274"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="68" y="35"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <inOutVariable localId="6" height="27" width="48"> + <position x="349" y="261"/> + <connectionPointIn> + <relPosition x="0" y="13"/> + <connection refLocalId="5" formalParameter="OUT"> + <position x="349" y="274"/> + <position x="339" y="274"/> + <position x="339" y="306"/> + <position x="563" y="306"/> + <position x="563" y="244"/> + <position x="550" y="244"/> + </connection> + </connectionPointIn> + <connectionPointOut> + <relPosition x="48" y="13"/> + </connectionPointOut> + <expression>count</expression> + </inOutVariable> + <block localId="8" width="67" height="60" typeName="CONCAT"> + <position x="868" y="174"/> + <inputVariables> + <variable formalParameter="IN1"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="2"> + <position x="868" y="204"/> + <position x="843" y="204"/> + <position x="843" y="201"/> + <position x="817" y="201"/> + </connection> + </connectionPointIn> + </variable> + <variable formalParameter="IN2"> + <connectionPointIn> + <relPosition x="0" y="50"/> + <connection refLocalId="9" formalParameter="OUT"> + <position x="868" y="224"/> + <position x="765" y="224"/> + <position x="765" y="232"/> + <position x="712" y="232"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="67" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="9" width="116" height="40" typeName="INT_TO_STRING"> + <position x="596" y="202"/> + <inputVariables> + <variable formalParameter="IN"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="5" formalParameter="OUT"> + <position x="596" y="232"/> + <position x="573" y="232"/> + <position x="573" y="244"/> + <position x="550" y="244"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="116" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + <block localId="10" width="105" height="40" typeName="BOOL_TO_INT"> + <position x="344" y="200"/> + <inputVariables> + <variable formalParameter="IN" edge="rising"> + <connectionPointIn> + <relPosition x="0" y="30"/> + <connection refLocalId="3" formalParameter="OUT"> + <position x="344" y="230"/> + <position x="242" y="230"/> + <position x="242" y="163"/> + <position x="282" y="163"/> + <position x="282" y="94"/> + <position x="272" y="94"/> + </connection> + </connectionPointIn> + </variable> + </inputVariables> + <inOutVariables/> + <outputVariables> + <variable formalParameter="OUT"> + <connectionPointOut> + <relPosition x="105" y="30"/> + </connectionPointOut> + </variable> + </outputVariables> + </block> + </FBD> + </body> + </pou> + </pous> + </types> + <instances> + <configurations> + <configuration name="config"> + <resource name="resource1"> + <task name="blob" interval="T#1ms" priority="0"> + <pouInstance name="blub" typeName="program0"/> + </task> + </resource> + </configuration> + </configurations> + </instances> +</project>