# HG changeset patch # User etisserant # Date 1190389714 -7200 # Node ID 45dc6a944ab6ff16805586fdf3a869f6c2219c4f # Parent 6b30cfee163e2ff9f4db1107728439d727d6e763 On the long wat towards generated code comilation... diff -r 6b30cfee163e -r 45dc6a944ab6 Beremiz.py --- a/Beremiz.py Thu Sep 20 17:32:52 2007 +0200 +++ b/Beremiz.py Fri Sep 21 17:48:34 2007 +0200 @@ -88,7 +88,8 @@ def fin(pid,ecode): self.exitcode = ecode if self.exitcode != 0: - self.write("pid %d exited with status %d\n"%(pid,ecode)) + self.write(Command + "\n") + self.write_warning("exited with status %d (pid %d)\n"%(ecode,pid)) def spin(p): while not p.finished: @@ -326,7 +327,7 @@ if projectOpen: self.PluginRoot.LoadProject(projectOpen, self.Log) self.RefreshPluginTree() - self.PluginTree.SelectItem(self.PluginTree.GetRoot()) + self.PluginTree.SelectItem(self.PluginTree.GetRootItem()) self.RefreshPluginParams() self.RefreshButtons() diff -r 6b30cfee163e -r 45dc6a944ab6 plugger.py --- a/plugger.py Thu Sep 20 17:32:52 2007 +0200 +++ b/plugger.py Fri Sep 21 17:48:34 2007 +0200 @@ -485,6 +485,7 @@ from PLCOpenEditor import PLCOpenEditor, ProjectDialog from TextViewer import TextViewer from plcopen.structures import IEC_KEYWORDS, AddPluginBlockList, ClearPluginTypes, PluginTypes +import runtime import re class PluginsRoot(PlugTemplate, PLCControler): @@ -680,7 +681,7 @@ ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...] @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND """ - return [(C_file_name, "-I"+ieclib_path) for C_file_name in self.PLCGeneratedCFiles ] , "" + return [(C_file_name, self.CFLAGS) for C_file_name in self.PLCGeneratedCFiles ] , "" def _getBuildPath(self): return os.path.join(self.ProjectPath, "build") @@ -749,6 +750,8 @@ self.PLCGeneratedCFiles = C_files # Keep track of generated located variables for later use by self._Generate_C self.PLCGeneratedLocatedVars = locations + # compute CFLAGS for plc + self.CFLAGS = "-I"+ieclib_path return True def _build(self, logger): @@ -791,6 +794,32 @@ #logger.write("LocationCFilesAndCFLAGS :\n"+pp.pformat(LocationCFilesAndCFLAGS)+"\n") #logger.write("LDFLAGS :\n"+pp.pformat(LDFLAGS)+"\n") + # Generate main + locstrs = map(lambda x:"_".join(map(str,x)), [loc for loc in zip(*LocationCFilesAndCFLAGS)[0] if loc]) + plc_main = runtime.code("plc_common_main") % { + "calls_prototypes":"".join([""" +void __init%(s)s(); +void __cleanup%(s)s(); +void __retrive%(s)s(); +void __publish%(s)s();"""%{'s':locstr} for locstr in locstrs]), + "retrive_calls":"".join([""" + __retrive%(s)s();"""%{'s':locstr} for locstr in locstrs]), + "publish_calls":"".join([""" + __publish%(s)s();"""%{'s':locstr} for locstr in locstrs]), + "init_calls":"".join([""" + __init%(s)s();"""%{'s':locstr} for locstr in locstrs]), + "cleanup_calls":"".join([""" + __cleanup%(s)s();"""%{'s':locstr} for locstr in locstrs])} + target_name = self.BeremizRoot.TargetType.content["name"] + plc_main += runtime.code("plc_%s_main"%target_name) + + main_path = os.path.join(buildpath, "main.c" ) + f = open(main_path,'w') + f.write(plc_main) + f.close() + # First element is necessarely root + LocationCFilesAndCFLAGS[0][1].insert(0,(main_path, self.CFLAGS)) + # Compile the resulting code into object files. compiler = self.BeremizRoot.getCompiler() for Location, CFilesAndCFLAGS in LocationCFilesAndCFLAGS: @@ -802,8 +831,13 @@ for CFile, CFLAGS in CFilesAndCFLAGS: bn = os.path.basename(CFile) logger.write(" [CC] "+bn+" -> "+os.path.splitext(bn)[0]+".o\n") - objectfilename = os.path.splitext(bn)[0]+".o" + objectfilename = os.path.splitext(CFile)[0]+".o" status, result, err_result = logger.LogCommand("%s -c %s -o %s %s"%(compiler, CFile, objectfilename, CFLAGS)) + if status != 0: + logger.write_error("Build failed\n") + return False + + return True # Link object files into something that can be executed on target diff -r 6b30cfee163e -r 45dc6a944ab6 plugins/c_ext/c_ext.py --- a/plugins/c_ext/c_ext.py Thu Sep 20 17:32:52 2007 +0200 +++ b/plugins/c_ext/c_ext.py Fri Sep 21 17:48:34 2007 +0200 @@ -130,7 +130,7 @@ location_str = "_".join(map(lambda x:str(x), current_location)) res = [] for CFile in self.CFileBaseNames(): - Gen_Cfile_path = os.path.join(buildpath, location_str + "_" + os.path.splitext(CFile)[0] + "_CFile.c" ) + Gen_Cfile_path = os.path.join(buildpath, "CFile_%s_%s.c"%(location_str, os.path.splitext(CFile)[0])) f = open(Gen_Cfile_path,'w') f.write("/* Header generated by Beremiz c_ext plugin */\n") f.write("#include \"iec_std_lib.h\"\n") diff -r 6b30cfee163e -r 45dc6a944ab6 plugins/canfestival/canfestival.py --- a/plugins/canfestival/canfestival.py Thu Sep 20 17:32:52 2007 +0200 +++ b/plugins/canfestival/canfestival.py Fri Sep 21 17:48:34 2007 +0200 @@ -1,13 +1,13 @@ import os, sys base_folder = os.path.split(sys.path[0])[0] -sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen")) -CanfestivalIncludePath = os.path.join(base_folder, "CanFestival-3", "include") -CanfestivalLibPath = os.path.join(base_folder, "CanFestival-3", "src") +CanFestivalPath = os.path.join(base_folder, "CanFestival-3") +sys.path.append(os.path.join(CanFestivalPath, "objdictgen")) from nodelist import NodeList from nodemanager import NodeManager import config_utils, gen_cfile from networkedit import networkedit +import canfestival_config class _NetworkEdit(networkedit): " Overload some of CanFestival Network Editor methods " @@ -78,14 +78,14 @@ current_location = self.GetCurrentLocation() # define a unique name for the generated C file prefix = "_".join(map(lambda x:str(x), current_location)) - Gen_OD_path = os.path.join(buildpath, prefix + "_OD.c" ) + Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) # Create a new copy of the model with DCF loaded with PDO mappings for desired location master = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs()) res = gen_cfile.GenerateFile(Gen_OD_path, master) if res : raise Exception, res - return [(Gen_OD_path,"-I"+CanfestivalIncludePath)],"" + return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"" class RootClass: XSD = """ @@ -101,6 +101,6 @@ PlugChildsTypes = [("CanOpenNode",_NodeListPlug)] def PlugGenerate_C(self, buildpath, locations, logger): - return [],"-L"+CanfestivalLibPath+" -lcanfestival" + return [],canfestival_config.getLDFLAGS(CanFestivalPath) diff -r 6b30cfee163e -r 45dc6a944ab6 plugins/svgui/svgui.py --- a/plugins/svgui/svgui.py Thu Sep 20 17:32:52 2007 +0200 +++ b/plugins/svgui/svgui.py Fri Sep 21 17:48:34 2007 +0200 @@ -758,7 +758,7 @@ def PlugGenerate_C(self, buildpath, locations, logger): current_location = self.GetCurrentLocation() self.BusNumber = "_".join(map(lambda x:str(x), current_location)) - progname = self.BusNumber + "_SVGUI" + progname = "SVGUI_" + self.BusNumber self.GenerateProgram(buildpath, progname) Gen_C_file = os.path.join(buildpath, progname+".cpp" ) return [(Gen_C_file,"")],"" diff -r 6b30cfee163e -r 45dc6a944ab6 runtime/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/__init__.py Fri Sep 21 17:48:34 2007 +0200 @@ -0,0 +1,10 @@ +# module which import C files as strings + +import os + +def code(name): + filename = os.path.join(os.path.split(__file__)[0],name + ".c") + if os.path.exists(filename): + return open(filename).read() + else: + return "#error %s target not implemented !!!\n"%name diff -r 6b30cfee163e -r 45dc6a944ab6 runtime/plc_Linux_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/plc_Linux_main.c Fri Sep 21 17:48:34 2007 +0200 @@ -0,0 +1,56 @@ +#include +#include +#include +#include + + +void timer_notify(sigval_t val) +{ + struct timespec CURRENT_TIME; + clock_gettime(CLOCK_REALTIME, &CURRENT_TIME); + __run(); +} + +void catch_signal(int sig) +{ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); + printf("Got Signal %d\n",sig); +} + +int main(int argc,char **argv) +{ + timer_t timer; + struct sigevent sigev; + long tv_nsec = 1000000 * (maxval(common_ticktime__,1)%1000); + time_t tv_sec = common_ticktime__/1000; + struct itimerspec timerValues; + + memset (&sigev, 0, sizeof (struct sigevent)); + memset (&timerValues, 0, sizeof (struct itimerspec)); + sigev.sigev_value.sival_int = 0; + sigev.sigev_notify = SIGEV_THREAD; + sigev.sigev_notify_attributes = NULL; + sigev.sigev_notify_function = timer_notify; + timerValues.it_value.tv_sec = tv_sec; + timerValues.it_value.tv_nsec = tv_nsec; + timerValues.it_interval.tv_sec = tv_sec; + timerValues.it_interval.tv_nsec = tv_nsec; + + __init(); + + timer_create (CLOCK_REALTIME, &sigev, &timer); + timer_settime (timer, 0, &timerValues, NULL); + + /* install signal handler for manual break */ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); + + pause(); + + timer_delete (timer); + + __cleanup(); + + return 0; +} diff -r 6b30cfee163e -r 45dc6a944ab6 runtime/plc_Win32_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/plc_Win32_main.c Fri Sep 21 17:48:34 2007 +0200 @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +void timer_notify() +{ + struct _timeb timebuffer; + + _ftime( &timebuffer ); + CURRENT_TIME.tv_sec = timebuffer.time; + CURRENT_TIME.tv_nsec = timebuffer.millitm * 1000000 + __run(); +} + +int main(int argc,char **argv) +{ + HANDLE hTimer = NULL; + LARGE_INTEGER liDueTime; + + liDueTime.QuadPart = -10000 * maxval(common_ticktime__,1);; + + // Create a waitable timer. + hTimer = CreateWaitableTimer(NULL, TRUE, "WaitableTimer"); + if (NULL == hTimer) + { + printf("CreateWaitableTimer failed (%d)\n", GetLastError()); + return 1; + } + + __init(); + + // Set a timer to wait for 10 seconds. + if (!SetWaitableTimer(hTimer, &liDueTime, common_ticktime__, NULL, NULL, 0)) + { + printf("SetWaitableTimer failed (%d)\n", GetLastError()); + return 2; + } + + while(1){ + // Wait for the timer. + if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) + { + printf("WaitForSingleObject failed (%d)\n", GetLastError()); + break; + } + timer_notify(); + } + + __cleanup(); + + return 0; +} diff -r 6b30cfee163e -r 45dc6a944ab6 runtime/plc_common_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/plc_common_main.c Fri Sep 21 17:48:34 2007 +0200 @@ -0,0 +1,48 @@ +/* + * Functions and variables provied by generated C softPLC + **/ +extern int common_ticktime__; + +/* + * Functions and variables provied by plc.c + **/ +void run(long int tv_sec, long int tv_nsec); + +#define maxval(a,b) ((a>b)?a:b) + +#include "iec_types.h" + +/* + * Functions and variables provied by generated C softPLC + **/ +void config_run__(int tick); +void config_init__(void); + +/* + * Functions and variables to export to generated C softPLC + **/ + +IEC_TIME __CURRENT_TIME; + +static int tick = 0; + +%(calls_prototypes)s + +void __run() +{ + %(retrive_calls)s + config_run__(tick++); + %(publish_calls)s +} + +void __init() +{ + config_init__(); + %(init_calls)s +} + +void __cleanup() +{ + %(cleanup_calls)s +} +