On the long wat towards generated code comilation...
--- 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()
--- 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
--- 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")
--- 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 = """<?xml version="1.0" encoding="ISO-8859-1" ?>
@@ -101,6 +101,6 @@
PlugChildsTypes = [("CanOpenNode",_NodeListPlug)]
def PlugGenerate_C(self, buildpath, locations, logger):
- return [],"-L"+CanfestivalLibPath+" -lcanfestival"
+ return [],canfestival_config.getLDFLAGS(CanFestivalPath)
--- 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,"")],""
--- /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
--- /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 <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+
+
+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;
+}
--- /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 <stdio.h>
+#include <sys/timeb.h>
+#include <time.h>
+#include <windows.h>
+
+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;
+}
--- /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
+}
+