Bugs on SFC generation fixed
authorlbessard
Wed, 17 Oct 2007 17:51:24 +0200
changeset 66 501e9d494744
parent 65 c6d41c1287de
child 67 08097122a922
Bugs on SFC generation fixed
lib/iec_std_lib.h
stage4/generate_cc/generate_cc.cc
stage4/generate_cc/generate_cc_sfc.cc
stage4/generate_cc/generate_cc_sfcdecl.cc
--- a/lib/iec_std_lib.h	Fri Oct 05 17:58:44 2007 +0200
+++ b/lib/iec_std_lib.h	Wed Oct 17 17:51:24 2007 +0200
@@ -179,8 +179,20 @@
     DATE    DATEvar;
 } __IL_DEFVAR_T;
 
-
-
+typedef struct {
+  char state;     // current step state. 0 : inative, 1: active
+  char prev_state;  // previous step state. 0 : inative, 1: active
+  TIME elapsed_time;  // time since step is active
+} STEP;
+
+typedef struct {
+  char stored;  // action storing state. 0 : not stored, 1: stored
+  char state; // current action state. 0 : inative, 1: active
+  char set;   // set have been requested (reset each time the body is evaluated)
+  char reset; // reset have been requested (reset each time the body is evaluated)
+  TIME set_remaining_time;    // time before set will be requested
+  TIME reset_remaining_time;  // time before reset will be requested
+} ACTION;
 
 /*****************/
 /* Misc internal */
--- a/stage4/generate_cc/generate_cc.cc	Fri Oct 05 17:58:44 2007 +0200
+++ b/stage4/generate_cc/generate_cc.cc	Wed Oct 17 17:51:24 2007 +0200
@@ -621,6 +621,7 @@
 //SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
 void *visit(function_block_declaration_c *symbol) {
   generate_cc_vardecl_c *vardecl;
+  generate_cc_sfcdecl_c *sfcdecl;
   TRACE("function_block_declaration_c");
 
   /* start off by adding this declaration to the global
@@ -655,9 +656,13 @@
   				      generate_cc_vardecl_c::external_vt);
   vardecl->print(symbol->var_declarations);
   delete vardecl;
+  /* (A.4) Generate private internal variables for SFC */
+  sfcdecl = new generate_cc_sfcdecl_c(&s4o, generate_cc_sfcdecl_c::sfcdecl_sd);
+  sfcdecl->print(symbol->fblock_body);
+  delete sfcdecl;
   s4o.print("\n");
 
-  /* (A.4) Function Block data structure type name. */
+  /* (A.5) Function Block data structure type name. */
   s4o.indent_left();
   s4o.print("} ");
   symbol->fblock_name->accept(*this);
@@ -688,14 +693,29 @@
   				      generate_cc_vardecl_c::private_vt |
 				        generate_cc_vardecl_c::located_vt |
 				        generate_cc_vardecl_c::external_vt);
-  vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
+  vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->");
   delete vardecl;
+  s4o.print("\n");
+  /* (B.3) Generate private internal variables for SFC */
+  sfcdecl = new generate_cc_sfcdecl_c(&s4o, generate_cc_sfcdecl_c::sfcinit_sd);
+  sfcdecl->print(symbol->fblock_body, FB_FUNCTION_PARAM"->");
+  delete sfcdecl;
   s4o.indent_left();
-  s4o.print("\n" + s4o.indent_spaces + "}\n\n");
+  s4o.print(s4o.indent_spaces + "}\n\n");
 
   
   /* (C) Function with FB body */
-  /* (C.1) Function declaration */
+  /* (C.1) Step definitions */
+  sfcdecl = new generate_cc_sfcdecl_c(&s4o, generate_cc_sfcdecl_c::stepdef_sd);
+  sfcdecl->print(symbol->fblock_body);
+  delete sfcdecl;
+  
+  /* (C.2) Action definitions */
+  sfcdecl = new generate_cc_sfcdecl_c(&s4o, generate_cc_sfcdecl_c::actiondef_sd);
+  sfcdecl->print(symbol->fblock_body);
+  delete sfcdecl;
+  
+  /* (C.3) Function declaration */
   s4o.print("// Code part\n");
   /* function interface */
   s4o.print("void ");
@@ -709,7 +729,7 @@
   s4o.print(") {\n");
   s4o.indent_right();
 
