|
|
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, 19 Mar 2026 |
·
Home
·
News
·
About
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |