1.定义功能块为全局时的bug
- 本地功能块对应POU.c和ST代码
void PROGRAM0_init__(PROGRAM0 *data__, BOOL retain) {
__INIT_VAR(data__->RESET,__BOOL_LITERAL(FALSE),retain)
__INIT_VAR(data__->COUNTOUT,0,retain)
COUNTERST_init__(&data__->COUNTLOCAL,retain);
}
// Code part
void PROGRAM0_body__(PROGRAM0 *data__) {
// Initialise TEMP variables
__SET_VAR(data__->COUNTLOCAL.,RESET,,__GET_VAR(data__->RESET,));
COUNTERST_body__(&data__->COUNTLOCAL);
__SET_VAR(data__->,COUNTOUT,,__GET_VAR(data__->COUNTLOCAL.OUT,));
goto __end;
__end:
return;
} // PROGRAM0_body__()
FUNCTION_BLOCK CounterST
VAR_INPUT
Reset : BOOL;
END_VAR
VAR
Cnt : INT;
END_VAR
VAR_OUTPUT
Out : INT;
END_VAR
IF Reset THEN
Cnt := 0;
ELSE
Cnt := Cnt + 1;
END_IF;
Out := Cnt;
END_FUNCTION_BLOCK
PROGRAM program0
VAR_INPUT
Reset : BOOL;
END_VAR
VAR_OUTPUT
CountOut : INT;
END_VAR
VAR
CountLocal : CounterST;
END_VAR
CountLocal(Reset:=Reset);
CountOut := CountLocal.Out;
END_PROGRAM
CONFIGURATION Config0
RESOURCE Res0 ON PLC
TASK task0(INTERVAL := T#20ms,PRIORITY := 0);
PROGRAM instance0 WITH task0 : program0;
END_RESOURCE
END_CONFIGURATION
- 全局功能块对应POU.c和ST代码
void PROGRAM0_init__(PROGRAM0 *data__, BOOL retain) {
__INIT_VAR(data__->RESET,__BOOL_LITERAL(FALSE),retain)
__INIT_VAR(data__->COUNTEROUT,0,retain)
__INIT_EXTERNAL_FB(COUNTERST,COUNTERGLOBAL,data__->COUNTERGLOBAL,retain)
}
// Code part
void PROGRAM0_body__(PROGRAM0 *data__) {
// Initialise TEMP variables
__SET_EXTERNAL_FB(data__->COUNTERGLOBAL.,RESET,,__GET_VAR(data__->RESET,));
COUNTERST_body__(data__->COUNTERGLOBAL);
__SET_VAR(data__->,COUNTEROUT,,__GET_VAR(data__->COUNTERGLOBAL->OUT,));
goto __end;
__end:
return;
} // PROGRAM0_body__()
FUNCTION_BLOCK CounterST
VAR_INPUT
Reset : BOOL;
END_VAR
VAR
Cnt : INT;
END_VAR
VAR_OUTPUT
Out : INT;
END_VAR
IF Reset THEN
Cnt := 0;
ELSE
Cnt := Cnt + 1;
END_IF;
Out := Cnt;
END_FUNCTION_BLOCK
PROGRAM program0
VAR_INPUT
Reset : BOOL;
END_VAR
VAR_OUTPUT
CounterOut : INT;
END_VAR
VAR_EXTERNAL
CounterGlobal : CounterST;
END_VAR
CounterGlobal(Reset:=Reset);
CounterOut := CounterGlobal.Out;
END_PROGRAM
CONFIGURATION Config0
VAR_GLOBAL
CounterGlobal : CounterST;
END_VAR
RESOURCE Res0 ON PLC
TASK task0(INTERVAL := T#20ms,PRIORITY := 0);
PROGRAM instance0 WITH task0 : program0;
END_RESOURCE
END_CONFIGURATION
2.错误位置
// variable setting macros
#define __SET_VAR(prefix, name, suffix, new_value)\
if (!(prefix name.flags & __IEC_FORCE_FLAG)) prefix name.value suffix = new_value
#define __SET_EXTERNAL(prefix, name, suffix, new_value)\
{extern IEC_BYTE __IS_GLOBAL_##name##_FORCED(void);\
if (!(prefix name.flags & __IEC_FORCE_FLAG || __IS_GLOBAL_##name##_FORCED()))\
(*(prefix name.value)) suffix = new_value;}
#define __SET_EXTERNAL_FB(prefix, name, suffix, new_value)\
__SET_VAR((*(prefix name)), suffix, new_value)
#define __SET_LOCATED(prefix, name, suffix, new_value)\
if (!(prefix name.flags & __IEC_FORCE_FLAG)) *(prefix name.value) suffix = new_value
#endif //__ACCESSOR_H
__SET_VAR会判断flags是否置位,如果没置位则进行变量赋值。
__SET_EXTERNAL_FB先取外部变量的指针,然后调用__SET_VAR进行赋值
本地变量宏替换后
__SET_VAR(data__->COUNTLOCAL.,RESET,,__GET_VAR(data__->RESET,));
//宏替换后
if (!(data__->COUNTLOCAL.RESET.flags & __IEC_FORCE_FLAG))
data__->COUNTLOCAL.RESET.value = __GET_VAR(data__->RESET,)
全局变量宏替换后
__SET_EXTERNAL_FB(data__->COUNTERGLOBAL.,RESET,,__GET_VAR(data__->RESET,));
//宏替换后
__SET_VAR(*(data__->COUNTERGLOBAL.RESET),,__GET_VAR(data__->RESET,))
//继续宏替换(此时调用__SET_VAR会缺少一个输入变量,但是可以推测替换结果)
if (!(*(data__->COUNTERGLOBAL.RESET).flags & __IEC_FORCE_FLAG))
*(data__->COUNTERGLOBAL.RESET).value = __GET_VAR(data__->RESET,)
修改后的代码和编译错误信息
// variable setting macros
#define __SET_VAR(prefix, name, suffix, new_value)\
if (!(prefix name.flags & __IEC_FORCE_FLAG)) prefix name.value suffix = new_value
#define __SET_EXTERNAL(prefix, name, suffix, new_value)\
{extern IEC_BYTE __IS_GLOBAL_##name##_FORCED(void);\
if (!(prefix name.flags & __IEC_FORCE_FLAG || __IS_GLOBAL_##name##_FORCED()))\
(*(prefix name.value)) suffix = new_value;}
#define __SET_EXTERNAL_FB(prefix, name, suffix, new_value)\
if (!(*(data__->COUNTERGLOBAL.RESET).flags & __IEC_FORCE_FLAG)) *(data__->COUNTERGLOBAL.RESET).value = __GET_VAR(data__->RESET,)
#define __SET_LOCATED(prefix, name, suffix, new_value)\
if (!(prefix name.flags & __IEC_FORCE_FLAG)) *(prefix name.value) suffix = new_value
#endif //__ACCESSOR_H
编译.c文件到.o文件
gcc -c Res0.c -I ./ -I ..\..\..\..\matiec\lib\C
最终matiec修改方案