-  /* (C.2) Initialize TEMP variables */
+  /* (C.4) Initialize TEMP variables */
   /* function body */
   s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n");
   vardecl = new generate_cc_vardecl_c(&s4o,
@@ -719,7 +739,7 @@
   delete vardecl;
   s4o.print("\n");
 
-  /* (C.3) Function code */
+  /* (C.5) Function code */
   generate_cc_SFC_IL_ST_c generate_cc_code(&s4o, symbol, FB_FUNCTION_PARAM"->");
   symbol->fblock_body->accept(generate_cc_code);
   s4o.indent_left();
@@ -728,6 +748,16 @@
   s4o.print(FB_FUNCTION_SUFFIX);
   s4o.print(s4o.indent_spaces + "() \n\n");
 
+  /* (C.6) Step undefinitions */
+  sfcdecl = new generate_cc_sfcdecl_c(&s4o, generate_cc_sfcdecl_c::stepundef_sd);
+  sfcdecl->print(symbol->fblock_body);
+  delete sfcdecl;
+  
+  /* (C.7) Action undefinitions */
+  sfcdecl = new generate_cc_sfcdecl_c(&s4o, generate_cc_sfcdecl_c::actionundef_sd);
+  sfcdecl->print(symbol->fblock_body);
+  delete sfcdecl;
+
   s4o.indent_left();
   s4o.print("\n\n\n\n");
 
--- a/stage4/generate_cc/generate_cc_sfc.cc	Fri Oct 05 17:58:44 2007 +0200
+++ b/stage4/generate_cc/generate_cc_sfc.cc	Wed Oct 17 17:51:24 2007 +0200
@@ -65,6 +65,7 @@
     generate_cc_il_c *generate_cc_il;
     generate_cc_st_c *generate_cc_st;
     generate_cc_SFC_IL_ST_c *generate_cc_code;
+    search_var_instance_decl_c *search_var_instance_decl;
     
     int transition_number;
     std::list<TRANSITION> transition_list;
@@ -80,6 +81,7 @@
       generate_cc_il = new generate_cc_il_c(s4o_ptr, scope, variable_prefix);
       generate_cc_st = new generate_cc_st_c(s4o_ptr, scope, variable_prefix);
       generate_cc_code = new generate_cc_SFC_IL_ST_c(s4o_ptr, scope, variable_prefix);
+      search_var_instance_decl = new search_var_instance_decl_c(scope);
       this->set_variable_prefix(variable_prefix);
     }
     
@@ -87,6 +89,7 @@
       delete generate_cc_il;
       delete generate_cc_st;
       delete generate_cc_code;
+      delete search_var_instance_decl;
     }
 
     void reset_transition_number(void) {transition_number = 0;}
@@ -147,6 +150,12 @@
       s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
     }
     
+    bool is_variable(symbol_c *symbol) {
+      /* we try to find the variable instance declaration, to determine its type... */
+      symbol_c *var_decl = search_var_instance_decl->get_decl(symbol);
+      
+      return var_decl != NULL;
+    }
 
 /*********************************************/
 /* B.1.6  Sequential function chart elements */
