Debug switch (file in CWD). LPC : better MD5 handling, Run button in boot mode, handling data feedback in boot protocol
--- a/Beremiz.py Thu Feb 03 18:23:24 2011 +0100
+++ b/Beremiz.py Thu Feb 17 10:11:04 2011 +0100
@@ -65,7 +65,12 @@
projectOpen = None
buildpath = None
- app = wx.PySimpleApp()
+ if os.path.exists("BEREMIZ_DEBUG"):
+ __builtins__.BMZ_DBG = True
+ else :
+ __builtins__.BMZ_DBG = False
+
+ app = wx.PySimpleApp(redirect=BMZ_DBG)
app.SetAppName('beremiz')
wx.InitAllImageHandlers()
--- a/LPCBeremiz.py Thu Feb 03 18:23:24 2011 +0100
+++ b/LPCBeremiz.py Thu Feb 17 10:11:04 2011 +0100
@@ -42,7 +42,12 @@
usage()
sys.exit()
-app = wx.PySimpleApp()
+ if os.path.exists("LPC_DEBUG"):
+ __builtins__.BMZ_DBG = True
+ else :
+ __builtins__.BMZ_DBG = False
+
+app = wx.PySimpleApp(redirect=BMZ_DBG)
app.SetAppName('beremiz')
wx.InitAllImageHandlers()
@@ -370,7 +375,7 @@
elif os.path.isfile(srcpath):
shutil.copy2(srcpath, dstpath)
-[SIMULATION_MODE, TRANSFER_MODE] = range(2)
+[SIMULATION_MODE, ONLINE_MODE] = range(2)
class LPCPluginsRoot(PluginsRoot):
@@ -489,19 +494,20 @@
if self.StatusTimer and not self.StatusTimer.IsRunning():
# Start the status Timer
- self.StatusTimer.Start(milliseconds=500, oneShot=False)
+ self.StatusTimer.Start(milliseconds=1000, oneShot=False)
if self.previous_plcstate=="Started":
if self.DebugAvailable() and self.GetIECProgramsAndVariables():
self.logger.write(_("Debug connect matching running PLC\n"))
- self._connect_debug()
+ #TODO re-enable
+ #self._connect_debug()
else:
self.logger.write_warning(_("Debug do not match PLC - stop/transfert/start to re-enable\n"))
elif self.StatusTimer and self.StatusTimer.IsRunning():
self.StatusTimer.Stop()
- if self.CurrentMode == TRANSFER_MODE:
+ if self.CurrentMode == ONLINE_MODE:
if self.OnlineMode == "BOOTLOADER":
self.BeginTransfer()
@@ -607,7 +613,7 @@
("_build", True),
("_Transfer", True)],
"Connected" : [("_Simulate", not simulating),
- ("_Run", False),
+ ("_Run", True),
("_Stop", simulating),
("_build", True),
("_Transfer", True)],
@@ -780,9 +786,16 @@
# warns controller that program match
self.ProgramTransferred()
+ def GetLastBuildMD5(self):
+ builder=self.GetBuilder()
+ if builder is not None:
+ return builder.GetBinaryCodeMD5(self.OnlineMode)
+ else:
+ return None
+
def _Transfer(self):
if self.CurrentMode is None and self.OnlineMode != "OFF":
- self.CurrentMode = TRANSFER_MODE
+ self.CurrentMode = ONLINE_MODE
PluginsRoot._build(self)
@@ -814,6 +827,19 @@
self.AbortTransferTimer = None
event.Skip()
+ def _Run(self):
+ """
+ Start PLC
+ """
+ if self.GetIECProgramsAndVariables():
+ self._connector.StartPLC()
+ self.logger.write(_("Starting PLC\n"))
+ #TODO re-enable
+ #self._connect_debug()
+ else:
+ self.logger.write_error(_("Couldn't start PLC !\n"))
+ self.UpdateMethodsFromPLCStatus()
+
#-------------------------------------------------------------------------------
# LPCBeremiz Class
#-------------------------------------------------------------------------------
@@ -1090,6 +1116,8 @@
if idx != -1:
line = self.Buffer[:idx+1]
self.Buffer = self.Buffer[idx+1:]
+ if BMZ_DBG:
+ print "command >"+line
return line
return ""
@@ -1132,8 +1160,8 @@
return eval_res
# Command log for debug, for viewing from wxInspector
- __builtins__.cmdlog = []
- #cmdlogf=open("bmzcmdlog.txt","w")
+ if BMZ_DBG:
+ __builtins__.cmdlog = []
class LPCBeremiz_Cmd(cmd.Cmd):
@@ -1421,19 +1449,13 @@
sys.stdout.flush()
return
- #cmdlogf.write(str((function,line))+'\n')
- #cmdlogf.flush()
-
func = getattr(self, function)
res = evaluator(func,*args)
- # Keep log for debug
- #cmdlogf.write("--->"+str(res)+'\n')
- #cmdlogf.flush()
-
- cmdlog.append((function,line,res))
- if len(cmdlog) > 100: #prevent debug log to grow too much
- cmdlog.pop(0)
+ if BMZ_DBG:
+ cmdlog.append((function,line,res))
+ if len(cmdlog) > 100: #prevent debug log to grow too much
+ cmdlog.pop(0)
if isinstance(res, (StringType, UnicodeType)):
self.Log.write(res)
--- a/connectors/LPC/LPCAppProto.py Thu Feb 03 18:23:24 2011 +0100
+++ b/connectors/LPC/LPCAppProto.py Thu Feb 17 10:11:04 2011 +0100
@@ -96,6 +96,7 @@
ExchangeData = LPCAppTransaction.GetData
if __name__ == "__main__":
+ __builtins__.BMZ_DBG = True
TestConnection = LPCAppProto(6,115200,2)
# TestConnection.HandleTransaction(GET_PLCIDTransaction())
TestConnection.HandleTransaction(STARTTransaction())
--- a/connectors/LPC/LPCBootObject.py Thu Feb 03 18:23:24 2011 +0100
+++ b/connectors/LPC/LPCBootObject.py Thu Feb 17 10:11:04 2011 +0100
@@ -37,12 +37,16 @@
self.HandleSerialTransaction(KEEPBOOTINGTransaction())
self.PLCStatus = "Stopped"
+ def StartPLC(self, debug=False):
+ self.HandleSerialTransaction(STARTTransaction())
+
def NewPLC(self, md5sum, data, extrafiles):
self.successfully_transfered = self.HandleSerialTransaction(LOADTransaction(data, self.PLCprint))
return self.successfully_transfered
def MatchMD5(self, MD5):
- return self.successfully_transfered
+ res = self.HandleSerialTransaction(CHECKMD5Transaction(MD5))
+ return "".join(res).find('FAILED') == -1
def SetTraceVariablesList(self, idxs):
--- a/connectors/LPC/LPCBootProto.py Thu Feb 03 18:23:24 2011 +0100
+++ b/connectors/LPC/LPCBootProto.py Thu Feb 17 10:11:04 2011 +0100
@@ -18,27 +18,31 @@
def SetPseudoFile(self, pseudofile):
self.pseudofile = pseudofile
- def SendData(self):
- res = self.pseudofile.write(self.OptData)
- return True
-
- def GetData(self):
- pass # not impl
-
def ExchangeData(self):
- pass
+ self.pseudofile.write(self.OptData)
+ return map(lambda x:self.pseudofile.readline(), xrange(self.expectedlines))
class KEEPBOOTINGTransaction(LPCBootTransaction):
def __init__(self):
+ self.expectedlines = 2
LPCBootTransaction.__init__(self, "md5\n")
- ExchangeData = LPCBootTransaction.SendData
+
+class STARTTransaction(LPCBootTransaction):
+ def __init__(self):
+ self.expectedlines = 0
+ LPCBootTransaction.__init__(self, "go\n")
+
+class CHECKMD5Transaction(LPCBootTransaction):
+ def __init__(self, md5ref):
+ self.expectedlines = 5
+ LPCBootTransaction.__init__(self, md5ref+"md5\n")
class LOADTransaction(LPCBootTransaction):
def __init__(self, data, PLCprint):
self.PLCprint = PLCprint
LPCBootTransaction.__init__(self, data)
- def sendDataHook(self):
+ def ExchangeData(self):
#file("fw.bin","w").write(self.OptData)
data = self.OptData
loptdata = len(self.OptData)
@@ -54,9 +58,9 @@
self.PLCprint(".")
self.PLCprint("\n")
return True
- ExchangeData = sendDataHook
if __name__ == "__main__":
+ __builtins__.BMZ_DBG = True
TestConnection = LPCBootProto(2,115200,1200)
mystr=file("fw.bin").read()
def mylog(blah):
--- a/connectors/LPC/LPCProto.py Thu Feb 03 18:23:24 2011 +0100
+++ b/connectors/LPC/LPCProto.py Thu Feb 17 10:11:04 2011 +0100
@@ -1,6 +1,7 @@
import serial
import exceptions
from threading import Lock
+import time
class LPCProtoError(exceptions.Exception):
"""Exception class"""
@@ -14,29 +15,45 @@
def __init__(self, port, rate, timeout):
# serialize access lock
self.TransactionLock = Lock()
- # open serial port
-# self.serialPort = serial.Serial( port, rate, timeout = timeout )
- # Debugging serial stuff
- self.serialPort = serial.Serial( port, rate, timeout = timeout )
-# class myser:
-# def read(self_,cnt):
-# res = self._serialPort.read(cnt)
-# if len(res) > 16:
-# print "Recv :", map(hex,map(ord,res[:16])), "[...]"
-# else:
-# print "Recv :", map(hex,map(ord,res))
-#
-# return res
-# def write(self_, str):
-# if len(str) > 16:
-# print "Send :", map(hex,map(ord,str[:16])), "[...]"
-# else:
-# print "Send :", map(hex,map(ord,str))
-# self._serialPort.write(str)
-# def flush(self_):
-# self._serialPort.flush()
-# self.serialPort = myser()
- # start with empty
+ if BMZ_DBG:
+ # Debugging serial stuff
+ self._serialPort = serial.Serial( port, rate, timeout = timeout, writeTimeout = timeout )
+ class myser:
+ def readline(self_):
+ res = self._serialPort.readline()
+ print 'Recv :"', res, '"'
+ return res
+
+ def read(self_,cnt):
+ res = self._serialPort.read(cnt)
+ if len(res) > 16:
+ print "Recv :", map(hex,map(ord,res[:16])), "[...]"
+ else:
+ print "Recv :", map(hex,map(ord,res))
+
+ return res
+ def write(self_, string):
+ lstr=len(string)
+ if lstr > 16:
+ print "Send :", map(hex,map(ord,string[:16])), "[...]"
+ else:
+ print "Send :", map(hex,map(ord,string))
+ return self._serialPort.write(string)
+ # while len(string)>0:
+ # i = self._serialPort.write(string[:4096])
+ # print ".",
+ # string = string[i:]
+ # print
+ #return lstr
+ def flush(self_):
+ return self._serialPort.flush()
+ def close(self_):
+ self._serialPort.close()
+ self.serialPort = myser()
+ else:
+ # open serial port
+ self.serialPort = serial.Serial( port, rate, timeout = timeout )
+ # start with empty buffer
self.serialPort.flush()
def __del__(self):
--- a/targets/LPC/__init__.py Thu Feb 03 18:23:24 2011 +0100
+++ b/targets/LPC/__init__.py Thu Feb 17 10:11:04 2011 +0100
@@ -1,22 +1,56 @@
-import os
-from subprocess import Popen,PIPE
-from .. import toolchain_makefile
-import hashlib
-
-class LPC_target(toolchain_makefile):
- extension = ".ld"
- DebugEnabled = False
-
- def GetBinaryCode(self):
- """Returns ready to send signed + sized intel formated hex program"""
- try:
- size = int(Popen(
- ['arm-elf-size','-B',os.path.join(self.buildpath,"ArmPLC_rom.elf")],
- stdout=PIPE).communicate()[0].splitlines()[1].split()[0])
- res = "&" + hashlib.md5(open(os.path.join(self.buildpath, "ArmPLC_rom.bin"), "rb").read(size)).hexdigest() + '\n' +\
- "$" + str(size) + '\n' +\
- open(os.path.join(self.buildpath, "ArmPLC_rom.hex"), "r").read()
- return res
- except Exception, e:
- return None
-
+import os
+from subprocess import Popen,PIPE
+from .. import toolchain_makefile
+import hashlib
+
+class LPC_target(toolchain_makefile):
+ #extension = ".ld"
+ #DebugEnabled = False
+ def __init__(self, PluginsRootInstance):
+ self.binmd5key = None
+ toolchain_makefile.__init__(self, PluginsRootInstance)
+
+ def _GetBinMD5FileName(self):
+ return os.path.join(self.buildpath, "lastbuildPLCbin.md5")
+
+ def _get_md5_header(self):
+ """Returns signature header"""
+ size = int(Popen(
+ ['arm-elf-size','-B',os.path.join(self.buildpath,"ArmPLC_rom.elf")],
+ stdout=PIPE).communicate()[0].splitlines()[1].split()[0])
+ res = "&" + hashlib.md5(open(os.path.join(self.buildpath, "ArmPLC_rom.bin"), "rb").read(size)).hexdigest() + '\n' +\
+ "$" + str(size) + '\n'
+ return res
+
+ def GetBinaryCode(self):
+ """Returns ready to send signed + sized intel formated hex program"""
+ try:
+ res = self._get_md5_header() +\
+ open(os.path.join(self.buildpath, "ArmPLC_rom.hex"), "r").read()
+ return res
+ except Exception, e:
+ return None
+
+ def _get_cached_md5_header(self):
+ if self.binmd5key is not None:
+ return self.binmd5key
+ else:
+ try:
+ return open(self._GetMD5FileName(), "r").read()
+ except IOError, e:
+ return None
+
+ def GetBinaryCodeMD5(self, mode):
+ if mode == "BOOTLOADER":
+ return self._get_cached_md5_header()
+ else:
+ return toolchain_makefile.GetBinaryCodeMD5(self)
+
+ def build(self):
+ res = toolchain_makefile.build(self)
+ self.binmd5key = self._get_md5_header()
+ f = open(self._GetBinMD5FileName(), "w")
+ f.write(self.binmd5key)
+ f.close()
+ return res
+
--- a/targets/toolchain_makefile.py Thu Feb 03 18:23:24 2011 +0100
+++ b/targets/toolchain_makefile.py Thu Feb 17 10:11:04 2011 +0100
@@ -1,74 +1,74 @@
-import os, re
-from wxPopen import ProcessLogger
-import hashlib
-
-import time
-
-includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*')
-
-class toolchain_makefile():
- def __init__(self, PluginsRootInstance):
- self.PluginsRootInstance = PluginsRootInstance
- self.md5key = None
- self.buildpath = None
- self.SetBuildPath(self.PluginsRootInstance._getBuildPath())
-
- def SetBuildPath(self, buildpath):
- self.buildpath = buildpath
-
- def GetBinaryCode(self):
- return None
-
- def _GetMD5FileName(self):
- return os.path.join(self.buildpath, "lastbuildPLC.md5")
-
- def GetBinaryCodeMD5(self):
- if self.md5key is not None:
- return self.md5key
- else:
- try:
- return open(self._GetMD5FileName(), "r").read()
- except Exception, e:
- return None
-
- def build(self):
- srcfiles= []
- cflags = []
- for Location, CFilesAndCFLAGS, DoCalls in self.PluginsRootInstance.LocationCFilesAndCFLAGS:
- wholesrcdata = ""
- # Get CFiles list to give it to makefile
- for CFile, CFLAGS in CFilesAndCFLAGS:
- CFileName = os.path.basename(CFile)
- wholesrcdata += open(CFile, "r").read()
- srcfiles.append(CFileName)
- if CFLAGS not in cflags:
- cflags.append(CFLAGS)
-
- self.md5key = hashlib.md5(wholesrcdata).hexdigest()
- props = self.PluginsRootInstance.GetProjectProperties()
- self.md5key += '#'.join([props[key] for key in ['companyName',
- 'projectName',
- 'productName']])
- self.md5key += '#'+','.join(map(str,time.localtime()))
- # Store new PLC filename based on md5 key
- f = open(self._GetMD5FileName(), "w")
- f.write(self.md5key)
- f.close()
- beremizcommand = {"src": ' '.join(srcfiles),
- "cflags": ' '.join(cflags),
- "md5": '"'+self.md5key+'"'
- }
-
- target = self.PluginsRootInstance.GetTarget().getcontent()["value"]
- command = target.getCommand().split(' ') +\
- [target.getBuildPath()] +\
- [arg % beremizcommand for arg in target.getArguments().split(' ')] +\
- target.getRule().split(' ')
-
- # Call Makefile to build PLC code and link it with target specific code
- status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger,
- command).spin()
- if status :
- self.PluginsRootInstance.logger.write_error(_("C compilation of %s failed.\n"))
- return False
- return True
+import os, re
+from wxPopen import ProcessLogger
+import hashlib
+
+import time
+
+includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*')
+
+class toolchain_makefile():
+ def __init__(self, PluginsRootInstance):
+ self.PluginsRootInstance = PluginsRootInstance
+ self.md5key = None
+ self.buildpath = None
+ self.SetBuildPath(self.PluginsRootInstance._getBuildPath())
+
+ def SetBuildPath(self, buildpath):
+ self.buildpath = buildpath
+
+ def GetBinaryCode(self):
+ return None
+
+ def _GetMD5FileName(self):
+ return os.path.join(self.buildpath, "lastbuildPLC.md5")
+
+ def GetBinaryCodeMD5(self):
+ if self.md5key is not None:
+ return self.md5key
+ else:
+ try:
+ return open(self._GetMD5FileName(), "r").read()
+ except IOError, e:
+ return None
+
+ def build(self):
+ srcfiles= []
+ cflags = []
+ for Location, CFilesAndCFLAGS, DoCalls in self.PluginsRootInstance.LocationCFilesAndCFLAGS:
+ wholesrcdata = ""
+ # Get CFiles list to give it to makefile
+ for CFile, CFLAGS in CFilesAndCFLAGS:
+ CFileName = os.path.basename(CFile)
+ wholesrcdata += open(CFile, "r").read()
+ srcfiles.append(CFileName)
+ if CFLAGS not in cflags:
+ cflags.append(CFLAGS)
+
+ self.md5key = hashlib.md5(wholesrcdata).hexdigest()
+ props = self.PluginsRootInstance.GetProjectProperties()
+ self.md5key += '#'.join([props[key] for key in ['companyName',
+ 'projectName',
+ 'productName']])
+ self.md5key += '#' #+','.join(map(str,time.localtime()))
+ # Store new PLC filename based on md5 key
+ f = open(self._GetMD5FileName(), "w")
+ f.write(self.md5key)
+ f.close()
+ beremizcommand = {"src": ' '.join(srcfiles),
+ "cflags": ' '.join(cflags),
+ "md5": '"'+self.md5key+'"'
+ }
+
+ target = self.PluginsRootInstance.GetTarget().getcontent()["value"]
+ command = target.getCommand().split(' ') +\
+ [target.getBuildPath()] +\
+ [arg % beremizcommand for arg in target.getArguments().split(' ')] +\
+ target.getRule().split(' ')
+
+ # Call Makefile to build PLC code and link it with target specific code
+ status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger,
+ command).spin()
+ if status :
+ self.PluginsRootInstance.logger.write_error(_("C compilation of %s failed.\n"))
+ return False
+ return True