Experimental Physics and
| |||||||||||||||
|
Hello everyone, I am using the asyn module to write a device IOC. I want to set the SCAN field as Intr I/O to adapt to the application requirement. The db file is like this: record(stringin,"$(P)Ver") { field(DESC,"Firmware version") field(DTYP, "asynOctetRead") field(INP, "@asyn($(PORT),$(ADDR)) VERSION") field(SCAN,"I/O Intr") } record(stringin,"$(P)Mod") { field(DESC,"Get counter mod") field(DTYP, "asynOctetRead") field(INP, "@asyn($(PORT),$(ADDR)) MOD") field(SCAN,"I/O Intr") } record(stringout,"$(P)Reboot") { field(DESC,"Reboot Device") field(DTYP,"asynOctetWrite") field(OUT,"@asyn($(PORT),$(ADDR))REBOOT") field(VAL, "REST") } record(stringin, "$(P)GateInStatus") { field(DESC,"DS:AlwaysON/EN:Need Input") field(DTYP,"asynOctetRead") field(INP,"@asyn($(PORT),$(ADDR)) GATEINSTATUS") field(SCAN,"I/O Intr") } record(longin,"$(P)Count07") { field(DESC,"Counter 07") field(DTYP, "asynInt32") field(INP, "@asyn($(PORT),$(ADDR)) COUNT07") field(SCAN,"I/O Intr") } ... ... When I run the st.cmd file, it prompt: ”initCommon enum registerInterruptUser asynManager: getInterruptPvt Driver does not support interrupts on intterface asynEnum”. All the test-error picture, st.cmd and the complete .cpp files are attatched. I don't know where the problem is and how to correct it. Maybe a polling function is necessary in the .cpp file when the SCAN filed is "I/O Intr", and the write or read functions should be called in the polling function? Looking forward to your feedback. Thank you very much. Best wishes, Yoon Attachment:
test-error.png /* * ct08.cpp * * Asyn driver that inherits from the asynPortDriver class to test connection handling * * Author: Mark Rivers * * Created June 2, 2012 */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <epicsTypes.h> #include <epicsTime.h> #include <epicsTimer.h> #include <epicsThread.h> #include <epicsString.h> #include <epicsMutex.h> #include <epicsEvent.h> #include <iocsh.h> #include <epicsExport.h> #include "ct08.h" /*Define symbolic constants*/ #define TIMEOUT (5.0) #define BUFFER_SIZE (100) #define POLLER_PERIOD 1 #define MAX_RESPONSE_LEN 256 static const char *driverName="ct08"; static void pollerTask(void *drvPvt); ct08::ct08(const char *portName, const char *IPPortName, const char *outputString) : asynPortDriver(portName, 1, /* maxAddr */ asynOctetMask | asynInt32Mask | asynFloat64Mask |asynFloat64ArrayMask |asynEnumMask |asynDrvUserMask,/* Interface mask */ asynOctetMask | asynInt32Mask | asynFloat64Mask |asynFloat64ArrayMask |asynEnumMask |asynDrvUserMask, /* Interrupt mask */ 0, ASYN_CANBLOCK, /* asynFlags. This driver does block and it is not multi-device*/ 1, /* Autoconnect */ 0, /* Default priority */ 0) /* Default stack size*/ { asynStatus status; const char *functionName = "ct08"; /*createParam*/ createParam(P_VersionString, asynParamOctet, &P_Version); createParam(P_ModString, asynParamOctet, &P_Mod); createParam(P_RebootString, asynParamOctet, &P_Reboot); createParam(P_GateinstatusString, asynParamOctet, &P_Gateinstatus); createParam(P_Count07String, asynParamInt32, &P_Count07); createParam(P_StartString, asynParamInt32, &P_Start); createParam(P_StopString, asynParamInt32, &P_Stop); createParam(P_DistimestopString, asynParamInt32, &P_Distimestop); createParam(P_EntimestopString, asynParamInt32, &P_Entimestop); createParam(P_SetTmsString, asynParamInt32, &P_SetTms); createParam(P_ReadTmsString, asynParamInt32, &P_ReadTms); outputString_ = epicsStrDup(outputString); /* Connect to the port */ status = pasynOctetSyncIO->connect(IPPortName, 0, &pasynUserIPPort_, NULL); if (status) { printf("%s:%s: pasynOctetSyncIO->connect failure, status=%d\n", driverName, functionName, status); return; } /* Create the thread that computes the waveforms in the background */ status = (asynStatus)(epicsThreadCreate("ct08Task", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)::pollerTask, this) == NULL); if (status) { printf("%s:%s: epicsThreadCreate failure, status=%d\n", driverName, functionName, status); return; } } static void pollerTask(void *drvPvt) { ct08 *pPvt = (ct08 *)drvPvt; pPvt->pollerTask(); } /** Poller task that runs as a separate thread. */ void ct08::pollerTask(void) { asynStatus status; char response[MAX_RESPONSE_LEN] = ""; size_t numWrite, numRead; int isConnected; int eomReason; static const char *functionName = "pollerTask"; } /** Called when asyn clients call pasynInt32->write(). * * This function sends a signal to the simTask thread if the value of P_Run has changed. * * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * * \param[in] pasynUser pasynUser structure that encodes the reason and address. * * \param[in] value Value to write. */ asynStatus ct08::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; asynStatus status = asynSuccess; size_t nRead; size_t nActual; int eomReason; //int readValue; const char *paramName; const char* functionName = "writeInt32"; /* Set the parameter in the parameter library. */ status = (asynStatus) setIntegerParam(function, value); /* Fetch the parameter string name for possible use in debugging */ // getParamName(function, ¶mName); //debug 2-1 if (function==P_Start) { sprintf(writeBuffer, "%d", value); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, strlen(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, &nActual, &nRead, &eomReason); //debug 2-2 //sscanf(readBuffer, "%d", readValue); printf("P_Start returns %s \r\n",readBuffer); } if (function==P_Stop) { sprintf(writeBuffer, "%d", value); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, strlen(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, &nActual, &nRead, &eomReason); //debug 2-2 // sscanf(readBuffer, "%d", readValue); printf("P_Start returns %s \r\n",readBuffer); } if (function==P_SetTms) { sprintf(writeBuffer, "%d", value); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, strlen(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, &nActual, &nRead, &eomReason); //debug 2-2 //sscanf(readBuffer, "%d", readValue); printf("P_SetTms returns %s \r\n",readBuffer); } /* Do callbacks so higher layers see any changes */ status = (asynStatus) callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=%d", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=%d\n", driverName, functionName, function, paramName, value); return status; } asynStatus ct08::readInt32(asynUser *pasynUser, epicsInt32* value) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char *functionName = "readInt32"; size_t nActual; size_t nRead; int eom; if(function==P_Count07) { sprintf(writeBuffer, "%s", "CTR?070701");// to change it tobe CTMR?000701, change the readBuffer size tobe 100,then send count and timer to it's PV seperately. status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer,sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, &nActual, &nRead, &eom); status=(asynStatus)setStringParam(P_Count07,readBuffer); } if(function==P_ReadTms) { sprintf(writeBuffer, "%s", "TPR?");// to change it tobe CTMR?000701, change the readBuffer size tobe 100,then send count and timer to it's PV seperately. status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer,sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, &nActual, &nRead, &eom); status=(asynStatus)setStringParam(P_ReadTms,readBuffer); } status=(asynStatus)callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d", driverName, functionName, status, function); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d\n", driverName, functionName, function); return status; } asynStatus ct08::writeFloat64(asynUser *pasynUser, epicsFloat64 value) { int function=pasynUser->reason; asynStatus status=asynSuccess; const char *paramName; const char* functionName="writeFloat64"; /*Set parameter in the parameter liberay*/ status=(asynStatus)setDoubleParam(function, value); /*Fetch the parameter in the parameter liberary*/ getParamName(function,¶mName); /*do callbacks so higher layers see any changes*/ status=(asynStatus)callParamCallbacks(); if(status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=%f", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=%f\n", driverName, functionName, paramName, value); return status; } asynStatus ct08::readFloat64(asynUser *pasynUser, epicsFloat64* value) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char *functionName = "readFloat64Array"; if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d", driverName, functionName, status, function); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d\n", driverName, functionName, function); return status; } asynStatus ct08::writeOctet(asynUser* pasynUser, const char* data, size_t maxchars, size_t *nActual) { int function=pasynUser->reason; asynStatus status=asynSuccess; size_t nRead; int eomReason; const char *functionName="writeOctet"; if(function==P_Reboot) { sprintf(writeBuffer,"%s","REST"); // status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, data, maxchars, readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, &eomReason); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, &eomReason); status=(asynStatus)setStringParam(P_Reboot,readBuffer); /*test code*/ const char *readData; getParamName(P_Reboot, &readData); printf("P_Reboot is %s \r\n",readData); /*test code end*/ } if(function==P_Distimestop) { sprintf(writeBuffer,"%s","DSAS"); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, &eomReason); status=(asynStatus)setStringParam(P_Distimestop,readBuffer); } if(function==P_Entimestop) { sprintf(writeBuffer,"%s","ENCS"); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, &eomReason); status=(asynStatus)setStringParam(P_Entimestop,readBuffer); } status=(asynStatus)callParamCallbacks(); if(status) epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s:%s:status=%d,function=%d,value=%s", driverName, functionName, status,function, data); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%s\n", driverName,functionName,function,data); return status; } asynStatus ct08::readOctet(asynUser* pasynUser, const char* data, size_t maxchars, size_t *nActual, int *eom) { int function=pasynUser->reason; asynStatus status=asynSuccess; size_t nRead; const char *functionName="readOctet"; if(function=P_Version) { sprintf(writeBuffer, "%s", "VER?"); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, eom); status=(asynStatus)setStringParam(P_Version,readBuffer); } if(function=P_Mod) { sprintf(writeBuffer,"%s","MOD?"); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, eom); status=(asynStatus)setStringParam(P_Mod,readBuffer); } if(function=P_Gateinstatus) { sprintf(writeBuffer,"%s","GATEIN?"); status=pasynOctetSyncIO->writeRead(pasynUserIPPort_, writeBuffer, sizeof(writeBuffer), readBuffer, sizeof(readBuffer), TIMEOUT, nActual, &nRead, eom); status=(asynStatus)setStringParam(P_Gateinstatus,readBuffer); } status=(asynStatus)callParamCallbacks(); if(status) epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s:%s:status=%d,function=%d,value=%s", driverName, functionName, status, function, data); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%s\n", driverName,functionName,function,data); return status; } extern "C" { int ct08Configure(const char *portName, const char *IPPortName, const char *outputString) { new ct08(portName, IPPortName, outputString); return(asynSuccess); } /* EPICS iocsh shell commands */ static const iocshArg initArg0 = { "portName",iocshArgString}; static const iocshArg initArg1 = { "IPPortName",iocshArgString}; static const iocshArg initArg2 = { "output string",iocshArgString}; static const iocshArg * const initArgs[] = {&initArg0, &initArg1, &initArg2}; static const iocshFuncDef initFuncDef = {"ct08Configure",3,initArgs}; static void initCallFunc(const iocshArgBuf *args) { ct08Configure(args[0].sval, args[1].sval, args[2].sval); } void ct08Register(void) { iocshRegister(&initFuncDef,initCallFunc); } epicsExportRegistrar(ct08Register); } #!../../bin/linux-x86_64/ct08 <envPaths cd "${TOP}" dbLoadDatabase("./dbd/testCt08.dbd") ct08_registerRecordDeviceDriver(pdbbase) # This is a bogus IP address that will never connect #drvAsynIPPortConfigure("IPPort", "164.54.160.220:20", 0, 0, 1); # This is a real IP address that will connect drvAsynIPPortConfigure("IPPort", "192.168.1.123:7777", 0, 0, 1); #drvAsynIPPortConfigure("IPPort", "newport-xps12:5001 COM", 0, 0, 1); ct08Configure("PORT1", "IPPort", NULL) #asynSetTraceMask("PORT1",0,9) asynSetTraceIOMask("PORT1",0,0x2) dbLoadRecords("./db/ct08App.db","P=ct08:,R=asyn1,PORT=PORT1,ADDR=0,OMAX=80,IMAX=80") iocInit()
| ||||||||||||||
ANJ, 22 Jan 2024 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |