Skip to content

Commit

Permalink
Change UDF logic for output records with asyn:READBACK.
Browse files Browse the repository at this point in the history
Change logic for output records with asyn:READBACK so they set udf=0 in
the outputcallbackcallback() function, and not in the processXX function.
This is needed to correctly clear the UDF status and severity.

This problem is happening because for EPICS output records the only way to clear a UDF alarm
is to put a value into the record, either from an external put from a CA or DB link
(in which case code in the dbAccess.c dbPut() routine clears UDF and the record would get processed)
or by reading a value through the DOL link during record processing triggered by some other means.
In both cases UDF will have been cleared before the call to checkAlarms() in the boRecord::process()
routine, which is where the UDF field is checked.

Unfortunately for asyn all output records call the checkAlarms() routine before the device support's
write_bo() routine, so clearing UDF in processBo() is too late for this process cycle,
the UDF_ALARM has already been registered.

This also means that if the bo record is configured with non-zero alarms in ZSV or OSV
the initial read wouldn't trigger the appropriate STATE_ALARM either,
since they get set in that routine as well.
  • Loading branch information
MarkRivers committed Jun 2, 2021
1 parent 603d54f commit fdfca2f
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 9 deletions.
3 changes: 2 additions & 1 deletion asyn/devEpics/devAsynFloat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,8 @@ static void outputCallbackCallback(CALLBACK *pcb)
dbScanLock(pr);
epicsMutexLock(pPvt->devPvtLock);
pPvt->newOutputCallbackValue = 1;
/* We need to set udf=0 here so that it is already cleared when dbProcess is called */
pr->udf = 0;
dbProcess(pr);
if (pPvt->newOutputCallbackValue != 0) {
/* We called dbProcess but the record did not process, perhaps because PACT was 1
Expand Down Expand Up @@ -664,7 +666,6 @@ static long processAo(aoRecord *pr)
if (pr->aslo != 0.0) val64 *= pr->aslo;
val64 += pr->aoff;
pr->val = val64;
pr->udf = 0;
}
} else if(pr->pact == 0) {
/* ASLO/AOFF conversion */
Expand Down
5 changes: 2 additions & 3 deletions asyn/devEpics/devAsynInt32.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ static void outputCallbackCallback(CALLBACK *pcb)
dbScanLock(pr);
epicsMutexLock(pPvt->devPvtLock);
pPvt->newOutputCallbackValue = 1;
/* We need to set udf=0 here so that it is already cleared when dbProcess is called */
pr->udf = 0;
dbProcess(pr);
if (pPvt->newOutputCallbackValue != 0) {
/* We called dbProcess but the record did not process, perhaps because PACT was 1
Expand Down Expand Up @@ -987,7 +989,6 @@ static long processAo(aoRecord *pr)
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
pr->rval = pPvt->result.value;
pr->udf = 0;
value = (double)pr->rval + (double)pr->roff;
if(pr->aslo!=0.0) value *= pr->aslo;
value += pr->aoff;
Expand Down Expand Up @@ -1113,7 +1114,6 @@ static long processLo(longoutRecord *pr)
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
pr->val = pPvt->result.value;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->val;
Expand Down Expand Up @@ -1219,7 +1219,6 @@ static long processBo(boRecord *pr)
if (pPvt->result.status == asynSuccess) {
pr->rval = pPvt->result.value;
pr->val = (pr->rval) ? 1 : 0;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->rval;
Expand Down
5 changes: 2 additions & 3 deletions asyn/devEpics/devAsynInt64.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ static void outputCallbackCallback(CALLBACK *pcb)
dbScanLock(pr);
epicsMutexLock(pPvt->devPvtLock);
pPvt->newOutputCallbackValue = 1;
/* We need to set udf=0 here so that it is already cleared when dbProcess is called */
pr->udf = 0;
dbProcess(pr);
if (pPvt->newOutputCallbackValue != 0) {
/* We called dbProcess but the record did not process, perhaps because PACT was 1
Expand Down Expand Up @@ -719,7 +721,6 @@ static long processLLo(int64outRecord *pr)
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
pr->val = pPvt->result.value;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->val;
Expand Down Expand Up @@ -912,7 +913,6 @@ static long processAo(aoRecord *pr)
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
value = (double)pPvt->result.value;
pr->udf = 0;
if (pr->linr == menuConvertNO_CONVERSION){
; /*do nothing*/
} else if ((pr->linr == menuConvertLINEAR) ||
Expand Down Expand Up @@ -1023,7 +1023,6 @@ static long processLo(longoutRecord *pr)
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
pr->val = (epicsInt32)pPvt->result.value;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->val;
Expand Down
2 changes: 2 additions & 0 deletions asyn/devEpics/devAsynOctet.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ static void outputCallbackCallback(CALLBACK *pcb)
dbScanLock(pr);
epicsMutexLock(pPvt->devPvtLock);
pPvt->newOutputCallbackValue = 1;
/* We need to set udf=0 here so that it is already cleared when dbProcess is called */
pr->udf = 0;
dbProcess(pr);
if (pPvt->newOutputCallbackValue != 0) {
/* We called dbProcess but the record did not process, perhaps because PACT was 1
Expand Down
4 changes: 2 additions & 2 deletions asyn/devEpics/devAsynUInt32Digital.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,8 @@ static void outputCallbackCallback(CALLBACK *pcb)
dbScanLock(pr);
epicsMutexLock(pPvt->devPvtLock);
pPvt->newOutputCallbackValue = 1;
/* We need to set udf=0 here so that it is already cleared when dbProcess is called */
pr->udf = 0;
dbProcess(pr);
if (pPvt->newOutputCallbackValue != 0) {
/* We called dbProcess but the record did not process, perhaps because PACT was 1
Expand Down Expand Up @@ -746,7 +748,6 @@ static long processBo(boRecord *pr)
if (pPvt->result.status == asynSuccess) {
pr->rval = pPvt->result.value & pr->mask;
pr->val = (pr->rval) ? 1 : 0;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->rval;;
Expand Down Expand Up @@ -851,7 +852,6 @@ static long processLo(longoutRecord *pr)
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
pr->val = pPvt->result.value & pPvt->mask;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->val & pPvt->mask;
Expand Down

0 comments on commit fdfca2f

Please sign in to comment.