115 |
115 |
116 def PlugImport(self, src_PlugPath): |
116 def PlugImport(self, src_PlugPath): |
117 shutil.copytree(src_PlugPath, self.PlugPath) |
117 shutil.copytree(src_PlugPath, self.PlugPath) |
118 return True |
118 return True |
119 |
119 |
120 def PlugGenerate_C(self, buildpath, current_location, locations): |
120 def PlugGenerate_C(self, buildpath, current_location, locations, logger): |
121 """ |
121 """ |
122 Generate C code |
122 Generate C code |
123 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
123 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
124 @param locations: List of complete variables locations \ |
124 @param locations: List of complete variables locations \ |
125 [(IEC_loc, IEC_Direction, IEC_Type, Name)]\ |
125 [(IEC_loc, IEC_Direction, IEC_Type, Name)]\ |
126 ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...] |
126 ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...] |
127 """ |
127 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
|
128 """ |
|
129 logger.write_warning(".".join(map(lambda x:str(x), current_location)) + " -> Nothing yo do") |
128 return [],"" |
130 return [],"" |
129 |
131 |
130 def _Generate_C(self, buildpath, current_location, locations): |
132 def _Generate_C(self, buildpath, current_location, locations, logger): |
131 # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS |
133 # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS |
132 PlugCFilesAndCFLAGS, PlugLDFLAGS = self.PlugGenerate_C(buildpath, current_location, locations) |
134 PlugCFilesAndCFLAGS, PlugLDFLAGS = self.PlugGenerate_C(buildpath, current_location, locations, logger) |
133 # recurse through all childs, and stack their results |
135 # recurse through all childs, and stack their results |
134 for PlugChild in self.IterChilds(): |
136 for PlugChild in self.IterChilds(): |
135 # Compute chile IEC location |
137 # Compute child's IEC location |
136 new_location = current_location + (self.BaseParams.getIEC_Channel()) |
138 new_location = current_location + (self.BaseParams.getIEC_Channel()) |
137 # Get childs [(Cfiles, CFLAGS)], LDFLAGS |
139 # Get childs [(Cfiles, CFLAGS)], LDFLAGS |
138 CFilesAndCFLAGS, LDFLAGS = \ |
140 CFilesAndCFLAGS, LDFLAGS = \ |
139 PlugChild._Generate_C( |
141 PlugChild._Generate_C( |
140 #keep the same path |
142 #keep the same path |
141 buildpath, |
143 buildpath, |
142 # but update location (add curent IEC channel at the end) |
144 # but update location (add curent IEC channel at the end) |
143 new_location, |
145 new_location, |
144 # filter locations that start with current IEC location |
146 # filter locations that start with current IEC location |
145 [ (l,d,t,n) for l,d,t,n in locations if l[0:len(new_location)] == new_location ]) |
147 [ (l,d,t,n) for l,d,t,n in locations if l[0:len(new_location)] == new_location ], |
|
148 #propagete logger |
|
149 logger) |
146 # stack the result |
150 # stack the result |
147 PlugCFilesAndCFLAGS += CFilesAndCFLAGS |
151 PlugCFilesAndCFLAGS += CFilesAndCFLAGS |
148 PlugLDFLAGS += LDFLAGS |
152 PlugLDFLAGS += LDFLAGS |
149 |
153 |
150 return PlugCFilesAndCFLAGS,PlugLDFLAGS |
154 return PlugCFilesAndCFLAGS,PlugLDFLAGS |
517 def PluginBaseXmlFilePath(self, PlugName=None): |
521 def PluginBaseXmlFilePath(self, PlugName=None): |
518 return None |
522 return None |
519 |
523 |
520 def PluginXmlFilePath(self, PlugName=None): |
524 def PluginXmlFilePath(self, PlugName=None): |
521 return os.path.join(self.PlugPath(PlugName), "beremiz.xml") |
525 return os.path.join(self.PlugPath(PlugName), "beremiz.xml") |
|
526 |
|
527 def PlugGenerate_C(self, buildpath, current_location, locations, logger): |
|
528 """ |
|
529 Generate C code |
|
530 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
|
531 @param locations: List of complete variables locations \ |
|
532 [(IEC_loc, IEC_Direction, IEC_Type, Name)]\ |
|
533 ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...] |
|
534 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
|
535 """ |
|
536 return [(C_file_name, "") for C_file_name in self.PLCGeneratedCFiles ] , "" |
|
537 |
|
538 def _Generate_SoftPLC(self, buildpath, logger): |
|
539 |
|
540 LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWD]))?,(?P<LOC>[,0-9]*)\)") |
|
541 |
|
542 if self.PLCManager: |
|
543 logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n") |
|
544 plc_file = os.path.join(self.TargetDir, "plc.st") |
|
545 result = self.PLCManager.GenerateProgram(plc_file) |
|
546 if not result: |
|
547 logger.write_error("Error : ST/IL/SFC code generator returned %d"%result) |
|
548 return False |
|
549 logger.write("Compiling ST Program in to C Program...\n") |
|
550 status, result, err_result = self.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, self.TargetDir)) |
|
551 if status: |
|
552 new_dialog = wx.Frame(None) |
|
553 ST_viewer = TextViewer(new_dialog, None, None) |
|
554 #ST_viewer.Enable(False) |
|
555 ST_viewer.SetKeywords(IEC_KEYWORDS) |
|
556 ST_viewer.SetText(file(plc_file).read()) |
|
557 new_dialog.Show() |
|
558 raise Exception, "Error : IEC to C compiler returned %d"%status |
|
559 C_files = result.splitlines() |
|
560 C_files.remove("POUS.c") |
|
561 C_files = map(lambda filename:os.path.join(self.TargetDir, filename), C_files) |
|
562 logger.write("Extracting Located Variables...\n") |
|
563 location_file = open(os.path.join(self.TargetDir,"LOCATED_VARIABLES.h")) |
|
564 locations = [] |
|
565 lines = [line.strip() for line in location_file.readlines()] |
|
566 for line in lines: |
|
567 result = LOCATED_MODEL.match(line) |
|
568 if result: |
|
569 resdict = result.groupdict() |
|
570 # rewrite location as a tuple of integers |
|
571 resdict['LOC'] = tuple(map(int,resdict['LOC'].split(','))) |
|
572 if not resdict['SIZE']: |
|
573 resdict['SIZE'] = 'X' |
|
574 locations.append(resdict) |
|
575 self.PLCGeneratedCFiles = C_files |
|
576 self.PLCGeneratedLocatedVars = locations |
|
577 return True |
|
578 |
|
579 def _build(self, logger): |
|
580 buildpath = os.path.join(self.ProjectPath, "build") |
|
581 if not os.path.exists(buildpath): |
|
582 os.mkdir(buildpath) |
|
583 |
|
584 logger.write("Start build in %s" % buildpath) |
|
585 |
|
586 if not self._Generate_SoftPLC(buildpath, logger): |
|
587 logger.write("SoftPLC code generation failed !") |
|
588 return |
|
589 |
|
590 logger.write("SoftPLC code generation successfull") |
|
591 |
|
592 try: |
|
593 CFilesAndCFLAGS, LDFLAGS = self._Generate_C( |
|
594 buildpath, |
|
595 (), |
|
596 self.PLCGeneratedLocatedVars, |
|
597 logger) |
|
598 except Exception, msg: |
|
599 logger.write_error("Plugins code generation Failed !") |
|
600 logger.write_error(str(msg)) |
|
601 return |
|
602 |
|
603 logger.write_error("Plugins code generation successfull") |
|
604 |
|
605 for CFile, CFLAG in CFilesAndCFLAGS: |
|
606 print CFile,CFLAG |
|
607 |
|
608 LDFLAGS |
|
609 |
|
610 PluginMethods = [("Build",_build), ("Clean",None), ("Run",None), ("EditPLC",None), ("Simulate",None)] |
|
611 |