Optimized plc_debug.c generated code. Should produce smaller code size. Added statically initialized array for PLC tracable variable description.
authorEdouard Tisserant
Thu, 29 Jan 2015 19:11:34 +0100
changeset 1432 8872223a675b
parent 1431 df59be5afb08
child 1433 4a45f6642523
Optimized plc_debug.c generated code. Should produce smaller code size. Added statically initialized array for PLC tracable variable description.
ProjectController.py
targets/plc_debug.c
--- a/ProjectController.py	Sun Jan 18 20:38:34 2015 +0100
+++ b/ProjectController.py	Thu Jan 29 19:11:34 2015 +0100
@@ -732,6 +732,7 @@
         """
         self._ProgramList = None
         self._VariablesList = None
+        self._DbgVariablesList = None
         self._IECPathToIdx = {}
         self._Ticktime = 0
         self.TracedIECPath = []
@@ -750,6 +751,7 @@
                 VariablesListAttributeName = ["num", "vartype", "IEC_path", "C_path", "type"]
                 self._ProgramList = []
                 self._VariablesList = []
+                self._DbgVariablesList = []
                 self._IECPathToIdx = {}
 
                 # Separate sections
@@ -774,6 +776,7 @@
 
                 # second section contains all variables
                 config_FBs = {}
+                Idx = 0
                 for line in ListGroup[1]:
                     # Split and Maps each field to dictionnary entries
                     attrs = dict(zip(VariablesListAttributeName,line.strip().split(';')))
@@ -790,12 +793,17 @@
                         attrs["C_path"] = '__'.join(parts)
                         if attrs["vartype"] == "FB":
                             config_FBs[tuple(parts)] = attrs["C_path"]
-                    # Push this dictionnary into result.
+                    if attrs["vartype"] != "FB":
+                        # Push this dictionnary into result.
+                        self._DbgVariablesList.append(attrs)
+                        # Fill in IEC<->C translation dicts
+                        IEC_path=attrs["IEC_path"]
+                        self._IECPathToIdx[IEC_path]=(Idx, attrs["type"])
+                        # Ignores numbers given in CSV file
+                        # Idx=int(attrs["num"])
+                        # Count variables only, ignore FBs
+                        Idx+=1
                     self._VariablesList.append(attrs)
-                    # Fill in IEC<->C translation dicts
-                    IEC_path=attrs["IEC_path"]
-                    Idx=int(attrs["num"])
-                    self._IECPathToIdx[IEC_path]=(Idx, attrs["type"])
 
                 # third section contains ticktime
                 if len(ListGroup) > 2:
@@ -816,8 +824,21 @@
         self.GetIECProgramsAndVariables()
 
         # prepare debug code
+        variable_decl_array = []
+        bofs = 0
+        for v in self._DbgVariablesList :
+            sz = DebugTypesSize.get(v["type"], 0)
+            variable_decl_array += [
+                "{&(%(C_path)s), "%v+
+                {"EXT":"%(type)s_P_ENUM",
+                 "IN":"%(type)s_P_ENUM",
+                 "MEM":"%(type)s_O_ENUM",
+                 "OUT":"%(type)s_O_ENUM",
+                 "VAR":"%(type)s_ENUM"}[v["vartype"]]%v +
+                 "}"]
+            bofs += sz
         debug_code = targets.GetCode("plc_debug.c") % {
-           "buffer_size": reduce(lambda x, y: x + y, [DebugTypesSize.get(v["type"], 0) for v in self._VariablesList], 0),
+           "buffer_size":bofs,
            "programs_declarations":
                "\n".join(["extern %(type)s %(C_path)s;"%p for p in self._ProgramList]),
            "extern_variables_declarations":"\n".join([
@@ -828,22 +849,8 @@
                "VAR":"extern __IEC_%(type)s_t %(C_path)s;",
                "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v
                for v in self._VariablesList if v["C_path"].find('.')<0]),
-           "for_each_variable_do_code":"\n".join([
-               {"EXT":"    (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n",
-                "IN":"    (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n",
-                "MEM":"    (*fp)((void*)&(%(C_path)s),%(type)s_O_ENUM);\n",
-                "OUT":"    (*fp)((void*)&(%(C_path)s),%(type)s_O_ENUM);\n",
-                "VAR":"    (*fp)((void*)&(%(C_path)s),%(type)s_ENUM);\n"}[v["vartype"]]%v
-                for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypesSize ]),
-           "find_variable_case_code":"\n".join([
-               "    case %(num)s:\n"%v+
-               "        *varp = (void*)&(%(C_path)s);\n"%v+
-               {"EXT":"        return %(type)s_P_ENUM;\n",
-                "IN":"        return %(type)s_P_ENUM;\n",
-                "MEM":"        return %(type)s_O_ENUM;\n",
-                "OUT":"        return %(type)s_O_ENUM;\n",
-                "VAR":"        return %(type)s_ENUM;\n"}[v["vartype"]]%v
-                for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypesSize ])}
+           "variable_decl_array": ",\n".join(variable_decl_array)
+           }
 
         return debug_code
 
@@ -1307,7 +1314,7 @@
                 self.IECdebug_datas.pop(IECPath)
             else:
                 IECdebug_data[4] = reduce(
-                    lambda x, y: x|y, 
+                    lambda x, y: x|y,
                     IECdebug_data[0].itervalues(),
                     False)
         self.IECdebug_lock.release()
--- a/targets/plc_debug.c	Sun Jan 18 20:38:34 2015 +0100
+++ b/targets/plc_debug.c	Thu Jan 29 19:11:34 2015 +0100
@@ -39,19 +39,23 @@
  **/
 %(extern_variables_declarations)s
 
-typedef void(*__for_each_variable_do_fp)(void*, __IEC_types_enum);
+typedef const struct {
+    void *ptr;
+    __IEC_types_enum type;
+} dbgvardsc_t;
+
+static dbgvardsc_t dbgvardsc[] = {
+%(variable_decl_array)s
+};
+
+typedef void(*__for_each_variable_do_fp)(dbgvardsc_t*);
 void __for_each_variable_do(__for_each_variable_do_fp fp)
 {
-%(for_each_variable_do_code)s
-}
-
-__IEC_types_enum __find_variable(unsigned int varindex, void ** varp)
-{
-    switch(varindex){
-%(find_variable_case_code)s
-     default:
-      *varp = NULL;
-      return UNKNOWN_ENUM;
+    int i;
+    for(i = 0; i < sizeof(dbgvardsc)/sizeof(dbgvardsc_t); i++){
+        dbgvardsc_t *dsc = &dbgvardsc[i];
+        if(dsc->type != UNKNOWN_ENUM) 
+            (*fp)(dsc);
     }
 }
 
@@ -70,12 +74,13 @@
             forced_value_p = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\
             break;
 
-void* UnpackVar(void* varp, __IEC_types_enum vartype, void **real_value_p, char *flags)
-{
+void* UnpackVar(dbgvardsc_t *dsc, void **real_value_p, char *flags)
+{
+    void *varp = dsc->ptr;
     void *forced_value_p = NULL;
     *flags = 0;
     /* find data to copy*/
-    switch(vartype){
+    switch(dsc->type){
         __ANY(__Unpack_case_t)
         __ANY(__Unpack_case_p)
     default:
@@ -88,14 +93,14 @@
 
 void Remind(unsigned int offset, unsigned int count, void * p);
 
-void RemindIterator(void* varp, __IEC_types_enum vartype)
+void RemindIterator(dbgvardsc_t *dsc)
 {
     void *real_value_p = NULL;
     char flags = 0;
-    UnpackVar(varp, vartype, &real_value_p, &flags);
+    UnpackVar(dsc, &real_value_p, &flags);
 
     if(flags & __IEC_RETAIN_FLAG){
-        USINT size = __get_type_enum_size(vartype);
+        USINT size = __get_type_enum_size(dsc->type);
         /* compute next cursor positon*/
         unsigned int next_retain_offset = retain_offset + size;
         /* if buffer not full */
@@ -136,23 +141,23 @@
 
 void Retain(unsigned int offset, unsigned int count, void * p);
 
-inline void BufferIterator(void* varp, __IEC_types_enum vartype, int do_debug)
+inline void BufferIterator(dbgvardsc_t *dsc, int do_debug)
 {
     void *real_value_p = NULL;
     void *visible_value_p = NULL;
     char flags = 0;
 
-    visible_value_p = UnpackVar(varp, vartype, &real_value_p, &flags);
+    visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
 
     if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
-        USINT size = __get_type_enum_size(vartype);
+        USINT size = __get_type_enum_size(dsc->type);
         if(flags & __IEC_DEBUG_FLAG){
             /* copy visible variable to buffer */;
             if(do_debug){
                 /* compute next cursor positon.
                    No need to check overflow, as BUFFER_SIZE
                    is computed large enough */
-                if(vartype == STRING_ENUM){
+                if(dsc->type == STRING_ENUM){
                     /* optimization for strings */
                     size = ((STRING*)visible_value_p)->len + 1;
                 }
@@ -178,12 +183,12 @@
     }
 }
 
-void DebugIterator(void* varp, __IEC_types_enum vartype){
-    BufferIterator(varp, vartype, 1);
-}
-
-void RetainIterator(void* varp, __IEC_types_enum vartype){
-    BufferIterator(varp, vartype, 0);
+void DebugIterator(dbgvardsc_t *dsc){
+    BufferIterator(dsc, 1);
+}
+
+void RetainIterator(dbgvardsc_t *dsc){
+    BufferIterator(dsc, 0);
 }
 
 extern void PLC_GetTime(IEC_TIME*);
@@ -251,13 +256,18 @@
             break;
 void RegisterDebugVariable(int idx, void* force)
 {
-    void *varp = NULL;
-    unsigned char flags = force ? __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG : __IEC_DEBUG_FLAG;
-    switch(__find_variable(idx, &varp)){
-        __ANY(__RegisterDebugVariable_case_t)
-        __ANY(__RegisterDebugVariable_case_p)
-    default:
-        break;
+    if(idx  < sizeof(dbgvardsc)/sizeof(dbgvardsc_t)){
+        unsigned char flags = force ?
+            __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG :
+            __IEC_DEBUG_FLAG;
+        dbgvardsc_t *dsc = &dbgvardsc[idx];
+        void *varp = dsc->ptr;
+        switch(dsc->type){
+            __ANY(__RegisterDebugVariable_case_t)
+            __ANY(__RegisterDebugVariable_case_p)
+        default:
+            break;
+        }
     }
 }
 
@@ -272,10 +282,11 @@
             ((__IEC_##TYPENAME##_p *)varp)->flags &= ~(__IEC_DEBUG_FLAG|__IEC_FORCE_FLAG);\
             break;
 
-void ResetDebugVariablesIterator(void* varp, __IEC_types_enum vartype)
+void ResetDebugVariablesIterator(dbgvardsc_t *dsc)
 {
     /* force debug flag to 0*/
-    switch(vartype){
+    void *varp = dsc->ptr;
+    switch(dsc->type){
         __ANY(__ResetDebugVariablesIterator_case_t)
         __ANY(__ResetDebugVariablesIterator_case_p)
     default: