Commit e2cd061c authored by Claes Sjofors's avatar Claes Sjofors

Plc Grafcet sequences can be used in component function objects

parent 8cacd265
......@@ -6999,6 +6999,11 @@ be displayed in an object graph with the dynamic type StatusColor. If you want t
in the plc code for the object, you have to consider that the attribute is a pointer and
fetch the value with GetIpPtr.
<b>ResetSequence
It is possible to use GRAFCET sequences in a component. One difference from an ordinary
sequence are that the reset object should be defined as an attribute of class Dv in the
main object, with the name 'SequenceReset'. SubSteps can not be used in the sequence.
<b>GraphConfiguration
GraphConfiguration is of type Enum and used to decide which object graph is to be opened
for the current instance. It is used by the 'ConfigureComponent' method (see below).
......
......@@ -6897,6 +6897,11 @@ objektsbild med dynamiktypen StatusColor. Om man vill anv
objektet, måste man tänka på att attributet är en pekare och hämta upp värdet upp med
GetIpPtr.
<b>ResetSequence
Det är möjligt att använda GRAFCET sekvenser i en komponent. En skillnad från en ordinär
sekvens är att resetobjektet ska vara definierat med ett attribut a klass Dv med namnet
'SequenceReset'i huvudobjektet. SubStep kan inte användas if sekvensen.
<b>GraphConfiguration
GraphConfiguration är av typ Enum och används för att bestämma vilken objektsbild som ska
öppnas för den aktuella instansen. Används av 'ConfigureComponent' metoden (se nedan).
......
......@@ -126,6 +126,7 @@ nomodif <Nothing is modified> /info
compileparent <Compile parent window> /info
disabled <Object is disabled> /error
maxsize <MaxSize is larger than cell size> /error
noseqreset <No SequenceReset object found in main object> /error
.facility FOE,280 /prefix = FOE__ ! Function object editor
......
......@@ -602,6 +602,7 @@ static int gcg_is_in_focode(
static void gcg_pending_compile_add( gcg_ctx gcgctx, pwr_tOid wind);
static int gcg_pending_compile_exec( gcg_ctx gcgctx);
static int gcg_check_grafcet_reset( gcg_ctx gcgctx, vldh_t_node node);
......@@ -6983,59 +6984,17 @@ int gcg_comp_m13( gcg_ctx gcgctx, vldh_t_node node)
unsigned long point;
unsigned long par_inverted;
int sts;
int size;
unsigned long point_count;
vldh_t_conpoint *pointlist;
vldh_t_node next_node;
unsigned long next_point;
int k;
vldh_t_plc plc;
pwr_sAttrRef resattrref;
pwr_sAttrRef *resattrref_ptr;
ldhses = (node->hn.wind)->hw.ldhses;
if ( gcgctx->reset_checked == FALSE )
{
/* Check the resetobject in the plcobject */
plc = (node->hn.wind)->hw.plc;
sts = ldh_GetObjectPar( ldhses,
plc->lp.oid,
"DevBody",
"ResetObject",
(char **)&resattrref_ptr, &size);
if ( EVEN(sts)) return sts;
resattrref = *resattrref_ptr;
free((char *) resattrref_ptr);
/* Indicate that the reset object is checked */
gcgctx->reset_checked = TRUE;
sts = gcg_replace_ref( gcgctx, &resattrref, node);
if ( EVEN(sts)) return sts;
/* The reset object has to be a di, do or dv */
sts = ldh_GetAttrRefOrigTid( ldhses, &resattrref, &cid);
if ( EVEN(sts)) {
gcg_error_msg( gcgctx, GSX__NORESET, node);
return GSX__NEXTNODE;
}
/* Check that the class of the reset object is correct */
if ( !(cid == pwr_cClass_Di ||
cid == pwr_cClass_Dv ||
cid == pwr_cClass_Po ||
cid == pwr_cClass_Do)) {
gcg_error_msg( gcgctx, GSX__CLASSRESET, node);
return GSX__NEXTNODE;
}
gcgctx->reset_object = resattrref;
/* Insert reset object in ioread list */
gcg_ioread_insert( gcgctx, resattrref, GCG_PREFIX_REF);
}
sts = gcg_check_grafcet_reset( gcgctx, node);
if ( EVEN(sts) || sts == GSX__NEXTNODE)
return sts;
/* Insert step object in ref list */
gcg_ref_insert( gcgctx, node->ln.oid, GCG_PREFIX_REF);
......@@ -9394,56 +9353,15 @@ int gcg_comp_m24( gcg_ctx gcgctx, vldh_t_node node)
unsigned long next_point;
int k;
int found;
vldh_t_plc plc;
pwr_sAttrRef resattrref;
pwr_sAttrRef *resattrref_ptr;
char *windbuffer;
pwr_tObjid windowobjdid;
pwr_tClassId windclass;
ldhses = (node->hn.wind)->hw.ldhses;
if ( gcgctx->reset_checked == FALSE )
{
/* Check the resetobject in the plcobject */
plc = (node->hn.wind)->hw.plc;
sts = ldh_GetObjectPar( ldhses,
plc->lp.oid,
"DevBody",
"ResetObject",
(char **)&resattrref_ptr, &size);
if ( EVEN(sts)) return sts;
resattrref = *resattrref_ptr;
free((char *) resattrref_ptr);
/* Indicate that the reset object is checked */
gcgctx->reset_checked = TRUE;
sts = gcg_replace_ref( gcgctx, &resattrref, node);
if ( EVEN(sts)) return sts;
/* The reset object has to be a di, do or dv */
sts = ldh_GetAttrRefOrigTid( ldhses, &resattrref, &cid);
if ( EVEN(sts)) {
gcg_error_msg( gcgctx, GSX__NORESET, node);
return GSX__NEXTNODE;
}
/* Check that the class of the reset object is correct */
if ( !(cid == pwr_cClass_Di ||
cid == pwr_cClass_Dv ||
cid == pwr_cClass_Po ||
cid == pwr_cClass_Do)) {
gcg_error_msg( gcgctx, GSX__CLASSRESET, node);
return GSX__NEXTNODE;
}
gcgctx->reset_object = resattrref;
/* Insert reset object in ioread list */
gcg_ioread_insert( gcgctx, resattrref, GCG_PREFIX_REF);
}
sts = gcg_check_grafcet_reset( gcgctx, node);
if ( EVEN(sts) || sts == GSX__NEXTNODE)
return sts;
/* Insert step object in ref list */
gcg_ref_insert( gcgctx, node->ln.oid, GCG_PREFIX_REF);
......@@ -9560,16 +9478,12 @@ int gcg_comp_m26( gcg_ctx gcgctx, vldh_t_node node)
unsigned long point;
unsigned long par_inverted;
int sts;
int size;
unsigned long point_count;
vldh_t_conpoint *pointlist;
vldh_t_node next_node;
unsigned long next_point;
int k;
vldh_t_plc plc;
pwr_sAttrRef resattrref;
pwr_tObjid refobjdid;
pwr_sAttrRef *resattrref_ptr;
unsigned long orderpar_index = 1;
ldhses = (node->hn.wind)->hw.ldhses;
......@@ -9600,45 +9514,9 @@ int gcg_comp_m26( gcg_ctx gcgctx, vldh_t_node node)
/* Insert parent object in ref list */
gcg_ref_insert( gcgctx, refobjdid, GCG_PREFIX_REF);
if ( gcgctx->reset_checked == FALSE )
{
/* Check the resetobject in the plcobject */
plc = (node->hn.wind)->hw.plc;
sts = ldh_GetObjectPar( ldhses, plc->lp.oid,
"DevBody", "ResetObject",
(char **)&resattrref_ptr, &size);
if ( EVEN(sts)) return sts;
resattrref = *resattrref_ptr;
free((char *) resattrref_ptr);
/* Indicate that the reset object is checked */
gcgctx->reset_checked = TRUE;
sts = gcg_replace_ref( gcgctx, &resattrref, node);
if ( EVEN(sts)) return sts;
/* The reset object has to be a di, do or dv */
sts = ldh_GetAttrRefOrigTid( ldhses, &resattrref, &cid);
if ( EVEN(sts)) {
gcg_error_msg( gcgctx, GSX__NORESET, node);
return GSX__NEXTNODE;
}
/* Check that the class of the reset object is correct */
if ( !(cid == pwr_cClass_Di ||
cid == pwr_cClass_Dv ||
cid == pwr_cClass_Po ||
cid == pwr_cClass_Do)) {
gcg_error_msg( gcgctx, GSX__CLASSRESET, node);
return GSX__NEXTNODE;
}
gcgctx->reset_object = resattrref;
/* Insert reset object in ioread list */
gcg_ioread_insert( gcgctx, resattrref, GCG_PREFIX_REF);
}
sts = gcg_check_grafcet_reset( gcgctx, node);
if ( EVEN(sts) || sts == GSX__NEXTNODE)
return sts;
/* Insert step object in ref list */
gcg_ref_insert( gcgctx, node->ln.oid, GCG_PREFIX_REF);
......@@ -16228,3 +16106,90 @@ static int gcg_pending_compile_exec( gcg_ctx gcgctx)
}
return GSX__SUCCESS;
}
static int gcg_check_grafcet_reset( gcg_ctx gcgctx, vldh_t_node node)
{
pwr_sAttrRef resattrref;
pwr_sAttrRef *resattrref_ptr;
pwr_tStatus sts;
int size;
vldh_t_plc plc;
pwr_tCid cid;
if ( gcgctx->reset_checked == FALSE ) {
if ( gcg_is_in_focode( gcgctx, node)) {
pwr_tOid parent;
pwr_tAttrRef *connect_arp;
pwr_tAttrRef connect_ar;
// Reset object should be found in connected main object
// Get Fo object two levels upp
sts = ldh_GetParent( gcgctx->ldhses, node->ln.oid, &parent);
if ( EVEN(sts)) return sts;
sts = ldh_GetParent( gcgctx->ldhses, parent, &parent);
if ( EVEN(sts)) return sts;
// Get Connected main object
sts = ldh_GetObjectPar( gcgctx->ldhses, parent, "RtBody", "PlcConnect",
(char **)&connect_arp, &size);
if ( EVEN(sts)) {
gcg_error_msg( gcgctx, GSX__BADWIND, node);
return GSX__NEXTNODE;
}
connect_ar = *connect_arp;
free((char *) connect_arp);
sts = gcg_replace_ref( gcgctx, &connect_ar, node);
if ( EVEN(sts)) return sts;
sts = ldh_ArefANameToAref( gcgctx->ldhses, &connect_ar, "SequenceReset", &resattrref);
if ( EVEN(sts)) {
gcg_error_msg( gcgctx, GSX__NOSEQRESET, node);
return GSX__NEXTNODE;
}
}
else {
/* Check the resetobject in the plcobject */
plc = (node->hn.wind)->hw.plc;
sts = ldh_GetObjectPar( gcgctx->ldhses,
plc->lp.oid,
"DevBody",
"ResetObject",
(char **)&resattrref_ptr, &size);
if ( EVEN(sts)) return sts;
resattrref = *resattrref_ptr;
free((char *) resattrref_ptr);
/* Indicate that the reset object is checked */
gcgctx->reset_checked = TRUE;
sts = gcg_replace_ref( gcgctx, &resattrref, node);
if ( EVEN(sts)) return sts;
}
/* The reset object has to be a di, do or dv */
sts = ldh_GetAttrRefOrigTid( gcgctx->ldhses, &resattrref, &cid);
if ( EVEN(sts)) {
gcg_error_msg( gcgctx, GSX__NORESET, node);
return GSX__NEXTNODE;
}
/* Check that the class of the reset object is correct */
if ( !(cid == pwr_cClass_Di ||
cid == pwr_cClass_Dv ||
cid == pwr_cClass_Po ||
cid == pwr_cClass_Do)) {
gcg_error_msg( gcgctx, GSX__CLASSRESET, node);
return GSX__NEXTNODE;
}
gcgctx->reset_object = resattrref;
/* Insert reset object in ioread list */
gcg_ioread_insert( gcgctx, resattrref, GCG_PREFIX_REF);
}
return GSX__SUCCESS;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment