全局功能块变量

98 阅读2分钟
ST代码
FUNCTION_BLOCK fb_cfc
  VAR_INPUT
    var_in : LINT;
  END_VAR
  VAR_OUTPUT
    var_out : LINT;
  END_VAR
  VAR
    _TMP_MOVE1_OUT : LINT;
  END_VAR

  _TMP_MOVE1_OUT := MOVE(var_in);
  var_out := _TMP_MOVE1_OUT;
END_FUNCTION_BLOCK

PROGRAM prg_sfc
  VAR_INPUT
    var_in : LINT;
  END_VAR
  VAR_OUTPUT
    var_out : LINT;
  END_VAR
  VAR_EXTERNAL
    fb1 : fb_cfc;
  END_VAR

  INITIAL_STEP Init:
    public_act(N);
  END_STEP

  ACTION public_act:
    fb1(var_in := var_in, var_out => var_out);
  END_ACTION

  TRANSITION (PRIORITY := 1) FROM Init TO Init
    := TRUE;
  END_TRANSITION

END_PROGRAM


CONFIGURATION Config0
  VAR_GLOBAL
    fb1 : fb_cfc;
  END_VAR

  RESOURCE Res0 ON PLC
    TASK task0(INTERVAL := T#20ms,PRIORITY := 1);
    PROGRAM instance0 WITH task0 : prg_sfc;
  END_RESOURCE
END_CONFIGURATION

对应POUS.c
  // Actions execution
if(__GET_VAR(data__->__action_list[__SFC_PUBLIC_ACT].state)) {
    __SET_EXTERNAL_FB(data__->FB1->,VAR_IN,,__GET_VAR(data__->VAR_IN,));
    FB_CFC_body__(data__->FB1);
    __SET_VAR(data__->,VAR_OUT,,__GET_VAR(data__->FB1.VAR_OUT));
}

//问题所在
__SET_VAR(data__->,VAR_OUT,,__GET_VAR(data__->FB1.VAR_OUT));
//应该修改为:
__SET_VAR(data__->,VAR_OUT,,__GET_VAR(data__->FB1->VAR_OUT));
相关matiec代码
void *print_setter(symbol_c* symbol,
        symbol_c* type,
        symbol_c* value,
        symbol_c* fb_symbol = NULL,
        symbol_c* fb_value = NULL) {
 
  if (fb_symbol == NULL) {
    unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol, scope_);
    symbol_c *first_nonfb = analyse_variable_c::find_first_nonfb(symbol);
    if (first_nonfb == NULL) ERROR;
    if (vartype == search_var_instance_decl_c::external_vt) {
      if (!get_datatype_info_c::is_type_valid    (first_nonfb->datatype)) ERROR;
      if ( get_datatype_info_c::is_function_block(first_nonfb->datatype)) // handle situation where we are copying a complete fb -> fb1.fb2.fb3 := fb4 (and fb3 is external!)
        s4o.print(SET_EXTERNAL_FB);
      else
        s4o.print(SET_EXTERNAL);
    }
    else if (vartype == search_var_instance_decl_c::located_vt)
      s4o.print(SET_LOCATED);
    else
      s4o.print(SET_VAR);
  }
  else {
    unsigned int vartype = search_var_instance_decl->get_vartype(fb_symbol);
    if (vartype == search_var_instance_decl_c::external_vt)
      s4o.print(SET_EXTERNAL_FB);
    else
      s4o.print(SET_VAR);
  }
  s4o.print("(");
  
  if (fb_symbol != NULL) {
    print_variable_prefix();
    // It is my (MJS) conviction that by this time the following will always be true...
    //   wanted_variablegeneration == expression_vg;
    fb_symbol->accept(*this);
    unsigned int vartype = search_var_instance_decl->get_vartype(fb_symbol);
    if (vartype == search_var_instance_decl_c::external_vt)
      s4o.print("->,");
    else
      s4o.print(".,");
    symbol->accept(*this);
    s4o.print(",");
    s4o.print(",");    
  } else {
    print_variable_prefix();
    s4o.print(",");    
    wanted_variablegeneration = complextype_base_vg;
    symbol->accept(*this);
    s4o.print(",");
    wanted_variablegeneration = complextype_suffix_vg;
    symbol->accept(*this);
    s4o.print(",");
  }
  wanted_variablegeneration = expression_vg;
  print_check_function(type, value, fb_value);
  s4o.print(")");
  wanted_variablegeneration = expression_vg;
  return NULL;
}
void *print_check_function(symbol_c *type,
      symbol_c *value,
      symbol_c *fb_name = NULL,
      bool temp = false) {
  if (!get_datatype_info_c::is_type_valid(type)) ERROR;
  bool is_subrange = get_datatype_info_c::is_subrange(type);
  if (is_subrange) {
    s4o.print("__CHECK_");
    type->accept(*this);
    s4o.print("(");
  }
  if (fb_name != NULL) {
    s4o.print(GET_VAR);
    s4o.print("(");
    print_variable_prefix();
    fb_name->accept(*this);
    s4o.print(".");
    value->accept(*this);
    s4o.print(")");
  }
  else {
    if (temp)
    s4o.print(TEMP_VAR);
    value->accept(*this);
  }
  if (is_subrange)
    s4o.print(")");
  return NULL;
}
修改方案
//generate_c_st.cc
if (fb_value != NULL){
    unsigned int vartype = search_var_instance_decl->get_vartype(fb_value);
    print_check_function(type, value, fb_value, false, vartype);
}
else
    print_check_function(type, value, fb_value);
//generate_c_base.cc
if (vartype == search_var_instance_decl_c::external_vt)
  s4o.print("->");
else
  s4o.print(".");