コード例 #1
0
static int writeRead(asynUser* pasynUser,const char* outBuf,char* inpBuf,int inputSize,int iface)
{
    int eomReason;
    asynStatus status;
    size_t nWrite,nRead,nWriteRequested=strlen(outBuf);
    ioPvt* pioPvt = (ioPvt*)pasynUser->userPvt;

    status = pasynOctetSyncIO->writeRead(pasynUser,outBuf,nWriteRequested,inpBuf,inputSize,TIMEOUT,&nWrite,&nRead,&eomReason);
    if( nWrite!=nWriteRequested ) status = asynError;
    if( status!=asynSuccess )
    {
        pasynManager->lockPort(pasynUser);
        pioPvt->pasynCommon->disconnect(pioPvt->pcommonPvt,pasynUser);
        pioPvt->pasynCommon->connect(pioPvt->pcommonPvt,pasynUser);
        pasynManager->unlockPort(pasynUser);

        asynPrint(pasynUser,ASYN_TRACE_ERROR,"writeRead: error sending %s,sent=%d,recv=%d,err=%d\n",outBuf,nWrite,nRead,status);
    }
    if( iface==IFACE_SERIAL )
    {
        char *token,*next;

        token = epicsStrtok_r(&inpBuf[strlen(outBuf)+2],IFACE_TERM,&next);
        strcpy(inpBuf,token);
    }

    return( status );
}
コード例 #2
0
/// Load a db file multiple times according to a list of items separated by known separator(s).
///
/// The \a dbFile and \a macros arguments are like the normal dbLoadRecords() however
/// it is possible to embed a macro within these whose value takes a value from the \a list.
/// You can either load the same \a dbFile multiple times with different macros, or even load
/// different database files by using \a loopVar as part of the filename. If you want to use a 
/// pure numeric range see dbLoadRecordsLoop()
///
/// The name of the macro to be used for substitution is contained in \a loopVar and needs to be
/// reference in an \\ escaped way to make sure EPICS does not try to substitute it too soon.
/// as well as the \a macros the \a dbFile is also passed the \a loopVar macro value
/// @code
///     dbLoadRecordsList("file\$(S).db", "P=1,Q=Hello\$(S)", "S", "A;B;C", ";")
/// @endcode 
///
/// @param[in] dbFile @copydoc dbLoadRecordsListInitArg0
/// @param[in] macros @copydoc dbLoadRecordsListInitArg1
/// @param[in] loopVar @copydoc dbLoadRecordsListInitArg2
/// @param[in] list @copydoc dbLoadRecordsListInitArg3
/// @param[in] sep @copydoc dbLoadRecordsListInitArg4
epicsShareFunc void dbLoadRecordsList(const char* dbFile, const char* macros, const char* loopVar, const char* list, const char* sep)
{
    static const char* default_sep = ";";
    if (loopVar == NULL || list == NULL)
    {
        dbLoadRecords(dbFile, macros);
        return;
    }
	if (sep == NULL)
	{
		sep = default_sep;
	}
    std::string macros_s, dbFile_s;
    subMacros(macros_s, macros, loopVar);
    subMacros(dbFile_s, dbFile, loopVar);
    MAC_HANDLE* mh = NULL;
	char macros_exp[1024], dbFile_exp[1024];
    macCreateHandle(&mh, NULL);
	loadMacEnviron(mh);
    char* saveptr = NULL;
    char* list_tmp = strdup(list);
    char* list_item = epicsStrtok_r(list_tmp, sep, &saveptr);
    while(list_item != NULL)
    {
		macPushScope(mh);
        macPutValue(mh, loopVar, list_item);   
        macExpandString(mh, macros_s.c_str(), macros_exp, sizeof(macros_exp));
        macExpandString(mh, dbFile_s.c_str(), dbFile_exp, sizeof(dbFile_exp));
        std::ostringstream new_macros;
        new_macros << macros_exp << (strlen(macros_exp) > 0 ? "," : "") << loopVar << "=" << list_item;
        std::cout << "--> (" << list_item << ") dbLoadRecords(\"" << dbFile_exp << "\",\"" << new_macros.str() << "\")" << std::endl;
        dbLoadRecords(dbFile_exp, new_macros.str().c_str());
        list_item = epicsStrtok_r(NULL, sep, &saveptr);
		macPopScope(mh);
    }
    free(list_tmp);
	macDeleteHandle(mh);		
}
コード例 #3
0
static char* process_string(int mode, char* str, const char* delim, int split_len, char** saveptr, char** memptr)
{
    char* tmpstr;
	size_t n;
    if (mode == 1)
	{
	    return epicsStrtok_r(str, delim, saveptr);
	}
	else if (mode == 2)
	{
	    if (split_len == 0)
		{
		    return NULL;
		}
	    if (str != NULL) /* first call */
		{
		    tmpstr = (char*)malloc(split_len + 1);
			*memptr = tmpstr;
			*saveptr = str;
		}
		else
		{
		    tmpstr = *memptr;
		}
		n = strlen(*saveptr);
		if (n == 0)
		{
		    free(tmpstr);
			*memptr = NULL;
		    return NULL;
		}
		strncpy(tmpstr, *saveptr, split_len);
		tmpstr[split_len] = '\0';
		if (n > split_len)
		{
		    *saveptr += split_len;
		}
		else
		{
		    *saveptr += n;
		}	    
		return tmpstr;
	}
	else
	{
	    return NULL;
	}
} 
コード例 #4
0
ファイル: drvMM4000Asyn.c プロジェクト: mark0n/motorRecord
int MM4000AsynConfig(int card,             /* Controller number */
                     const char *portName, /* asyn port name of serial or GPIB port */
                     int asynAddress,      /* asyn subaddress for GPIB */
                     int numAxes,          /* Number of axes this controller supports */
                     int movingPollPeriod, /* Time to poll (msec) when an axis is in motion */
                     int idlePollPeriod)   /* Time to poll (msec) when an axis is idle. 0 for no polling */

