Hi Adrian,
2022/07/06 10:46:59.429 asynPortDriver:drvUserCreate: addr=0, cannot find parameter Ctrl_RstSw
SL-SCL-CM3:DIA-BPM-3:ResetSoftStat devAsynInt32::initCommon drvUserCreate
This error is not shown for all the PVs and not always for the same PVs. For example, the first compilation shows error for PV1, PV2 and PV3, and the second compilation (immediately) shows error for PV2, PV4 and PV5.
Summing up, it is almost impossible to compile with 0 errors.
First, let me clarify. Those are not compile errors, they are errors at run time, almost certainly during iocInit when the record is being initialized.
This sounds like a race condition where not all parameters have been created before iocInit is called.
Your driver should be creating all of the parameters in the constructor, which will run in the main thread of the startup script. It is OK if createParam() is called in another function that is called from the constructor, but if it is
done in another thread then the constructor must wait for that thread to complete.
It would probably be helpful if you shared your driver code so we could look for the problem.
Mark
From: Tech-talk <tech-talk-bounces at aps.anl.gov>
On Behalf Of Adrian Martinez via Tech-talk
Sent: Thursday, July 7, 2022 2:39 AM
To: tech-talk at aps.anl.gov
Subject: EPICS compilation errors
Hello,
I am developing an epics driver using epics-3.15.5 and asyn-4-33. The driver works correctly but, sometimes (aprox 90% of the time), returns an error when the procces variables (PV) are initialized:
2022/07/06 10:46:59.429 asynPortDriver:drvUserCreate: addr=0, cannot find parameter Ctrl_RstSw
SL-SCL-CM3:DIA-BPM-3:ResetSoftStat devAsynInt32::initCommon drvUserCreate
This error is not shown for all the PVs and not always for the same PVs. For example, the first compilation shows error for PV1, PV2 and PV3, and the second compilation (immediately) shows error for PV2, PV4 and PV5. Summing up, it is almost impossible to
compile with 0 errors.
These errors just affect to PV readbacks, which never change its values, although the value can be read correctly in the memory register corresponding to the modified PV.
The error could be related with the asynPortDriver class so, createParam function from asynPortDriver.cpp it is working correctly, creating the param list with all PVs (it has been checked using a for loop after each createParam invocation):
Last createParam invocation to add mrf_time PV
PUSH = mrf_time
VALS[0] = Ctrl_RstSw
VALS[1] = Ctrl_PosMesEna
VALS[2] = Ctrl_Alarm
VALS[3] = Ctrl_Acqst
VALS[4] = Ctrl_UserBufDump
VALS[5] = Ctrl_SelfClbEna
VALS[6] = Ctrl_CableClbEna
VALS[7] = Ctrl_cnf_rdy
VALS[8] = Ctrl_bpm_rdy
VALS[9] = Ctrl_alarm_x
VALS[10] = Ctrl_alarm_y
VALS[11] = Ctrl_alarm_i
VALS[12] = Ctrl_alarm_p
VALS[13] = Ctrl_alarm_x_ack
VALS[14] = Ctrl_alarm_y_ack
VALS[15] = Ctrl_alarm_i_ack
VALS[16] = Ctrl_alarm_p_ack
VALS[17] = Ctrl_get_idle
VALS[18] = Ctrl_BpmState
VALS[19] = overage_adc_top
VALS[20] = overage_adc_bottom
VALS[21] = overage_adc_right
VALS[22] = overage_adc_left
VALS[23] = calibration_msg
VALS[24] = reset_calibration
VALS[25] = Cavity_present
VALS[26] = disable_calibration
VALS[27] = nfs_status
VALS[28] = enable_compensation
VALS[29] = ntp_status
VALS[30] = ctl_pps_utc_sw
VALS[31] = syncTimeMode
VALS[32] = mrf_time
VALS.SIZE() = 33
The problem comes when drvUserCreate() function is invocated and check all the PVs included in the param list.
/** Called by asynManager to pass a pasynUser structure and drvInfo string to the driver;
* Assigns pasynUser->reason based on the value of the drvInfo string.
* This base class implementation looks up the drvInfo string in the parameter list.
* \param[in] pasynUser pasynUser structure that driver will modify
* \param[in] drvInfo String containing information about what driver function is being referenced
* \param[out] pptypeName Location in which driver can write information.
* \param[out] psize Location where driver can write information about size of pptypeName */
asynStatus asynPortDriver::drvUserCreate(asynUser *pasynUser,
const char *drvInfo,
const char **pptypeName, size_t *psize)
{
static const char *functionName = "drvUserCreate";
asynStatus status;
int index;
int addr;
status = getAddress(pasynUser, &addr); if (status != asynSuccess) return(status);
status = this->findParam(addr, drvInfo, &index); // ¡¡¡ERROR!!!
if (status) {
asynPrint(pasynUser, ASYN_TRACE_ERROR,
"%s:%s: addr=%d, cannot find parameter %s\n",
driverName, functionName, addr, drvInfo);
return(status);
}
pasynUser->reason = index;
asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s:%s: drvInfo=%s, index=%d\n",
driverName, functionName, drvInfo, index);
return(asynSuccess);
}
findParam() is not able to find all the PVs and the if statement is executed. I have print each index after the findParam() execution and the param list has not all the PVs, missing just the ones not found.
Thanks in advance, Adrián.