Log redirected to console, dump of all available log to console when connecting to PLC
--- 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):
--- 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:
--- 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;
}
}
--- /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>
--- /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>