{
    AXIS_HDL pAxis;
    int axis;
    MM4000Controller *pController;
    char threadName[20];
    int status;
    int totalAxes;
    int loopState;
    int digits;
    int modelNum;
    int retry = 0;
    char *p, *tokSave;
    char inputBuff[BUFFER_SIZE];
    char outputBuff[BUFFER_SIZE];

    if (numMM4000Controllers < 1) {
        printf("MM4000Config: no MM4000 controllers allocated, call MM4000Setup first\n");
        return MOTOR_AXIS_ERROR;
    }
    if ((card < 0) || (card >= numMM4000Controllers)) {
        printf("MM4000Config: card must in range 0 to %d\n", numMM4000Controllers-1);
        return MOTOR_AXIS_ERROR;
    }
    if ((numAxes < 1) || (numAxes > MM4000_MAX_AXES)) {
        printf("MM4000Config: numAxes must in range 1 to %d\n", MM4000_MAX_AXES);
        return MOTOR_AXIS_ERROR;
    }

    pController = &pMM4000Controller[card];
    pController->pAxis = (AXIS_HDL) calloc(numAxes, sizeof(motorAxis));
    pController->numAxes = numAxes;
    pController->movingPollPeriod = movingPollPeriod/1000.;
    pController->idlePollPeriod = idlePollPeriod/1000.;

    status = pasynOctetSyncIO->connect(portName, asynAddress, &pController->pasynUser, NULL);

    if (status != asynSuccess) {
        printf("MM4000AsynConfig: cannot connect to asyn port %s\n", portName);
        return MOTOR_AXIS_ERROR;
    }

    do
    {
        status = sendAndReceive(pController, "VE;", inputBuff, sizeof(inputBuff));
        retry++;
        /* Return value is length of response string */
    } while (status != asynSuccess && retry < 3);

    if (status != asynSuccess)
        return (MOTOR_AXIS_ERROR);

    strcpy(pController->firmwareVersion, &inputBuff[2]);  /* Skip "VE" */

    /* Set Motion Master model indicator. */
    p = strstr(pController->firmwareVersion, "MM");
    if (p == NULL) {
        printf("MM4000AsynConfig: invalid model = %s\n", pController->firmwareVersion);
        return MOTOR_AXIS_ERROR;
    }
    modelNum = atoi(p+2);
    if (modelNum == 4000)
        pController->model = MM4000;
    else if (modelNum == 4005 || modelNum == 4006)
        pController->model = MM4005;
    else
    {
        printf("MM4000AsynConfig: invalid model = %s\n", pController->firmwareVersion);
        return MOTOR_AXIS_ERROR;
    }

    sendAndReceive(pController, "TP;", inputBuff, sizeof(inputBuff));

    /* The return string will tell us how many axes this controller has */
    for (totalAxes = 0, tokSave = NULL, p = epicsStrtok_r(inputBuff, ",", &tokSave);
             p != 0; p = epicsStrtok_r(NULL, ",", &tokSave), totalAxes++)
        ;

    if (totalAxes < numAxes)
    {
        printf("MM4000AsynConfig: actual number of axes=%d < numAxes=%d\n", totalAxes, numAxes);
        return MOTOR_AXIS_ERROR;
    }

    for (axis=0; axis<numAxes; axis++) {
        pAxis = &pController->pAxis[axis];
        pAxis->pController = pController;
        pAxis->card = card;
        pAxis->axis = axis;
        pAxis->mutexId = epicsMutexMustCreate();
        pAxis->params = motorParam->create(0, MOTOR_AXIS_NUM_PARAMS);

        /* Determine if encoder present based on open/closed loop mode. */
        sprintf(outputBuff, "%dTC", axis+1);
        sendAndReceive(pController, outputBuff, inputBuff, sizeof(inputBuff));
        loopState = atoi(&inputBuff[3]);    /* Skip first 3 characters */
        if (loopState != 0)
            pAxis->closedLoop = 1;

        /* Determine drive resolution. */
        sprintf(outputBuff, "%dTU", axis+1);
        sendAndReceive(pController, outputBuff, inputBuff, sizeof(inputBuff));
        pAxis->stepSize = atof(&inputBuff[3]);
        digits = (int) -log10(pAxis->stepSize) + 2;
        if (digits < 1)
            digits = 1;
        pAxis->maxDigits = digits;

        /* Save home preset position. */
        sprintf(outputBuff, "%dXH", axis+1);
        sendAndReceive(pController, outputBuff, inputBuff, sizeof(inputBuff));
        pAxis->homePreset = atof(&inputBuff[3]);

        /* Determine low limit */
        sprintf(outputBuff, "%dTL", axis+1);
        sendAndReceive(pController, outputBuff, inputBuff, sizeof(inputBuff));
        pAxis->lowLimit = atof(&inputBuff[3]);

        /* Determine high limit */
        sprintf(outputBuff, "%dTR", axis+1);
        sendAndReceive(pController, outputBuff, inputBuff, sizeof(inputBuff));
        pAxis->highLimit = atof(&inputBuff[3]);
    }

    pController->pollEventId = epicsEventMustCreate(epicsEventEmpty);

    /* Create the poller thread for this controller */
    epicsSnprintf(threadName, sizeof(threadName), "MM4000:%d", card);
    epicsThreadCreate(threadName,
                      epicsThreadPriorityMedium,
                      epicsThreadGetStackSize(epicsThreadStackMedium),
                      (EPICSTHREADFUNC) MM4000Poller, (void *) pController);

    return MOTOR_AXIS_OK;
}
コード例 #5
0
ファイル: drvMM4000Asyn.c プロジェクト: mark0n/motorRecord
static void MM4000Poller(MM4000Controller *pController)
{
    /* This is the task that polls the MM4000 */
    double timeout;
    AXIS_HDL pAxis;
    int status;
    int itera, j;
    int axisDone;
    int offset;
    int anyMoving;
    int comStatus;
    int forcedFastPolls=0;
    char *p, *tokSave;
    char statusAllString[BUFFER_SIZE];
    char positionAllString[BUFFER_SIZE];
    char buff[BUFFER_SIZE];

    timeout = pController->idlePollPeriod;
    epicsEventSignal(pController->pollEventId);  /* Force on poll at startup */

    while (1)
    {
        if (timeout != 0.)
            status = epicsEventWaitWithTimeout(pController->pollEventId, timeout);
        else
            status = epicsEventWait(pController->pollEventId);

        if (status == epicsEventWaitOK)
        {
            /* We got an event, rather than a timeout.  This is because other software
             * knows that an axis should have changed state (started moving, etc.).
             * Force a minimum number of fast polls, because the controller status
             * might not have changed the first few polls
             */
            forcedFastPolls = 10;
        }

        anyMoving = 0;

        /* Lock all the controller's axis. */
        for (itera = 0; itera < pController->numAxes; itera++)
        {
            pAxis = &pController->pAxis[itera];
            if (!pAxis->mutexId)
                break;
            epicsMutexLock(pAxis->mutexId);
        }

        comStatus = sendAndReceive(pController, "MS;", statusAllString, sizeof(statusAllString));
        if (comStatus == 0)
            comStatus = sendAndReceive(pController, "TP;", positionAllString, sizeof(positionAllString));

        for (itera=0; itera < pController->numAxes; itera++)
        {
            pAxis = &pController->pAxis[itera];
            if (!pAxis->mutexId)
                break;
            if (comStatus != 0)
            {
                PRINT(pAxis->logParam, MOTOR_ERROR, "MM4000Poller: error reading status=%d\n", comStatus);
                motorParam->setInteger(pAxis->params, motorAxisCommError, 1);
            }
            else
            {
                PARAMS params = pAxis->params;
                int intval, axisStatus;

                motorParam->setInteger(params, motorAxisCommError, 0);
                /*
                 * Parse the status string
                 * Status string format: 1MSx,2MSy,3MSz,... where x, y and z are the status
                 * bytes for the motors
                 */
                offset = pAxis->axis*5 + 3;  /* Offset in status string */
                axisStatus = pAxis->axisStatus = statusAllString[offset];
                if (axisStatus & MM4000_MOVING)
                {
                    axisDone = 0;
                    anyMoving = 1;
                }
                else
                    axisDone = 1;
                motorParam->setInteger(params, motorAxisDone, axisDone);

                motorParam->setInteger(params, motorAxisHomeSignal,    (axisStatus & MM4000_HOME));
                motorParam->setInteger(params, motorAxisHighHardLimit, (axisStatus & MM4000_HIGH_LIMIT));
                motorParam->setInteger(params, motorAxisLowHardLimit,  (axisStatus & MM4000_LOW_LIMIT));
                motorParam->setInteger(params, motorAxisDirection,     (axisStatus & MM4000_DIRECTION));
                motorParam->setInteger(params, motorAxisPowerOn,      !(axisStatus & MM4000_POWER_OFF));

                /*
                 * Parse motor position
                 * Position string format: 1TP5.012,2TP1.123,3TP-100.567,...
                 * Skip to substring for this motor, convert to double
                 */

                strcpy(buff, positionAllString);
                tokSave = NULL;
                p = epicsStrtok_r(buff, ",", &tokSave);
                for (j=0; j < pAxis->axis; j++)
                    p = epicsStrtok_r(NULL, ",", &tokSave);
                pAxis->currentPosition = atof(p+3);
                motorParam->setDouble(params, motorAxisPosition,    (pAxis->currentPosition/pAxis->stepSize));
                motorParam->setDouble(params, motorAxisEncoderPosn, (pAxis->currentPosition/pAxis->stepSize));
                PRINT(pAxis->logParam, IODRIVER, "MM4000Poller: axis %d axisStatus=%x, position=%f\n",
                      pAxis->axis, pAxis->axisStatus, pAxis->currentPosition);

                /* We would like a way to query the actual velocity, but this is not possible.  If we could we could
                 * set the direction, and Moving flags */

                /* Check for controller error. */
                comStatus = sendAndReceive(pController, "TE;", buff, sizeof(statusAllString));
                if (buff[2] == '@')
                    intval = 0;
                else
                {
                    intval = 1;
                    PRINT(pAxis->logParam, MOTOR_ERROR, "MM4000Poller: controller error %s\n", buff);
                }
                motorParam->setInteger(params, motorAxisProblem, intval);
            }

            motorParam->callCallback(pAxis->params);
        } /* Next axis */

        /* UnLock all the controller's axis. */
        for (itera = 0; itera < pController->numAxes; itera++)
        {
            pAxis = &pController->pAxis[itera];
            if (!pAxis->mutexId)
                break;
            epicsMutexUnlock(pAxis->mutexId);
        }

        if (forcedFastPolls > 0)
        {
            timeout = pController->movingPollPeriod;
            forcedFastPolls--;
        }
        else if (anyMoving)
            timeout = pController->movingPollPeriod;
        else
            timeout = pController->idlePollPeriod;
    } /* End while */
}
コード例 #6
0
// jcaput pv [value1] [value2] [value3]
// if no value, uses stdin
int main(int argc, char* argv[])
{
    std::string comp_str, str;
	std::list<std::string> items;
	const char* delims = " \t\r\n";
	int opt;
	long double waittime = 1.0f;
	bool single_element = false;
	bool verbose = false;
	bool no_whitespace = false;
    while ((opt = getopt(argc, argv, "1vhiw:s:")) != -1) 
	{
        switch (opt) {
        case 'h':             
            usage();
            return 0;
			
        case 'v':              
            verbose = true;
            break;

		case 's':              
            delims = strdup(optarg);
            break;
			
		case '1':              
            single_element = true;
            break;
		
		case 'i':
			no_whitespace = true;
			break;
		
		case 'w':
			waittime = atof(optarg);
			break;
			
		default:
			break;
		}
	}
	int nargs = argc - optind;
	const char* pv = argv[optind];
	if (nargs < 1)
	{
	    usage();
		return -1;
	}
	if (nargs == 1)
	{
	    std::getline(std::cin, str);
		char* buffer = strdup(str.c_str());
		char* saveptr;
		const char* item = epicsStrtok_r(buffer, delims, &saveptr);
		while( item != NULL )
		{
			items.push_back(item);
		    item = epicsStrtok_r(NULL, delims, &saveptr); 
		}
	}
	else
	{
		if (!no_whitespace)
		{
			for(int i=optind+1; i<argc; ++i)
			{
				items.push_back(argv[i]);
			}
		} else {
			std::string input = "";
			for(int i=optind+1; i<argc; ++i)
			{
				input.append(argv[i]);
				input.append(" ");
			}
			items.push_back(input);
		}
	}
	std::string json;
	if (!single_element && (items.size() == 1))
	{
	    json = "\"" + items.front() + "\"";
	}
	else
	{
	    json = json_list_to_array(items);
	}
	int ret = compressString(json, comp_str);
	if (ret == 0)
	{
	    std::ostringstream command;
	    command <<  "caput -S -w" << waittime <<  " " << pv << " " << comp_str;
		if (verbose)
		{
			std::cout << "jcaput: JSON: " << json << std::endl;
			std::cout << "jcaput: " << command.str() << std::endl;
		}
	    system(command.str().c_str());
    }		
	return ret;
}
コード例 #7
0
ファイル: devEpidFast.c プロジェクト: epics-modules/std
static long init_record(epidRecord *pepid)
{
    struct instio *pinstio;
    asynStatus status;
    asynUser *pasynUser;
    asynInterface *pasynInterface;
    epidFastPvt *pPvt;
    char *tok_save;
    char *p;
    const char *drvUserName;
    size_t drvUserSize;
    asynDrvUser *pdrvUser;
    void *drvUserPvt;
    char temp[256];
    void *registrarPvt;

    pPvt = callocMustSucceed(1, sizeof(*pPvt), "devEpidFast::init_record");
    pepid->dpvt = pPvt;
    pPvt->KP = 1;
    pPvt->lowLimit = 1.;
    pPvt->highLimit =-1.;

    pinstio = (struct instio*)&(pepid->inp.value);
    /* Parse to get inputName, inputChannel, dataString, intervalString,
     * outputName, outputChannel, outputString
     * Copy to temp, since epicsStrtok_r overwrites it */
    strcpy(temp, pinstio->string);
    strcat(temp, " ");
    strcat(temp, pepid->desc);
    tok_save = NULL;
    p = epicsStrtok_r(temp, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing inputName\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->inputName = epicsStrDup(p);
    p = epicsStrtok_r(NULL, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing inputChannel\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->inputChannel = atoi(p);
    p = epicsStrtok_r(NULL, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing inputDataString\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->inputDataString = epicsStrDup(p);
    p = epicsStrtok_r(NULL, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing inputIntervalString\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->inputIntervalString = epicsStrDup(p);
    p = epicsStrtok_r(NULL, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing outputName\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->outputName = epicsStrDup(p);
    p = epicsStrtok_r(NULL, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing outputChannel\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->outputChannel = atoi(p);
    p = epicsStrtok_r(NULL, ", ", &tok_save);
    if (!p) {
        errlogPrintf("devEpidFast::init_record %s, INP field=\"%s\" is missing outputDataString\n",
                     pepid->name, temp);
        goto bad;
    }
    pPvt->outputDataString = epicsStrDup(p);
    pPvt->mutexId = epicsMutexCreate();

    /* Connect to input asyn driver */
    pasynUser = pasynManager->createAsynUser(0, 0);
    pPvt->pcallbackDataAsynUser = pasynUser;
    status = pasynManager->connectDevice(pasynUser, pPvt->inputName,
                                         pPvt->inputChannel);
    if (status != asynSuccess) {
        errlogPrintf("devEpidFast::init_record, %s error in connectDevice"
                     " to input %s\n",
                     pepid->name, pasynUser->errorMessage);
        goto bad;
    }
    pasynInterface = pasynManager->findInterface(pasynUser,
                     asynFloat64Type, 1);
    if (!pasynInterface) {
        errlogPrintf("devEpidFast::init_record %s, cannot find "
                     "asynFloat64 interface %s\n",
                     pepid->name, pasynUser->errorMessage);
        goto bad;
    }
    pPvt->pfloat64Input = (asynFloat64 *) pasynInterface->pinterface;
    pPvt->float64InputPvt = pasynInterface->drvPvt;

    pasynInterface = pasynManager->findInterface(pasynUser,
                     asynDrvUserType, 1);
    if (!pasynInterface) {
        errlogPrintf("devEpidFast::init_record %s, cannot find "
                     "asynDrvUser interface %s\n",
                     pepid->name, pasynUser->errorMessage);
        goto bad;
    }
    pdrvUser = (asynDrvUser *)pasynInterface->pinterface;
    drvUserPvt = pasynInterface->drvPvt;

    status = pdrvUser->create(drvUserPvt, pPvt->pcallbackDataAsynUser,
                              pPvt->inputDataString, &drvUserName, &drvUserSize);
    if (status) {
        errlogPrintf("devEpidFast::init_record %s, asynDrvUser->create "
                     "failed for input data string %s %s\n",
                     pepid->name, pPvt->inputDataString, pPvt->pcallbackDataAsynUser->errorMessage);
        goto bad;
    }
    status = pPvt->pfloat64Input->registerInterruptUser(pPvt->float64InputPvt,
             pPvt->pcallbackDataAsynUser,
             dataCallback, pPvt, &registrarPvt);
    if (status) {
        errlogPrintf("devEpidFast::init_record %s, pfloat64Input->registerInterruptUser failed for dataCallback %s\n",
                     pepid->name, pPvt->pcallbackDataAsynUser->errorMessage);
        goto bad;
    }

    pasynUser = pasynManager->createAsynUser(0, 0);
    pPvt->pcallbackIntervalAsynUser = pasynUser;
    status = pasynManager->connectDevice(pasynUser, pPvt->inputName, 0);
    status = pdrvUser->create(drvUserPvt, pPvt->pcallbackIntervalAsynUser,
                              pPvt->inputIntervalString, &drvUserName, &drvUserSize);
    if (status) {
        errlogPrintf("devEpidFast::init_record %s, asynDrvUser->create "
                     "failed for interval string %s %s\n",
                     pepid->name, pPvt->inputIntervalString, pPvt->pcallbackIntervalAsynUser->errorMessage);
        goto bad;
    }
    status = pPvt->pfloat64Input->registerInterruptUser(pPvt->float64InputPvt,
             pPvt->pcallbackIntervalAsynUser,
             intervalCallback, pPvt,
             &registrarPvt);
    if (status) {
        errlogPrintf("devEpidFast::init_record %s, pfloat64Input->registerInterruptUser failed for intervalCallback %s\n",
                     pepid->name, pPvt->pcallbackIntervalAsynUser->errorMessage);
        goto bad;
    }
    status = pPvt->pfloat64Input->read(pPvt->float64InputPvt,
                                       pPvt->pcallbackIntervalAsynUser,
                                       &pPvt->callbackInterval);
    if (status) {
        errlogPrintf("devEpidFast::init_record %s, pfloat64Input->read failed for callbackInterval %s\n",
                     pepid->name, pPvt->pcallbackIntervalAsynUser->errorMessage);
        goto bad;
    }


    /* Connect to output asyn driver */
    pasynUser = pasynManager->createAsynUser(0, 0);
    pPvt->pfloat64OutputAsynUser = pasynUser;
    status = pasynManager->connectDevice(pasynUser, pPvt->outputName,
                                         pPvt->outputChannel);
    if (status != asynSuccess) {
        errlogPrintf("devEpidFast::init_record %s, error in connectDevice"
                     " to output %s\n",
                     pepid->name, pasynUser->errorMessage);
        goto bad;
    }
    pasynInterface = pasynManager->findInterface(pasynUser,
                     asynFloat64Type, 1);
    if (!pasynInterface) {
        errlogPrintf("devEpidFast::init_record %s, cannot find "
                     "asynFloat64 interface %s\n",
                     pepid->name, pasynUser->errorMessage);
        goto bad;
    }
    pPvt->pfloat64Output = (asynFloat64 *)pasynInterface->pinterface;
    pPvt->float64OutputPvt = pasynInterface->drvPvt;

    pasynInterface = pasynManager->findInterface(pasynUser,
                     asynDrvUserType, 1);
    if (!pasynInterface) {
        errlogPrintf("devEpidFast::init_record %s, cannot find "
                     "asynDrvUser interface %s\n",
                     pepid->name, pasynUser->errorMessage);
        goto bad;
    }
    pdrvUser = (asynDrvUser *)pasynInterface->pinterface;
    drvUserPvt = pasynInterface->drvPvt;
    status = pdrvUser->create(drvUserPvt, pPvt->pfloat64OutputAsynUser,
                              pPvt->outputDataString, &drvUserName, &drvUserSize);
    if (status) {
        errlogPrintf("devEpidFast::init_record %s, asynDrvUser->create "
                     "failed for output data string %s status=%d, drvUserSize=%d %s\n",
                     pepid->name, pPvt->outputDataString, status, (int)drvUserSize, pPvt->pfloat64OutputAsynUser->errorMessage);
        goto bad;
    }
    update_params(pepid);
    return(0);
bad:
    pepid->pact=1;
    return(0);
}
コード例 #8
0
void NetShrVarInterface::getParams()
{
	m_params.clear();
	char control_name_xpath[MAX_PATH_LEN];
	epicsSnprintf(control_name_xpath, sizeof(control_name_xpath), "/netvar/section[@name='%s']/param", m_configSection.c_str());
    pugi::xpath_node_set params;
	try
	{
	    params = m_xmlconfig.select_nodes(control_name_xpath);
	    if (params.size() == 0)
	    {
	        std::cerr << "getParams failed" << std::endl;
		    return;
	    }
	}
	catch(const std::exception& ex)
	{
	    std::cerr << "getParams failed " << ex.what() << std::endl;
		return;
	}
	int field;
	unsigned access_mode;
	char *last_str = NULL;
	char *access_str, *str;
	for (pugi::xpath_node_set::const_iterator it = params.begin(); it != params.end(); ++it)
	{
		pugi::xpath_node node = *it;	
		std::string attr1 = node.node().attribute("name").value();
		std::string attr2 = node.node().attribute("type").value();
		std::string attr3 = node.node().attribute("access").value();
		std::string attr4 = node.node().attribute("netvar").value();
		std::string attr5 = node.node().attribute("field").value();	
		if (attr5.size() == 0)
		{
			field = -1;
		}
		else
		{
			field = atoi(attr5.c_str());
		}
		access_str = strdup(attr3.c_str());
		access_mode = 0;
		str = epicsStrtok_r(access_str, ",", &last_str);
		while( str != NULL )
		{
			if (!strcmp(str, "R"))
			{
				access_mode |= NvItem::Read;
			}
			else if (!strcmp(str, "BR"))
			{
				access_mode |= NvItem::BufferedRead;
			}
			else if (!strcmp(str, "W"))
			{
				access_mode |= NvItem::Write;
			}
			else if (!strcmp(str, "BW"))
			{
				access_mode |= NvItem::BufferedWrite;
			}
			else
			{
				std::cerr << "getParams: Unknown access mode \"" << str << "\" for param " << attr1 << std::endl;
			}
			str = epicsStrtok_r(NULL, ",", &last_str);
		}
		free(access_str);
		m_params[attr1] = new NvItem(attr4.c_str(),attr2.c_str(),access_mode,field);
		
	}	
}
コード例 #9
0
static asynStatus readItRaw(void* ppvt,asynUser* pasynUser,char* data,size_t maxchars,size_t* nbytes,int* eom)
{
    int i,addr,status;
    const char *pcmd;
    char *token,*next;
    Port* pport = (Port*)ppvt;
    char inpBuf[BUFFER_SIZE],strings[5][24];

    asynPrint(pasynUser,ASYN_TRACE_FLOW,"drvAsynColby::readItRaw %s: read\n",pport->myport);
    if( pasynManager->getAddr(pasynUser,&addr)) return( asynError );

    switch( addr )
    {
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
        pcmd = "NET?";
        break;
    case 13:
        pcmd = "NETM?";
        break;
    default:
        return( asynError );
    }

    epicsMutexMustLock(pport->syncLock);
    status = writeRead(pport->pasynUser,pcmd,inpBuf,sizeof(inpBuf),pport->iface);
    epicsMutexUnlock(pport->syncLock);

    if( status ) {*nbytes=0;*eom=0;return( asynError );};

    if( addr!=13 )
    {
        token = epicsStrtok_r(inpBuf,",",&next);
        for( i=0; token; ++i ) {strcpy(strings[i],token);token=epicsStrtok_r(NULL,",",&next);};
    }

    *eom = ASYN_EOM_END;

    switch( addr )
    {
    case 8:
        strcpy(data,strings[0]);
        *nbytes=strlen(strings[0]);
        break;
    case 9:
        strcpy(data,strings[1]);
        *nbytes=strlen(strings[1]);
        break;
    case 10:
        strcpy(data,strings[2]);
        *nbytes=strlen(strings[2]);
        break;
    case 11:
        strcpy(data,strings[3]);
        *nbytes=strlen(strings[3]);
        break;
    case 12:
        strcpy(data,strings[4]);
        *nbytes=strlen(strings[4]);
        break;
    case 13:
        strcpy(data,inpBuf);
        *nbytes=strlen(inpBuf);
        break;
    }
    asynPrint(pasynUser,ASYN_TRACEIO_DRIVER,"drvAsynColby::readItRaw %s: read %.*s from %s\n",pport->myport,*nbytes,data,pport->ioport);

    return( asynSuccess );
}