@@ -231,7 +240,7 @@
             if (symbol->integer != NULL) {
               transition->priority = atoi(((token_c *)symbol->integer)->value);
               std::list<TRANSITION>::iterator pt = transition_list.begin();
-              while (pt != transition_list.end() && pt->priority > transition->priority) {
+              while (pt != transition_list.end() && pt->priority <= transition->priority) {
                 pt++;
               } 
               transition_list.insert(pt, *transition);
@@ -467,12 +476,24 @@
               s4o.print(" = 1;\n");  
             }
             if (strcmp(qualifier, "S") == 0) {
-              print_action_argument(current_action, "set");
+              if (is_variable(current_action)) {
+                print_variable_prefix();
+                current_action->accept(*this);
+              }
+              else
+                print_action_argument(current_action, "set");
               s4o.print(" = 1;\n");
             }
             if (strcmp(qualifier, "R") == 0) {
-              print_action_argument(current_action, "reset");
-              s4o.print(" = 1;\n");
+              if (is_variable(current_action)) {
+                print_variable_prefix();
+                current_action->accept(*this);
+                s4o.print(" = 0;\n");
+              }
+              else {
+                print_action_argument(current_action, "reset");
+                s4o.print(" = 1;\n");
+              }
             }
             if (strcmp(qualifier, "SD") == 0 || strcmp(qualifier, "DS") == 0 || 
                 strcmp(qualifier, "SL") == 0) {
@@ -564,7 +585,9 @@
       print_variable_prefix();
       s4o.print("step_list[i].elapsed_time = __time_add(");
       print_variable_prefix();
-      s4o.print("step_list[i].elapsed_time, PERIOD);\n");
+      s4o.print("step_list[i].elapsed_time, ");
+      print_variable_prefix();
+      s4o.print("period);\n");
       s4o.indent_left();
       s4o.print(s4o.indent_spaces + "}\n");
       s4o.indent_left();
@@ -586,17 +609,21 @@
       print_variable_prefix();
       s4o.print("action_list[i].reset = 0;\n");
       s4o.print(s4o.indent_spaces + "if (");
-      print_variable_prefix();
-      s4o.print("__gt_TIME(action_list[i].set_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n");
+      s4o.print("__gt_TIME(2, ");
+      print_variable_prefix();
+      s4o.print("action_list[i].set_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0))) {\n");
       s4o.indent_right();
       s4o.print(s4o.indent_spaces);
       print_variable_prefix();
       s4o.print("action_list[i].set_remaining_time = __time_sub(");
       print_variable_prefix();
-      s4o.print("action_list[i].set_remaining_time, PERIOD);\n");
+      s4o.print("action_list[i].set_remaining_time, ");
+      print_variable_prefix();
+      s4o.print("period);\n");
       s4o.print(s4o.indent_spaces + "if (");
-      print_variable_prefix();
-      s4o.print("__le_TIME(action_list[i].set_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n");
+      s4o.print("__le_TIME(2, ");
+      print_variable_prefix();
+      s4o.print("action_list[i].set_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0))) {\n");
       s4o.indent_right();
       s4o.print(s4o.indent_spaces);
       print_variable_prefix();
@@ -609,17 +636,21 @@
       s4o.indent_left();
       s4o.print(s4o.indent_spaces + "}\n");
       s4o.print(s4o.indent_spaces + "if (");
-      print_variable_prefix();
-      s4o.print("__gt_TIME(action_list[i].reset_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n");
+      s4o.print("__gt_TIME(2, ");
+      print_variable_prefix();
+      s4o.print("action_list[i].reset_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0))) {\n");
       s4o.indent_right();
       s4o.print(s4o.indent_spaces);
       print_variable_prefix();
       s4o.print("action_list[i].reset_remaining_time = __time_sub(");
       print_variable_prefix();
-      s4o.print("action_list[i].reset_remaining_time, PERIOD);\n");
+      s4o.print("action_list[i].reset_remaining_time, ");
+      print_variable_prefix();
+      s4o.print("period);\n");
       s4o.print(s4o.indent_spaces + "if (");
-      print_variable_prefix();
-      s4o.print("__le_TIME(action_list[i].reset_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n");
+      s4o.print("__le_TIME(2, ");
+      print_variable_prefix();
+      s4o.print("action_list[i].reset_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0))) {\n");
       s4o.indent_right();
       s4o.print(s4o.indent_spaces);
       print_variable_prefix();
@@ -676,9 +707,9 @@
       s4o.indent_right();
       s4o.print(s4o.indent_spaces);
       print_variable_prefix();
-      s4o.print("action_list[i].set_remaining_time = 0;\n" + s4o.indent_spaces);
-      print_variable_prefix();
-      s4o.print("action_list[i].reset_remaining_time = 0;\n" + s4o.indent_spaces);
+      s4o.print("action_list[i].set_remaining_time = __time_to_timespec(1, 0, 0, 0, 0, 0);\n" + s4o.indent_spaces);
+      print_variable_prefix();
+      s4o.print("action_list[i].reset_remaining_time = __time_to_timespec(1, 0, 0, 0, 0, 0);\n" + s4o.indent_spaces);
       print_variable_prefix();
       s4o.print("action_list[i].stored = 0;\n");
       s4o.indent_left();
--- a/stage4/generate_cc/generate_cc_sfcdecl.cc	Fri Oct 05 17:58:44 2007 +0200
+++ b/stage4/generate_cc/generate_cc_sfcdecl.cc	Wed Oct 17 17:51:24 2007 +0200
@@ -45,10 +45,12 @@
       typedef enum {
         sfcdecl_sd,
         sfcinit_sd,
+        stepcount_sd,
         stepdef_sd,
         stepundef_sd,
         actiondef_sd,
-        actionundef_sd
+        actionundef_sd,
+        actioncount_sd
        } sfcdeclaration_t;
   
   private:
@@ -88,27 +90,41 @@
           s4o.print(s4o.indent_spaces + "STEP step_list[");
           s4o.print_integer(step_number);
           s4o.print("];\n");
-          s4o.print(s4o.indent_spaces + "UINT nb_steps = ");
-          s4o.print_integer(step_number);
-          s4o.print(";\n");
+          s4o.print(s4o.indent_spaces + "UINT nb_steps;\n");
           
           /* actions table declaration */
           s4o.print(s4o.indent_spaces + "ACTION action_list[");
           s4o.print_integer(action_number);
           s4o.print("];\n");
-          s4o.print(s4o.indent_spaces + "UINT nb_actions = ");
-          s4o.print_integer(action_number);
-          s4o.print(";\n");
+          s4o.print(s4o.indent_spaces + "UINT nb_actions;\n");
           
           /* transitions table declaration */
           s4o.print(s4o.indent_spaces + "USINT transition_list[");
           s4o.print_integer(transition_number);
           s4o.print("];\n");
+          
+          /* period declaration */
+          s4o.print(s4o.indent_spaces + "TIME period;\n");
           break;
         case sfcinit_sd:
+          s4o.print(s4o.indent_spaces);
+          s4o.print("UINT i;\n");
+          
+          /* steps table count */
+          wanted_sfcdeclaration = stepcount_sd;
+          for(int i = 0; i < symbol->n; i++)
+            symbol->elements[i]->accept(*this);
+          s4o.print(s4o.indent_spaces);
+          print_variable_prefix();
+          s4o.print("nb_steps = ");
+          s4o.print_integer(step_number);
+          s4o.print(";\n");
+          step_number = 0;
+          wanted_sfcdeclaration = sfcinit_sd;
+          
           /* steps table initialisation */
           s4o.print(s4o.indent_spaces + "STEP temp_step = {0, 0, 0};\n");
-          s4o.print(s4o.indent_spaces + "for(UINT i = 0; i < ");
+          s4o.print(s4o.indent_spaces + "for(i = 0; i < ");
           print_variable_prefix();
           s4o.print("nb_steps; i++) {\n");
           s4o.indent_right();
@@ -120,15 +136,33 @@
           for(int i = 0; i < symbol->n; i++)
             symbol->elements[i]->accept(*this);
           
+          /* steps table count */
+          wanted_sfcdeclaration = actioncount_sd;
+          for(int i = 0; i < symbol->n; i++)
+            symbol->elements[i]->accept(*this);
+          s4o.print(s4o.indent_spaces);
+          print_variable_prefix();
+          s4o.print("nb_actions = ");
+          s4o.print_integer(action_number);
+          s4o.print(";\n");
+          action_number = 0;
+          wanted_sfcdeclaration = sfcinit_sd;
+          
           /* actions table initialisation */
           s4o.print(s4o.indent_spaces + "ACTION temp_action = {0, 0, 0, 0, 0, 0};\n");
-          s4o.print(s4o.indent_spaces + "for(UINT i = 0; i < ");
+          s4o.print(s4o.indent_spaces + "for(i = 0; i < ");
           print_variable_prefix();
           s4o.print("nb_actions; i++) {\n");
           s4o.indent_right();
           s4o.print(s4o.indent_spaces);
           print_variable_prefix();
           s4o.print("action_list[i] = temp_action;\n");
+          
+          /* period initialisation */
+          s4o.print(s4o.indent_spaces);
+          print_variable_prefix();
+          s4o.print("period = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
+          
           s4o.indent_left();
           s4o.print(s4o.indent_spaces + "}\n");
           break;
@@ -156,19 +190,22 @@
             symbol->elements[i]->accept(*this);
           s4o.print("\n");
           break;
+        default:
+          break;
       }
       return NULL;
     }
     
     void *visit(initial_step_c *symbol) {
       switch (wanted_sfcdeclaration) {
+        case stepcount_sd:
         case sfcdecl_sd:
           step_number++;
           break;
         case sfcinit_sd:
           s4o.print(s4o.indent_spaces);
           print_variable_prefix();
-          s4o.print("action_list[");
+          s4o.print("step_list[");
           s4o.print_integer(step_number);
           s4o.print("].state = 1;\n");
           step_number++;
@@ -196,6 +233,7 @@
     
     void *visit(step_c *symbol) {
       switch (wanted_sfcdeclaration) {
+        case stepcount_sd:
         case sfcdecl_sd:
           step_number++;
           break;
@@ -248,6 +286,7 @@
           symbol->action_name->accept(*this);
           s4o.print("\n");
           break;
+        case actioncount_sd:
         case sfcdecl_sd:
           action_number++;
           break;