Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
osie
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
osie
Commits
5ca48d3b
Commit
5ca48d3b
authored
Sep 12, 2023
by
Ivan Tyagov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename.
parent
45be5af0
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
3971 additions
and
0 deletions
+3971
-0
Beremiz/beremiz_oi_production_line/beremiz.xml
Beremiz/beremiz_oi_production_line/beremiz.xml
+0
-0
Beremiz/beremiz_oi_production_line/build/LOCATED_VARIABLES.h
Beremiz/beremiz_oi_production_line/build/LOCATED_VARIABLES.h
+5
-0
Beremiz/beremiz_oi_production_line/build/POUS.c
Beremiz/beremiz_oi_production_line/build/POUS.c
+572
-0
Beremiz/beremiz_oi_production_line/build/POUS.h
Beremiz/beremiz_oi_production_line/build/POUS.h
+236
-0
Beremiz/beremiz_oi_production_line/build/VARIABLES.csv
Beremiz/beremiz_oi_production_line/build/VARIABLES.csv
+32
-0
Beremiz/beremiz_oi_production_line/build/beremiz.h
Beremiz/beremiz_oi_production_line/build/beremiz.h
+44
-0
Beremiz/beremiz_oi_production_line/build/config.c
Beremiz/beremiz_oi_production_line/build/config.c
+52
-0
Beremiz/beremiz_oi_production_line/build/config.h
Beremiz/beremiz_oi_production_line/build/config.h
+9
-0
Beremiz/beremiz_oi_production_line/build/extra_files/runtime_00_pyext.py
..._oi_production_line/build/extra_files/runtime_00_pyext.py
+91
-0
Beremiz/beremiz_oi_production_line/build/generated_plc.st
Beremiz/beremiz_oi_production_line/build/generated_plc.st
+76
-0
Beremiz/beremiz_oi_production_line/build/lastbuildPLC.md5
Beremiz/beremiz_oi_production_line/build/lastbuildPLC.md5
+1
-0
Beremiz/beremiz_oi_production_line/build/opcua_client__0.c
Beremiz/beremiz_oi_production_line/build/opcua_client__0.c
+181
-0
Beremiz/beremiz_oi_production_line/build/opcua_client__1.c
Beremiz/beremiz_oi_production_line/build/opcua_client__1.c
+175
-0
Beremiz/beremiz_oi_production_line/build/opcua_client__2.c
Beremiz/beremiz_oi_production_line/build/opcua_client__2.c
+175
-0
Beremiz/beremiz_oi_production_line/build/plc.st
Beremiz/beremiz_oi_production_line/build/plc.st
+302
-0
Beremiz/beremiz_oi_production_line/build/plc_debugger.c
Beremiz/beremiz_oi_production_line/build/plc_debugger.c
+557
-0
Beremiz/beremiz_oi_production_line/build/plc_main.c
Beremiz/beremiz_oi_production_line/build/plc_main.c
+1114
-0
Beremiz/beremiz_oi_production_line/build/py_ext.c
Beremiz/beremiz_oi_production_line/build/py_ext.c
+221
-0
Beremiz/beremiz_oi_production_line/build/resource1.c
Beremiz/beremiz_oi_production_line/build/resource1.c
+37
-0
Beremiz/beremiz_oi_production_line/build/runtime_00_pyext.py
Beremiz/beremiz_oi_production_line/build/runtime_00_pyext.py
+91
-0
Beremiz/beremiz_oi_production_line/opcua_0_oi_sensor@opcua/baseconfnode.xml
..._production_line/opcua_0_oi_sensor@opcua/baseconfnode.xml
+0
-0
Beremiz/beremiz_oi_production_line/opcua_0_oi_sensor@opcua/confnode.xml
...z_oi_production_line/opcua_0_oi_sensor@opcua/confnode.xml
+0
-0
Beremiz/beremiz_oi_production_line/opcua_0_oi_sensor@opcua/selected.csv
...z_oi_production_line/opcua_0_oi_sensor@opcua/selected.csv
+0
-0
Beremiz/beremiz_oi_production_line/opcua_1_coupler@opcua/baseconfnode.xml
...oi_production_line/opcua_1_coupler@opcua/baseconfnode.xml
+0
-0
Beremiz/beremiz_oi_production_line/opcua_1_coupler@opcua/confnode.xml
...miz_oi_production_line/opcua_1_coupler@opcua/confnode.xml
+0
-0
Beremiz/beremiz_oi_production_line/opcua_1_coupler@opcua/selected.csv
...miz_oi_production_line/opcua_1_coupler@opcua/selected.csv
+0
-0
Beremiz/beremiz_oi_production_line/opcua_2_mes5@opcua/baseconfnode.xml
...iz_oi_production_line/opcua_2_mes5@opcua/baseconfnode.xml
+0
-0
Beremiz/beremiz_oi_production_line/opcua_2_mes5@opcua/confnode.xml
...eremiz_oi_production_line/opcua_2_mes5@opcua/confnode.xml
+0
-0
Beremiz/beremiz_oi_production_line/opcua_2_mes5@opcua/selected.csv
...eremiz_oi_production_line/opcua_2_mes5@opcua/selected.csv
+0
-0
Beremiz/beremiz_oi_production_line/plc.xml
Beremiz/beremiz_oi_production_line/plc.xml
+0
-0
No files found.
Beremiz/beremiz_oi_
sensor_tutorial
/beremiz.xml
→
Beremiz/beremiz_oi_
production_line
/beremiz.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_production_line/build/LOCATED_VARIABLES.h
0 → 100644
View file @
5ca48d3b
__LOCATED_VAR
(
LREAL
,
__IL1_2
,
I
,
L
,
1
,
2
)
__LOCATED_VAR
(
DINT
,
__QD0_0
,
Q
,
D
,
0
,
0
)
__LOCATED_VAR
(
DINT
,
__QD0_1
,
Q
,
D
,
0
,
1
)
__LOCATED_VAR
(
LINT
,
__IL2_2
,
I
,
L
,
2
,
2
)
__LOCATED_VAR
(
LINT
,
__QL2_2
,
Q
,
L
,
2
,
2
)
Beremiz/beremiz_oi_production_line/build/POUS.c
0 → 100644
View file @
5ca48d3b
void
LOGGER_init__
(
LOGGER
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
TRIG
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
MSG
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
LEVEL
,
LOGLEVEL__INFO
,
retain
)
__INIT_VAR
(
data__
->
TRIG0
,
__BOOL_LITERAL
(
FALSE
),
retain
)
}
// Code part
void
LOGGER_body__
(
LOGGER
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
if
((
__GET_VAR
(
data__
->
TRIG
,)
&&
!
(
__GET_VAR
(
data__
->
TRIG0
,))))
{
#define GetFbVar(var,...) __GET_VAR(data__->var,__VA_ARGS__)
#define SetFbVar(var,val,...) __SET_VAR(data__->,var,__VA_ARGS__,val)
LogMessage
(
GetFbVar
(
LEVEL
),(
char
*
)
GetFbVar
(
MSG
,
.
body
),
GetFbVar
(
MSG
,
.
len
));
#undef GetFbVar
#undef SetFbVar
;
};
__SET_VAR
(
data__
->
,
TRIG0
,,
__GET_VAR
(
data__
->
TRIG
,));
goto
__end
;
__end:
return
;
}
// LOGGER_body__()
void
PYTHON_EVAL_init__
(
PYTHON_EVAL
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
TRIG
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
CODE
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
ACK
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
RESULT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
STATE
,
0
,
retain
)
__INIT_VAR
(
data__
->
BUFFER
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
PREBUFFER
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
TRIGM1
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
TRIGGED
,
__BOOL_LITERAL
(
FALSE
),
retain
)
}
// Code part
void
PYTHON_EVAL_body__
(
PYTHON_EVAL
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__IL_DEFVAR_T
__IL_DEFVAR
;
__IL_DEFVAR_T
__IL_DEFVAR_BACK
;
#define GetFbVar(var,...) __GET_VAR(data__->var,__VA_ARGS__)
#define SetFbVar(var,val,...) __SET_VAR(data__->,var,__VA_ARGS__,val)
extern
void
__PythonEvalFB
(
int
,
PYTHON_EVAL
*
);
__PythonEvalFB
(
0
,
data__
);
#undef GetFbVar
#undef SetFbVar
;
goto
__end
;
__end:
return
;
}
// PYTHON_EVAL_body__()
void
CSV_READ_BY_STRING_init__
(
CSV_READ_BY_STRING
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_EXTERNAL
(
BOOL
,
PYEXT_CSV_UPDATE
,
data__
->
PYEXT_CSV_UPDATE
,
retain
)
__INIT_VAR
(
data__
->
ACK
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
RESULT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
FILE_NAME
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
ROW
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
COLUMN
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
OLDCODE
,
__STRING_LITERAL
(
0
,
""
),
retain
)
PYTHON_EVAL_init__
(
&
data__
->
PY_EVAL
,
retain
);
R_TRIG_init__
(
&
data__
->
R_TRIG0
,
retain
);
R_TRIG_init__
(
&
data__
->
R_TRIG1
,
retain
);
SR_init__
(
&
data__
->
SR0
,
retain
);
__INIT_VAR
(
data__
->
_TMP_CONCAT7_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_NE16_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_SEL18_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_OR15_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_LEFT33_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_NE34_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_AND39_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
R_TRIG_init__
(
&
data__
->
R_TRIG2
,
retain
);
}
// Code part
void
CSV_READ_BY_STRING_body__
(
CSV_READ_BY_STRING
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__SET_VAR
(
data__
->
,
_TMP_CONCAT7_OUT
,,
CONCAT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
7
,
(
STRING
)
__STRING_LITERAL
(
10
,
"CSVRdStr(
\"
"
),
(
STRING
)
__GET_VAR
(
data__
->
FILE_NAME
,),
(
STRING
)
__STRING_LITERAL
(
3
,
"
\"
,
\"
"
),
(
STRING
)
__GET_VAR
(
data__
->
ROW
,),
(
STRING
)
__STRING_LITERAL
(
3
,
"
\"
,
\"
"
),
(
STRING
)
__GET_VAR
(
data__
->
COLUMN
,),
(
STRING
)
__STRING_LITERAL
(
2
,
"
\"
)"
)));
__SET_VAR
(
data__
->
,
_TMP_NE16_OUT
,,
NE__BOOL__STRING__STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
STRING
)
__GET_VAR
(
data__
->
_TMP_CONCAT7_OUT
,),
(
STRING
)
__GET_VAR
(
data__
->
OLDCODE
,)));
__SET_VAR
(
data__
->
,
_TMP_SEL18_OUT
,,
SEL__STRING__BOOL__STRING__STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NE16_OUT
,),
(
STRING
)
__GET_VAR
(
data__
->
OLDCODE
,),
(
STRING
)
__GET_VAR
(
data__
->
_TMP_CONCAT7_OUT
,)));
__SET_VAR
(
data__
->
,
OLDCODE
,,
__GET_VAR
(
data__
->
_TMP_SEL18_OUT
,));
__SET_VAR
(
data__
->
R_TRIG0
.,
CLK
,,
__GET_EXTERNAL
(
data__
->
PYEXT_CSV_UPDATE
,));
R_TRIG_body__
(
&
data__
->
R_TRIG0
);
__SET_VAR
(
data__
->
,
_TMP_OR15_OUT
,,
OR__BOOL__BOOL
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
BOOL
)
__GET_VAR
(
data__
->
R_TRIG0
.
Q
,),
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NE16_OUT
,)));
__SET_VAR
(
data__
->
PY_EVAL
.,
TRIG
,,
__GET_VAR
(
data__
->
_TMP_OR15_OUT
,));
__SET_VAR
(
data__
->
PY_EVAL
.,
CODE
,,
__GET_VAR
(
data__
->
_TMP_CONCAT7_OUT
,));
PYTHON_EVAL_body__
(
&
data__
->
PY_EVAL
);
__SET_VAR
(
data__
->
R_TRIG1
.,
CLK
,,
__GET_VAR
(
data__
->
PY_EVAL
.
ACK
,));
R_TRIG_body__
(
&
data__
->
R_TRIG1
);
__SET_VAR
(
data__
->
,
_TMP_LEFT33_OUT
,,
LEFT__STRING__STRING__SINT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
STRING
)
__GET_VAR
(
data__
->
PY_EVAL
.
RESULT
,),
(
SINT
)
1
));
__SET_VAR
(
data__
->
,
_TMP_NE34_OUT
,,
NE__BOOL__STRING__STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
STRING
)
__GET_VAR
(
data__
->
_TMP_LEFT33_OUT
,),
(
STRING
)
__STRING_LITERAL
(
1
,
"#"
)));
__SET_VAR
(
data__
->
,
_TMP_AND39_OUT
,,
AND__BOOL__BOOL
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
BOOL
)
__GET_VAR
(
data__
->
R_TRIG1
.
Q
,),
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NE34_OUT
,)));
__SET_VAR
(
data__
->
R_TRIG2
.,
CLK
,,
__GET_VAR
(
data__
->
_TMP_OR15_OUT
,));
R_TRIG_body__
(
&
data__
->
R_TRIG2
);
__SET_VAR
(
data__
->
SR0
.,
S1
,,
__GET_VAR
(
data__
->
_TMP_AND39_OUT
,));
__SET_VAR
(
data__
->
SR0
.,
R
,,
__GET_VAR
(
data__
->
R_TRIG2
.
Q
,));
SR_body__
(
&
data__
->
SR0
);
__SET_VAR
(
data__
->
,
ACK
,,
__GET_VAR
(
data__
->
SR0
.
Q1
,));
__SET_VAR
(
data__
->
,
RESULT
,,
__GET_VAR
(
data__
->
PY_EVAL
.
RESULT
,));
goto
__end
;
__end:
return
;
}
// CSV_READ_BY_STRING_body__()
void
PYTHON_GEAR_init__
(
PYTHON_GEAR
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
N
,
0
,
retain
)
__INIT_VAR
(
data__
->
TRIG
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
CODE
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
ACK
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
RESULT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
PYTHON_EVAL_init__
(
&
data__
->
PY_EVAL
,
retain
);
__INIT_VAR
(
data__
->
COUNTER
,
0
,
retain
)
__INIT_VAR
(
data__
->
_TMP_ADD10_OUT
,
0
,
retain
)
__INIT_VAR
(
data__
->
_TMP_EQ13_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_SEL15_OUT
,
0
,
retain
)
__INIT_VAR
(
data__
->
_TMP_AND7_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
}
// Code part
void
PYTHON_GEAR_body__
(
PYTHON_GEAR
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__SET_VAR
(
data__
->
,
_TMP_ADD10_OUT
,,
ADD__UINT__UINT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
UINT
)
__GET_VAR
(
data__
->
COUNTER
,),
(
UINT
)
1
));
__SET_VAR
(
data__
->
,
_TMP_EQ13_OUT
,,
EQ__BOOL__UINT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
UINT
)
__GET_VAR
(
data__
->
N
,),
(
UINT
)
__GET_VAR
(
data__
->
_TMP_ADD10_OUT
,)));
__SET_VAR
(
data__
->
,
_TMP_SEL15_OUT
,,
SEL__UINT__BOOL__UINT__UINT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_EQ13_OUT
,),
(
UINT
)
__GET_VAR
(
data__
->
_TMP_ADD10_OUT
,),
(
UINT
)
0
));
__SET_VAR
(
data__
->
,
COUNTER
,,
__GET_VAR
(
data__
->
_TMP_SEL15_OUT
,));
__SET_VAR
(
data__
->
,
_TMP_AND7_OUT
,,
AND__BOOL__BOOL
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_EQ13_OUT
,),
(
BOOL
)
__GET_VAR
(
data__
->
TRIG
,)));
__SET_VAR
(
data__
->
PY_EVAL
.,
TRIG
,,
__GET_VAR
(
data__
->
_TMP_AND7_OUT
,));
__SET_VAR
(
data__
->
PY_EVAL
.,
CODE
,,
__GET_VAR
(
data__
->
CODE
,));
PYTHON_EVAL_body__
(
&
data__
->
PY_EVAL
);
__SET_VAR
(
data__
->
,
ACK
,,
__GET_VAR
(
data__
->
PY_EVAL
.
ACK
,));
__SET_VAR
(
data__
->
,
RESULT
,,
__GET_VAR
(
data__
->
PY_EVAL
.
RESULT
,));
goto
__end
;
__end:
return
;
}
// PYTHON_GEAR_body__()
static
inline
BOOL
__CSV_RELOAD_MOVE__BOOL__BOOL1
(
BOOL
EN
,
BOOL
IN
,
CSV_RELOAD
*
data__
)
{
BOOL
__res
;
BOOL
__TMP_ENO
=
__GET_VAR
(
data__
->
_TMP_MOVE12_ENO
,);
__res
=
MOVE__BOOL__BOOL
(
EN
,
&
__TMP_ENO
,
IN
);
__SET_VAR
(,
data__
->
_TMP_MOVE12_ENO
,,
__TMP_ENO
);
return
__res
;
}
void
CSV_RELOAD_init__
(
CSV_RELOAD
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_EXTERNAL
(
BOOL
,
PYEXT_CSV_UPDATE
,
data__
->
PYEXT_CSV_UPDATE
,
retain
)
__INIT_VAR
(
data__
->
ACK
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
RESULT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
PYTHON_EVAL_init__
(
&
data__
->
PY_EVAL
,
retain
);
__INIT_VAR
(
data__
->
TRIG
,
__BOOL_LITERAL
(
FALSE
),
retain
)
R_TRIG_init__
(
&
data__
->
R_TRIG0
,
retain
);
F_TRIG_init__
(
&
data__
->
F_TRIG0
,
retain
);
__INIT_VAR
(
data__
->
_TMP_OR11_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_NOT13_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_MOVE12_ENO
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_MOVE12_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
}
// Code part
void
CSV_RELOAD_body__
(
CSV_RELOAD
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__SET_VAR
(
data__
->
PY_EVAL
.,
TRIG
,,
__GET_VAR
(
data__
->
TRIG
,));
__SET_VAR
(
data__
->
PY_EVAL
.,
CODE
,,
__STRING_LITERAL
(
18
,
"pyext_csv_reload()"
));
PYTHON_EVAL_body__
(
&
data__
->
PY_EVAL
);
__SET_VAR
(
data__
->
R_TRIG0
.,
CLK
,,
__GET_VAR
(
data__
->
PY_EVAL
.
ACK
,));
R_TRIG_body__
(
&
data__
->
R_TRIG0
);
__SET_VAR
(
data__
->
F_TRIG0
.,
CLK
,,
__GET_VAR
(
data__
->
PY_EVAL
.
ACK
,));
F_TRIG_body__
(
&
data__
->
F_TRIG0
);
__SET_VAR
(
data__
->
,
_TMP_OR11_OUT
,,
OR__BOOL__BOOL
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
BOOL
)
__GET_VAR
(
data__
->
R_TRIG0
.
Q
,),
(
BOOL
)
__GET_VAR
(
data__
->
F_TRIG0
.
Q
,)));
__SET_VAR
(
data__
->
,
_TMP_NOT13_OUT
,,
!
(
__GET_VAR
(
data__
->
R_TRIG0
.
Q
,)));
__SET_VAR
(
data__
->
,
_TMP_MOVE12_OUT
,,
__CSV_RELOAD_MOVE__BOOL__BOOL1
(
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_OR11_OUT
,),
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NOT13_OUT
,),
data__
));
if
(
__GET_VAR
(
data__
->
_TMP_MOVE12_ENO
,))
{
__SET_EXTERNAL
(
data__
->
,
PYEXT_CSV_UPDATE
,,
__GET_VAR
(
data__
->
_TMP_MOVE12_OUT
,));
};
__SET_VAR
(
data__
->
,
ACK
,,
__GET_VAR
(
data__
->
PY_EVAL
.
ACK
,));
__SET_VAR
(
data__
->
,
RESULT
,,
__GET_VAR
(
data__
->
PY_EVAL
.
RESULT
,));
goto
__end
;
__end:
return
;
}
// CSV_RELOAD_body__()
void
CSV_READ_BY_INT_init__
(
CSV_READ_BY_INT
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_EXTERNAL
(
BOOL
,
PYEXT_CSV_UPDATE
,
data__
->
PYEXT_CSV_UPDATE
,
retain
)
__INIT_VAR
(
data__
->
ACK
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
RESULT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
FILE_NAME
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
ROW
,
0
,
retain
)
__INIT_VAR
(
data__
->
COLUMN
,
0
,
retain
)
__INIT_VAR
(
data__
->
OLDCODE
,
__STRING_LITERAL
(
0
,
""
),
retain
)
PYTHON_EVAL_init__
(
&
data__
->
PY_EVAL0
,
retain
);
R_TRIG_init__
(
&
data__
->
R_TRIG1
,
retain
);
R_TRIG_init__
(
&
data__
->
R_TRIG2
,
retain
);
SR_init__
(
&
data__
->
SR0
,
retain
);
__INIT_VAR
(
data__
->
_TMP_INT_TO_STRING31_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_INT_TO_STRING2_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_CONCAT7_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_NE16_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_SEL18_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_OR15_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_LEFT33_OUT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
_TMP_NE34_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
_TMP_AND39_OUT
,
__BOOL_LITERAL
(
FALSE
),
retain
)
R_TRIG_init__
(
&
data__
->
R_TRIG3
,
retain
);
}
// Code part
void
CSV_READ_BY_INT_body__
(
CSV_READ_BY_INT
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__SET_VAR
(
data__
->
,
_TMP_INT_TO_STRING31_OUT
,,
INT_TO_STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
INT
)
__GET_VAR
(
data__
->
ROW
,)));
__SET_VAR
(
data__
->
,
_TMP_INT_TO_STRING2_OUT
,,
INT_TO_STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
INT
)
__GET_VAR
(
data__
->
COLUMN
,)));
__SET_VAR
(
data__
->
,
_TMP_CONCAT7_OUT
,,
CONCAT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
7
,
(
STRING
)
__STRING_LITERAL
(
10
,
"CSVRdInt(
\"
"
),
(
STRING
)
__GET_VAR
(
data__
->
FILE_NAME
,),
(
STRING
)
__STRING_LITERAL
(
2
,
"
\"
,"
),
(
STRING
)
__GET_VAR
(
data__
->
_TMP_INT_TO_STRING31_OUT
,),
(
STRING
)
__STRING_LITERAL
(
1
,
","
),
(
STRING
)
__GET_VAR
(
data__
->
_TMP_INT_TO_STRING2_OUT
,),
(
STRING
)
__STRING_LITERAL
(
1
,
")"
)));
__SET_VAR
(
data__
->
,
_TMP_NE16_OUT
,,
NE__BOOL__STRING__STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
STRING
)
__GET_VAR
(
data__
->
_TMP_CONCAT7_OUT
,),
(
STRING
)
__GET_VAR
(
data__
->
OLDCODE
,)));
__SET_VAR
(
data__
->
,
_TMP_SEL18_OUT
,,
SEL__STRING__BOOL__STRING__STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NE16_OUT
,),
(
STRING
)
__GET_VAR
(
data__
->
OLDCODE
,),
(
STRING
)
__GET_VAR
(
data__
->
_TMP_CONCAT7_OUT
,)));
__SET_VAR
(
data__
->
,
OLDCODE
,,
__GET_VAR
(
data__
->
_TMP_SEL18_OUT
,));
__SET_VAR
(
data__
->
R_TRIG1
.,
CLK
,,
__GET_EXTERNAL
(
data__
->
PYEXT_CSV_UPDATE
,));
R_TRIG_body__
(
&
data__
->
R_TRIG1
);
__SET_VAR
(
data__
->
,
_TMP_OR15_OUT
,,
OR__BOOL__BOOL
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
BOOL
)
__GET_VAR
(
data__
->
R_TRIG1
.
Q
,),
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NE16_OUT
,)));
__SET_VAR
(
data__
->
PY_EVAL0
.,
TRIG
,,
__GET_VAR
(
data__
->
_TMP_OR15_OUT
,));
__SET_VAR
(
data__
->
PY_EVAL0
.,
CODE
,,
__GET_VAR
(
data__
->
_TMP_CONCAT7_OUT
,));
PYTHON_EVAL_body__
(
&
data__
->
PY_EVAL0
);
__SET_VAR
(
data__
->
R_TRIG2
.,
CLK
,,
__GET_VAR
(
data__
->
PY_EVAL0
.
ACK
,));
R_TRIG_body__
(
&
data__
->
R_TRIG2
);
__SET_VAR
(
data__
->
,
_TMP_LEFT33_OUT
,,
LEFT__STRING__STRING__SINT
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
STRING
)
__GET_VAR
(
data__
->
PY_EVAL0
.
RESULT
,),
(
SINT
)
1
));
__SET_VAR
(
data__
->
,
_TMP_NE34_OUT
,,
NE__BOOL__STRING__STRING
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
STRING
)
__GET_VAR
(
data__
->
_TMP_LEFT33_OUT
,),
(
STRING
)
__STRING_LITERAL
(
1
,
"#"
)));
__SET_VAR
(
data__
->
,
_TMP_AND39_OUT
,,
AND__BOOL__BOOL
(
(
BOOL
)
__BOOL_LITERAL
(
TRUE
),
NULL
,
(
UINT
)
2
,
(
BOOL
)
__GET_VAR
(
data__
->
R_TRIG2
.
Q
,),
(
BOOL
)
__GET_VAR
(
data__
->
_TMP_NE34_OUT
,)));
__SET_VAR
(
data__
->
R_TRIG3
.,
CLK
,,
__GET_VAR
(
data__
->
_TMP_OR15_OUT
,));
R_TRIG_body__
(
&
data__
->
R_TRIG3
);
__SET_VAR
(
data__
->
SR0
.,
S1
,,
__GET_VAR
(
data__
->
_TMP_AND39_OUT
,));
__SET_VAR
(
data__
->
SR0
.,
R
,,
__GET_VAR
(
data__
->
R_TRIG3
.
Q
,));
SR_body__
(
&
data__
->
SR0
);
__SET_VAR
(
data__
->
,
ACK
,,
__GET_VAR
(
data__
->
SR0
.
Q1
,));
__SET_VAR
(
data__
->
,
RESULT
,,
__GET_VAR
(
data__
->
PY_EVAL0
.
RESULT
,));
goto
__end
;
__end:
return
;
}
// CSV_READ_BY_INT_body__()
void
PYTHON_POLL_init__
(
PYTHON_POLL
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
TRIG
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
CODE
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
ACK
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
RESULT
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
STATE
,
0
,
retain
)
__INIT_VAR
(
data__
->
BUFFER
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
PREBUFFER
,
__STRING_LITERAL
(
0
,
""
),
retain
)
__INIT_VAR
(
data__
->
TRIGM1
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
TRIGGED
,
__BOOL_LITERAL
(
FALSE
),
retain
)
}
// Code part
void
PYTHON_POLL_body__
(
PYTHON_POLL
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__IL_DEFVAR_T
__IL_DEFVAR
;
__IL_DEFVAR_T
__IL_DEFVAR_BACK
;
#define GetFbVar(var,...) __GET_VAR(data__->var,__VA_ARGS__)
#define SetFbVar(var,val,...) __SET_VAR(data__->,var,__VA_ARGS__,val)
extern
void
__PythonEvalFB
(
int
,
PYTHON_EVAL
*
);
__PythonEvalFB
(
1
,(
PYTHON_EVAL
*
)(
void
*
)
data__
);
#undef GetFbVar
#undef SetFbVar
;
goto
__end
;
__end:
return
;
}
// PYTHON_POLL_body__()
void
COUNTERST_init__
(
COUNTERST
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
EN
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
ENO
,
__BOOL_LITERAL
(
TRUE
),
retain
)
__INIT_VAR
(
data__
->
RESET
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
OUT1
,
0
,
retain
)
__INIT_VAR
(
data__
->
OUT0
,
0
,
retain
)
__INIT_VAR
(
data__
->
CNT0
,
0
,
retain
)
__INIT_EXTERNAL
(
INT
,
RESETCOUNTERVALUE
,
data__
->
RESETCOUNTERVALUE
,
retain
)
__INIT_EXTERNAL
(
LREAL
,
OI_SENSOR_COUNTER
,
data__
->
OI_SENSOR_COUNTER
,
retain
)
__INIT_EXTERNAL
(
DINT
,
VFD_RELAY0
,
data__
->
VFD_RELAY0
,
retain
)
__INIT_EXTERNAL
(
DINT
,
AIR_VALVE_RELAY0
,
data__
->
AIR_VALVE_RELAY0
,
retain
)
__INIT_EXTERNAL
(
LINT
,
MES5_INT_COUNTER_IN
,
data__
->
MES5_INT_COUNTER_IN
,
retain
)
__INIT_EXTERNAL
(
LINT
,
MES5_INT_COUNTER_OUT
,
data__
->
MES5_INT_COUNTER_OUT
,
retain
)
}
// Code part
void
COUNTERST_body__
(
COUNTERST
*
data__
)
{
// Control execution
if
(
!
__GET_VAR
(
data__
->
EN
))
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
FALSE
));
return
;
}
else
{
__SET_VAR
(
data__
->
,
ENO
,,
__BOOL_LITERAL
(
TRUE
));
}
// Initialise TEMP variables
__SET_EXTERNAL
(
data__
->
,
VFD_RELAY0
,,
1
);
if
((
__GET_EXTERNAL
(
data__
->
OI_SENSOR_COUNTER
,)
==
2
.
0
))
{
__SET_EXTERNAL
(
data__
->
,
AIR_VALVE_RELAY0
,,
1
);
__SET_EXTERNAL
(
data__
->
,
MES5_INT_COUNTER_IN
,,(
__GET_EXTERNAL
(
data__
->
MES5_INT_COUNTER_IN
,)
+
1
));
__SET_EXTERNAL
(
data__
->
,
MES5_INT_COUNTER_OUT
,,
__GET_EXTERNAL
(
data__
->
MES5_INT_COUNTER_IN
,));
};
if
((((
__GET_EXTERNAL
(
data__
->
OI_SENSOR_COUNTER
,)
==
0
.
0
)
||
(
__GET_EXTERNAL
(
data__
->
OI_SENSOR_COUNTER
,)
==
1
.
0
))
||
(
__GET_EXTERNAL
(
data__
->
OI_SENSOR_COUNTER
,)
==
3
.
0
)))
{
__SET_EXTERNAL
(
data__
->
,
AIR_VALVE_RELAY0
,,
0
);
};
goto
__end
;
__end:
return
;
}
// COUNTERST_body__()
void
PLC_PRG_init__
(
PLC_PRG
*
data__
,
BOOL
retain
)
{
__INIT_VAR
(
data__
->
RESET
,
__BOOL_LITERAL
(
FALSE
),
retain
)
__INIT_VAR
(
data__
->
CNT0
,
0
,
retain
)
__INIT_VAR
(
data__
->
CNT1
,
0
,
retain
)
COUNTERST_init__
(
&
data__
->
COUNTERST0
,
retain
);
}
// Code part
void
PLC_PRG_body__
(
PLC_PRG
*
data__
)
{
// Initialise TEMP variables
__SET_VAR
(
data__
->
COUNTERST0
.,
RESET
,,
__GET_VAR
(
data__
->
RESET
,));
COUNTERST_body__
(
&
data__
->
COUNTERST0
);
__SET_VAR
(
data__
->
,
CNT1
,,
__GET_VAR
(
data__
->
COUNTERST0
.
OUT1
,));
__SET_VAR
(
data__
->
,
CNT0
,,
__GET_VAR
(
data__
->
COUNTERST0
.
OUT0
,));
goto
__end
;
__end:
return
;
}
// PLC_PRG_body__()
Beremiz/beremiz_oi_production_line/build/POUS.h
0 → 100644
View file @
5ca48d3b
#include "beremiz.h"
#ifndef __POUS_H
#define __POUS_H
#include "accessor.h"
#include "iec_std_lib.h"
__DECLARE_ENUMERATED_TYPE
(
LOGLEVEL
,
LOGLEVEL__CRITICAL
,
LOGLEVEL__WARNING
,
LOGLEVEL__INFO
,
LOGLEVEL__DEBUG
)
// FUNCTION_BLOCK LOGGER
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
TRIG
)
__DECLARE_VAR
(
STRING
,
MSG
)
__DECLARE_VAR
(
LOGLEVEL
,
LEVEL
)
// FB private variables - TEMP, private and located variables
__DECLARE_VAR
(
BOOL
,
TRIG0
)
}
LOGGER
;
void
LOGGER_init__
(
LOGGER
*
data__
,
BOOL
retain
);
// Code part
void
LOGGER_body__
(
LOGGER
*
data__
);
// FUNCTION_BLOCK PYTHON_EVAL
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
TRIG
)
__DECLARE_VAR
(
STRING
,
CODE
)
__DECLARE_VAR
(
BOOL
,
ACK
)
__DECLARE_VAR
(
STRING
,
RESULT
)
// FB private variables - TEMP, private and located variables
__DECLARE_VAR
(
DWORD
,
STATE
)
__DECLARE_VAR
(
STRING
,
BUFFER
)
__DECLARE_VAR
(
STRING
,
PREBUFFER
)
__DECLARE_VAR
(
BOOL
,
TRIGM1
)
__DECLARE_VAR
(
BOOL
,
TRIGGED
)
}
PYTHON_EVAL
;
void
PYTHON_EVAL_init__
(
PYTHON_EVAL
*
data__
,
BOOL
retain
);
// Code part
void
PYTHON_EVAL_body__
(
PYTHON_EVAL
*
data__
);
// FUNCTION_BLOCK CSV_READ_BY_STRING
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
ACK
)
__DECLARE_VAR
(
STRING
,
RESULT
)
__DECLARE_VAR
(
STRING
,
FILE_NAME
)
__DECLARE_VAR
(
STRING
,
ROW
)
__DECLARE_VAR
(
STRING
,
COLUMN
)
// FB private variables - TEMP, private and located variables
__DECLARE_EXTERNAL
(
BOOL
,
PYEXT_CSV_UPDATE
)
__DECLARE_VAR
(
STRING
,
OLDCODE
)
PYTHON_EVAL
PY_EVAL
;
R_TRIG
R_TRIG0
;
R_TRIG
R_TRIG1
;
SR
SR0
;
__DECLARE_VAR
(
STRING
,
_TMP_CONCAT7_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_NE16_OUT
)
__DECLARE_VAR
(
STRING
,
_TMP_SEL18_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_OR15_OUT
)
__DECLARE_VAR
(
STRING
,
_TMP_LEFT33_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_NE34_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_AND39_OUT
)
R_TRIG
R_TRIG2
;
}
CSV_READ_BY_STRING
;
void
CSV_READ_BY_STRING_init__
(
CSV_READ_BY_STRING
*
data__
,
BOOL
retain
);
// Code part
void
CSV_READ_BY_STRING_body__
(
CSV_READ_BY_STRING
*
data__
);
// FUNCTION_BLOCK PYTHON_GEAR
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
UINT
,
N
)
__DECLARE_VAR
(
BOOL
,
TRIG
)
__DECLARE_VAR
(
STRING
,
CODE
)
__DECLARE_VAR
(
BOOL
,
ACK
)
__DECLARE_VAR
(
STRING
,
RESULT
)
// FB private variables - TEMP, private and located variables
PYTHON_EVAL
PY_EVAL
;
__DECLARE_VAR
(
UINT
,
COUNTER
)
__DECLARE_VAR
(
UINT
,
_TMP_ADD10_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_EQ13_OUT
)
__DECLARE_VAR
(
UINT
,
_TMP_SEL15_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_AND7_OUT
)
}
PYTHON_GEAR
;
void
PYTHON_GEAR_init__
(
PYTHON_GEAR
*
data__
,
BOOL
retain
);
// Code part
void
PYTHON_GEAR_body__
(
PYTHON_GEAR
*
data__
);
// FUNCTION_BLOCK CSV_RELOAD
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
ACK
)
__DECLARE_VAR
(
STRING
,
RESULT
)
__DECLARE_VAR
(
BOOL
,
TRIG
)
// FB private variables - TEMP, private and located variables
__DECLARE_EXTERNAL
(
BOOL
,
PYEXT_CSV_UPDATE
)
PYTHON_EVAL
PY_EVAL
;
R_TRIG
R_TRIG0
;
F_TRIG
F_TRIG0
;
__DECLARE_VAR
(
BOOL
,
_TMP_OR11_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_NOT13_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_MOVE12_ENO
)
__DECLARE_VAR
(
BOOL
,
_TMP_MOVE12_OUT
)
}
CSV_RELOAD
;
void
CSV_RELOAD_init__
(
CSV_RELOAD
*
data__
,
BOOL
retain
);
// Code part
void
CSV_RELOAD_body__
(
CSV_RELOAD
*
data__
);
// FUNCTION_BLOCK CSV_READ_BY_INT
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
ACK
)
__DECLARE_VAR
(
STRING
,
RESULT
)
__DECLARE_VAR
(
STRING
,
FILE_NAME
)
__DECLARE_VAR
(
INT
,
ROW
)
__DECLARE_VAR
(
INT
,
COLUMN
)
// FB private variables - TEMP, private and located variables
__DECLARE_EXTERNAL
(
BOOL
,
PYEXT_CSV_UPDATE
)
__DECLARE_VAR
(
STRING
,
OLDCODE
)
PYTHON_EVAL
PY_EVAL0
;
R_TRIG
R_TRIG1
;
R_TRIG
R_TRIG2
;
SR
SR0
;
__DECLARE_VAR
(
STRING
,
_TMP_INT_TO_STRING31_OUT
)
__DECLARE_VAR
(
STRING
,
_TMP_INT_TO_STRING2_OUT
)
__DECLARE_VAR
(
STRING
,
_TMP_CONCAT7_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_NE16_OUT
)
__DECLARE_VAR
(
STRING
,
_TMP_SEL18_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_OR15_OUT
)
__DECLARE_VAR
(
STRING
,
_TMP_LEFT33_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_NE34_OUT
)
__DECLARE_VAR
(
BOOL
,
_TMP_AND39_OUT
)
R_TRIG
R_TRIG3
;
}
CSV_READ_BY_INT
;
void
CSV_READ_BY_INT_init__
(
CSV_READ_BY_INT
*
data__
,
BOOL
retain
);
// Code part
void
CSV_READ_BY_INT_body__
(
CSV_READ_BY_INT
*
data__
);
// FUNCTION_BLOCK PYTHON_POLL
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
TRIG
)
__DECLARE_VAR
(
STRING
,
CODE
)
__DECLARE_VAR
(
BOOL
,
ACK
)
__DECLARE_VAR
(
STRING
,
RESULT
)
// FB private variables - TEMP, private and located variables
__DECLARE_VAR
(
DWORD
,
STATE
)
__DECLARE_VAR
(
STRING
,
BUFFER
)
__DECLARE_VAR
(
STRING
,
PREBUFFER
)
__DECLARE_VAR
(
BOOL
,
TRIGM1
)
__DECLARE_VAR
(
BOOL
,
TRIGGED
)
}
PYTHON_POLL
;
void
PYTHON_POLL_init__
(
PYTHON_POLL
*
data__
,
BOOL
retain
);
// Code part
void
PYTHON_POLL_body__
(
PYTHON_POLL
*
data__
);
// FUNCTION_BLOCK COUNTERST
// Data part
typedef
struct
{
// FB Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
EN
)
__DECLARE_VAR
(
BOOL
,
ENO
)
__DECLARE_VAR
(
BOOL
,
RESET
)
__DECLARE_VAR
(
INT
,
OUT1
)
__DECLARE_VAR
(
INT
,
OUT0
)
// FB private variables - TEMP, private and located variables
__DECLARE_VAR
(
INT
,
CNT0
)
__DECLARE_EXTERNAL
(
INT
,
RESETCOUNTERVALUE
)
__DECLARE_EXTERNAL
(
LREAL
,
OI_SENSOR_COUNTER
)
__DECLARE_EXTERNAL
(
DINT
,
VFD_RELAY0
)
__DECLARE_EXTERNAL
(
DINT
,
AIR_VALVE_RELAY0
)
__DECLARE_EXTERNAL
(
LINT
,
MES5_INT_COUNTER_IN
)
__DECLARE_EXTERNAL
(
LINT
,
MES5_INT_COUNTER_OUT
)
}
COUNTERST
;
void
COUNTERST_init__
(
COUNTERST
*
data__
,
BOOL
retain
);
// Code part
void
COUNTERST_body__
(
COUNTERST
*
data__
);
// PROGRAM PLC_PRG
// Data part
typedef
struct
{
// PROGRAM Interface - IN, OUT, IN_OUT variables
__DECLARE_VAR
(
BOOL
,
RESET
)
__DECLARE_VAR
(
INT
,
CNT0
)
__DECLARE_VAR
(
INT
,
CNT1
)
// PROGRAM private variables - TEMP, private and located variables
COUNTERST
COUNTERST0
;
}
PLC_PRG
;
void
PLC_PRG_init__
(
PLC_PRG
*
data__
,
BOOL
retain
);
// Code part
void
PLC_PRG_body__
(
PLC_PRG
*
data__
);
#endif //__POUS_H
Beremiz/beremiz_oi_production_line/build/VARIABLES.csv
0 → 100644
View file @
5ca48d3b
// Programs
0;CONFIG.RESOURCE1.INSTANCE0;PLC_PRG;
// Variables
0;VAR;CONFIG.RESETCOUNTERVALUE;CONFIG.RESETCOUNTERVALUE;INT;INT;0;
1;IN;CONFIG.OI_SENSOR_COUNTER;CONFIG.OI_SENSOR_COUNTER;LREAL;LREAL;0;
2;OUT;CONFIG.VFD_RELAY0;CONFIG.VFD_RELAY0;DINT;DINT;0;
3;OUT;CONFIG.AIR_VALVE_RELAY0;CONFIG.AIR_VALVE_RELAY0;DINT;DINT;0;
4;IN;CONFIG.MES5_INT_COUNTER_IN;CONFIG.MES5_INT_COUNTER_IN;LINT;LINT;0;
5;OUT;CONFIG.MES5_INT_COUNTER_OUT;CONFIG.MES5_INT_COUNTER_OUT;LINT;LINT;0;
6;VAR;CONFIG.PYEXT_CSV_UPDATE;CONFIG.PYEXT_CSV_UPDATE;BOOL;BOOL;0;
7;FB;CONFIG.RESOURCE1.INSTANCE0;CONFIG.RESOURCE1.INSTANCE0;PLC_PRG;;0;
8;VAR;CONFIG.RESOURCE1.INSTANCE0.RESET;CONFIG.RESOURCE1.INSTANCE0.RESET;BOOL;BOOL;0;
9;VAR;CONFIG.RESOURCE1.INSTANCE0.CNT0;CONFIG.RESOURCE1.INSTANCE0.CNT0;INT;INT;0;
10;VAR;CONFIG.RESOURCE1.INSTANCE0.CNT1;CONFIG.RESOURCE1.INSTANCE0.CNT1;INT;INT;0;
11;FB;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0;COUNTERST;;0;
12;VAR;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.EN;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.EN;BOOL;BOOL;0;
13;VAR;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.ENO;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.ENO;BOOL;BOOL;0;
14;VAR;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.RESET;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.RESET;BOOL;BOOL;0;
15;VAR;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.OUT1;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.OUT1;INT;INT;0;
16;VAR;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.OUT0;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.OUT0;INT;INT;0;
17;VAR;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.CNT0;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.CNT0;INT;INT;0;
18;EXT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.RESETCOUNTERVALUE;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.RESETCOUNTERVALUE;INT;INT;0;
19;EXT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.OI_SENSOR_COUNTER;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.OI_SENSOR_COUNTER;LREAL;LREAL;0;
20;EXT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.VFD_RELAY0;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.VFD_RELAY0;DINT;DINT;0;
21;EXT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.AIR_VALVE_RELAY0;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.AIR_VALVE_RELAY0;DINT;DINT;0;
22;EXT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.MES5_INT_COUNTER_IN;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.MES5_INT_COUNTER_IN;LINT;LINT;0;
23;EXT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.MES5_INT_COUNTER_OUT;CONFIG.RESOURCE1.INSTANCE0.COUNTERST0.MES5_INT_COUNTER_OUT;LINT;LINT;0;
// Ticktime
50000000
Beremiz/beremiz_oi_production_line/build/beremiz.h
0 → 100644
View file @
5ca48d3b
#ifndef _BEREMIZ_H_
#define _BEREMIZ_H_
/* Beremiz' header file for use by extensions */
#include "iec_types.h"
#define LOG_LEVELS 4
#define LOG_CRITICAL 0
#define LOG_WARNING 1
#define LOG_INFO 2
#define LOG_DEBUG 3
extern
unsigned
long
long
common_ticktime__
;
#ifdef TARGET_LOGGING_DISABLE
static
inline
int
LogMessage
(
uint8_t
level
,
char
*
buf
,
uint32_t
size
)
{
(
void
)
level
;
(
void
)
buf
;
(
void
)
size
;
return
0
;
}
#else
int
LogMessage
(
uint8_t
level
,
char
*
buf
,
uint32_t
size
);
#endif
long
AtomicCompareExchange
(
long
*
atomicvar
,
long
compared
,
long
exchange
);
void
*
create_RT_to_nRT_signal
(
char
*
name
);
void
delete_RT_to_nRT_signal
(
void
*
handle
);
int
wait_RT_to_nRT_signal
(
void
*
handle
);
int
unblock_RT_to_nRT_signal
(
void
*
handle
);
void
nRT_reschedule
(
void
);
#ifdef REALTIME_LINUX
#ifndef PLC_THREAD_PRIORITY
#define PLC_THREAD_PRIORITY 80
#endif
#endif
#endif
Beremiz/beremiz_oi_production_line/build/config.c
0 → 100644
View file @
5ca48d3b
/*******************************************/
/* FILE GENERATED BY iec2c */
/* Editing this file is not recommended... */
/*******************************************/
#include "iec_std_lib.h"
#include "accessor.h"
#include "POUS.h"
// CONFIGURATION CONFIG
__DECLARE_GLOBAL
(
INT
,
CONFIG
,
RESETCOUNTERVALUE
)
__DECLARE_GLOBAL_LOCATION
(
LREAL
,
__IL1_2
)
__DECLARE_GLOBAL_LOCATED
(
LREAL
,
CONFIG
,
OI_SENSOR_COUNTER
)
__DECLARE_GLOBAL_LOCATION
(
DINT
,
__QD0_0
)
__DECLARE_GLOBAL_LOCATED
(
DINT
,
CONFIG
,
VFD_RELAY0
)
__DECLARE_GLOBAL_LOCATION
(
DINT
,
__QD0_1
)
__DECLARE_GLOBAL_LOCATED
(
DINT
,
CONFIG
,
AIR_VALVE_RELAY0
)
__DECLARE_GLOBAL_LOCATION
(
LINT
,
__IL2_2
)
__DECLARE_GLOBAL_LOCATED
(
LINT
,
CONFIG
,
MES5_INT_COUNTER_IN
)
__DECLARE_GLOBAL_LOCATION
(
LINT
,
__QL2_2
)
__DECLARE_GLOBAL_LOCATED
(
LINT
,
CONFIG
,
MES5_INT_COUNTER_OUT
)
__DECLARE_GLOBAL
(
BOOL
,
CONFIG
,
PYEXT_CSV_UPDATE
)
void
RESOURCE1_init__
(
void
);
void
config_init__
(
void
)
{
BOOL
retain
;
retain
=
0
;
__INIT_GLOBAL
(
INT
,
RESETCOUNTERVALUE
,
__INITIAL_VALUE
(
0
),
retain
)
__INIT_GLOBAL_LOCATED
(
CONFIG
,
OI_SENSOR_COUNTER
,
__IL1_2
,
retain
)
__INIT_GLOBAL
(
LREAL
,
OI_SENSOR_COUNTER
,
__INITIAL_VALUE
(
0
),
retain
)
__INIT_GLOBAL_LOCATED
(
CONFIG
,
VFD_RELAY0
,
__QD0_0
,
retain
)
__INIT_GLOBAL
(
DINT
,
VFD_RELAY0
,
__INITIAL_VALUE
(
0
),
retain
)
__INIT_GLOBAL_LOCATED
(
CONFIG
,
AIR_VALVE_RELAY0
,
__QD0_1
,
retain
)
__INIT_GLOBAL
(
DINT
,
AIR_VALVE_RELAY0
,
__INITIAL_VALUE
(
0
),
retain
)
__INIT_GLOBAL_LOCATED
(
CONFIG
,
MES5_INT_COUNTER_IN
,
__IL2_2
,
retain
)
__INIT_GLOBAL
(
LINT
,
MES5_INT_COUNTER_IN
,
__INITIAL_VALUE
(
0
),
retain
)
__INIT_GLOBAL_LOCATED
(
CONFIG
,
MES5_INT_COUNTER_OUT
,
__QL2_2
,
retain
)
__INIT_GLOBAL
(
LINT
,
MES5_INT_COUNTER_OUT
,
__INITIAL_VALUE
(
0
),
retain
)
__INIT_GLOBAL
(
BOOL
,
PYEXT_CSV_UPDATE
,
__INITIAL_VALUE
(
__BOOL_LITERAL
(
TRUE
)),
retain
)
RESOURCE1_init__
();
}
void
RESOURCE1_run__
(
unsigned
long
tick
);
void
config_run__
(
unsigned
long
tick
)
{
RESOURCE1_run__
(
tick
);
}
unsigned
long
long
common_ticktime__
=
50000000ULL
*
1ULL
;
/*ns*/
unsigned
long
greatest_tick_count__
=
(
unsigned
long
)
0UL
;
/*tick*/
Beremiz/beremiz_oi_production_line/build/config.h
0 → 100644
View file @
5ca48d3b
#include "beremiz.h"
__DECLARE_GLOBAL_PROTOTYPE
(
INT
,
RESETCOUNTERVALUE
)
__DECLARE_GLOBAL_PROTOTYPE
(
LREAL
,
OI_SENSOR_COUNTER
)
__DECLARE_GLOBAL_PROTOTYPE
(
DINT
,
VFD_RELAY0
)
__DECLARE_GLOBAL_PROTOTYPE
(
DINT
,
AIR_VALVE_RELAY0
)
__DECLARE_GLOBAL_PROTOTYPE
(
LINT
,
MES5_INT_COUNTER_IN
)
__DECLARE_GLOBAL_PROTOTYPE
(
LINT
,
MES5_INT_COUNTER_OUT
)
__DECLARE_GLOBAL_PROTOTYPE
(
BOOL
,
PYEXT_CSV_UPDATE
)
Beremiz/beremiz_oi_production_line/build/extra_files/runtime_00_pyext.py
0 → 100644
View file @
5ca48d3b
import
csv
from
collections
import
OrderedDict
csv_int_files
=
{}
def
CSVRdInt
(
fname
,
rowidx
,
colidx
):
"""
Return value at row/column pointed by integer indexes
Assumes data starts at first row and first column, no headers.
"""
global
csv_int_files
data
=
csv_int_files
.
get
(
fname
,
None
)
if
data
is
None
:
data
=
list
()
try
:
csvfile
=
open
(
fname
,
'rb'
)
except
IOError
:
return
"#FILE_NOT_FOUND"
try
:
dialect
=
csv
.
Sniffer
().
sniff
(
csvfile
.
read
(
1024
))
csvfile
.
seek
(
0
)
reader
=
csv
.
reader
(
csvfile
,
dialect
)
for
row
in
reader
:
data
.
append
(
row
)
except
csv
.
Error
:
return
"#CSV_ERROR"
finally
:
csvfile
.
close
()
csv_int_files
[
fname
]
=
data
try
:
row
=
data
[
rowidx
]
except
IndexError
:
return
"#ROW_NOT_FOUND"
try
:
return
row
[
colidx
]
except
IndexError
:
return
"#COL_NOT_FOUND"
csv_str_files
=
{}
def
CSVRdStr
(
fname
,
rowname
,
colname
):
"""
Return value at row/column pointed by a pair of names as string
Assumes first row is column headers and first column is row name.
"""
global
csv_str_files
entry
=
csv_str_files
.
get
(
fname
,
None
)
if
entry
is
None
:
data
=
dict
()
try
:
csvfile
=
open
(
fname
,
'rb'
)
except
IOError
:
return
"#FILE_NOT_FOUND"
try
:
dialect
=
csv
.
Sniffer
().
sniff
(
csvfile
.
read
(
1024
))
csvfile
.
seek
(
0
)
reader
=
csv
.
reader
(
csvfile
,
dialect
)
headers
=
dict
([(
name
,
index
)
for
index
,
name
in
enumerate
(
reader
.
next
()[
1
:])])
for
row
in
reader
:
data
[
row
[
0
]]
=
row
[
1
:]
except
csv
.
Error
:
return
"#CSV_ERROR"
finally
:
csvfile
.
close
()
csv_str_files
[
fname
]
=
(
headers
,
data
)
else
:
headers
,
data
=
entry
try
:
row
=
data
[
rowname
]
except
KeyError
:
return
"#ROW_NOT_FOUND"
try
:
colidx
=
headers
[
colname
]
except
KeyError
:
return
"#COL_NOT_FOUND"
try
:
return
row
[
colidx
]
except
IndexError
:
return
"#COL_NOT_FOUND"
def
pyext_csv_reload
():
global
csv_int_files
,
csv_str_files
csv_int_files
.
clear
()
csv_str_files
.
clear
()
Beremiz/beremiz_oi_production_line/build/generated_plc.st
0 → 100644
View file @
5ca48d3b
FUNCTION_BLOCK
CounterST
VAR_INPUT
Reset
:
BOOL
;
END_VAR
VAR_OUTPUT
Out1
:
INT
;
Out0
:
INT
;
END_VAR
VAR
Cnt0
:
INT
;
END_VAR
VAR_EXTERNAL
ResetCounterValue
:
INT
;
OI_sensor_counter
:
LREAL
;
VFD_relay0
:
DINT
;
Air_Valve_Relay0
:
DINT
;
MES5_int_counter_in
:
LINT
;
MES5_int_counter_out
:
LINT
;
END_VAR
(
*
this
will
always
switch
on
VFD_relay0
which
controls
conveyor
line*
)
VFD_relay0
:=
1
;
IF
OI_sensor_counter=
2.0
THEN
(
*
a
rectangle
was
recognized
thus
switch
ON
air
valve
*
)
Air_Valve_Relay0
:=
1
;
(
*
read
from
MES5
counter
value
so
we
continue
from
where
we
were
.
In
this
case
increment
blow
counter
at
MES5*
)
MES5_int_counter_in
:=
MES5_int_counter_in
+
1
;
(
*
set
to
MES5
the
counter
value
so
it
is
kept
permanently
*
)
MES5_int_counter_out
:=
MES5_int_counter_in
;
END_IF
;
IF
OI_sensor_counter=
0.0
OR
OI_sensor_counter=
1.0
OR
OI_sensor_counter=
3.0
THEN
(
*
a
circle
/
triangle
or
nothing
was
recognized
thus
switch
OFF
air
valve
*
)
Air_Valve_Relay0
:=
0
;
END_IF
;
END_FUNCTION_BLOCK
PROGRAM
plc_prg
VAR_INPUT
Reset
:
BOOL
;
END_VAR
VAR_OUTPUT
Cnt0
:
INT
;
Cnt1
:
INT
;
END_VAR
VAR
CounterST0
:
CounterST
;
END_VAR
CounterST0
(
Reset
:=
Reset
);
Cnt1
:=
CounterST0
.
Out1
;
Cnt0
:=
CounterST0
.
Out0
;
END_PROGRAM
CONFIGURATION
config
VAR_GLOBAL
ResetCounterValue
:
INT
:=
0
;
OI_sensor_counter
AT
%
IL1
.
2
:
LREAL
;
VFD_relay0
AT
%
QD0
.
0
:
DINT
;
Air_Valve_Relay0
AT
%
QD0
.
1
:
DINT
;
MES5_int_counter_in
AT
%
IL2
.
2
:
LINT
;
MES5_int_counter_out
AT
%
QL2
.
2
:
LINT
;
END_VAR
VAR_GLOBAL
pyext_csv_update
:
BOOL
:=
TRUE
;
END_VAR
RESOURCE
resource1
ON
PLC
TASK
task0
(
INTERVAL
:=
T
#50ms
,
PRIORITY
:=
0
);
PROGRAM
instance0
WITH
task0
:
plc_prg
;
END_RESOURCE
END_CONFIGURATION
Beremiz/beremiz_oi_production_line/build/lastbuildPLC.md5
0 → 100644
View file @
5ca48d3b
e68d19e5f7e402decececb757d5ae127
\ No newline at end of file
Beremiz/beremiz_oi_production_line/build/opcua_client__0.c
0 → 100644
View file @
5ca48d3b
#include "beremiz.h"
/* code generated by beremiz OPC-UA extension */
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/log_stdout.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/plugin/securitypolicy_default.h>
#include <open62541/types.h>
#include <open62541/types_generated_handling.h>
#define _Log(level, ...) \
{ \
char mstr[256]; \
snprintf(mstr, 255, __VA_ARGS__); \
LogMessage(level, mstr, strlen(mstr)); \
}
#define LogInfo(...) _Log(LOG_INFO, __VA_ARGS__);
#define LogError(...) _Log(LOG_CRITICAL, __VA_ARGS__);
#define LogWarning(...) _Log(LOG_WARNING, __VA_ARGS__);
static
UA_INLINE
UA_ByteString
loadFile
(
const
char
*
const
path
)
{
UA_ByteString
fileContents
=
UA_STRING_NULL
;
FILE
*
fp
=
fopen
(
path
,
"rb"
);
if
(
!
fp
)
{
errno
=
0
;
LogError
(
"OPC-UA could not open %s"
,
path
);
return
fileContents
;
}
fseek
(
fp
,
0
,
SEEK_END
);
fileContents
.
length
=
(
size_t
)
ftell
(
fp
);
fileContents
.
data
=
(
UA_Byte
*
)
UA_malloc
(
fileContents
.
length
*
sizeof
(
UA_Byte
));
if
(
fileContents
.
data
)
{
fseek
(
fp
,
0
,
SEEK_SET
);
size_t
read
=
fread
(
fileContents
.
data
,
sizeof
(
UA_Byte
),
fileContents
.
length
,
fp
);
if
(
read
!=
fileContents
.
length
){
UA_ByteString_clear
(
&
fileContents
);
LogError
(
"OPC-UA could not read %s"
,
path
);
}
}
else
{
fileContents
.
length
=
0
;
LogError
(
"OPC-UA Not enough memoty to load %s"
,
path
);
}
fclose
(
fp
);
return
fileContents
;
}
static
UA_Client
*
client
;
static
UA_ClientConfig
*
cc
;
#define DECL_VAR(ua_type, C_type, c_loc_name) \
static UA_Variant c_loc_name##_variant; \
static C_type c_loc_name##_buf = 0; \
C_type *c_loc_name = &c_loc_name##_buf;
DECL_VAR
(
UA_Int32
,
uint32_t
,
__ID0_0
)
DECL_VAR
(
UA_Int32
,
uint32_t
,
__ID0_1
)
DECL_VAR
(
UA_Int32
,
uint32_t
,
__QD0_0
)
DECL_VAR
(
UA_Int32
,
uint32_t
,
__QD0_1
)
void
__cleanup_0
(
void
)
{
UA_Client_disconnect
(
client
);
UA_Client_delete
(
client
);
}
#define INIT_NoAuth() \
LogInfo("OPC-UA Init no auth"); \
UA_ClientConfig_setDefault(cc); \
retval = UA_Client_connect(client, uri);
/* Note : Single policy is enforced here, by default open62541 client supports all policies */
#define INIT_x509(Policy, UpperCaseMode, PrivateKey, Certificate) \
LogInfo("OPC-UA Init x509 %s,%s,%s,%s", #Policy, #UpperCaseMode, PrivateKey, Certificate); \
\
UA_ByteString certificate = loadFile(Certificate); \
UA_ByteString privateKey = loadFile(PrivateKey); \
\
cc->securityMode = UA_MESSAGESECURITYMODE_##UpperCaseMode; \
\
/* replacement for default behaviour */
\
/* UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, NULL, 0, NULL, 0); */
\
do{ \
retval = UA_ClientConfig_setDefault(cc); \
if(retval != UA_STATUSCODE_GOOD) \
break; \
\
UA_SecurityPolicy *sp = (UA_SecurityPolicy*) \
UA_realloc(cc->securityPolicies, sizeof(UA_SecurityPolicy) * 2); \
if(!sp){ \
retval = UA_STATUSCODE_BADOUTOFMEMORY; \
break; \
} \
cc->securityPolicies = sp; \
\
retval = UA_SecurityPolicy_##Policy(&cc->securityPolicies[cc->securityPoliciesSize], \
certificate, privateKey, &cc->logger); \
if(retval != UA_STATUSCODE_GOOD) { \
UA_LOG_WARNING(&cc->logger, UA_LOGCATEGORY_USERLAND, \
"Could not add SecurityPolicy Policy with error code %s", \
UA_StatusCode_name(retval)); \
UA_free(cc->securityPolicies); \
cc->securityPolicies = NULL; \
break; \
} \
\
++cc->securityPoliciesSize; \
} while(0); \
\
retval = UA_Client_connect(client, uri); \
\
UA_ByteString_clear(&certificate); \
UA_ByteString_clear(&privateKey);
#define INIT_UserPassword(User, Password) \
LogInfo("OPC-UA Init UserPassword %s,%s", User, Password); \
UA_ClientConfig_setDefault(cc); \
retval = UA_Client_connectUsername(client, uri, User, Password);
#define INIT_READ_VARIANT(ua_type, c_loc_name) \
UA_Variant_init(&c_loc_name##_variant);
#define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name) \
UA_Variant_setScalar(&c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]);
int
__init_0
(
int
argc
,
char
**
argv
)
{
UA_StatusCode
retval
;
client
=
UA_Client_new
();
cc
=
UA_Client_getConfig
(
client
);
char
*
uri
=
"opc.tcp://192.168.0.135:4840"
;
INIT_NoAuth
()
INIT_READ_VARIANT
(
UA_Int32
,
__ID0_0
)
INIT_READ_VARIANT
(
UA_Int32
,
__ID0_1
)
INIT_WRITE_VARIANT
(
UA_Int32
,
UA_TYPES_INT32
,
__QD0_0
)
INIT_WRITE_VARIANT
(
UA_Int32
,
UA_TYPES_INT32
,
__QD0_1
)
if
(
retval
!=
UA_STATUSCODE_GOOD
)
{
LogError
(
"OPC-UA Init Failed %d"
,
retval
);
UA_Client_delete
(
client
);
return
EXIT_FAILURE
;
}
return
0
;
}
#define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \
retval = UA_Client_readValueAttribute( \
client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant); \
if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(&c_loc_name##_variant) && \
c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) { \
c_loc_name##_buf = *(ua_type*)c_loc_name##_variant.data; \
UA_Variant_clear(&c_loc_name##_variant);
/* Unalloc requiered on each read ! */
\
}
void
__retrieve_0
(
void
)
{
UA_StatusCode
retval
;
READ_VALUE
(
UA_Int32
,
UA_TYPES_INT32
,
__ID0_0
,
UA_NODEID_STRING
,
1
,
"i2c0.relay0"
)
READ_VALUE
(
UA_Int32
,
UA_TYPES_INT32
,
__ID0_1
,
UA_NODEID_STRING
,
1
,
"i2c0.relay1"
)
}
#define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \
UA_Client_writeValueAttribute( \
client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);
void
__publish_0
(
void
)
{
WRITE_VALUE
(
UA_Int32
,
__QD0_0
,
UA_NODEID_STRING
,
1
,
"i2c0.relay0"
)
WRITE_VALUE
(
UA_Int32
,
__QD0_1
,
UA_NODEID_STRING
,
1
,
"i2c0.relay1"
)
}
Beremiz/beremiz_oi_production_line/build/opcua_client__1.c
0 → 100644
View file @
5ca48d3b
#include "beremiz.h"
/* code generated by beremiz OPC-UA extension */
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/log_stdout.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/plugin/securitypolicy_default.h>
#include <open62541/types.h>
#include <open62541/types_generated_handling.h>
#define _Log(level, ...) \
{ \
char mstr[256]; \
snprintf(mstr, 255, __VA_ARGS__); \
LogMessage(level, mstr, strlen(mstr)); \
}
#define LogInfo(...) _Log(LOG_INFO, __VA_ARGS__);
#define LogError(...) _Log(LOG_CRITICAL, __VA_ARGS__);
#define LogWarning(...) _Log(LOG_WARNING, __VA_ARGS__);
static
UA_INLINE
UA_ByteString
loadFile
(
const
char
*
const
path
)
{
UA_ByteString
fileContents
=
UA_STRING_NULL
;
FILE
*
fp
=
fopen
(
path
,
"rb"
);
if
(
!
fp
)
{
errno
=
0
;
LogError
(
"OPC-UA could not open %s"
,
path
);
return
fileContents
;
}
fseek
(
fp
,
0
,
SEEK_END
);
fileContents
.
length
=
(
size_t
)
ftell
(
fp
);
fileContents
.
data
=
(
UA_Byte
*
)
UA_malloc
(
fileContents
.
length
*
sizeof
(
UA_Byte
));
if
(
fileContents
.
data
)
{
fseek
(
fp
,
0
,
SEEK_SET
);
size_t
read
=
fread
(
fileContents
.
data
,
sizeof
(
UA_Byte
),
fileContents
.
length
,
fp
);
if
(
read
!=
fileContents
.
length
){
UA_ByteString_clear
(
&
fileContents
);
LogError
(
"OPC-UA could not read %s"
,
path
);
}
}
else
{
fileContents
.
length
=
0
;
LogError
(
"OPC-UA Not enough memoty to load %s"
,
path
);
}
fclose
(
fp
);
return
fileContents
;
}
static
UA_Client
*
client
;
static
UA_ClientConfig
*
cc
;
#define DECL_VAR(ua_type, C_type, c_loc_name) \
static UA_Variant c_loc_name##_variant; \
static C_type c_loc_name##_buf = 0; \
C_type *c_loc_name = &c_loc_name##_buf;
DECL_VAR
(
UA_Double
,
double
,
__IL1_2
)
DECL_VAR
(
UA_Double
,
double
,
__QL1_2
)
void
__cleanup_1
(
void
)
{
UA_Client_disconnect
(
client
);
UA_Client_delete
(
client
);
}
#define INIT_NoAuth() \
LogInfo("OPC-UA Init no auth"); \
UA_ClientConfig_setDefault(cc); \
retval = UA_Client_connect(client, uri);
/* Note : Single policy is enforced here, by default open62541 client supports all policies */
#define INIT_x509(Policy, UpperCaseMode, PrivateKey, Certificate) \
LogInfo("OPC-UA Init x509 %s,%s,%s,%s", #Policy, #UpperCaseMode, PrivateKey, Certificate); \
\
UA_ByteString certificate = loadFile(Certificate); \
UA_ByteString privateKey = loadFile(PrivateKey); \
\
cc->securityMode = UA_MESSAGESECURITYMODE_##UpperCaseMode; \
\
/* replacement for default behaviour */
\
/* UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, NULL, 0, NULL, 0); */
\
do{ \
retval = UA_ClientConfig_setDefault(cc); \
if(retval != UA_STATUSCODE_GOOD) \
break; \
\
UA_SecurityPolicy *sp = (UA_SecurityPolicy*) \
UA_realloc(cc->securityPolicies, sizeof(UA_SecurityPolicy) * 2); \
if(!sp){ \
retval = UA_STATUSCODE_BADOUTOFMEMORY; \
break; \
} \
cc->securityPolicies = sp; \
\
retval = UA_SecurityPolicy_##Policy(&cc->securityPolicies[cc->securityPoliciesSize], \
certificate, privateKey, &cc->logger); \
if(retval != UA_STATUSCODE_GOOD) { \
UA_LOG_WARNING(&cc->logger, UA_LOGCATEGORY_USERLAND, \
"Could not add SecurityPolicy Policy with error code %s", \
UA_StatusCode_name(retval)); \
UA_free(cc->securityPolicies); \
cc->securityPolicies = NULL; \
break; \
} \
\
++cc->securityPoliciesSize; \
} while(0); \
\
retval = UA_Client_connect(client, uri); \
\
UA_ByteString_clear(&certificate); \
UA_ByteString_clear(&privateKey);
#define INIT_UserPassword(User, Password) \
LogInfo("OPC-UA Init UserPassword %s,%s", User, Password); \
UA_ClientConfig_setDefault(cc); \
retval = UA_Client_connectUsername(client, uri, User, Password);
#define INIT_READ_VARIANT(ua_type, c_loc_name) \
UA_Variant_init(&c_loc_name##_variant);
#define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name) \
UA_Variant_setScalar(&c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]);
int
__init_1
(
int
argc
,
char
**
argv
)
{
UA_StatusCode
retval
;
client
=
UA_Client_new
();
cc
=
UA_Client_getConfig
(
client
);
char
*
uri
=
"opc.tcp://192.168.0.118:4840"
;
INIT_NoAuth
()
INIT_READ_VARIANT
(
UA_Double
,
__IL1_2
)
INIT_WRITE_VARIANT
(
UA_Double
,
UA_TYPES_DOUBLE
,
__QL1_2
)
if
(
retval
!=
UA_STATUSCODE_GOOD
)
{
LogError
(
"OPC-UA Init Failed %d"
,
retval
);
UA_Client_delete
(
client
);
return
EXIT_FAILURE
;
}
return
0
;
}
#define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \
retval = UA_Client_readValueAttribute( \
client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant); \
if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(&c_loc_name##_variant) && \
c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) { \
c_loc_name##_buf = *(ua_type*)c_loc_name##_variant.data; \
UA_Variant_clear(&c_loc_name##_variant);
/* Unalloc requiered on each read ! */
\
}
void
__retrieve_1
(
void
)
{
UA_StatusCode
retval
;
READ_VALUE
(
UA_Double
,
UA_TYPES_DOUBLE
,
__IL1_2
,
UA_NODEID_NUMERIC
,
2
,
2
)
}
#define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \
UA_Client_writeValueAttribute( \
client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);
void
__publish_1
(
void
)
{
WRITE_VALUE
(
UA_Double
,
__QL1_2
,
UA_NODEID_NUMERIC
,
2
,
2
)
}
Beremiz/beremiz_oi_production_line/build/opcua_client__2.c
0 → 100644
View file @
5ca48d3b
#include "beremiz.h"
/* code generated by beremiz OPC-UA extension */
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/log_stdout.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/plugin/securitypolicy_default.h>
#include <open62541/types.h>
#include <open62541/types_generated_handling.h>
#define _Log(level, ...) \
{ \
char mstr[256]; \
snprintf(mstr, 255, __VA_ARGS__); \
LogMessage(level, mstr, strlen(mstr)); \
}
#define LogInfo(...) _Log(LOG_INFO, __VA_ARGS__);
#define LogError(...) _Log(LOG_CRITICAL, __VA_ARGS__);
#define LogWarning(...) _Log(LOG_WARNING, __VA_ARGS__);
static
UA_INLINE
UA_ByteString
loadFile
(
const
char
*
const
path
)
{
UA_ByteString
fileContents
=
UA_STRING_NULL
;
FILE
*
fp
=
fopen
(
path
,
"rb"
);
if
(
!
fp
)
{
errno
=
0
;
LogError
(
"OPC-UA could not open %s"
,
path
);
return
fileContents
;
}
fseek
(
fp
,
0
,
SEEK_END
);
fileContents
.
length
=
(
size_t
)
ftell
(
fp
);
fileContents
.
data
=
(
UA_Byte
*
)
UA_malloc
(
fileContents
.
length
*
sizeof
(
UA_Byte
));
if
(
fileContents
.
data
)
{
fseek
(
fp
,
0
,
SEEK_SET
);
size_t
read
=
fread
(
fileContents
.
data
,
sizeof
(
UA_Byte
),
fileContents
.
length
,
fp
);
if
(
read
!=
fileContents
.
length
){
UA_ByteString_clear
(
&
fileContents
);
LogError
(
"OPC-UA could not read %s"
,
path
);
}
}
else
{
fileContents
.
length
=
0
;
LogError
(
"OPC-UA Not enough memoty to load %s"
,
path
);
}
fclose
(
fp
);
return
fileContents
;
}
static
UA_Client
*
client
;
static
UA_ClientConfig
*
cc
;
#define DECL_VAR(ua_type, C_type, c_loc_name) \
static UA_Variant c_loc_name##_variant; \
static C_type c_loc_name##_buf = 0; \
C_type *c_loc_name = &c_loc_name##_buf;
DECL_VAR
(
UA_Int64
,
int64_t
,
__IL2_2
)
DECL_VAR
(
UA_Int64
,
int64_t
,
__QL2_2
)
void
__cleanup_2
(
void
)
{
UA_Client_disconnect
(
client
);
UA_Client_delete
(
client
);
}
#define INIT_NoAuth() \
LogInfo("OPC-UA Init no auth"); \
UA_ClientConfig_setDefault(cc); \
retval = UA_Client_connect(client, uri);
/* Note : Single policy is enforced here, by default open62541 client supports all policies */
#define INIT_x509(Policy, UpperCaseMode, PrivateKey, Certificate) \
LogInfo("OPC-UA Init x509 %s,%s,%s,%s", #Policy, #UpperCaseMode, PrivateKey, Certificate); \
\
UA_ByteString certificate = loadFile(Certificate); \
UA_ByteString privateKey = loadFile(PrivateKey); \
\
cc->securityMode = UA_MESSAGESECURITYMODE_##UpperCaseMode; \
\
/* replacement for default behaviour */
\
/* UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, NULL, 0, NULL, 0); */
\
do{ \
retval = UA_ClientConfig_setDefault(cc); \
if(retval != UA_STATUSCODE_GOOD) \
break; \
\
UA_SecurityPolicy *sp = (UA_SecurityPolicy*) \
UA_realloc(cc->securityPolicies, sizeof(UA_SecurityPolicy) * 2); \
if(!sp){ \
retval = UA_STATUSCODE_BADOUTOFMEMORY; \
break; \
} \
cc->securityPolicies = sp; \
\
retval = UA_SecurityPolicy_##Policy(&cc->securityPolicies[cc->securityPoliciesSize], \
certificate, privateKey, &cc->logger); \
if(retval != UA_STATUSCODE_GOOD) { \
UA_LOG_WARNING(&cc->logger, UA_LOGCATEGORY_USERLAND, \
"Could not add SecurityPolicy Policy with error code %s", \
UA_StatusCode_name(retval)); \
UA_free(cc->securityPolicies); \
cc->securityPolicies = NULL; \
break; \
} \
\
++cc->securityPoliciesSize; \
} while(0); \
\
retval = UA_Client_connect(client, uri); \
\
UA_ByteString_clear(&certificate); \
UA_ByteString_clear(&privateKey);
#define INIT_UserPassword(User, Password) \
LogInfo("OPC-UA Init UserPassword %s,%s", User, Password); \
UA_ClientConfig_setDefault(cc); \
retval = UA_Client_connectUsername(client, uri, User, Password);
#define INIT_READ_VARIANT(ua_type, c_loc_name) \
UA_Variant_init(&c_loc_name##_variant);
#define INIT_WRITE_VARIANT(ua_type, ua_type_enum, c_loc_name) \
UA_Variant_setScalar(&c_loc_name##_variant, (ua_type*)c_loc_name, &UA_TYPES[ua_type_enum]);
int
__init_2
(
int
argc
,
char
**
argv
)
{
UA_StatusCode
retval
;
client
=
UA_Client_new
();
cc
=
UA_Client_getConfig
(
client
);
char
*
uri
=
"opc.tcp://192.168.0.118:4841"
;
INIT_NoAuth
()
INIT_READ_VARIANT
(
UA_Int64
,
__IL2_2
)
INIT_WRITE_VARIANT
(
UA_Int64
,
UA_TYPES_INT64
,
__QL2_2
)
if
(
retval
!=
UA_STATUSCODE_GOOD
)
{
LogError
(
"OPC-UA Init Failed %d"
,
retval
);
UA_Client_delete
(
client
);
return
EXIT_FAILURE
;
}
return
0
;
}
#define READ_VALUE(ua_type, ua_type_enum, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \
retval = UA_Client_readValueAttribute( \
client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant); \
if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(&c_loc_name##_variant) && \
c_loc_name##_variant.type == &UA_TYPES[ua_type_enum]) { \
c_loc_name##_buf = *(ua_type*)c_loc_name##_variant.data; \
UA_Variant_clear(&c_loc_name##_variant);
/* Unalloc requiered on each read ! */
\
}
void
__retrieve_2
(
void
)
{
UA_StatusCode
retval
;
READ_VALUE
(
UA_Int64
,
UA_TYPES_INT64
,
__IL2_2
,
UA_NODEID_NUMERIC
,
2
,
2
)
}
#define WRITE_VALUE(ua_type, c_loc_name, ua_nodeid_type, ua_nsidx, ua_node_id) \
UA_Client_writeValueAttribute( \
client, ua_nodeid_type(ua_nsidx, ua_node_id), &c_loc_name##_variant);
void
__publish_2
(
void
)
{
WRITE_VALUE
(
UA_Int64
,
__QL2_2
,
UA_NODEID_NUMERIC
,
2
,
2
)
}
Beremiz/beremiz_oi_production_line/build/plc.st
0 → 100644
View file @
5ca48d3b
TYPE
LOGLEVEL
:
(
CRITICAL
,
WARNING
,
INFO
,
DEBUG
)
:=
INFO
;
END_TYPE
FUNCTION_BLOCK
LOGGER
VAR_INPUT
TRIG
:
BOOL
;
MSG
:
STRING
;
LEVEL
:
LOGLEVEL
:=
INFO
;
END_VAR
VAR
TRIG0
:
BOOL
;
END_VAR
IF
TRIG
AND
NOT
TRIG0
THEN
{{
LogMessage
(
GetFbVar
(
LEVEL
)
,
(
char
*
)
GetFbVar
(
MSG
,
.
body
)
,
GetFbVar
(
MSG
,
.
len
));
}}
END_IF
;
TRIG0:
=
TRIG
;
END_FUNCTION_BLOCK
FUNCTION_BLOCK
python_eval
VAR_INPUT
TRIG
:
BOOL
;
CODE
:
STRING
;
END_VAR
VAR_OUTPUT
ACK
:
BOOL
;
RESULT
:
STRING
;
END_VAR
VAR
STATE
:
DWORD
;
BUFFER
:
STRING
;
PREBUFFER
:
STRING
;
TRIGM1
:
BOOL
;
TRIGGED
:
BOOL
;
END_VAR
{
extern
void
__
PythonEvalFB
(
int
,
PYTHON_EVAL
*
);
__
PythonEvalFB
(
0
,
data__
);}
END_FUNCTION_BLOCK
FUNCTION_BLOCK
csv_read_by_string
VAR_EXTERNAL
pyext_csv_update
:
BOOL
;
END_VAR
VAR_OUTPUT
ACK
:
BOOL
;
RESULT
:
STRING
;
END_VAR
VAR_INPUT
FILE_NAME
:
STRING
;
ROW
:
STRING
;
COLUMN
:
STRING
;
END_VAR
VAR
OLDCODE
:
STRING
;
py_eval
:
python_eval
;
R_TRIG0
:
R_TRIG
;
R_TRIG1
:
R_TRIG
;
SR0
:
SR
;
_
TMP_CONCAT7_OUT
:
STRING
;
_
TMP_NE16_OUT
:
BOOL
;
_
TMP_SEL18_OUT
:
STRING
;
_
TMP_OR15_OUT
:
BOOL
;
_
TMP_LEFT33_OUT
:
STRING
;
_
TMP_NE34_OUT
:
BOOL
;
_
TMP_AND39_OUT
:
BOOL
;
R_TRIG2
:
R_TRIG
;
END_VAR
_
TMP_CONCAT7_OUT
:=
CONCAT
(
'CSVRdStr("'
,
FILE_NAME
,
'","'
,
ROW
,
'","'
,
COLUMN
,
'")'
);
_
TMP_NE16_OUT
:=
NE
(
_
TMP_CONCAT7_OUT
,
OLDCODE
);
_
TMP_SEL18_OUT
:=
SEL
(
_
TMP_NE16_OUT
,
OLDCODE
,
_
TMP_CONCAT7_OUT
);
OLDCODE
:=
_
TMP_SEL18_OUT
;
R_TRIG0
(
CLK
:=
pyext_csv_update
);
_
TMP_OR15_OUT
:=
OR
(
R_TRIG0
.
Q
,
_
TMP_NE16_OUT
);
py_eval
(
TRIG
:=
_
TMP_OR15_OUT
,
CODE
:=
_
TMP_CONCAT7_OUT
);
R_TRIG1
(
CLK
:=
py_eval
.
ACK
);
_
TMP_LEFT33_OUT
:=
LEFT
(
py_eval
.
RESULT
,
1
);
_
TMP_NE34_OUT
:=
NE
(
_
TMP_LEFT33_OUT
,
'#'
);
_
TMP_AND39_OUT
:=
AND
(
R_TRIG1
.
Q
,
_
TMP_NE34_OUT
);
R_TRIG2
(
CLK
:=
_
TMP_OR15_OUT
);
SR0
(
S1
:=
_
TMP_AND39_OUT
,
R
:=
R_TRIG2
.
Q
);
ACK
:=
SR0
.
Q1
;
RESULT
:=
py_eval
.
RESULT
;
END_FUNCTION_BLOCK
FUNCTION_BLOCK
python_gear
VAR_INPUT
N
:
UINT
;
TRIG
:
BOOL
;
CODE
:
STRING
;
END_VAR
VAR_OUTPUT
ACK
:
BOOL
;
RESULT
:
STRING
;
END_VAR
VAR
py_eval
:
python_eval
;
COUNTER
:
UINT
;
_
TMP_ADD10_OUT
:
UINT
;
_
TMP_EQ13_OUT
:
BOOL
;
_
TMP_SEL15_OUT
:
UINT
;
_
TMP_AND7_OUT
:
BOOL
;
END_VAR
_
TMP_ADD10_OUT
:=
ADD
(
COUNTER
,
1
);
_
TMP_EQ13_OUT
:=
EQ
(
N
,
_
TMP_ADD10_OUT
);
_
TMP_SEL15_OUT
:=
SEL
(
_
TMP_EQ13_OUT
,
_
TMP_ADD10_OUT
,
0
);
COUNTER
:=
_
TMP_SEL15_OUT
;
_
TMP_AND7_OUT
:=
AND
(
_
TMP_EQ13_OUT
,
TRIG
);
py_eval
(
TRIG
:=
_
TMP_AND7_OUT
,
CODE
:=
CODE
);
ACK
:=
py_eval
.
ACK
;
RESULT
:=
py_eval
.
RESULT
;
END_FUNCTION_BLOCK
FUNCTION_BLOCK
csv_reload
VAR_EXTERNAL
pyext_csv_update
:
BOOL
;
END_VAR
VAR_OUTPUT
ACK
:
BOOL
;
RESULT
:
STRING
;
END_VAR
VAR
py_eval
:
python_eval
;
END_VAR
VAR_INPUT
TRIG
:
BOOL
;
END_VAR
VAR
R_TRIG0
:
R_TRIG
;
F_TRIG0
:
F_TRIG
;
_
TMP_OR11_OUT
:
BOOL
;
_
TMP_NOT13_OUT
:
BOOL
;
_
TMP_MOVE12_ENO
:
BOOL
;
_
TMP_MOVE12_OUT
:
BOOL
;
END_VAR
py_eval
(
TRIG
:=
TRIG
,
CODE
:=
'pyext_csv_reload()'
);
R_TRIG0
(
CLK
:=
py_eval
.
ACK
);
F_TRIG0
(
CLK
:=
py_eval
.
ACK
);
_
TMP_OR11_OUT
:=
OR
(
R_TRIG0
.
Q
,
F_TRIG0
.
Q
);
_
TMP_NOT13_OUT
:=
NOT
(
R_TRIG0
.
Q
);
_
TMP_MOVE12_OUT
:=
MOVE
(
EN
:=
_
TMP_OR11_OUT
,
IN
:=
_
TMP_NOT13_OUT
,
ENO
=>
_
TMP_MOVE12_ENO
);
IF
_
TMP_MOVE12_ENO
THEN
pyext_csv_update
:=
_
TMP_MOVE12_OUT
;
END_IF
;
ACK
:=
py_eval
.
ACK
;
RESULT
:=
py_eval
.
RESULT
;
END_FUNCTION_BLOCK
FUNCTION_BLOCK
csv_read_by_int
VAR_EXTERNAL
pyext_csv_update
:
BOOL
;
END_VAR
VAR_OUTPUT
ACK
:
BOOL
;
RESULT
:
STRING
;
END_VAR
VAR_INPUT
FILE_NAME
:
STRING
;
ROW
:
INT
;
COLUMN
:
INT
;
END_VAR
VAR
OLDCODE
:
STRING
;
py_eval0
:
python_eval
;
R_TRIG1
:
R_TRIG
;
R_TRIG2
:
R_TRIG
;
SR0
:
SR
;
_
TMP_INT_TO_STRING31_OUT
:
STRING
;
_
TMP_INT_TO_STRING2_OUT
:
STRING
;
_
TMP_CONCAT7_OUT
:
STRING
;
_
TMP_NE16_OUT
:
BOOL
;
_
TMP_SEL18_OUT
:
STRING
;
_
TMP_OR15_OUT
:
BOOL
;
_
TMP_LEFT33_OUT
:
STRING
;
_
TMP_NE34_OUT
:
BOOL
;
_
TMP_AND39_OUT
:
BOOL
;
R_TRIG3
:
R_TRIG
;
END_VAR
_
TMP_INT_TO_STRING31_OUT
:=
INT_TO_STRING
(
ROW
);
_
TMP_INT_TO_STRING2_OUT
:=
INT_TO_STRING
(
COLUMN
);
_
TMP_CONCAT7_OUT
:=
CONCAT
(
'CSVRdInt("'
,
FILE_NAME
,
'",'
,
_
TMP_INT_TO_STRING31_OUT
,
','
,
_
TMP_INT_TO_STRING2_OUT
,
')'
);
_
TMP_NE16_OUT
:=
NE
(
_
TMP_CONCAT7_OUT
,
OLDCODE
);
_
TMP_SEL18_OUT
:=
SEL
(
_
TMP_NE16_OUT
,
OLDCODE
,
_
TMP_CONCAT7_OUT
);
OLDCODE
:=
_
TMP_SEL18_OUT
;
R_TRIG1
(
CLK
:=
pyext_csv_update
);
_
TMP_OR15_OUT
:=
OR
(
R_TRIG1
.
Q
,
_
TMP_NE16_OUT
);
py_eval0
(
TRIG
:=
_
TMP_OR15_OUT
,
CODE
:=
_
TMP_CONCAT7_OUT
);
R_TRIG2
(
CLK
:=
py_eval0
.
ACK
);
_
TMP_LEFT33_OUT
:=
LEFT
(
py_eval0
.
RESULT
,
1
);
_
TMP_NE34_OUT
:=
NE
(
_
TMP_LEFT33_OUT
,
'#'
);
_
TMP_AND39_OUT
:=
AND
(
R_TRIG2
.
Q
,
_
TMP_NE34_OUT
);
R_TRIG3
(
CLK
:=
_
TMP_OR15_OUT
);
SR0
(
S1
:=
_
TMP_AND39_OUT
,
R
:=
R_TRIG3
.
Q
);
ACK
:=
SR0
.
Q1
;
RESULT
:=
py_eval0
.
RESULT
;
END_FUNCTION_BLOCK
FUNCTION_BLOCK
python_poll
VAR_INPUT
TRIG
:
BOOL
;
CODE
:
STRING
;
END_VAR
VAR_OUTPUT
ACK
:
BOOL
;
RESULT
:
STRING
;
END_VAR
VAR
STATE
:
DWORD
;
BUFFER
:
STRING
;
PREBUFFER
:
STRING
;
TRIGM1
:
BOOL
;
TRIGGED
:
BOOL
;
END_VAR
{
extern
void
__
PythonEvalFB
(
int
,
PYTHON_EVAL
*
);
__
PythonEvalFB
(
1
,
(
PYTHON_EVAL
*
)(
void
*
)
data__
);}
END_FUNCTION_BLOCK
FUNCTION_BLOCK
CounterST
VAR_INPUT
Reset
:
BOOL
;
END_VAR
VAR_OUTPUT
Out1
:
INT
;
Out0
:
INT
;
END_VAR
VAR
Cnt0
:
INT
;
END_VAR
VAR_EXTERNAL
ResetCounterValue
:
INT
;
OI_sensor_counter
:
LREAL
;
VFD_relay0
:
DINT
;
Air_Valve_Relay0
:
DINT
;
MES5_int_counter_in
:
LINT
;
MES5_int_counter_out
:
LINT
;
END_VAR
(
*
this
will
always
switch
on
VFD_relay0
which
controls
conveyor
line*
)
VFD_relay0
:=
1
;
IF
OI_sensor_counter=
2.0
THEN
(
*
a
rectangle
was
recognized
thus
switch
ON
air
valve
*
)
Air_Valve_Relay0
:=
1
;
(
*
read
from
MES5
counter
value
so
we
continue
from
where
we
were
.
In
this
case
increment
blow
counter
at
MES5*
)
MES5_int_counter_in
:=
MES5_int_counter_in
+
1
;
(
*
set
to
MES5
the
counter
value
so
it
is
kept
permanently
*
)
MES5_int_counter_out
:=
MES5_int_counter_in
;
END_IF
;
IF
OI_sensor_counter=
0.0
OR
OI_sensor_counter=
1.0
OR
OI_sensor_counter=
3.0
THEN
(
*
a
circle
/
triangle
or
nothing
was
recognized
thus
switch
OFF
air
valve
*
)
Air_Valve_Relay0
:=
0
;
END_IF
;
END_FUNCTION_BLOCK
PROGRAM
plc_prg
VAR_INPUT
Reset
:
BOOL
;
END_VAR
VAR_OUTPUT
Cnt0
:
INT
;
Cnt1
:
INT
;
END_VAR
VAR
CounterST0
:
CounterST
;
END_VAR
CounterST0
(
Reset
:=
Reset
);
Cnt1
:=
CounterST0
.
Out1
;
Cnt0
:=
CounterST0
.
Out0
;
END_PROGRAM
CONFIGURATION
config
VAR_GLOBAL
ResetCounterValue
:
INT
:=
0
;
OI_sensor_counter
AT
%
IL1
.
2
:
LREAL
;
VFD_relay0
AT
%
QD0
.
0
:
DINT
;
Air_Valve_Relay0
AT
%
QD0
.
1
:
DINT
;
MES5_int_counter_in
AT
%
IL2
.
2
:
LINT
;
MES5_int_counter_out
AT
%
QL2
.
2
:
LINT
;
END_VAR
VAR_GLOBAL
pyext_csv_update
:
BOOL
:=
TRUE
;
END_VAR
RESOURCE
resource1
ON
PLC
TASK
task0
(
INTERVAL
:=
T
#50ms
,
PRIORITY
:=
0
);
PROGRAM
instance0
WITH
task0
:
plc_prg
;
END_RESOURCE
END_CONFIGURATION
Beremiz/beremiz_oi_production_line/build/plc_debugger.c
0 → 100644
View file @
5ca48d3b
/*
* DEBUGGER code
*
* On "publish", when buffer is free, debugger stores arbitrary variables
* content into, and mark this buffer as filled
*
*
* Buffer content is read asynchronously, (from non real time part),
* and then buffer marked free again.
*
*
* */
#ifdef TARGET_DEBUG_AND_RETAIN_DISABLE
void
__init_debug
(
void
){}
void
__cleanup_debug
(
void
){}
void
__retrieve_debug
(
void
){}
void
__publish_debug
(
void
){}
#else
#include "iec_types_all.h"
#include "POUS.h"
/*for memcpy*/
#include <string.h>
#include <stdio.h>
typedef
unsigned
int
dbgvardsc_index_t
;
typedef
unsigned
short
trace_buf_offset_t
;
#define BUFFER_EMPTY 0
#define BUFFER_FULL 1
#ifndef TARGET_ONLINE_DEBUG_DISABLE
#define TRACE_BUFFER_SIZE 4096
#define TRACE_LIST_SIZE 1024
/* Atomically accessed variable for buffer state */
static
long
trace_buffer_state
=
BUFFER_EMPTY
;
typedef
struct
trace_item_s
{
dbgvardsc_index_t
dbgvardsc_index
;
}
trace_item_t
;
trace_item_t
trace_list
[
TRACE_LIST_SIZE
];
char
trace_buffer
[
TRACE_BUFFER_SIZE
];
/* Trace's cursor*/
static
trace_item_t
*
trace_list_collect_cursor
=
trace_list
;
static
trace_item_t
*
trace_list_addvar_cursor
=
trace_list
;
static
const
trace_item_t
*
trace_list_end
=
&
trace_list
[
TRACE_LIST_SIZE
-
1
];
static
char
*
trace_buffer_cursor
=
trace_buffer
;
static
const
char
*
trace_buffer_end
=
trace_buffer
+
TRACE_BUFFER_SIZE
;
#define FORCE_BUFFER_SIZE 1024
#define FORCE_LIST_SIZE 256
typedef
struct
force_item_s
{
dbgvardsc_index_t
dbgvardsc_index
;
void
*
value_pointer_backup
;
}
force_item_t
;
force_item_t
force_list
[
FORCE_LIST_SIZE
];
char
force_buffer
[
FORCE_BUFFER_SIZE
];
/* Force's cursor*/
static
force_item_t
*
force_list_apply_cursor
=
force_list
;
static
force_item_t
*
force_list_addvar_cursor
=
force_list
;
static
const
force_item_t
*
force_list_end
=
&
force_list
[
FORCE_LIST_SIZE
-
1
];
static
char
*
force_buffer_cursor
=
force_buffer
;
static
const
char
*
force_buffer_end
=
force_buffer
+
FORCE_BUFFER_SIZE
;
#endif
/***
* Declare programs
**/
extern
PLC_PRG
RESOURCE1__INSTANCE0
;
/***
* Declare global variables from resources and conf
**/
extern
__IEC_INT_t
CONFIG__RESETCOUNTERVALUE
;
extern
__IEC_LREAL_p
CONFIG__OI_SENSOR_COUNTER
;
extern
__IEC_DINT_p
CONFIG__VFD_RELAY0
;
extern
__IEC_DINT_p
CONFIG__AIR_VALVE_RELAY0
;
extern
__IEC_LINT_p
CONFIG__MES5_INT_COUNTER_IN
;
extern
__IEC_LINT_p
CONFIG__MES5_INT_COUNTER_OUT
;
extern
__IEC_BOOL_t
CONFIG__PYEXT_CSV_UPDATE
;
extern
PLC_PRG
RESOURCE1__INSTANCE0
;
typedef
const
struct
{
void
*
ptr
;
__IEC_types_enum
type
;
}
dbgvardsc_t
;
static
const
dbgvardsc_t
dbgvardsc
[]
=
{
{
&
(
CONFIG__RESETCOUNTERVALUE
),
INT_ENUM
},
{
&
(
CONFIG__OI_SENSOR_COUNTER
),
LREAL_P_ENUM
},
{
&
(
CONFIG__VFD_RELAY0
),
DINT_O_ENUM
},
{
&
(
CONFIG__AIR_VALVE_RELAY0
),
DINT_O_ENUM
},
{
&
(
CONFIG__MES5_INT_COUNTER_IN
),
LINT_P_ENUM
},
{
&
(
CONFIG__MES5_INT_COUNTER_OUT
),
LINT_O_ENUM
},
{
&
(
CONFIG__PYEXT_CSV_UPDATE
),
BOOL_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
RESET
),
BOOL_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
CNT0
),
INT_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
CNT1
),
INT_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
EN
),
BOOL_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
ENO
),
BOOL_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
RESET
),
BOOL_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
OUT1
),
INT_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
OUT0
),
INT_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
CNT0
),
INT_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
RESETCOUNTERVALUE
),
INT_P_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
OI_SENSOR_COUNTER
),
LREAL_P_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
VFD_RELAY0
),
DINT_P_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
AIR_VALVE_RELAY0
),
DINT_P_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
MES5_INT_COUNTER_IN
),
LINT_P_ENUM
},
{
&
(
RESOURCE1__INSTANCE0
.
COUNTERST0
.
MES5_INT_COUNTER_OUT
),
LINT_P_ENUM
}
};
static
const
dbgvardsc_index_t
retain_list
[]
=
{
};
static
unsigned
int
retain_list_collect_cursor
=
0
;
static
const
unsigned
int
retain_list_size
=
sizeof
(
retain_list
)
/
sizeof
(
dbgvardsc_index_t
);
typedef
void
(
*
__for_each_variable_do_fp
)(
dbgvardsc_t
*
);
void
__for_each_variable_do
(
__for_each_variable_do_fp
fp
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
dbgvardsc
)
/
sizeof
(
dbgvardsc_t
);
i
++
){
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
i
];
if
(
dsc
->
type
!=
UNKNOWN_ENUM
)
(
*
fp
)(
dsc
);
}
}
#define __Unpack_desc_type dbgvardsc_t
#define __Unpack_case_t(TYPENAME) \
case TYPENAME##_ENUM : \
if(flags) *flags = ((__IEC_##TYPENAME##_t *)varp)->flags; \
if(value_p) *value_p = &((__IEC_##TYPENAME##_t *)varp)->value; \
if(size) *size = sizeof(TYPENAME); \
break;
#define __Unpack_case_p(TYPENAME) \
case TYPENAME##_O_ENUM : \
case TYPENAME##_P_ENUM : \
if(flags) *flags = ((__IEC_##TYPENAME##_p *)varp)->flags; \
if(value_p) *value_p = ((__IEC_##TYPENAME##_p *)varp)->value; \
if(size) *size = sizeof(TYPENAME); \
break;
#define __Is_a_string(dsc) (dsc->type == STRING_ENUM) ||\
(dsc->type == STRING_P_ENUM) ||\
(dsc->type == STRING_O_ENUM)
static
int
UnpackVar
(
__Unpack_desc_type
*
dsc
,
void
**
value_p
,
char
*
flags
,
size_t
*
size
)
{
void
*
varp
=
dsc
->
ptr
;
/* find data to copy*/
switch
(
dsc
->
type
){
__ANY
(
__Unpack_case_t
)
__ANY
(
__Unpack_case_p
)
default:
return
0
;
/* should never happen */
}
return
1
;
}
void
Remind
(
unsigned
int
offset
,
unsigned
int
count
,
void
*
p
);
extern
int
CheckRetainBuffer
(
void
);
extern
void
InitRetain
(
void
);
void
__init_debug
(
void
)
{
/* init local static vars */
#ifndef TARGET_ONLINE_DEBUG_DISABLE
trace_buffer_cursor
=
trace_buffer
;
trace_list_addvar_cursor
=
trace_list
;
trace_list_collect_cursor
=
trace_list
;
trace_buffer_state
=
BUFFER_EMPTY
;
force_buffer_cursor
=
force_buffer
;
force_list_addvar_cursor
=
force_list
;
force_list_apply_cursor
=
force_list
;
#endif
InitRetain
();
/* Iterate over all variables to fill debug buffer */
if
(
CheckRetainBuffer
()){
unsigned
int
retain_offset
=
0
;
retain_list_collect_cursor
=
0
;
/* iterate over retain list */
while
(
retain_list_collect_cursor
<
retain_list_size
){
void
*
value_p
=
NULL
;
size_t
size
;
char
*
next_cursor
;
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
retain_list
[
retain_list_collect_cursor
]];
UnpackVar
(
dsc
,
&
value_p
,
NULL
,
&
size
);
/* if buffer not full */
Remind
(
retain_offset
,
size
,
value_p
);
/* increment cursor according size*/
retain_offset
+=
size
;
retain_list_collect_cursor
++
;
}
}
else
{
char
mstr
[]
=
"RETAIN memory invalid - defaults used"
;
LogMessage
(
LOG_WARNING
,
mstr
,
sizeof
(
mstr
));
}
}
extern
void
InitiateDebugTransfer
(
void
);
extern
void
CleanupRetain
(
void
);
extern
unsigned
long
__tick
;
void
__cleanup_debug
(
void
)
{
#ifndef TARGET_ONLINE_DEBUG_DISABLE
trace_buffer_cursor
=
trace_buffer
;
InitiateDebugTransfer
();
#endif
CleanupRetain
();
}
void
__retrieve_debug
(
void
)
{
}
void
Retain
(
unsigned
int
offset
,
unsigned
int
count
,
void
*
p
);
/* Return size of all retain variables */
unsigned
int
GetRetainSize
(
void
)
{
unsigned
int
retain_size
=
0
;
retain_list_collect_cursor
=
0
;
/* iterate over retain list */
while
(
retain_list_collect_cursor
<
retain_list_size
){
void
*
value_p
=
NULL
;
size_t
size
;
char
*
next_cursor
;
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
retain_list
[
retain_list_collect_cursor
]];
UnpackVar
(
dsc
,
&
value_p
,
NULL
,
&
size
);
retain_size
+=
size
;
retain_list_collect_cursor
++
;
}
return
retain_size
;
}
extern
void
PLC_GetTime
(
IEC_TIME
*
);
extern
int
TryEnterDebugSection
(
void
);
extern
long
AtomicCompareExchange
(
long
*
,
long
,
long
);
extern
long
long
AtomicCompareExchange64
(
long
long
*
,
long
long
,
long
long
);
extern
void
LeaveDebugSection
(
void
);
extern
void
ValidateRetainBuffer
(
void
);
extern
void
InValidateRetainBuffer
(
void
);
#define __ReForceOutput_case_p(TYPENAME) \
case TYPENAME##_P_ENUM : \
case TYPENAME##_O_ENUM : \
{ \
char *next_cursor = force_buffer_cursor + sizeof(TYPENAME); \
if(next_cursor <= force_buffer_end ){ \
/* outputs real value must be systematically forced */
\
if(vartype == TYPENAME##_O_ENUM) \
/* overwrite value pointed by backup */
\
*((TYPENAME *)force_list_apply_cursor->value_pointer_backup) = \
*((TYPENAME *)force_buffer_cursor); \
/* inc force_buffer cursor */
\
force_buffer_cursor = next_cursor; \
}else{ \
stop = 1; \
} \
} \
break;
void
__publish_debug
(
void
)
{
InValidateRetainBuffer
();
#ifndef TARGET_ONLINE_DEBUG_DISABLE
/* Check there is no running debugger re-configuration */
if
(
TryEnterDebugSection
()){
/* Lock buffer */
long
latest_state
=
AtomicCompareExchange
(
&
trace_buffer_state
,
BUFFER_EMPTY
,
BUFFER_FULL
);
/* If buffer was free */
if
(
latest_state
==
BUFFER_EMPTY
)
{
int
stop
=
0
;
/* Reset force list cursor */
force_list_apply_cursor
=
force_list
;
/* iterate over force list */
while
(
!
stop
&&
force_list_apply_cursor
<
force_list_addvar_cursor
){
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
force_list_apply_cursor
->
dbgvardsc_index
];
void
*
varp
=
dsc
->
ptr
;
__IEC_types_enum
vartype
=
dsc
->
type
;
switch
(
vartype
){
__ANY
(
__ReForceOutput_case_p
)
default:
break
;
}
force_list_apply_cursor
++
;
}
/* Reset buffer cursor */
trace_buffer_cursor
=
trace_buffer
;
/* Reset trace list cursor */
trace_list_collect_cursor
=
trace_list
;
/* iterate over trace list */
while
(
trace_list_collect_cursor
<
trace_list_addvar_cursor
){
void
*
value_p
=
NULL
;
size_t
size
;
char
*
next_cursor
;
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
trace_list_collect_cursor
->
dbgvardsc_index
];
UnpackVar
(
dsc
,
&
value_p
,
NULL
,
&
size
);
/* copy visible variable to buffer */
;
if
(
__Is_a_string
(
dsc
)){
/* optimization for strings */
/* assume NULL terminated strings */
size
=
((
STRING
*
)
value_p
)
->
len
+
1
;
}
/* compute next cursor positon.*/
next_cursor
=
trace_buffer_cursor
+
size
;
/* check for buffer overflow */
if
(
next_cursor
<
trace_buffer_end
)
/* copy data to the buffer */
memcpy
(
trace_buffer_cursor
,
value_p
,
size
);
else
/* stop looping in case of overflow */
break
;
/* increment cursor according size*/
trace_buffer_cursor
=
next_cursor
;
trace_list_collect_cursor
++
;
}
/* Leave debug section,
* Trigger asynchronous transmission
* (returns immediately) */
InitiateDebugTransfer
();
/* size */
}
LeaveDebugSection
();
}
#endif
unsigned
int
retain_offset
=
0
;
/* when not debugging, do only retain */
retain_list_collect_cursor
=
0
;
/* iterate over retain list */
while
(
retain_list_collect_cursor
<
retain_list_size
){
void
*
value_p
=
NULL
;
size_t
size
;
char
*
next_cursor
;
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
retain_list
[
retain_list_collect_cursor
]];
UnpackVar
(
dsc
,
&
value_p
,
NULL
,
&
size
);
/* if buffer not full */
Retain
(
retain_offset
,
size
,
value_p
);
/* increment cursor according size*/
retain_offset
+=
size
;
retain_list_collect_cursor
++
;
}
ValidateRetainBuffer
();
}
#ifndef TARGET_ONLINE_DEBUG_DISABLE
#define TRACE_LIST_OVERFLOW 1
#define FORCE_LIST_OVERFLOW 2
#define FORCE_BUFFER_OVERFLOW 3
#define __ForceVariable_case_t(TYPENAME) \
case TYPENAME##_ENUM : \
/* add to force_list*/
\
force_list_addvar_cursor->dbgvardsc_index = idx; \
((__IEC_##TYPENAME##_t *)varp)->flags |= __IEC_FORCE_FLAG; \
((__IEC_##TYPENAME##_t *)varp)->value = *((TYPENAME *)force); \
break;
#define __ForceVariable_case_p(TYPENAME) \
case TYPENAME##_P_ENUM : \
case TYPENAME##_O_ENUM : \
{ \
char *next_cursor = force_buffer_cursor + sizeof(TYPENAME); \
if(next_cursor <= force_buffer_end ){ \
/* add to force_list*/
\
force_list_addvar_cursor->dbgvardsc_index = idx; \
/* save pointer to backup */
\
force_list_addvar_cursor->value_pointer_backup = \
((__IEC_##TYPENAME##_p *)varp)->value; \
/* store forced value in force_buffer */
\
*((TYPENAME *)force_buffer_cursor) = *((TYPENAME *)force); \
/* replace pointer with pointer to force_buffer */
\
((__IEC_##TYPENAME##_p *)varp)->value = \
(TYPENAME *)force_buffer_cursor; \
/* mark variable as forced */
\
((__IEC_##TYPENAME##_p *)varp)->flags |= __IEC_FORCE_FLAG; \
/* inc force_buffer cursor */
\
force_buffer_cursor = next_cursor; \
/* outputs real value must be systematically forced */
\
if(vartype == TYPENAME##_O_ENUM) \
*(((__IEC_##TYPENAME##_p *)varp)->value) = *((TYPENAME *)force);\
} else { \
error_code = FORCE_BUFFER_OVERFLOW; \
goto error_cleanup; \
} \
} \
break;
void
ResetDebugVariables
(
void
);
int
RegisterDebugVariable
(
dbgvardsc_index_t
idx
,
void
*
force
)
{
int
error_code
=
0
;
if
(
idx
<
sizeof
(
dbgvardsc
)
/
sizeof
(
dbgvardsc_t
)){
/* add to trace_list, inc trace_list_addvar_cursor*/
if
(
trace_list_addvar_cursor
<=
trace_list_end
){
trace_list_addvar_cursor
->
dbgvardsc_index
=
idx
;
trace_list_addvar_cursor
++
;
}
else
{
error_code
=
TRACE_LIST_OVERFLOW
;
goto
error_cleanup
;
}
if
(
force
){
if
(
force_list_addvar_cursor
<=
force_list_end
){
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
idx
];
void
*
varp
=
dsc
->
ptr
;
__IEC_types_enum
vartype
=
dsc
->
type
;
switch
(
vartype
){
__ANY
(
__ForceVariable_case_t
)
__ANY
(
__ForceVariable_case_p
)
default:
break
;
}
/* inc force_list cursor */
force_list_addvar_cursor
++
;
}
else
{
error_code
=
FORCE_LIST_OVERFLOW
;
goto
error_cleanup
;
}
}
}
return
0
;
error_cleanup:
ResetDebugVariables
();
trace_buffer_state
=
BUFFER_EMPTY
;
return
error_code
;
}
#define ResetForcedVariable_case_t(TYPENAME) \
case TYPENAME##_ENUM : \
((__IEC_##TYPENAME##_t *)varp)->flags &= ~__IEC_FORCE_FLAG; \
/* for local variable we don't restore original value */
\
/* that can be added if needed, but it was like that since ever */
\
break;
#define ResetForcedVariable_case_p(TYPENAME) \
case TYPENAME##_P_ENUM : \
case TYPENAME##_O_ENUM : \
((__IEC_##TYPENAME##_p *)varp)->flags &= ~__IEC_FORCE_FLAG; \
/* restore backup to pointer */
\
((__IEC_##TYPENAME##_p *)varp)->value = \
force_list_apply_cursor->value_pointer_backup; \
break;
void
ResetDebugVariables
(
void
)
{
/* Reset trace list */
trace_list_addvar_cursor
=
trace_list
;
force_list_apply_cursor
=
force_list
;
/* Restore forced variables */
while
(
force_list_apply_cursor
<
force_list_addvar_cursor
){
dbgvardsc_t
*
dsc
=
&
dbgvardsc
[
force_list_apply_cursor
->
dbgvardsc_index
];
void
*
varp
=
dsc
->
ptr
;
switch
(
dsc
->
type
){
__ANY
(
ResetForcedVariable_case_t
)
__ANY
(
ResetForcedVariable_case_p
)
default:
break
;
}
/* inc force_list cursor */
force_list_apply_cursor
++
;
}
/* else TODO: warn user about failure to force */
/* Reset force list */
force_list_addvar_cursor
=
force_list
;
/* Reset force buffer */
force_buffer_cursor
=
force_buffer
;
}
void
FreeDebugData
(
void
)
{
/* atomically mark buffer as free */
AtomicCompareExchange
(
&
trace_buffer_state
,
BUFFER_FULL
,
BUFFER_EMPTY
);
}
int
WaitDebugData
(
unsigned
long
*
tick
);
/* Wait until debug data ready and return pointer to it */
int
GetDebugData
(
unsigned
long
*
tick
,
unsigned
long
*
size
,
void
**
buffer
){
int
wait_error
=
WaitDebugData
(
tick
);
if
(
!
wait_error
){
*
size
=
trace_buffer_cursor
-
trace_buffer
;
*
buffer
=
trace_buffer
;
}
return
wait_error
;
}
#endif
#endif
Beremiz/beremiz_oi_production_line/build/plc_main.c
0 → 100644
View file @
5ca48d3b
/**
* Head of code common to all C targets
**/
#include "beremiz.h"
#include <string.h>
/*
* Prototypes of functions provided by generated C softPLC
**/
void
config_run__
(
unsigned
long
tick
);
void
config_init__
(
void
);
/*
* Prototypes of functions provided by generated target C code
* */
long
long
AtomicCompareExchange64
(
long
long
*
,
long
long
,
long
long
);
void
__init_debug
(
void
);
void
__cleanup_debug
(
void
);
/*void __retrieve_debug(void);*/
void
__publish_debug
(
void
);
/*
* Variables used by generated C softPLC and plugins
**/
IEC_TIME
__CURRENT_TIME
;
IEC_BOOL
__DEBUG
=
0
;
unsigned
long
__tick
=
0
;
char
*
PLC_ID
=
NULL
;
/*
* Variable generated by C softPLC and plugins
**/
extern
unsigned
long
greatest_tick_count__
;
/* Help to quit cleanly when init fail at a certain level */
static
int
init_level
=
0
;
/*
* Prototypes of functions exported by plugins
**/
int
__init_py_ext
(
int
argc
,
char
**
argv
);
void
__cleanup_py_ext
(
void
);
void
__retrieve_py_ext
(
void
);
void
__publish_py_ext
(
void
);
int
__init_0
(
int
argc
,
char
**
argv
);
void
__cleanup_0
(
void
);
void
__retrieve_0
(
void
);
void
__publish_0
(
void
);
int
__init_1
(
int
argc
,
char
**
argv
);
void
__cleanup_1
(
void
);
void
__retrieve_1
(
void
);
void
__publish_1
(
void
);
int
__init_2
(
int
argc
,
char
**
argv
);
void
__cleanup_2
(
void
);
void
__retrieve_2
(
void
);
void
__publish_2
(
void
);
/*
* Retrieve input variables, run PLC and publish output variables
**/
void
__run
(
void
)
{
__tick
++
;
if
(
greatest_tick_count__
)
__tick
%=
greatest_tick_count__
;
__retrieve_py_ext
();
__retrieve_0
();
__retrieve_1
();
__retrieve_2
();
/*__retrieve_debug();*/
config_run__
(
__tick
);
__publish_debug
();
__publish_2
();
__publish_1
();
__publish_0
();
__publish_py_ext
();
}
/*
* Initialize variables according to PLC's default values,
* and then init plugins with that values
**/
int
__init
(
int
argc
,
char
**
argv
)
{
int
res
=
0
;
init_level
=
0
;
/* Effective tick time with 1ms default value */
if
(
!
common_ticktime__
)
common_ticktime__
=
1000000
;
config_init__
();
__init_debug
();
init_level
=
1
;
if
((
res
=
__init_py_ext
(
argc
,
argv
))){
return
res
;}
init_level
=
2
;
if
((
res
=
__init_0
(
argc
,
argv
))){
return
res
;}
init_level
=
3
;
if
((
res
=
__init_1
(
argc
,
argv
))){
return
res
;}
init_level
=
4
;
if
((
res
=
__init_2
(
argc
,
argv
))){
return
res
;}
return
res
;
}
/*
* Calls plugin cleanup proc.
**/
void
__cleanup
(
void
)
{
if
(
init_level
>=
4
)
__cleanup_2
();
if
(
init_level
>=
3
)
__cleanup_1
();
if
(
init_level
>=
2
)
__cleanup_0
();
if
(
init_level
>=
1
)
__cleanup_py_ext
();
__cleanup_debug
();
}
void
PLC_GetTime
(
IEC_TIME
*
CURRENT_TIME
);
void
PLC_SetTimer
(
unsigned
long
long
next
,
unsigned
long
long
period
);
/**
* Linux specific code
**/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <locale.h>
#include <semaphore.h>
#ifdef REALTIME_LINUX
#include <sys/mman.h>
#endif
#define _Log(level,text,...) \
{\
char mstr[256];\
snprintf(mstr, 255, text, ##__VA_ARGS__);\
LogMessage(LOG_CRITICAL, mstr, strlen(mstr));\
}
#define _LogError(text,...) _Log(LOG_CRITICAL, text, ##__VA_ARGS__)
#define _LogWarning(text,...) _Log(LOG_WARNING, text, ##__VA_ARGS__)
static
unsigned
long
__debug_tick
;
static
pthread_t
PLC_thread
;
static
pthread_mutex_t
python_wait_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
python_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
debug_wait_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
debug_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
int
PLC_shutdown
=
0
;
long
AtomicCompareExchange
(
long
*
atomicvar
,
long
compared
,
long
exchange
)
{
return
__sync_val_compare_and_swap
(
atomicvar
,
compared
,
exchange
);
}
long
long
AtomicCompareExchange64
(
long
long
*
atomicvar
,
long
long
compared
,
long
long
exchange
)
{
return
__sync_val_compare_and_swap
(
atomicvar
,
compared
,
exchange
);
}
void
PLC_GetTime
(
IEC_TIME
*
CURRENT_TIME
)
{
struct
timespec
tmp
;
clock_gettime
(
CLOCK_REALTIME
,
&
tmp
);
CURRENT_TIME
->
tv_sec
=
tmp
.
tv_sec
;
CURRENT_TIME
->
tv_nsec
=
tmp
.
tv_nsec
;
}
static
long
long
period_ns
=
0
;
struct
timespec
next_cycle_time
;
static
void
inc_timespec
(
struct
timespec
*
ts
,
unsigned
long
long
value_ns
)
{
long
long
next_ns
=
((
long
long
)
ts
->
tv_sec
*
1000000000
)
+
ts
->
tv_nsec
+
value_ns
;
#ifdef __lldiv_t_defined
lldiv_t
next_div
=
lldiv
(
next_ns
,
1000000000
);
ts
->
tv_sec
=
next_div
.
quot
;
ts
->
tv_nsec
=
next_div
.
rem
;
#else
ts
->
tv_sec
=
next_ns
/
1000000000
;
ts
->
tv_nsec
=
next_ns
%
1000000000
;
#endif
}
void
PLC_SetTimer
(
unsigned
long
long
next
,
unsigned
long
long
period
)
{
/*
printf("SetTimer(%lld,%lld)\n",next, period);
*/
period_ns
=
period
;
clock_gettime
(
CLOCK_MONOTONIC
,
&
next_cycle_time
);
inc_timespec
(
&
next_cycle_time
,
next
);
// interrupt clock_nanpsleep
pthread_kill
(
PLC_thread
,
SIGUSR1
);
}
void
catch_signal
(
int
sig
)
{
// signal(SIGTERM, catch_signal);
signal
(
SIGINT
,
catch_signal
);
printf
(
"Got Signal %d
\n
"
,
sig
);
exit
(
0
);
}
void
PLCThreadSignalHandler
(
int
sig
)
{
if
(
sig
==
SIGUSR2
)
pthread_exit
(
NULL
);
}
int
ForceSaveRetainReq
(
void
)
{
return
PLC_shutdown
;
}
#define MAX_JITTER period_ns/10
#define MIN_IDLE_TIME_NS 1000000
/* 1ms */
/* Macro to compare timespec, evaluate to True if a is past b */
#define timespec_gt(a,b) (a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec > b.tv_nsec))
void
PLC_thread_proc
(
void
*
arg
)
{
/* initialize next occurence and period */
period_ns
=
common_ticktime__
;
clock_gettime
(
CLOCK_MONOTONIC
,
&
next_cycle_time
);
while
(
!
PLC_shutdown
)
{
int
res
;
struct
timespec
plc_end_time
;
int
periods
=
0
;
#ifdef REALTIME_LINUX
struct
timespec
deadline_time
;
struct
timespec
plc_start_time
;
#endif
// BEREMIZ_TEST_CYCLES is defined in tests that need to emulate time:
// - all BEREMIZ_TEST_CYCLES cycles are executed in a row with no pause
// - __CURRENT_TIME is incremented each cycle according to emulated cycle period
#ifndef BEREMIZ_TEST_CYCLES
// Sleep until next PLC run
res
=
clock_nanosleep
(
CLOCK_MONOTONIC
,
TIMER_ABSTIME
,
&
next_cycle_time
,
NULL
);
if
(
res
==
EINTR
){
continue
;
}
if
(
res
!=
0
){
_LogError
(
"PLC thread timer returned error %d
\n
"
,
res
);
return
;
}
#endif // BEREMIZ_TEST_CYCLES
#ifdef REALTIME_LINUX
// timer overrun detection
clock_gettime
(
CLOCK_MONOTONIC
,
&
plc_start_time
);
deadline_time
=
next_cycle_time
;
inc_timespec
(
&
deadline_time
,
MAX_JITTER
);
if
(
timespec_gt
(
plc_start_time
,
deadline_time
)){
_LogWarning
(
"PLC thread woken up too late. PLC cyclic task interval is too small.
\n
"
);
}
#endif
#ifdef BEREMIZ_TEST_CYCLES
#define xstr(s) str(s)
#define str(arg) #arg
// fake current time
__CURRENT_TIME
.
tv_sec
=
next_cycle_time
.
tv_sec
;
__CURRENT_TIME
.
tv_nsec
=
next_cycle_time
.
tv_nsec
;
// exit loop when enough cycles
if
(
__tick
>=
BEREMIZ_TEST_CYCLES
)
{
_LogWarning
(
"TEST PLC thread ended after "
xstr
(
BEREMIZ_TEST_CYCLES
)
" cycles.
\n
"
);
// After pre-defined test cycles count, PLC thread exits.
// Remaining PLC runtime is expected to be cleaned-up/killed by test script
return
;
}
#else
PLC_GetTime
(
&
__CURRENT_TIME
);
#endif
__run
();
#ifndef BEREMIZ_TEST_CYCLES
// ensure next PLC cycle occurence is in the future
clock_gettime
(
CLOCK_MONOTONIC
,
&
plc_end_time
);
while
(
timespec_gt
(
plc_end_time
,
next_cycle_time
))
#endif
{
periods
+=
1
;
inc_timespec
(
&
next_cycle_time
,
period_ns
);
}
// plc execution time overrun detection
if
(
periods
>
1
)
{
// Mitigate CPU hogging, in case of too small cyclic task interval:
// - since cycle deadline already missed, better keep system responsive
// - test if next cycle occurs after minimal idle
// - enforce minimum idle time if not
struct
timespec
earliest_possible_time
=
plc_end_time
;
inc_timespec
(
&
earliest_possible_time
,
MIN_IDLE_TIME_NS
);
while
(
timespec_gt
(
earliest_possible_time
,
next_cycle_time
)){
periods
+=
1
;
inc_timespec
(
&
next_cycle_time
,
period_ns
);
}
// increment tick count anyhow, so that task scheduling keeps consistent
__tick
+=
periods
-
1
;
_LogWarning
(
"PLC execution time is longer than requested PLC cyclic task interval. %d cycles skipped
\n
"
,
periods
);
}
}
pthread_exit
(
0
);
}
#define maxval(a,b) ((a>b)?a:b)
int
startPLC
(
int
argc
,
char
**
argv
)
{
int
ret
;
pthread_attr_t
*
pattr
=
NULL
;
#ifdef REALTIME_LINUX
struct
sched_param
param
;
pthread_attr_t
attr
;
/* Lock memory */
ret
=
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
if
(
ret
==
-
1
)
{
_LogError
(
"mlockall failed: %m
\n
"
);
return
ret
;
}
/* Initialize pthread attributes (default values) */
ret
=
pthread_attr_init
(
&
attr
);
if
(
ret
)
{
_LogError
(
"init pthread attributes failed
\n
"
);
return
ret
;
}
/* Set scheduler policy and priority of pthread */
ret
=
pthread_attr_setschedpolicy
(
&
attr
,
SCHED_FIFO
);
if
(
ret
)
{
_LogError
(
"pthread setschedpolicy failed
\n
"
);
return
ret
;
}
param
.
sched_priority
=
PLC_THREAD_PRIORITY
;
ret
=
pthread_attr_setschedparam
(
&
attr
,
&
param
);
if
(
ret
)
{
_LogError
(
"pthread setschedparam failed
\n
"
);
return
ret
;
}
/* Use scheduling parameters of attr */
ret
=
pthread_attr_setinheritsched
(
&
attr
,
PTHREAD_EXPLICIT_SCHED
);
if
(
ret
)
{
_LogError
(
"pthread setinheritsched failed
\n
"
);
return
ret
;
}
pattr
=
&
attr
;
#endif
PLC_shutdown
=
0
;
pthread_mutex_init
(
&
debug_wait_mutex
,
NULL
);
pthread_mutex_init
(
&
debug_mutex
,
NULL
);
pthread_mutex_init
(
&
python_wait_mutex
,
NULL
);
pthread_mutex_init
(
&
python_mutex
,
NULL
);
pthread_mutex_lock
(
&
debug_wait_mutex
);
pthread_mutex_lock
(
&
python_wait_mutex
);
if
((
ret
=
__init
(
argc
,
argv
))
==
0
){
/* Signal to wakeup PLC thread when period changes */
signal
(
SIGUSR1
,
PLCThreadSignalHandler
);
/* Signal to end PLC thread */
signal
(
SIGUSR2
,
PLCThreadSignalHandler
);
/* install signal handler for manual break */
signal
(
SIGINT
,
catch_signal
);
ret
=
pthread_create
(
&
PLC_thread
,
pattr
,
(
void
*
)
&
PLC_thread_proc
,
NULL
);
if
(
ret
)
{
_LogError
(
"create pthread failed
\n
"
);
return
ret
;
}
}
else
{
return
ret
;
}
return
0
;
}
int
TryEnterDebugSection
(
void
)
{
if
(
pthread_mutex_trylock
(
&
debug_mutex
)
==
0
){
/* Only enter if debug active */
if
(
__DEBUG
){
return
1
;
}
pthread_mutex_unlock
(
&
debug_mutex
);
}
return
0
;
}
void
LeaveDebugSection
(
void
)
{
pthread_mutex_unlock
(
&
debug_mutex
);
}
int
stopPLC
()
{
/* Stop the PLC */
PLC_shutdown
=
1
;
/* Order PLCThread to exit */
pthread_kill
(
PLC_thread
,
SIGUSR2
);
pthread_join
(
PLC_thread
,
NULL
);
__cleanup
();
pthread_mutex_destroy
(
&
debug_wait_mutex
);
pthread_mutex_destroy
(
&
debug_mutex
);
pthread_mutex_destroy
(
&
python_wait_mutex
);
pthread_mutex_destroy
(
&
python_mutex
);
return
0
;
}
extern
unsigned
long
__tick
;
int
WaitDebugData
(
unsigned
long
*
tick
)
{
int
res
;
if
(
PLC_shutdown
)
return
1
;
/* Wait signal from PLC thread */
res
=
pthread_mutex_lock
(
&
debug_wait_mutex
);
*
tick
=
__debug_tick
;
return
res
;
}
/* Called by PLC thread when debug_publish finished
* This is supposed to unlock debugger thread in WaitDebugData*/
void
InitiateDebugTransfer
()
{
/* remember tick */
__debug_tick
=
__tick
;
/* signal debugger thread it can read data */
pthread_mutex_unlock
(
&
debug_wait_mutex
);
}
int
suspendDebug
(
int
disable
)
{
/* Prevent PLC to enter debug code */
pthread_mutex_lock
(
&
debug_mutex
);
/*__DEBUG is protected by this mutex */
__DEBUG
=
!
disable
;
if
(
disable
)
pthread_mutex_unlock
(
&
debug_mutex
);
return
0
;
}
void
resumeDebug
(
void
)
{
__DEBUG
=
1
;
/* Let PLC enter debug code */
pthread_mutex_unlock
(
&
debug_mutex
);
}
/* from plc_python.c */
int
WaitPythonCommands
(
void
)
{
/* Wait signal from PLC thread */
return
pthread_mutex_lock
(
&
python_wait_mutex
);
}
/* Called by PLC thread on each new python command*/
void
UnBlockPythonCommands
(
void
)
{
/* signal python thread it can read data */
pthread_mutex_unlock
(
&
python_wait_mutex
);
}
int
TryLockPython
(
void
)
{
return
pthread_mutex_trylock
(
&
python_mutex
)
==
0
;
}
void
UnLockPython
(
void
)
{
pthread_mutex_unlock
(
&
python_mutex
);
}
void
LockPython
(
void
)
{
pthread_mutex_lock
(
&
python_mutex
);
}
struct
RT_to_nRT_signal_s
{
int
used
;
pthread_cond_t
WakeCond
;
pthread_mutex_t
WakeCondLock
;
};
typedef
struct
RT_to_nRT_signal_s
RT_to_nRT_signal_t
;
#define _LogAndReturnNull(text) \
{\
char mstr[256] = text " for ";\
strncat(mstr, name, 255);\
LogMessage(LOG_CRITICAL, mstr, strlen(mstr));\
return NULL;\
}
void
*
create_RT_to_nRT_signal
(
char
*
name
){
RT_to_nRT_signal_t
*
sig
=
(
RT_to_nRT_signal_t
*
)
malloc
(
sizeof
(
RT_to_nRT_signal_t
));
if
(
!
sig
)
_LogAndReturnNull
(
"Failed allocating memory for RT_to_nRT signal"
);
sig
->
used
=
1
;
pthread_cond_init
(
&
sig
->
WakeCond
,
NULL
);
pthread_mutex_init
(
&
sig
->
WakeCondLock
,
NULL
);
return
(
void
*
)
sig
;
}
void
delete_RT_to_nRT_signal
(
void
*
handle
){
RT_to_nRT_signal_t
*
sig
=
(
RT_to_nRT_signal_t
*
)
handle
;
pthread_mutex_lock
(
&
sig
->
WakeCondLock
);
sig
->
used
=
0
;
pthread_cond_signal
(
&
sig
->
WakeCond
);
pthread_mutex_unlock
(
&
sig
->
WakeCondLock
);
}
int
wait_RT_to_nRT_signal
(
void
*
handle
){
int
ret
;
RT_to_nRT_signal_t
*
sig
=
(
RT_to_nRT_signal_t
*
)
handle
;
pthread_mutex_lock
(
&
sig
->
WakeCondLock
);
ret
=
pthread_cond_wait
(
&
sig
->
WakeCond
,
&
sig
->
WakeCondLock
);
if
(
!
sig
->
used
)
ret
=
-
EINVAL
;
pthread_mutex_unlock
(
&
sig
->
WakeCondLock
);
if
(
!
sig
->
used
){
pthread_cond_destroy
(
&
sig
->
WakeCond
);
pthread_mutex_destroy
(
&
sig
->
WakeCondLock
);
free
(
sig
);
}
return
ret
;
}
int
unblock_RT_to_nRT_signal
(
void
*
handle
){
RT_to_nRT_signal_t
*
sig
=
(
RT_to_nRT_signal_t
*
)
handle
;
return
pthread_cond_signal
(
&
sig
->
WakeCond
);
}
void
nRT_reschedule
(
void
){
sched_yield
();
}
/*
This file is part of Beremiz, a Integrated Development Environment for
programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
See COPYING.runtime
Copyright (C) 2018: Sergey Surkov <surkov.sv@summatechnology.ru>
Copyright (C) 2018: Andrey Skvortsov <andrej.skvortzov@gmail.com>
*/
#ifndef HAVE_RETAIN
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include "iec_types.h"
int
GetRetainSize
(
void
);
/* Retain buffer. */
FILE
*
retain_buffer
;
const
char
rb_file
[]
=
"retain_buffer_file"
;
const
char
rb_file_bckp
[]
=
"retain_buffer_file.bak"
;
/* Retain header struct. */
struct
retain_info_t
{
uint32_t
retain_size
;
uint32_t
hash_size
;
uint8_t
*
hash
;
uint32_t
header_offset
;
uint32_t
header_crc
;
};
/* Init retain info structure. */
struct
retain_info_t
retain_info
;
/* CRC lookup table and initial state. */
static
const
uint32_t
crc32_table
[
256
]
=
{
0x00000000
,
0x77073096
,
0xEE0E612C
,
0x990951BA
,
0x076DC419
,
0x706AF48F
,
0xE963A535
,
0x9E6495A3
,
0x0EDB8832
,
0x79DCB8A4
,
0xE0D5E91E
,
0x97D2D988
,
0x09B64C2B
,
0x7EB17CBD
,
0xE7B82D07
,
0x90BF1D91
,
0x1DB71064
,
0x6AB020F2
,
0xF3B97148
,
0x84BE41DE
,
0x1ADAD47D
,
0x6DDDE4EB
,
0xF4D4B551
,
0x83D385C7
,
0x136C9856
,
0x646BA8C0
,
0xFD62F97A
,
0x8A65C9EC
,
0x14015C4F
,
0x63066CD9
,
0xFA0F3D63
,
0x8D080DF5
,
0x3B6E20C8
,
0x4C69105E
,
0xD56041E4
,
0xA2677172
,
0x3C03E4D1
,
0x4B04D447
,
0xD20D85FD
,
0xA50AB56B
,
0x35B5A8FA
,
0x42B2986C
,
0xDBBBC9D6
,
0xACBCF940
,
0x32D86CE3
,
0x45DF5C75
,
0xDCD60DCF
,
0xABD13D59
,
0x26D930AC
,
0x51DE003A
,
0xC8D75180
,
0xBFD06116
,
0x21B4F4B5
,
0x56B3C423
,
0xCFBA9599
,
0xB8BDA50F
,
0x2802B89E
,
0x5F058808
,
0xC60CD9B2
,
0xB10BE924
,
0x2F6F7C87
,
0x58684C11
,
0xC1611DAB
,
0xB6662D3D
,
0x76DC4190
,
0x01DB7106
,
0x98D220BC
,
0xEFD5102A
,
0x71B18589
,
0x06B6B51F
,
0x9FBFE4A5
,
0xE8B8D433
,
0x7807C9A2
,
0x0F00F934
,
0x9609A88E
,
0xE10E9818
,
0x7F6A0DBB
,
0x086D3D2D
,
0x91646C97
,
0xE6635C01
,
0x6B6B51F4
,
0x1C6C6162
,
0x856530D8
,
0xF262004E
,
0x6C0695ED
,
0x1B01A57B
,
0x8208F4C1
,
0xF50FC457
,
0x65B0D9C6
,
0x12B7E950
,
0x8BBEB8EA
,
0xFCB9887C
,
0x62DD1DDF
,
0x15DA2D49
,
0x8CD37CF3
,
0xFBD44C65
,
0x4DB26158
,
0x3AB551CE
,
0xA3BC0074
,
0xD4BB30E2
,
0x4ADFA541
,
0x3DD895D7
,
0xA4D1C46D
,
0xD3D6F4FB
,
0x4369E96A
,
0x346ED9FC
,
0xAD678846
,
0xDA60B8D0
,
0x44042D73
,
0x33031DE5
,
0xAA0A4C5F
,
0xDD0D7CC9
,
0x5005713C
,
0x270241AA
,
0xBE0B1010
,
0xC90C2086
,
0x5768B525
,
0x206F85B3
,
0xB966D409
,
0xCE61E49F
,
0x5EDEF90E
,
0x29D9C998
,
0xB0D09822
,
0xC7D7A8B4
,
0x59B33D17
,
0x2EB40D81
,
0xB7BD5C3B
,
0xC0BA6CAD
,
0xEDB88320
,
0x9ABFB3B6
,
0x03B6E20C
,
0x74B1D29A
,
0xEAD54739
,
0x9DD277AF
,
0x04DB2615
,
0x73DC1683
,
0xE3630B12
,
0x94643B84
,
0x0D6D6A3E
,
0x7A6A5AA8
,
0xE40ECF0B
,
0x9309FF9D
,
0x0A00AE27
,
0x7D079EB1
,
0xF00F9344
,
0x8708A3D2
,
0x1E01F268
,
0x6906C2FE
,
0xF762575D
,
0x806567CB
,
0x196C3671
,
0x6E6B06E7
,
0xFED41B76
,
0x89D32BE0
,
0x10DA7A5A
,
0x67DD4ACC
,
0xF9B9DF6F
,
0x8EBEEFF9
,
0x17B7BE43
,
0x60B08ED5
,
0xD6D6A3E8
,
0xA1D1937E
,
0x38D8C2C4
,
0x4FDFF252
,
0xD1BB67F1
,
0xA6BC5767
,
0x3FB506DD
,
0x48B2364B
,
0xD80D2BDA
,
0xAF0A1B4C
,
0x36034AF6
,
0x41047A60
,
0xDF60EFC3
,
0xA867DF55
,
0x316E8EEF
,
0x4669BE79
,
0xCB61B38C
,
0xBC66831A
,
0x256FD2A0
,
0x5268E236
,
0xCC0C7795
,
0xBB0B4703
,
0x220216B9
,
0x5505262F
,
0xC5BA3BBE
,
0xB2BD0B28
,
0x2BB45A92
,
0x5CB36A04
,
0xC2D7FFA7
,
0xB5D0CF31
,
0x2CD99E8B
,
0x5BDEAE1D
,
0x9B64C2B0
,
0xEC63F226
,
0x756AA39C
,
0x026D930A
,
0x9C0906A9
,
0xEB0E363F
,
0x72076785
,
0x05005713
,
0x95BF4A82
,
0xE2B87A14
,
0x7BB12BAE
,
0x0CB61B38
,
0x92D28E9B
,
0xE5D5BE0D
,
0x7CDCEFB7
,
0x0BDBDF21
,
0x86D3D2D4
,
0xF1D4E242
,
0x68DDB3F8
,
0x1FDA836E
,
0x81BE16CD
,
0xF6B9265B
,
0x6FB077E1
,
0x18B74777
,
0x88085AE6
,
0xFF0F6A70
,
0x66063BCA
,
0x11010B5C
,
0x8F659EFF
,
0xF862AE69
,
0x616BFFD3
,
0x166CCF45
,
0xA00AE278
,
0xD70DD2EE
,
0x4E048354
,
0x3903B3C2
,
0xA7672661
,
0xD06016F7
,
0x4969474D
,
0x3E6E77DB
,
0xAED16A4A
,
0xD9D65ADC
,
0x40DF0B66
,
0x37D83BF0
,
0xA9BCAE53
,
0xDEBB9EC5
,
0x47B2CF7F
,
0x30B5FFE9
,
0xBDBDF21C
,
0xCABAC28A
,
0x53B39330
,
0x24B4A3A6
,
0xBAD03605
,
0xCDD70693
,
0x54DE5729
,
0x23D967BF
,
0xB3667A2E
,
0xC4614AB8
,
0x5D681B02
,
0x2A6F2B94
,
0xB40BBE37
,
0xC30C8EA1
,
0x5A05DF1B
,
0x2D02EF8D
,
};
uint32_t
retain_crc
;
/* Calculate CRC32 for len bytes from pointer buf with init starting value. */
uint32_t
GenerateCRC32Sum
(
const
void
*
buf
,
unsigned
int
len
,
uint32_t
init
)
{
uint32_t
crc
=
~
init
;
unsigned
char
*
current
=
(
unsigned
char
*
)
buf
;
while
(
len
--
)
crc
=
crc32_table
[(
crc
^
*
current
++
)
&
0xFF
]
^
(
crc
>>
8
);
return
~
crc
;
}
/* Calc CRC32 for retain file byte by byte. */
int
CheckFileCRC
(
FILE
*
file_buffer
)
{
/* Set the magic constant for one-pass CRC calc according to ZIP CRC32. */
const
uint32_t
magic_number
=
0x2144df1c
;
/* CRC initial state. */
uint32_t
calc_crc32
=
0
;
char
data_block
=
0
;
while
(
!
feof
(
file_buffer
)){
if
(
fread
(
&
data_block
,
sizeof
(
data_block
),
1
,
file_buffer
))
calc_crc32
=
GenerateCRC32Sum
(
&
data_block
,
sizeof
(
char
),
calc_crc32
);
}
/* Compare crc result with a magic number. */
return
(
calc_crc32
==
magic_number
)
?
1
:
0
;
}
/* Compare current hash with hash from file byte by byte. */
int
CheckFilehash
(
void
)
{
int
k
,
ret
;
int
offset
=
sizeof
(
retain_info
.
retain_size
);
rewind
(
retain_buffer
);
fseek
(
retain_buffer
,
offset
,
SEEK_SET
);
uint32_t
size
;
ret
=
fread
(
&
size
,
sizeof
(
size
),
1
,
retain_buffer
);
if
(
size
!=
retain_info
.
hash_size
)
return
0
;
for
(
k
=
0
;
k
<
retain_info
.
hash_size
;
k
++
){
uint8_t
file_digit
;
ret
=
fread
(
&
file_digit
,
sizeof
(
char
),
1
,
retain_buffer
);
if
(
file_digit
!=
*
(
retain_info
.
hash
+
k
))
return
0
;
}
return
1
;
}
void
InitRetain
(
void
)
{
int
i
;
/* Get retain size in bytes */
retain_info
.
retain_size
=
GetRetainSize
();
/* Hash stored in retain file as array of char in hex digits
(that's why we divide strlen in two). */
retain_info
.
hash_size
=
PLC_ID
?
strlen
(
PLC_ID
)
/
2
:
0
;
//retain_info.hash_size = 0;
retain_info
.
hash
=
malloc
(
retain_info
.
hash_size
);
/* Transform hash string into byte sequence. */
for
(
i
=
0
;
i
<
retain_info
.
hash_size
;
i
++
)
{
int
byte
=
0
;
sscanf
((
PLC_ID
+
i
*
2
),
"%02X"
,
&
byte
);
retain_info
.
hash
[
i
]
=
byte
;
}
/* Calc header offset. */
retain_info
.
header_offset
=
sizeof
(
retain_info
.
retain_size
)
+
\
sizeof
(
retain_info
.
hash_size
)
+
\
retain_info
.
hash_size
;
/* Set header CRC initial state. */
retain_info
.
header_crc
=
0
;
/* Calc crc for header. */
retain_info
.
header_crc
=
GenerateCRC32Sum
(
&
retain_info
.
retain_size
,
sizeof
(
retain_info
.
retain_size
),
retain_info
.
header_crc
);
retain_info
.
header_crc
=
GenerateCRC32Sum
(
&
retain_info
.
hash_size
,
sizeof
(
retain_info
.
hash_size
),
retain_info
.
header_crc
);
retain_info
.
header_crc
=
GenerateCRC32Sum
(
retain_info
.
hash
,
retain_info
.
hash_size
,
retain_info
.
header_crc
);
}
void
CleanupRetain
(
void
)
{
/* Free hash memory. */
free
(
retain_info
.
hash
);
}
int
CheckRetainFile
(
const
char
*
file
)
{
retain_buffer
=
fopen
(
file
,
"rb"
);
if
(
retain_buffer
)
{
/* Check CRC32 and hash. */
if
(
CheckFileCRC
(
retain_buffer
))
if
(
CheckFilehash
())
return
1
;
fclose
(
retain_buffer
);
retain_buffer
=
NULL
;
}
return
0
;
}
int
CheckRetainBuffer
(
void
)
{
retain_buffer
=
NULL
;
if
(
!
retain_info
.
retain_size
)
return
1
;
/* Check latest retain file. */
if
(
CheckRetainFile
(
rb_file
))
return
1
;
/* Check if we have backup. */
if
(
CheckRetainFile
(
rb_file_bckp
))
return
1
;
/* We don't have any valid retain buffer - nothing to remind. */
return
0
;
}
#ifndef FILE_RETAIN_SAVE_PERIOD_S
#define FILE_RETAIN_SAVE_PERIOD_S 1.0
#endif
static
double
CalcDiffSeconds
(
IEC_TIME
*
t1
,
IEC_TIME
*
t2
)
{
IEC_TIME
dt
=
{
t1
->
tv_sec
-
t2
->
tv_sec
,
t1
->
tv_nsec
-
t2
->
tv_nsec
};
if
((
dt
.
tv_nsec
<
-
1000000000
)
||
((
dt
.
tv_sec
>
0
)
&&
(
dt
.
tv_nsec
<
0
))){
dt
.
tv_sec
--
;
dt
.
tv_nsec
+=
1000000000
;
}
if
((
dt
.
tv_nsec
>
+
1000000000
)
||
((
dt
.
tv_sec
<
0
)
&&
(
dt
.
tv_nsec
>
0
))){
dt
.
tv_sec
++
;
dt
.
tv_nsec
-=
1000000000
;
}
return
dt
.
tv_sec
+
1e-9
*
dt
.
tv_nsec
;
}
int
RetainSaveNeeded
(
void
)
{
int
ret
=
0
;
static
IEC_TIME
last_save
;
IEC_TIME
now
;
double
diff_s
;
/* no retain */
if
(
!
retain_info
.
retain_size
)
return
0
;
/* periodic retain flush to avoid high I/O load */
PLC_GetTime
(
&
now
);
diff_s
=
CalcDiffSeconds
(
&
now
,
&
last_save
);
if
((
diff_s
>
FILE_RETAIN_SAVE_PERIOD_S
)
||
ForceSaveRetainReq
())
{
ret
=
1
;
last_save
=
now
;
}
return
ret
;
}
void
ValidateRetainBuffer
(
void
)
{
if
(
!
retain_buffer
)
return
;
/* Add retain data CRC to the end of buffer file. */
fseek
(
retain_buffer
,
0
,
SEEK_END
);
fwrite
(
&
retain_crc
,
sizeof
(
uint32_t
),
1
,
retain_buffer
);
/* Sync file buffer and close file. */
#ifdef __WIN32
fflush
(
retain_buffer
);
#else
fsync
(
fileno
(
retain_buffer
));
#endif
fclose
(
retain_buffer
);
retain_buffer
=
NULL
;
}
void
InValidateRetainBuffer
(
void
)
{
if
(
!
RetainSaveNeeded
())
return
;
/* Rename old retain file into *.bak if it exists. */
rename
(
rb_file
,
rb_file_bckp
);
/* Set file CRC initial value. */
retain_crc
=
retain_info
.
header_crc
;
/* Create new retain file. */
retain_buffer
=
fopen
(
rb_file
,
"wb+"
);
if
(
!
retain_buffer
)
{
fprintf
(
stderr
,
"Failed to create retain file : %s
\n
"
,
rb_file
);
return
;
}
/* Write header to the new file. */
fwrite
(
&
retain_info
.
retain_size
,
sizeof
(
retain_info
.
retain_size
),
1
,
retain_buffer
);
fwrite
(
&
retain_info
.
hash_size
,
sizeof
(
retain_info
.
hash_size
),
1
,
retain_buffer
);
fwrite
(
retain_info
.
hash
,
sizeof
(
char
),
retain_info
.
hash_size
,
retain_buffer
);
}
void
Retain
(
unsigned
int
offset
,
unsigned
int
count
,
void
*
p
)
{
if
(
!
retain_buffer
)
return
;
/* Generate CRC 32 for each data block. */
retain_crc
=
GenerateCRC32Sum
(
p
,
count
,
retain_crc
);
/* Save current var in file. */
fseek
(
retain_buffer
,
retain_info
.
header_offset
+
offset
,
SEEK_SET
);
fwrite
(
p
,
count
,
1
,
retain_buffer
);
}
void
Remind
(
unsigned
int
offset
,
unsigned
int
count
,
void
*
p
)
{
int
ret
;
/* Remind variable from file. */
fseek
(
retain_buffer
,
retain_info
.
header_offset
+
offset
,
SEEK_SET
);
ret
=
fread
((
void
*
)
p
,
count
,
1
,
retain_buffer
);
}
#endif // !HAVE_RETAIN
/**
* Tail of code common to all C targets
**/
/**
* LOGGING
**/
#ifndef TARGET_LOGGING_DISABLE
#ifndef LOG_BUFFER_SIZE
#define LOG_BUFFER_SIZE (1<<14)
/*16Ko*/
#endif
#ifndef LOG_BUFFER_ATTRS
#define LOG_BUFFER_ATTRS
#endif
#define LOG_BUFFER_MASK (LOG_BUFFER_SIZE-1)
static
char
LogBuff
[
LOG_LEVELS
][
LOG_BUFFER_SIZE
]
LOG_BUFFER_ATTRS
;
static
void
inline
copy_to_log
(
uint8_t
level
,
uint32_t
buffpos
,
void
*
buf
,
uint32_t
size
){
if
(
buffpos
+
size
<
LOG_BUFFER_SIZE
){
memcpy
(
&
LogBuff
[
level
][
buffpos
],
buf
,
size
);
}
else
{
uint32_t
remaining
=
LOG_BUFFER_SIZE
-
buffpos
;
memcpy
(
&
LogBuff
[
level
][
buffpos
],
buf
,
remaining
);
memcpy
(
LogBuff
[
level
],
(
char
*
)
buf
+
remaining
,
size
-
remaining
);
}
}
static
void
inline
copy_from_log
(
uint8_t
level
,
uint32_t
buffpos
,
void
*
buf
,
uint32_t
size
){
if
(
buffpos
+
size
<
LOG_BUFFER_SIZE
){
memcpy
(
buf
,
&
LogBuff
[
level
][
buffpos
],
size
);
}
else
{
uint32_t
remaining
=
LOG_BUFFER_SIZE
-
buffpos
;
memcpy
(
buf
,
&
LogBuff
[
level
][
buffpos
],
remaining
);
memcpy
((
char
*
)
buf
+
remaining
,
LogBuff
[
level
],
size
-
remaining
);
}
}
/* Log buffer structure
|<-Tail1.msgsize->|<-sizeof(mTail)->|<--Tail2.msgsize-->|<-sizeof(mTail)->|...
| Message1 Body | Tail1 | Message2 Body | Tail2 |
*/
typedef
struct
{
uint32_t
msgidx
;
uint32_t
msgsize
;
unsigned
long
tick
;
IEC_TIME
time
;
}
mTail
;
/* Log cursor : 64b
|63 ... 32|31 ... 0|
| Message | Buffer |
| counter | Index | */
static
uint64_t
LogCursor
[
LOG_LEVELS
]
LOG_BUFFER_ATTRS
=
{
0x0
,
0x0
,
0x0
,
0x0
};
void
ResetLogCount
(
void
)
{
uint8_t
level
;
for
(
level
=
0
;
level
<
LOG_LEVELS
;
level
++
){
LogCursor
[
level
]
=
0
;
}
}
/* Store one log message of give size */
int
LogMessage
(
uint8_t
level
,
char
*
buf
,
uint32_t
size
){
if
(
size
<
LOG_BUFFER_SIZE
-
sizeof
(
mTail
)){
uint32_t
buffpos
;
uint64_t
new_cursor
,
old_cursor
;
mTail
tail
;
tail
.
msgsize
=
size
;
tail
.
tick
=
__tick
;
PLC_GetTime
(
&
tail
.
time
);
/* We cannot increment both msg index and string pointer
in a single atomic operation but we can detect having been interrupted.
So we can try with atomic compare and swap in a loop until operation
succeeds non interrupted */
do
{
old_cursor
=
LogCursor
[
level
];
buffpos
=
(
uint32_t
)
old_cursor
;
tail
.
msgidx
=
(
old_cursor
>>
32
);
new_cursor
=
((
uint64_t
)(
tail
.
msgidx
+
1
)
<<
32
)
|
(
uint64_t
)((
buffpos
+
size
+
sizeof
(
mTail
))
&
LOG_BUFFER_MASK
);
}
while
(
AtomicCompareExchange64
(
(
long
long
*
)
&
LogCursor
[
level
],
(
long
long
)
old_cursor
,
(
long
long
)
new_cursor
)
!=
(
long
long
)
old_cursor
);
copy_to_log
(
level
,
buffpos
,
buf
,
size
);
copy_to_log
(
level
,
(
buffpos
+
size
)
&
LOG_BUFFER_MASK
,
&
tail
,
sizeof
(
mTail
));
return
1
;
/* Success */
}
else
{
char
mstr
[]
=
"Logging error : message too big"
;
LogMessage
(
LOG_CRITICAL
,
mstr
,
sizeof
(
mstr
));
}
return
0
;
}
uint32_t
GetLogCount
(
uint8_t
level
){
return
(
uint64_t
)
LogCursor
[
level
]
>>
32
;
}
/* Return message size and content */
uint32_t
GetLogMessage
(
uint8_t
level
,
uint32_t
msgidx
,
char
*
buf
,
uint32_t
max_size
,
uint32_t
*
tick
,
uint32_t
*
tv_sec
,
uint32_t
*
tv_nsec
){
uint64_t
cursor
=
LogCursor
[
level
];
if
(
cursor
){
/* seach cursor */
uint32_t
stailpos
=
(
uint32_t
)
cursor
;
uint32_t
smsgidx
;
mTail
tail
;
tail
.
msgidx
=
cursor
>>
32
;
tail
.
msgsize
=
0
;
/* Message search loop */
do
{
smsgidx
=
tail
.
msgidx
;
stailpos
=
(
stailpos
-
sizeof
(
mTail
)
-
tail
.
msgsize
)
&
LOG_BUFFER_MASK
;
copy_from_log
(
level
,
stailpos
,
&
tail
,
sizeof
(
mTail
));
}
while
((
tail
.
msgidx
==
smsgidx
-
1
)
&&
(
tail
.
msgidx
>
msgidx
));
if
(
tail
.
msgidx
==
msgidx
){
uint32_t
sbuffpos
=
(
stailpos
-
tail
.
msgsize
)
&
LOG_BUFFER_MASK
;
uint32_t
totalsize
=
tail
.
msgsize
;
*
tick
=
tail
.
tick
;
*
tv_sec
=
tail
.
time
.
tv_sec
;
*
tv_nsec
=
tail
.
time
.
tv_nsec
;
copy_from_log
(
level
,
sbuffpos
,
buf
,
totalsize
>
max_size
?
max_size
:
totalsize
);
return
totalsize
;
}
}
return
0
;
}
#endif
#ifndef TARGET_EXT_SYNC_DISABLE
#define CALIBRATED -2
#define NOT_CALIBRATED -1
static
int
calibration_count
=
NOT_CALIBRATED
;
static
IEC_TIME
cal_begin
;
static
long
long
Tsync
=
0
;
static
long
long
FreqCorr
=
0
;
static
int
Nticks
=
0
;
static
unsigned
long
last_tick
=
0
;
/*
* Called on each external periodic sync event
* make PLC tick synchronous with external sync
* ratio defines when PLC tick occurs between two external sync
* @param sync_align_ratio
* 0->100 : align ratio
* < 0 : no align, calibrate period
**/
void
align_tick
(
int
sync_align_ratio
)
{
/*
printf("align_tick(%d)\n", calibrate);
*/
if
(
sync_align_ratio
<
0
){
/* Calibration */
if
(
calibration_count
==
CALIBRATED
)
/* Re-calibration*/
calibration_count
=
NOT_CALIBRATED
;
if
(
calibration_count
==
NOT_CALIBRATED
)
/* Calibration start, get time*/
PLC_GetTime
(
&
cal_begin
);
calibration_count
++
;
}
else
{
/* do alignment (if possible) */
if
(
calibration_count
>=
0
){
/* End of calibration */
/* Get final time */
IEC_TIME
cal_end
;
PLC_GetTime
(
&
cal_end
);
/*adjust calibration_count*/
calibration_count
++
;
/* compute mean of Tsync, over calibration period */
Tsync
=
((
long
long
)(
cal_end
.
tv_sec
-
cal_begin
.
tv_sec
)
*
(
long
long
)
1000000000
+
(
cal_end
.
tv_nsec
-
cal_begin
.
tv_nsec
))
/
calibration_count
;
if
(
(
Nticks
=
(
Tsync
/
common_ticktime__
))
>
0
){
FreqCorr
=
(
Tsync
%
common_ticktime__
);
/* to be divided by Nticks */
}
else
{
FreqCorr
=
Tsync
-
(
common_ticktime__
%
Tsync
);
}
/*
printf("Tsync = %ld\n", Tsync);
printf("calibration_count = %d\n", calibration_count);
printf("Nticks = %d\n", Nticks);
*/
calibration_count
=
CALIBRATED
;
}
if
(
calibration_count
==
CALIBRATED
){
/* Get Elapsed time since last PLC tick (__CURRENT_TIME) */
IEC_TIME
now
;
long
long
elapsed
;
long
long
Tcorr
;
long
long
PhaseCorr
;
long
long
PeriodicTcorr
;
PLC_GetTime
(
&
now
);
elapsed
=
(
now
.
tv_sec
-
__CURRENT_TIME
.
tv_sec
)
*
1000000000
+
now
.
tv_nsec
-
__CURRENT_TIME
.
tv_nsec
;
if
(
Nticks
>
0
){
PhaseCorr
=
elapsed
-
(
common_ticktime__
+
FreqCorr
/
Nticks
)
*
sync_align_ratio
/
100
;
/* to be divided by Nticks */
Tcorr
=
common_ticktime__
+
(
PhaseCorr
+
FreqCorr
)
/
Nticks
;
if
(
Nticks
<
2
){
/* When Sync source period is near Tick time */
/* PhaseCorr may not be applied to Periodic time given to timer */
PeriodicTcorr
=
common_ticktime__
+
FreqCorr
/
Nticks
;
}
else
{
PeriodicTcorr
=
Tcorr
;
}
}
else
if
(
__tick
>
last_tick
){
last_tick
=
__tick
;
PhaseCorr
=
elapsed
-
(
Tsync
*
sync_align_ratio
/
100
);
PeriodicTcorr
=
Tcorr
=
common_ticktime__
+
PhaseCorr
+
FreqCorr
;
}
else
{
/*PLC did not run meanwhile. Nothing to do*/
return
;
}
/* DO ALIGNEMENT */
PLC_SetTimer
(
Tcorr
-
elapsed
,
PeriodicTcorr
);
}
}
}
#endif
Beremiz/beremiz_oi_production_line/build/py_ext.c
0 → 100644
View file @
5ca48d3b
/*
* Python Asynchronous execution code
*
* PLC put python commands in a fifo, respecting execution order
* with the help of C pragmas inserted in python_eval FB code
*
* Buffer content is read asynchronously, (from non real time part),
* commands are executed and result stored for later use by PLC.
*
* In this implementation, fifo is a list of pointer to python_eval
* function blocks structures. Some local variables have been added in
* python_eval interface. We use those local variables as buffer and state
* flags.
*
* */
#include "iec_types_all.h"
#include "POUS.h"
#include <string.h>
/* The fifo (fixed size, as number of FB is fixed) */
static
PYTHON_EVAL
*
EvalFBs
[
1
];
/* Producer and consumer cursors */
static
int
Current_PLC_EvalFB
;
static
int
Current_Python_EvalFB
;
/* A global IEC-Python gateway state, for use inside python_eval FBs*/
static
int
PythonState
;
#define PYTHON_LOCKED_BY_PYTHON 0
#define PYTHON_LOCKED_BY_PLC 1
#define PYTHON_MUSTWAKEUP 2
#define PYTHON_FINISHED 4
/* Each python_eval FunctionBlock have it own state */
#define PYTHON_FB_FREE 0
#define PYTHON_FB_REQUESTED 1
#define PYTHON_FB_PROCESSING 2
#define PYTHON_FB_ANSWERED 3
int
WaitPythonCommands
(
void
);
void
UnBlockPythonCommands
(
void
);
int
TryLockPython
(
void
);
void
UnLockPython
(
void
);
void
LockPython
(
void
);
int
__init_py_ext
()
{
int
i
;
/* Initialize cursors */
Current_Python_EvalFB
=
0
;
Current_PLC_EvalFB
=
0
;
PythonState
=
PYTHON_LOCKED_BY_PYTHON
;
for
(
i
=
0
;
i
<
1
;
i
++
)
EvalFBs
[
i
]
=
NULL
;
return
0
;
}
void
__cleanup_py_ext
()
{
PythonState
=
PYTHON_FINISHED
;
UnBlockPythonCommands
();
}
void
__retrieve_py_ext
()
{
/* Check Python thread is not being
* modifying internal python_eval data */
PythonState
=
TryLockPython
()
?
PYTHON_LOCKED_BY_PLC
:
PYTHON_LOCKED_BY_PYTHON
;
/* If python thread _is_ in, then PythonState remains PYTHON_LOCKED_BY_PYTHON
* and python_eval will no do anything */
}
void
__publish_py_ext
()
{
if
(
PythonState
&
PYTHON_LOCKED_BY_PLC
){
/* If runnig PLC did push something in the fifo*/
if
(
PythonState
&
PYTHON_MUSTWAKEUP
){
/* WakeUp python thread */
UnBlockPythonCommands
();
}
UnLockPython
();
}
}
/**
* Called by the PLC, each time a python_eval
* FB instance is executed
*/
void
__PythonEvalFB
(
int
poll
,
PYTHON_EVAL
*
data__
)
{
if
(
!
__GET_VAR
(
data__
->
TRIG
)){
/* ACK is False when TRIG is false, except a pulse when receiving result */
__SET_VAR
(
data__
->
,
ACK
,,
0
);
}
/* detect rising edge on TRIG to trigger evaluation */
if
(((
__GET_VAR
(
data__
->
TRIG
)
&&
!
__GET_VAR
(
data__
->
TRIGM1
))
||
/* polling is equivalent to trig on value rather than on rising edge*/
(
poll
&&
__GET_VAR
(
data__
->
TRIG
)
))
&&
/* trig only if not already trigged */
__GET_VAR
(
data__
->
TRIGGED
)
==
0
){
/* mark as trigged */
__SET_VAR
(
data__
->
,
TRIGGED
,,
1
);
/* make a safe copy of the code */
__SET_VAR
(
data__
->
,
PREBUFFER
,,
__GET_VAR
(
data__
->
CODE
));
}
/* retain value for next rising edge detection */
__SET_VAR
(
data__
->
,
TRIGM1
,,
__GET_VAR
(
data__
->
TRIG
));
/* python thread is not in ? */
if
(
PythonState
&
PYTHON_LOCKED_BY_PLC
){
/* if some answer are waiting, publish*/
if
(
__GET_VAR
(
data__
->
STATE
)
==
PYTHON_FB_ANSWERED
){
/* Copy buffer content into result*/
__SET_VAR
(
data__
->
,
RESULT
,,
__GET_VAR
(
data__
->
BUFFER
));
/* signal result presence to PLC*/
__SET_VAR
(
data__
->
,
ACK
,,
1
);
/* Mark as free */
__SET_VAR
(
data__
->
,
STATE
,,
PYTHON_FB_FREE
);
/* mark as not trigged */
if
(
!
poll
)
__SET_VAR
(
data__
->
,
TRIGGED
,,
0
);
/*printf("__PythonEvalFB pop %d - %*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/
}
else
if
(
poll
){
/* when in polling, no answer == ack down */
__SET_VAR
(
data__
->
,
ACK
,,
0
);
}
/* got the order to act ?*/
if
(
__GET_VAR
(
data__
->
TRIGGED
)
==
1
&&
/* and not already being processed */
__GET_VAR
(
data__
->
STATE
)
==
PYTHON_FB_FREE
)
{
/* Enter the block in the fifo
* Don't have to check if fifo cell is free
* as fifo size == FB count, and a FB cannot
* be requested twice */
EvalFBs
[
Current_PLC_EvalFB
]
=
data__
;
/* copy into BUFFER local*/
__SET_VAR
(
data__
->
,
BUFFER
,,
__GET_VAR
(
data__
->
PREBUFFER
));
/* Set ACK pin to low so that we can set a rising edge on result */
if
(
!
poll
){
/* when not polling, a new answer imply reseting ack*/
__SET_VAR
(
data__
->
,
ACK
,,
0
);
}
else
{
/* when in polling, acting reset trigger */
__SET_VAR
(
data__
->
,
TRIGGED
,,
0
);
}
/* Mark FB busy */
__SET_VAR
(
data__
->
,
STATE
,,
PYTHON_FB_REQUESTED
);
/* Have to wakeup python thread in case he was asleep */
PythonState
|=
PYTHON_MUSTWAKEUP
;
/*printf("__PythonEvalFB push %d - %*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/
/* Get a new line */
Current_PLC_EvalFB
=
(
Current_PLC_EvalFB
+
1
)
%
1
;
}
}
}
char
*
PythonIterator
(
char
*
result
,
void
**
id
)
{
char
*
next_command
;
PYTHON_EVAL
*
data__
;
//printf("PythonIterator result %s\n", result);
/*emergency exit*/
if
(
PythonState
&
PYTHON_FINISHED
)
return
NULL
;
/* take python mutex to prevent changing PLC data while PLC running */
LockPython
();
/* Get current FB */
data__
=
EvalFBs
[
Current_Python_EvalFB
];
if
(
data__
&&
/* may be null at first run */
__GET_VAR
(
data__
->
STATE
)
==
PYTHON_FB_PROCESSING
){
/* some answer awaited*/
/* If result not None */
if
(
result
){
/* Get results len */
__SET_VAR
(
data__
->
,
BUFFER
,
.
len
,
strlen
(
result
));
/* prevent results overrun */
if
(
__GET_VAR
(
data__
->
BUFFER
,
.
len
)
>
STR_MAX_LEN
)
{
__SET_VAR
(
data__
->
,
BUFFER
,
.
len
,
STR_MAX_LEN
);
/* TODO : signal error */
}
/* Copy results to buffer */
strncpy
((
char
*
)
__GET_VAR
(
data__
->
BUFFER
,
.
body
),
result
,
__GET_VAR
(
data__
->
BUFFER
,.
len
));
}
else
{
__SET_VAR
(
data__
->
,
BUFFER
,
.
len
,
0
);
}
/* remove block from fifo*/
EvalFBs
[
Current_Python_EvalFB
]
=
NULL
;
/* Mark block as answered */
__SET_VAR
(
data__
->
,
STATE
,,
PYTHON_FB_ANSWERED
);
/* Get a new line */
Current_Python_EvalFB
=
(
Current_Python_EvalFB
+
1
)
%
1
;
//printf("PythonIterator ++ Current_Python_EvalFB %d\n", Current_Python_EvalFB);
}
/* while next slot is empty */
while
(((
data__
=
EvalFBs
[
Current_Python_EvalFB
])
==
NULL
)
||
/* or doesn't contain command */
__GET_VAR
(
data__
->
STATE
)
!=
PYTHON_FB_REQUESTED
)
{
UnLockPython
();
/* wait next FB to eval */
//printf("PythonIterator wait\n");
if
(
WaitPythonCommands
())
return
NULL
;
/*emergency exit*/
if
(
PythonState
&
PYTHON_FINISHED
)
return
NULL
;
LockPython
();
}
/* Mark block as processing */
__SET_VAR
(
data__
->
,
STATE
,,
PYTHON_FB_PROCESSING
);
//printf("PythonIterator\n");
/* make BUFFER a null terminated string */
__SET_VAR
(
data__
->
,
BUFFER
,
.
body
[
__GET_VAR
(
data__
->
BUFFER
,
.
len
)],
0
);
/* next command is BUFFER */
next_command
=
(
char
*
)
__GET_VAR
(
data__
->
BUFFER
,
.
body
);
*
id
=
data__
;
/* free python mutex */
UnLockPython
();
/* return the next command to eval */
return
next_command
;
}
Beremiz/beremiz_oi_production_line/build/resource1.c
0 → 100644
View file @
5ca48d3b
/*******************************************/
/* FILE GENERATED BY iec2c */
/* Editing this file is not recommended... */
/*******************************************/
#include "iec_std_lib.h"
// RESOURCE RESOURCE1
extern
unsigned
long
long
common_ticktime__
;
#include "accessor.h"
#include "POUS.h"
#include "config.h"
#include "POUS.c"
BOOL
TASK0
;
PLC_PRG
RESOURCE1__INSTANCE0
;
#define INSTANCE0 RESOURCE1__INSTANCE0
void
RESOURCE1_init__
(
void
)
{
BOOL
retain
;
retain
=
0
;
TASK0
=
__BOOL_LITERAL
(
FALSE
);
PLC_PRG_init__
(
&
INSTANCE0
,
retain
);
}
void
RESOURCE1_run__
(
unsigned
long
tick
)
{
TASK0
=
!
(
tick
%
1
);
if
(
TASK0
)
{
PLC_PRG_body__
(
&
INSTANCE0
);
}
}
Beremiz/beremiz_oi_production_line/build/runtime_00_pyext.py
0 → 100644
View file @
5ca48d3b
import
csv
from
collections
import
OrderedDict
csv_int_files
=
{}
def
CSVRdInt
(
fname
,
rowidx
,
colidx
):
"""
Return value at row/column pointed by integer indexes
Assumes data starts at first row and first column, no headers.
"""
global
csv_int_files
data
=
csv_int_files
.
get
(
fname
,
None
)
if
data
is
None
:
data
=
list
()
try
:
csvfile
=
open
(
fname
,
'rb'
)
except
IOError
:
return
"#FILE_NOT_FOUND"
try
:
dialect
=
csv
.
Sniffer
().
sniff
(
csvfile
.
read
(
1024
))
csvfile
.
seek
(
0
)
reader
=
csv
.
reader
(
csvfile
,
dialect
)
for
row
in
reader
:
data
.
append
(
row
)
except
csv
.
Error
:
return
"#CSV_ERROR"
finally
:
csvfile
.
close
()
csv_int_files
[
fname
]
=
data
try
:
row
=
data
[
rowidx
]
except
IndexError
:
return
"#ROW_NOT_FOUND"
try
:
return
row
[
colidx
]
except
IndexError
:
return
"#COL_NOT_FOUND"
csv_str_files
=
{}
def
CSVRdStr
(
fname
,
rowname
,
colname
):
"""
Return value at row/column pointed by a pair of names as string
Assumes first row is column headers and first column is row name.
"""
global
csv_str_files
entry
=
csv_str_files
.
get
(
fname
,
None
)
if
entry
is
None
:
data
=
dict
()
try
:
csvfile
=
open
(
fname
,
'rb'
)
except
IOError
:
return
"#FILE_NOT_FOUND"
try
:
dialect
=
csv
.
Sniffer
().
sniff
(
csvfile
.
read
(
1024
))
csvfile
.
seek
(
0
)
reader
=
csv
.
reader
(
csvfile
,
dialect
)
headers
=
dict
([(
name
,
index
)
for
index
,
name
in
enumerate
(
reader
.
next
()[
1
:])])
for
row
in
reader
:
data
[
row
[
0
]]
=
row
[
1
:]
except
csv
.
Error
:
return
"#CSV_ERROR"
finally
:
csvfile
.
close
()
csv_str_files
[
fname
]
=
(
headers
,
data
)
else
:
headers
,
data
=
entry
try
:
row
=
data
[
rowname
]
except
KeyError
:
return
"#ROW_NOT_FOUND"
try
:
colidx
=
headers
[
colname
]
except
KeyError
:
return
"#COL_NOT_FOUND"
try
:
return
row
[
colidx
]
except
IndexError
:
return
"#COL_NOT_FOUND"
def
pyext_csv_reload
():
global
csv_int_files
,
csv_str_files
csv_int_files
.
clear
()
csv_str_files
.
clear
()
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_0_oi_sensor@opcua/baseconfnode.xml
→
Beremiz/beremiz_oi_
production_line
/opcua_0_oi_sensor@opcua/baseconfnode.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_0_oi_sensor@opcua/confnode.xml
→
Beremiz/beremiz_oi_
production_line
/opcua_0_oi_sensor@opcua/confnode.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_0_oi_sensor@opcua/selected.csv
→
Beremiz/beremiz_oi_
production_line
/opcua_0_oi_sensor@opcua/selected.csv
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_1_coupler@opcua/baseconfnode.xml
→
Beremiz/beremiz_oi_
production_line
/opcua_1_coupler@opcua/baseconfnode.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_1_coupler@opcua/confnode.xml
→
Beremiz/beremiz_oi_
production_line
/opcua_1_coupler@opcua/confnode.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_1_coupler@opcua/selected.csv
→
Beremiz/beremiz_oi_
production_line
/opcua_1_coupler@opcua/selected.csv
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_2_mes5@opcua/baseconfnode.xml
→
Beremiz/beremiz_oi_
production_line
/opcua_2_mes5@opcua/baseconfnode.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_2_mes5@opcua/confnode.xml
→
Beremiz/beremiz_oi_
production_line
/opcua_2_mes5@opcua/confnode.xml
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/opcua_2_mes5@opcua/selected.csv
→
Beremiz/beremiz_oi_
production_line
/opcua_2_mes5@opcua/selected.csv
View file @
5ca48d3b
File moved
Beremiz/beremiz_oi_
sensor_tutorial
/plc.xml
→
Beremiz/beremiz_oi_
production_line
/plc.xml
View file @
5ca48d3b
File moved
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment