--- 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.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.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") + 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) + to_console.insert(0, '#' + repr(msgidx) + ": " + msg) + #self.logger.write(repr(msgidx) + " : GetLogMessage returned None\n") + to_console.insert(0, 'No log before #'+repr(msgidx)) + self.logger.write("\n".join(to_console)) + self.previous_log_count = log_count def UpdateMethodsFromPLCStatus(self):
if self._connector is not None:
status, log_count = self._connector.GetPLCstatus()
+ self.UpdatePLCLog(log_count) @@ -1103,9 +1118,6 @@
self.previous_plcstate = status
- if(self.previous_log_count != log_count):
- self.logger.write("Now log count is %d"%log_count)
- self.previous_log_count = log_count
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)) + 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) + self._log_read_buffer[sz] = '\x00' + return self._log_read_buffer.value 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] 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 @@
+ self.LogMessage("Hello Log") if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
c_argv = ctypes.c_char_p * len(self.argv)
@@ -293,7 +322,7 @@
- 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.PLClibraryLock.release()
if offset and offset == size.value:
- return self.PLCStatus, self._GetLogCount(), tick.value, res
+ return self.PLCStatus, self.GetLogCount(), tick.value, res #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):
--- 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);
- 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;
- /* feeding cursor values */
- uint32_t curbuffpos = (uint32_t)cursor;
- uint32_t curmsgidx = (cursor >> 32);
- uint32_t stailpos = (curbuffpos - sizeof(mTail)) & LOG_BUFFER_MASK;
+ uint32_t stailpos = (uint32_t)cursor; - tail.msgidx = curmsgidx;
+ tail.msgidx = cursor >> 32; /* Message search loop */
+ 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); --- /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"> --- /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" + creationDateTime="2013-01-29T14:01:00"/> + <contentHeader name="Unnamed" + modificationDateTime="2013-01-29T15:56:10"> + <pou name="LOGGER" pouType="functionBlock"> + <variable name="TRIG0"> +<![CDATA[IF TRIG AND NOT TRIG0 THEN + LogMessage(GetFbVar(MSG, .body),GetFbVar(MSG, .len)); + <pou name="program0" pouType="program"> + <variable name="LOGGER0"> + <derived name="LOGGER"/> + <variable name="count"> + <block localId="1" width="65" height="71" typeName="LOGGER" instanceName="LOGGER0"> + <position x="1008" y="64"/> + <variable formalParameter="TRIG"> + <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"/> + <variable formalParameter="MSG"> + <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"/> + <inVariable localId="2" height="27" width="85"> + <position x="732" y="188"/> + <relPosition x="85" y="13"/> + <expression>'Moooooo'</expression> + <block localId="3" width="59" height="40" typeName="NOT"> + <position x="213" y="64"/> + <variable formalParameter="IN"> + <relPosition x="0" y="30"/> + <connection refLocalId="4"> + <position x="213" y="94"/> + <position x="179" y="94"/> + <variable formalParameter="OUT"> + <relPosition x="59" y="30"/> + <inOutVariable localId="4" height="27" width="41"> + <position x="138" y="81"/> + <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"/> + <relPosition x="41" y="13"/> + <expression>beat</expression> + <block localId="5" width="68" height="80" typeName="ADD"> + <position x="482" y="209"/> + <variable formalParameter="IN1"> + <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"/> + <variable formalParameter="IN2"> + <relPosition x="0" y="65"/> + <connection refLocalId="6"> + <position x="482" y="274"/> + <position x="397" y="274"/> + <variable formalParameter="OUT"> + <relPosition x="68" y="35"/> + <inOutVariable localId="6" height="27" width="48"> + <position x="349" y="261"/> + <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"/> + <relPosition x="48" y="13"/> + <expression>count</expression> + <block localId="8" width="67" height="60" typeName="CONCAT"> + <position x="868" y="174"/> + <variable formalParameter="IN1"> + <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"/> + <variable formalParameter="IN2"> + <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"/> + <variable formalParameter="OUT"> + <relPosition x="67" y="30"/> + <block localId="9" width="116" height="40" typeName="INT_TO_STRING"> + <position x="596" y="202"/> + <variable formalParameter="IN"> + <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"/> + <variable formalParameter="OUT"> + <relPosition x="116" y="30"/> + <block localId="10" width="105" height="40" typeName="BOOL_TO_INT"> + <position x="344" y="200"/> + <variable formalParameter="IN" edge="rising"> + <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"/> + <variable formalParameter="OUT"> + <relPosition x="105" y="30"/> + <configuration name="config"> + <resource name="resource1"> + <task name="blob" interval="T#1ms" priority="0"> + <pouInstance name="blub" typeName="program0"/>