# HG changeset patch
# User Edouard Tisserant
# Date 1359532452 -39600
# Node ID 401e44bae7c073e8d3ccb46895883fe45426d1e4
# Parent 697d8b77d7163fe80753e5761d294befde19bb9d
Now logging have 4 levels
diff -r 697d8b77d716 -r 401e44bae7c0 ProjectController.py
--- a/ProjectController.py Tue Jan 29 23:41:00 2013 +0100
+++ b/ProjectController.py Wed Jan 30 18:54:12 2013 +1100
@@ -25,7 +25,7 @@
from dialogs import DiscoveryDialog
from PLCControler import PLCControler
from plcopen.structures import IEC_KEYWORDS
-from targets.typemapping import DebugTypesSize
+from targets.typemapping import DebugTypesSize, LogLevelsCount, LogLevels
from ConfigTreeNode import ConfigTreeNode
base_folder = os.path.split(sys.path[0])[0]
@@ -113,7 +113,7 @@
self.DebugThread = None
self.debug_break = False
self.previous_plcstate = None
- self.previous_log_count = None
+ self.previous_log_count = [None]*LogLevelsCount
# copy ConfNodeMethods so that it can be later customized
self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
@@ -1077,24 +1077,26 @@
self.CompareLocalAndRemotePLC()
def UpdatePLCLog(self, log_count):
- if log_count and self.previous_log_count != log_count:
- # XXX replace dump to console with dedicated log panel.
- to_console = ['']
- dump_end = max( # request message sent after the last one we already got
- self.previous_log_count - 1 if self.previous_log_count is not None else -1,
- log_count - 100) # 100 is purely arbitrary number
- # dedicated panel should only ask for a small range,
- # depending on how user navigate in the panel
- # and only ask for last one in follow mode
- for msgidx in xrange(log_count-1, dump_end,-1):
- msg = self._connector.GetLogMessage(msgidx)
- if msg is not None :
- to_console.insert(0, '#' + repr(msgidx) + ": " + msg)
- else:
- to_console.insert(0, 'No log before #'+repr(msgidx))
- break;
- self.logger.write("\n".join(to_console))
- self.previous_log_count = log_count
+ if log_count :
+ for level, count, prev in zip(xrange(LogLevelsCount), log_count,self.previous_log_count):
+ if count is not None and prev != count:
+ # XXX replace dump to console with dedicated log panel.
+ to_console = ['']
+ dump_end = max( # request message sent after the last one we already got
+ prev - 1 if prev is not None else -1,
+ count - 100) # 100 is purely arbitrary number
+ # dedicated panel should only ask for a small range,
+ # depending on how user navigate in the panel
+ # and only ask for last one in follow mode
+ for msgidx in xrange(count-1, dump_end,-1):
+ msg = self._connector.GetLogMessage(level, msgidx)
+ if msg is not None :
+ to_console.insert(0, LogLevels[level]+ ':#' + repr(msgidx) + ": " + msg)
+ else:
+ to_console.insert(0, LogLevels[level]+ ': No log before #'+repr(msgidx))
+ break;
+ self.logger.write("\n".join(to_console))
+ self.previous_log_count[level] = count
def UpdateMethodsFromPLCStatus(self):
status = None
@@ -1289,7 +1291,7 @@
while (not self.debug_break) and (self._connector is not None):
Trace = self._connector.GetTraceVariables()
if(Trace):
- plc_status, log_count, debug_tick, debug_vars = Trace
+ plc_status, debug_tick, debug_vars = Trace
else:
plc_status = None
debug_getvar_retry += 1
@@ -1331,7 +1333,7 @@
def _connect_debug(self):
self.previous_plcstate = None
- self.previous_log_count = None
+ self.previous_log_count = [None]*LogLevelsCount
if self.AppFrame:
self.AppFrame.ResetGraphicViewers()
self.RegisterDebugVarToConnector()
@@ -1511,7 +1513,7 @@
else:
self.logger.write_error(_("No PLC to transfer (did build succeed ?)\n"))
- self.previous_log_count = None
+ self.previous_log_count = [None]*LogLevelsCount
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
diff -r 697d8b77d716 -r 401e44bae7c0 connectors/PYRO/__init__.py
--- a/connectors/PYRO/__init__.py Tue Jan 29 23:41:00 2013 +0100
+++ b/connectors/PYRO/__init__.py Wed Jan 30 18:54:12 2013 +1100
@@ -140,7 +140,7 @@
if self.RemotePLCObjectProxyCopy is None:
self.RemotePLCObjectProxyCopy = copy.copy(confnodesroot._connector.GetPyroProxy())
return self.RemotePLCObjectProxyCopy.GetTraceVariables()
- GetTraceVariables = PyroCatcher(_PyroGetTraceVariables,("Broken",-1,None,None))
+ GetTraceVariables = PyroCatcher(_PyroGetTraceVariables,("Broken",None,None))
def _PyroGetPLCstatus(self):
return RemotePLCObjectProxy.GetPLCstatus()
diff -r 697d8b77d716 -r 401e44bae7c0 runtime/PLCObject.py
--- a/runtime/PLCObject.py Tue Jan 29 23:41:00 2013 +0100
+++ b/runtime/PLCObject.py Wed Jan 30 18:54:12 2013 +1100
@@ -25,7 +25,8 @@
import Pyro.core as pyro
from threading import Timer, Thread, Lock, Semaphore
import ctypes, os, commands, types, sys
-from targets.typemapping import SameEndianessTypeTranslator as TypeTranslator
+from targets.typemapping import LogLevelsDefault, LogLevelsCount, SameEndianessTypeTranslator as TypeTranslator
+
if os.name in ("nt", "ce"):
from _ctypes import LoadLibrary as dlopen
@@ -80,25 +81,29 @@
if self.statuschange is not None:
self.statuschange(self.PLCStatus)
- def LogMessage(self, msg):
- return self._LogMessage(msg, len(msg))
-
-
- def GetLogCount(self):
+ def LogMessage(self, *args):
+ if len(args) == 2:
+ level, msg = args
+ else:
+ level = LogLevelsDefault
+ msg, = args
+ return self._LogMessage(level, msg, len(msg))
+
+
+ def GetLogCount(self, level):
if self._GetLogCount is not None :
- return int(self._GetLogCount())
- elif self._loading_error is not None:
+ return int(self._GetLogCount(level))
+ elif self._loading_error is not None and level==0:
return 1;
-
- def GetLogMessage(self, msgid):
+ def GetLogMessage(self, level, msgid):
if self._GetLogMessage is not None:
maxsz = len(self._log_read_buffer)-1
- sz = self._GetLogMessage(msgid, self._log_read_buffer, maxsz)
+ sz = self._GetLogMessage(level, msgid, self._log_read_buffer, maxsz)
if sz and sz <= maxsz:
self._log_read_buffer[sz] = '\x00'
return self._log_read_buffer.value
- elif self._loading_error is not None :
+ elif self._loading_error is not None and level==0:
return self._loading_error
return None
@@ -171,15 +176,16 @@
self._GetLogCount = self.PLClibraryHandle.GetLogCount
self._GetLogCount.restype = ctypes.c_uint32
+ self._GetLogCount.argtypes = [ctypes.c_uint8]
self._LogMessage = self.PLClibraryHandle.LogMessage
self._LogMessage.restype = ctypes.c_int
- self._LogMessage.argtypes = [ctypes.c_char_p, ctypes.c_uint32]
+ self._LogMessage.argtypes = [ctypes.c_uint8, 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]
+ self._GetLogMessage.argtypes = [ctypes.c_uint8, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32]
self._loading_error = None
return True
@@ -206,7 +212,7 @@
self._resumeDebug = lambda:None
self._PythonIterator = lambda:""
self._GetLogCount = None
- self._LogMessage = lambda m,s:PLCprint("OFF LOG :"+m)
+ self._LogMessage = lambda l,m,s:PLCprint("OFF LOG :"+m)
self._GetLogMessage = None
self.PLClibraryHandle = None
# Unload library explicitely
@@ -293,8 +299,6 @@
self.evaluator(self.FinishRuntimePy)
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
@@ -304,14 +308,15 @@
self.PythonThread = Thread(target=self.PythonThreadProc)
self.PythonThread.start()
self.StartSem.acquire()
+ self.LogMessage("PLC started")
else:
- PLCprint(_("Problem starting PLC : error %d" % res))
+ self.LogMessage(_("Problem starting PLC : error %d" % res))
self.PLCStatus = "Broken"
self.StatusChange()
def StopPLC(self):
- PLCprint("StopPLC")
if self.PLCStatus == "Started":
+ self.LogMessage("PLC stopped")
self._stopPLC()
self.PythonThread.join()
return True
@@ -330,10 +335,10 @@
return True
def GetPLCstatus(self):
- return self.PLCStatus, self.GetLogCount()
+ return self.PLCStatus, map(self.GetLogCount,xrange(LogLevelsCount))
def NewPLC(self, md5sum, data, extrafiles):
- PLCprint("NewPLC (%s)"%md5sum)
+ self.LogMessage("NewPLC (%s)"%md5sum)
if self.PLCStatus in ["Stopped", "Empty", "Broken"]:
NewFileName = md5sum + lib_ext
extra_files_log = os.path.join(self.workingdir,"extra_files.txt")
@@ -451,10 +456,10 @@
self._FreeDebugData()
self.PLClibraryLock.release()
if offset and offset == size.value:
- return self.PLCStatus, self.GetLogCount(), tick.value, res
+ return self.PLCStatus, 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, None, []
def RemoteExec(self, script, **kwargs):
try:
diff -r 697d8b77d716 -r 401e44bae7c0 targets/plc_debug.c
--- a/targets/plc_debug.c Tue Jan 29 23:41:00 2013 +0100
+++ b/targets/plc_debug.c Wed Jan 30 18:54:12 2013 +1100
@@ -306,25 +306,31 @@
/* LOGGING
*/
+#define LOG_LEVELS 4
+#define LOG_CRITICAL 0
+#define LOG_WARNING 1
+#define LOG_INFO 2
+#define LOG_DEBUG 4
+
#define LOG_BUFFER_SIZE (1<<14) /*16Ko*/
#define LOG_BUFFER_MASK (LOG_BUFFER_SIZE-1)
-static char LogBuff[LOG_BUFFER_SIZE];
-void inline copy_to_log(uint32_t buffpos, void* buf, uint32_t size){
+static char LogBuff[LOG_LEVELS][LOG_BUFFER_SIZE];
+void inline copy_to_log(uint8_t level, uint32_t buffpos, void* buf, uint32_t size){
if(buffpos + size < LOG_BUFFER_SIZE){
- memcpy(&LogBuff[buffpos], buf, size);
+ memcpy(&LogBuff[level][buffpos], buf, size);
}else{
uint32_t remaining = LOG_BUFFER_SIZE - buffpos - 1;
- memcpy(&LogBuff[buffpos], buf, remaining);
- memcpy(LogBuff, buf + remaining, size - remaining);
- }
-}
-void inline copy_from_log(uint32_t buffpos, void* buf, uint32_t size){
+ memcpy(&LogBuff[level][buffpos], buf, remaining);
+ memcpy(LogBuff[level], buf + remaining, size - remaining);
+ }
+}
+void inline copy_from_log(uint8_t level, uint32_t buffpos, void* buf, uint32_t size){
if(buffpos + size < LOG_BUFFER_SIZE){
- memcpy(buf, &LogBuff[buffpos], size);
+ memcpy(buf, &LogBuff[level][buffpos], size);
}else{
uint32_t remaining = LOG_BUFFER_SIZE - buffpos;
- memcpy(buf, &LogBuff[buffpos], remaining);
- memcpy(buf + remaining, LogBuff, size - remaining);
+ memcpy(buf, &LogBuff[level][buffpos], remaining);
+ memcpy(buf + remaining, LogBuff[level], size - remaining);
}
}
@@ -345,10 +351,10 @@
|63 ... 32|31 ... 0|
| Message | Buffer |
| counter | Index | */
-static uint64_t LogCursor = 0x0;
+static uint64_t LogCursor[LOG_LEVELS] = {0x0,0x0,0x0,0x0};
/* Store one log message of give size */
-int LogMessage(char* buf, uint32_t size){
+int LogMessage(uint8_t level, char* buf, uint32_t size){
if(size < LOG_BUFFER_SIZE - sizeof(mTail)){
uint32_t buffpos;
mTail tail;
@@ -358,34 +364,34 @@
succeeds non interrupted */
uint64_t new_cursor, old_cursor;
do{
- old_cursor = LogCursor;
+ old_cursor = LogCursor[level];
buffpos = (uint32_t)old_cursor;
tail.msgidx = (old_cursor >> 32);
new_cursor = ((uint64_t)(tail.msgidx + 1)<<32)
| (uint64_t)((buffpos + size + sizeof(mTail)) & LOG_BUFFER_MASK);
- }while(!__sync_bool_compare_and_swap(&LogCursor,old_cursor,new_cursor));
-
- copy_to_log(buffpos, buf, size);
+ }while(!__sync_bool_compare_and_swap(&LogCursor[level],old_cursor,new_cursor));
+
+ copy_to_log(level, buffpos, buf, size);
tail.msgsize = size;
/*XXX tick*/
/*XXX RTC*/
- copy_to_log((buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
+ copy_to_log(level, (buffpos + size) & LOG_BUFFER_MASK, &tail, sizeof(mTail));
return 1; /* Success */
}else{
char mstr[] = "Logging error : message too big";
- LogMessage(mstr, sizeof(mstr));
+ LogMessage(LOG_CRITICAL, mstr, sizeof(mstr));
}
return 0;
}
-uint32_t GetLogCount(){
- return (uint64_t)LogCursor >> 32;
+uint32_t GetLogCount(uint8_t level){
+ return (uint64_t)LogCursor[level] >> 32;
}
/* Return message size and content */
-uint32_t GetLogMessage(uint32_t msgidx, char* buf, uint32_t max_size){
- uint64_t cursor = LogCursor;
+uint32_t GetLogMessage(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size){
+ uint64_t cursor = LogCursor[level];
if(cursor){
/* seach cursor */
uint32_t stailpos = (uint32_t)cursor;
@@ -398,13 +404,13 @@
do {
smsgidx = tail.msgidx;
stailpos = (stailpos - sizeof(mTail) - tail.msgsize ) & LOG_BUFFER_MASK;
- copy_from_log(stailpos, &tail, sizeof(mTail));
+ copy_from_log(level, stailpos, &tail, sizeof(mTail));
}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(sbuffpos, buf, totalsize > max_size ? max_size : totalsize);
+ copy_from_log(level, sbuffpos, buf, totalsize > max_size ? max_size : totalsize);
return totalsize;
}
}
diff -r 697d8b77d716 -r 401e44bae7c0 targets/typemapping.py
--- a/targets/typemapping.py Tue Jan 29 23:41:00 2013 +0100
+++ b/targets/typemapping.py Wed Jan 30 18:54:12 2013 +1100
@@ -76,3 +76,7 @@
# Construct debugger natively supported types
DebugTypesSize = dict([(key,sizeof(t)) for key,(t,p,u) in SameEndianessTypeTranslator.iteritems() if t is not None])
+LogLevels = ["CRITICAL","WARNING","INFO","DEBUG"]
+LogLevelsCount = len(LogLevels)
+LogLevelsDict = dict(zip(LogLevels,range(LogLevelsCount)))
+LogLevelsDefault = LogLevelsDict["DEBUG"]
diff -r 697d8b77d716 -r 401e44bae7c0 tests/logging/plc.xml
--- a/tests/logging/plc.xml Tue Jan 29 23:41:00 2013 +0100
+++ b/tests/logging/plc.xml Wed Jan 30 18:54:12 2013 +1100
@@ -8,7 +8,7 @@
productVersion="1"
creationDateTime="2013-01-29T14:01:00"/>
+ modificationDateTime="2013-01-30T18:24:53">
@@ -22,7 +22,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -37,6 +53,14 @@
+
+
+
+
+
+
+
+
@@ -50,7 +74,7 @@
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -292,6 +287,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+