コード例 #1
1
ファイル: ca_test.c プロジェクト: ukaea/epics
/*
 * 	cagft()
 *
 *	ca get field test
 *
 *	test ca get over the range of CA data types
 */
static int cagft(char *pname)
{	
	const unsigned maxTries = 1000ul;
	unsigned ntries = 0u;
	chid chan_id;
	int status;
	int i;

	/* 
	 *	convert name to chan id 
	 */
	status = ca_search(pname, &chan_id);
	SEVCHK(status,NULL);
	status = ca_pend_io(5.0);
	if(status != ECA_NORMAL){
        SEVCHK(ca_clear_channel(chan_id),NULL);
		printf("Not Found %s\n", pname);
		return -1;
	}

	printf("name:\t%s\n", 
        ca_name(chan_id));
	printf("native type:\t%s\n", 
        dbr_type_to_text(ca_field_type(chan_id)));
	printf("native count:\t%lu\n", 
        ca_element_count(chan_id));


	/* 
 	 * fetch as each type 
	 */
	for(i=0; i<=LAST_BUFFER_TYPE; i++){
		if(ca_field_type(chan_id)==DBR_STRING) {
			if( (i!=DBR_STRING)
			  && (i!=DBR_STS_STRING)
			  && (i!=DBR_TIME_STRING)
			  && (i!=DBR_GR_STRING)
              && (i!=DBR_CTRL_STRING)) {
                  continue;
            }
        }
        /* ignore write only types */
        if ( 
            i == DBR_PUT_ACKT || 
            i == DBR_PUT_ACKS ) {
                continue;
        }

		status = ca_array_get_callback(
				i, 
				ca_element_count(chan_id),
				chan_id, 
				printit, 
				NULL);
		SEVCHK(status, NULL);

		outstanding++;
	}

	/*
	 * wait for the operation to complete
	 * before returning 
	 */
	while ( ntries < maxTries ) {
		unsigned long oldOut;

		oldOut = outstanding;
		ca_pend_event ( 0.05 );

		if ( ! outstanding ) {
            SEVCHK ( ca_clear_channel ( chan_id ), NULL );
			printf ( "\n\n" );
			return 0;
		}

		if ( outstanding == oldOut ) {
			ntries++;
		}
	}

    SEVCHK ( ca_clear_channel ( chan_id ), NULL );
	return -1;
}
コード例 #2
0
ファイル: EtosServer2.c プロジェクト: Sangil-Lee/RefCode
void SearchTag()
{
	int	i = 0;
	
	//MAXI2_GAUGE(Dual Gauge)
	for(i=0;i<2;i++)
	{
		ca_search(VacTagData2[i], &VacTagDatachid2[i]);
		istatus = ca_pend_io(0.1);
		printf("Maxi2 %d : %d\n", i, istatus);		
	}        

	//TMP3~4
	for(i=0;i<2;i++)
	{
		ca_search(TmpStsTagData[i], &TmpStsTagDatachid[i]);
		istatus = ca_pend_io(0.1);
		printf("TmpSts %d : %d\n", i, istatus);		

		ca_search(TmpAmpTagData[i], &TmpAmpTagDatachid[i]);
		istatus = ca_pend_io(0.1);
		printf("TmpAmp %d : %d\n", i, istatus);		

		ca_search(TmpRpmTagData[i], &TmpRpmTagDatachid[i]);
		istatus = ca_pend_io(0.1);
		printf("TmpRpm %d : %d\n", i, istatus);	

		ca_search(TmpTempTagData[i], &TmpTempTagDatachid[i]);
		istatus = ca_pend_io(0.1);
		printf("TmpTemp %d : %d\n", i, istatus);		
	}        
	


}
コード例 #3
0
static int  CACommand(string strcmd)
{
#if 0
	//In event callback function, It' dosen't work ca_get() function. I don't understand the reason.
	struct dbr_time_long shotdata;
	chid shot_id;
	ca_create_channel("CCS_SHOT_NUMBER",NULL, NULL,20,&shot_id);
	ca_pend_io(1.0);
	int state = ca_state(shot_id);
	printf("State:%d\n", state);
	ca_get(DBR_TIME_LONG, shot_id, (void *)&shotdata);
	int status = ca_pend_io(1.0);
	if(status != ECA_NORMAL)
	{
		fprintf(stdout, "SHOT number: %s denied access\n",ca_name(shot_id));
		return;
	};
	fprintf(stdout, "%s:%d\n",ca_name(shot_id),shotdata.value);
#else
	FILE *fp= popen (strcmd.c_str(), "r");
	char buf[20];
	while (fgets (buf, sizeof(buf), fp) ) {};
	pclose(fp);
	return ((strcmd.compare("ShotNum")== 0)?atoi(buf):0);
#endif
}
コード例 #4
0
void ECCD_Calorimetric::slot_SET_DATA(void)
{
	chid   searchID;
	int    istatus;
	int	 iDATA = 1;
	
	ca_search ("EC1_WCS_SET_DATA", &searchID);
	istatus = ca_pend_io(0.1);
	ca_put(DBR_INT, searchID, &iDATA);
	istatus = ca_pend_io(0.1);
}
コード例 #5
0
ファイル: testConvertENUM.c プロジェクト: akazakov/epicstest
int main(int argc,char **argv)
{
  int indval,field;

  SEVCHK(ca_task_initialize(),"ca_task_initialize");
  SEVCHK(ca_search("enumCputDTYP",&putCchid[0]),"ca_search failure");
  SEVCHK(ca_search("enumCputPRIO",&putCchid[1]),"ca_search failure");
  SEVCHK(ca_search("enumCputVAL" ,&putCchid[2]),"ca_search failure");
  SEVCHK(ca_search("enumMDbputDTYP",&putMDbchid[0]),"ca_search failure");
  SEVCHK(ca_search("enumMDbputPRIO",&putMDbchid[1]),"ca_search failure");
  SEVCHK(ca_search("enumMDbputVAL" ,&putMDbchid[2]),"ca_search failure");
  SEVCHK(ca_search("enumMCaputDTYP",&putMCachid[0]),"ca_search failure");
  SEVCHK(ca_search("enumMCaputPRIO",&putMCachid[1]),"ca_search failure");
  SEVCHK(ca_search("enumMCaputVAL" ,&putMCachid[2]),"ca_search failure");
  SEVCHK(ca_search("enumCmbbi.DTYP" ,&getCchid[0]),"ca_search failure");
  SEVCHK(ca_search("enumCmbbi.PRIO" ,&getCchid[1]),"ca_search failure");
  SEVCHK(ca_search("enumCmbbi.VAL" ,&getCchid[2]),"ca_search failure");
  SEVCHK(ca_search("enumMDbmbbi.DTYP" ,&getMDbchid[0]),"ca_search failure");
  SEVCHK(ca_search("enumMDbmbbi.PRIO" ,&getMDbchid[1]),"ca_search failure");
  SEVCHK(ca_search("enumMDbmbbi.VAL" ,&getMDbchid[2]),"ca_search failure");
  SEVCHK(ca_search("enumMCambbi.DTYP" ,&getMCachid[0]),"ca_search failure");
  SEVCHK(ca_search("enumMCambbi.PRIO" ,&getMCachid[1]),"ca_search failure");
  SEVCHK(ca_search("enumMCambbi.VAL" ,&getMCachid[2]),"ca_search failure");
  SEVCHK(ca_pend_io(5.0),"ca_pend_io failure");

  for(indval=0; indval<2; indval++) {
      SEVCHK(ca_put(DBR_STRING,putCchid[0],dtypValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putCchid[1],prioValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putCchid[2],valValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putMDbchid[0],dtypValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putMDbchid[1],prioValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putMDbchid[2],valValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putMCachid[0],dtypValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putMCachid[1],prioValue[indval]),"ca_put");
      SEVCHK(ca_put(DBR_STRING,putMCachid[2],valValue[indval]),"ca_put");
      /*Wait until evertthing updated*/
      ca_pend_event(2.0);
      for(field=0; field<3; field++) {
	SEVCHK(ca_get(DBR_STRING,getCchid[field],&getCvalue[field]),
		"ca_get");
	SEVCHK(ca_get(DBR_STRING,getMDbchid[field],&getMDbvalue[field]),
		"ca_get");
	SEVCHK(ca_get(DBR_STRING,getMCachid[field],&getMCavalue[field]),
		"ca_get");
      }
      SEVCHK(ca_pend_io(5.0),"ca_pend_io failure");
      printReport(indval);
  }
  return(0);
}
コード例 #6
0
ファイル: EtosServer2.c プロジェクト: Sangil-Lee/RefCode
int readtag(cUINT utype, chid searchID)
{
	cUINT type;

	switch(utype)
	{
		case T_CIP_INT:
			type = DBR_INT;
			ca_get(type, searchID, &iDATA);
			break;
		case T_CIP_DINT:
			type = DBR_DOUBLE;
			ca_get(type, searchID, &dblDATA);
			break;
		case T_CIP_REAL:
			type = DBR_FLOAT;
			ca_get(type, searchID, &fltDATA);
			break;
		case T_CIP_BITS:
			type = T_CIP_DINT;
			ca_get(type, searchID, &fltDATA);
			break;
	}
	istatus = ca_pend_io(0.1);
	if(istatus != 1)	return 0;
	return 1;
}
コード例 #7
0
ファイル: testsyncgroup.c プロジェクト: akazakov/epicstest
int main(int argc,char **argv)
{
    int		status;
    double	value=1.0;
    double	newvalue=0.0;
    char        *pvname;
    double	blockTime;

    if(argc!=3) {
	printf("usage: testsyncgroup <pvname> <blockTime>\n");
	exit(1);
    }
    pvname = argv[1];
    sscanf(argv[2],"%le",&blockTime);
    SEVCHK(ca_task_initialize(),"ca_task_initialize");
    SEVCHK(ca_search(pvname,&mychid),"ca_search_and_connect");
    SEVCHK(ca_pend_io(1.0),"ca_pend_io");
    SEVCHK(ca_sg_create(&gid),"ca_sg_create");
    SEVCHK(ca_sg_array_put(gid,DBR_DOUBLE,1,mychid,(void *)&value),
	"ca_sg_array_put");
    SEVCHK(ca_sg_array_get(gid,DBR_DOUBLE,1,mychid,(void *)&newvalue),
	"ca_sg_array_put");
    status = ca_sg_block(gid,blockTime);
    printf("ca_sg_block status=%s\n",ca_message(status));
    status = ca_sg_test(gid);
    printf("ca_sg_test status=%s\n",ca_message(status));
    printf("newvalue=%f\n",newvalue);
    return(0);
}
コード例 #8
0
ファイル: EtosServer2.c プロジェクト: Sangil-Lee/RefCode
void writetag(cUINT utype, chid searchID)
{
	cUINT  type;

	switch (utype)
	{
		case T_CIP_INT:
			type   = DBR_INT;
			ca_put(type, searchID, &iWriteDATA);
			break;

		case T_CIP_DINT:
			type   = DBR_DOUBLE;
			ca_put(type, searchID, &dblWriteDATA);
			break;

		case T_CIP_BITS:
			type   = DBR_INT;
			if (bDATA%2==0)
				bDATA=0;
			else
			bDATA=255;
			ca_put(type, searchID, &bWriteDATA);
			break;

		case T_CIP_REAL:
			type   = DBR_FLOAT;
			ca_put(type, searchID, &fltWriteDATA);
			break;
	}//end switch
	istatus = ca_pend_io(0.1);
	//printf("WRITEtag   istatus : %d\n", istatus);
}
コード例 #9
0
ファイル: access.cpp プロジェクト: ukaea/epics
// extern "C"
int epicsShareAPI ca_pend ( ca_real timeout, int early )
{
    if ( early ) {
        return ca_pend_io ( timeout );
    }
    else {
        return ca_pend_event ( timeout );
    }
}
コード例 #10
0
ファイル: tool_lib.c プロジェクト: ASukhanov/ado2epics
int connect_pvs (pv* pvs, int nPvs)
{
    int returncode = create_pvs ( pvs, nPvs, 0);
    if ( returncode == 0 ) {
                            /* Wait for channels to connect */
        int result = ca_pend_io (caTimeout);
        if (result == ECA_TIMEOUT)
        {
            if (nPvs > 1)
            {
                fprintf(stderr, "Channel connect timed out: some PV(s) not found.\n");
            } else {
                fprintf(stderr, "Channel connect timed out: '%s' not found.\n", 
                        pvs[0].name);
            }
            returncode = 1;
        }
    }
    return returncode;
}
コード例 #11
0
ファイル: caputackt.c プロジェクト: akazakov/epicstest
int main(int argc,char **argv)
{
    chid		mychid;
    unsigned short	value;

    if(argc!=3) {
	printf("usage: caputackt pvname value\n");
	exit(1);
    }
    sscanf(argv[2],"%hu",&value);
    SEVCHK(ca_task_initialize(),"ca_task_initialize");
    SEVCHK(ca_search(argv[1],&mychid), "ca_search");
    ca_pend_io(5.0);
    SEVCHK(ca_put(DBR_PUT_ACKT,mychid,&value),"ca_put");
    ca_pend_event(1.0);
/*
    ca_task_exit();
*/
    return(0);
}
コード例 #12
0
ファイル: testputnotify.c プロジェクト: akazakov/epicstest
int main(int argc,char **argv)
{
    int		status;
    double	value=1.0;
    char	*pvname;
    double	pendEventTime;
    int		maxTrys = 3;

    if(argc!=3) {
	printf("usage: testputnotify <pvname> <pendEventTime>\n");
	exit(1);
    }
    pvname = argv[1];
    sscanf(argv[2],"%le",&pendEventTime);
    SEVCHK(ca_task_initialize(),"ca_task_initialize");
    SEVCHK(ca_search(pvname,&mychid),"ca_search_and_connect");
    SEVCHK(ca_pend_io(1.0),"ca_pend_io");
    while(TRUE) {
	SEVCHK(ca_array_put_callback(DBR_DOUBLE,1,mychid,
		(void *)&value,putCallback,NULL),
		"ca_put_callback");
	ntrys=0;
	gotCallback=FALSE;
	while(!gotCallback && ntrys <=maxTrys) {
	    status = ca_pend_event(pendEventTime);
	    if(status!=ECA_NORMAL && status!=ECA_TIMEOUT)
		printf("ca_pend_event status=%s\n",ca_message(status));
	    ntrys++;
	    if(ntrys==maxTrys) {
		printf(" Never got callback\n");
		break;
	    }
	}
	printf(" number ca_pend_event = %d\n",ntrys);
    }
    return(0);
}
コード例 #13
0
void popupPvInfo(DisplayInfo *displayInfo)
{
    DlElement *pE;
    Record **records;
    chid chId;
    int i, status;
    Record *pR;
    Channel *pCh;
    char descName[MAX_TOKEN_LENGTH];
    char *pDot;
    double connTimeout;

#if DEBUG_PVINFO
    XUngrabPointer(display,CurrentTime);
#endif

  /* Check if another call is in progress */
    if(pvInfo) {
	medmPostMsg(1,"popupPvInfo: "
	  "Another PV Info request is already in progress\n"
	  "  It is probably having problems\n"
	  "  Wait for it to finish\n");
	return;
    }

  /* Create the dialog box if it has not been created */
    if(!pvInfoS) createPvInfoDlg();

  /* Get the records */
    records = getPvInfoFromDisplay(displayInfo, &nPvInfoPvs, &pE);
    if(!records) return;
    pvInfoElement = pE;

  /* Allocate space */
    pvInfo = (PvInfo *)calloc(nPvInfoPvs, sizeof(PvInfo));
    if(!pvInfo) {
	medmPostMsg(1,"popupPvInfo: Memory allocation error\n");
	if(records) free(records);
	if(pvInfoS && XtIsManaged(pvInfoS)) return;
    }

  /* Loop over the records, initialize, and initiate search for DESC */
    for(i=0; i < nPvInfoPvs; i++) {
      /* Initialize */
	pvInfo[i].pvChid = NULL;
	pvInfo[i].pvOk = False;
	pvInfo[i].timeOk = False;
	pvInfo[i].descChid = NULL;
	pvInfo[i].descOk = False;
	strcpy(pvInfo[i].descVal, NOT_AVAILABLE);
#if defined(DBR_CLASS_NAME) && DO_RTYP
	pvInfo[i].rtypOk = False;
	strcpy(pvInfo[i].rtypVal, NOT_AVAILABLE);
#endif

      /* Check for a valid record */
	if(records[i]) {
	    pR = pvInfo[i].record = records[i];
	    pCh = getChannelFromRecord(pR);
	    if(!pCh) continue;
	    if(!pCh->chid) continue;
	    chId = pvInfo[i].pvChid = pCh->chid;
	} else continue;
	pvInfo[i].pvOk = True;

      /* Don't try the others unless the PV is connected */
	if(ca_state(chId) != cs_conn || !ca_read_access(chId))
	  continue;

      /* Construct the DESC name */
	strcpy(descName,ca_name(chId));
	pDot = strchr(descName,'.');
	if(pDot) {
	  /* Assume it is a name with a field and replace the field
	   * with DESC */
	    strcpy(pDot,".DESC");
	} else {
	  /* Append .DESC */
	    strcat(descName,".DESC");
	}
      /* Search for the DESC */
	status = ca_search(descName, &pvInfo[i].descChid);
	if(status == ECA_NORMAL) {
	    pvInfo[i].descOk = True;
	} else {
	    medmPostMsg(1,"popupPvInfo: DESC: ca_search for %s: %s\n",
	      descName, ca_message(status));
	}
    }

  /* Free the records, they are now stored in pvInfo */
    if(records) free(records);

  /* Wait for the searches (Timeouts should be uncommon) */
    status=ca_pend_io(CA_PEND_IO_TIME);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"popupPvInfo: Waited %g seconds.  "
	  "Did not find the DESC information (%s).\n",
	  CA_PEND_IO_TIME, descName);
    }

  /* Loop over the records and do the gets */
    nPvInfoCbs = 0;
    for(i=0; i < nPvInfoPvs; i++) {
	if(!pvInfo[i].pvOk) continue;

      /* Don't try the others unless the PV is connected */
	chId = pvInfo[i].pvChid;
	if(ca_state(chId) != cs_conn || !ca_read_access(chId))
	  continue;

      /* Get the DESC */
	if(ca_state(pvInfo[i].descChid) == cs_conn &&
	  ca_read_access(pvInfo[i].descChid)) {
	  /* Do the get */
	    status = ca_get_callback(DBR_STRING, pvInfo[i].descChid,
	      pvInfoDescGetCb, &pvInfo[i]);
	    if(status == ECA_NORMAL) {
		nPvInfoCbs++;
	    } else {
		pvInfo[i].descOk = False;
		medmPostMsg(1,"pvInfoConnectCb: DESC: ca_array_get_callback"
		  " for %s: %s\n",
		  ca_name(pvInfo[i].descChid), ca_message(status));
	    }
	} else {
	    pvInfo[i].descOk = False;
	}

      /* Get the time value as a string */
	status = ca_get_callback(DBR_TIME_STRING, chId, pvInfoTimeGetCb,
	  &pvInfo[i]);
	if(status == ECA_NORMAL) {
	    nPvInfoCbs++;
	} else {
	    medmPostMsg(1,"popupPvInfo: STAMP: ca_get_callback for %s: %s\n",
	      ca_name(chId), ca_message(status));
	}

#if defined(DBR_CLASS_NAME) && DO_RTYP
      /* Get the RTYP */
	status = ca_get_callback(DBR_CLASS_NAME, chId, pvInfoRtypGetCb,
	  &pvInfo[i]);
	if(status == ECA_NORMAL) {
	    nPvInfoCbs++;
	} else {
	    medmPostMsg(1,"popupPvInfo: RTYP: ca_get_callback for %s: %s\n",
	      ca_name(chId), ca_message(status));
	}
#endif
    }

  /* Add a timeout and poll if there are callbacks
   *   The timeout is a safety net and should never be called
   *   All callbacks should come back inside the EPICS_CA_CONN_TMO
   *   Wait for 2 times this */
    if(nPvInfoCbs) {
	ca_poll();     /* May not be really necessary here */
	status = envGetDoubleConfigParam(&EPICS_CA_CONN_TMO, &connTimeout);
	if (status == 0) pvInfoTime = (unsigned long)(2000.*connTimeout+.5);
	else pvInfoTime = PVINFO_TIMEOUT;
	pvInfoTimeoutId = XtAppAddTimeOut(appContext, pvInfoTime,
	  pvInfoTimeout, NULL);
	pvInfoTimerOn = True;
    } else {
	pvInfoWriteInfo();
    }

#if DEBUG_PVINFO
    print("popupPvInfo: nPvInfoCbs=%d timeout=%ld\n",
      nPvInfoCbs, nPvInfoCbs?pvInfoTime:0L);
#endif
}
コード例 #14
0
ファイル: ca_test.c プロジェクト: ukaea/epics
/*
 *	capft
 *
 *	test ca_put() over a range of data types
 *	
 */
static int capft(
char		*pname,
char		*pvalue
)
{
	dbr_short_t			shortvalue;
	dbr_long_t			longvalue;
	dbr_float_t			floatvalue;
	dbr_char_t			charvalue;
	dbr_double_t		doublevalue;
	unsigned long		ntries = 10ul;
	int					status;
	chid				chan_id;

	if (((*pname < ' ') || (*pname > 'z'))
	  || ((*pvalue < ' ') || (*pvalue > 'z'))){
		printf("\nusage \"pv name\",\"value\"\n");
		return -1;
	}

	/* 
	 *	convert name to chan id 
	 */
	status = ca_search(pname, &chan_id);
	SEVCHK(status,NULL);
	status = ca_pend_io(5.0);
	if(status != ECA_NORMAL){
        SEVCHK(ca_clear_channel(chan_id),NULL);
		printf("Not Found %s\n", pname);
		return -1;
	}

	printf("name:\t%s\n", ca_name(chan_id));
	printf("native type:\t%d\n", ca_field_type(chan_id));
	printf("native count:\t%lu\n", ca_element_count(chan_id));

	/*
	 *  string value ca_put
	 */
	status = ca_put(
			DBR_STRING, 
			chan_id, 
			pvalue);
	SEVCHK(status, NULL);
	verify_value(chan_id, DBR_STRING);

	if(ca_field_type(chan_id)==0)goto skip_rest;

	if(sscanf(pvalue,"%hd",&shortvalue)==1) {
		/*
		 * short integer ca_put
		 */
		status = ca_put(
				DBR_SHORT, 
				chan_id, 
				&shortvalue);
		SEVCHK(status, NULL);
		verify_value(chan_id, DBR_SHORT);
		status = ca_put(
				DBR_ENUM, 
				chan_id, 
				&shortvalue);
		SEVCHK(status, NULL);
		verify_value(chan_id, DBR_ENUM);
		charvalue=(dbr_char_t)shortvalue;
		status = ca_put(
				DBR_CHAR, 
				chan_id, 
				&charvalue);
		SEVCHK(status, NULL);
		verify_value(chan_id, DBR_CHAR);
	}
	if(sscanf(pvalue,"%d",&longvalue)==1) {
		/*
		 * long integer ca_put
		 */
		status = ca_put(
				DBR_LONG, 
				chan_id, 
				&longvalue);
		SEVCHK(status, NULL);
		verify_value(chan_id, DBR_LONG);
	}
	if(epicsScanFloat(pvalue, &floatvalue)==1) {
		/*
		 * single precision float ca_put
		 */
		status = ca_put(
				DBR_FLOAT, 
				chan_id, 
				&floatvalue);
		SEVCHK(status, NULL);
		verify_value(chan_id, DBR_FLOAT);
	}
	if(epicsScanDouble(pvalue, &doublevalue)==1) {
		/*
		 * double precision float ca_put
		 */
		status = ca_put(
				DBR_DOUBLE, 
				chan_id, 
				&doublevalue);
		SEVCHK(status, NULL);
		verify_value(chan_id, DBR_DOUBLE);
	}

skip_rest:

	/*
	 * wait for the operation to complete
	 * (outstabnding decrements to zero)
	 */
	while(ntries){
		ca_pend_event(1.0);

		if(!outstanding){
            SEVCHK(ca_clear_channel(chan_id),NULL);
			printf("\n\n");
			return 0;
		}

		ntries--;
	}

    SEVCHK(ca_clear_channel(chan_id),NULL);
	return -1;
}
コード例 #15
0
ファイル: cagetfuze.c プロジェクト: webertr/epicsPVServer
int cagetFuZE(char *pvName, char *pvValue) {

  RequestT request = get;
  OutputT format = plain;
  chtype dbrType = -1;
  unsigned long reqElems = 0;
  int n, result;
  pv* pvs;
  int i;
  unsigned long nElems;
  

  result = ca_context_create(ca_disable_preemptive_callback);

  pvs = calloc(1, sizeof(pv));

  pvs[0].name = pvName;
  
  connect_pvs(pvs, 1);
  
  for (n = 0; n < 1; n++) {
    
    /* Set up pvs structure */
    /* -------------------- */

    /* Get natural type and array count */
    nElems         = ca_element_count(pvs[n].chid);
    pvs[n].dbfType = ca_field_type(pvs[n].chid);
    pvs[n].dbrType = dbrType;

    /* Set up value structures */
    if (format != specifiedDbr)
      {
	pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */
	if (dbr_type_is_ENUM(pvs[n].dbrType))                  /* Enums honour -n option */
	  {
	    if (enumAsNr) pvs[n].dbrType = DBR_TIME_INT;
	    else          pvs[n].dbrType = DBR_TIME_STRING;
	  }
	else if (floatAsString &&
		 (dbr_type_is_FLOAT(pvs[n].dbrType) || dbr_type_is_DOUBLE(pvs[n].dbrType)))
	  {
	    pvs[n].dbrType = DBR_TIME_STRING;
	  }
      }

    /* Issue CA request */
    /* ---------------- */

    if (ca_state(pvs[n].chid) == cs_conn)
      {
  	nConn++;
  	pvs[n].onceConnected = 1;
  	if (request == callback)
  	  {
  	    /* Event handler will allocate value and set nElems */
  	    pvs[n].reqElems = reqElems > nElems ? nElems : reqElems;
  	    result = ca_array_get_callback(pvs[n].dbrType,
  					   pvs[n].reqElems,
  					   pvs[n].chid,
  					   event_handler,
  					   (void*)&pvs[n]);
  	  } else {
  	  /* We allocate value structure and set nElems */
	  pvs[n].nElems = reqElems && reqElems < nElems ? reqElems : nElems;
  	  pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].nElems));
	  if (!pvs[n].value) {
  	    fprintf(stderr,"Memory allocation failed\n");
  	    return -1;
  	  }
  	  result = ca_array_get(pvs[n].dbrType,
  				pvs[n].nElems,
  				pvs[n].chid,
  				pvs[n].value);
  	}
  	pvs[n].status = result;
      } else {
      pvs[n].status = ECA_DISCONN;
    }
  }

  if (!nConn) return -1;              /* No connection? We're done. */

  /* Wait for completion */
  /* ------------------- */

  result = ca_pend_io(caTimeout);
  if (result == ECA_TIMEOUT) {
    fprintf(stderr, "Read operation timed out: some PV data was not read.\n");
    return -1;
  }

  if (request == callback)    /* Also wait for callbacks */
    {
      if (caTimeout != 0)
        {
	  double slice = caTimeout / PEND_EVENT_SLICES;
	  for (n = 0; n < PEND_EVENT_SLICES; n++)
            {
	      ca_pend_event(slice);
	      if (nRead >= nConn) break;
            }
	  if (nRead < nConn) {
	    fprintf(stderr, "Read operation timed out: some PV data was not read.\n");
	    return -1;
	  }
	} else {
	/* For 0 timeout keep waiting until all are done */
	    while (nRead < nConn) {
	      ca_pend_event(1.0);
	    }
      }
    }


  // Does this kill the connection??
  ca_context_destroy();
  
  sprintf(pvValue, "%s\n", val2str(pvs[0].value, pvs[0].dbrType, 0));

  return 1;

}
コード例 #16
0
void mexFunction(	int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{   
    int i,j, k, status,buflen,Cnt, Hndl, L,M,N,  NumHandles, commandswitch;
    
    int *HndlArray;
    mxArray  *mymxArray;
    double *myDblPr;
    chtype RequestType;
    
    char PVName[PV_NAME_LENGTH_MAX+1];
    // char MCAMessageString[MCA_MESSAGE_STRING_LENGTH_MAX+1];
    
    
      

    dbr_string_t StrBuffer;
    
        
    
    const char *MCAInfoFields[]={"PVName","ElementCount","NativeType","State","MCAMessage","Host"};
    char *NativeTypeStrings[] = {"STRING","INT","FLOAT","ENUM","CHAR","LONG","DOUBLE"};
    


    
    if(!CA_INITIALIZED) // Initialize CA if not initialized (first call)
    {   mexPrintf("Initializing MATLAB Channel Access ... \n");
        status = ca_task_initialize();
        if(status!=ECA_NORMAL)
            mexErrMsgTxt("Unable to initialise Challel Access\n");
        CA_INITIALIZED = true;
        // Register a function to be called when a this mex-file is cleared from memory
        // with 'clear' or when exitting MATLAB
        mexAtExit(mca_cleanup);
        // Lock the mex-file so that it can not be cleared without explicitly
        // mexUnclock
        mexLock();
        
        //start periodic polling:
/*        PollTimerHandle = SetTimer(NULL,NULL,MCA_POLL_PERIOD,background_poll);
        if(PollTimerHandle)
            mexPrintf("Periodic CA polling started! System Timer ID: %u\n",PollTimerHandle);
        else
            mexWarnMsgTxt("Failed to start periodic CA polling\n");
 */       
        
    }

    commandswitch = (int)mxGetScalar(prhs[0]);
   
    switch(commandswitch)
    {  case 0: 
            mexUnlock();
            break;
    
        case 1: // MCAOPEN - add channel(s) by PV names, all arguments following prhs[0]
               // must be strings - names of PV's
            for(i=1;i<nrhs;i++)
            {   mxGetString(prhs[i],PVName,PV_NAME_LENGTH_MAX+1);
                status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID));
                if(status == ECA_NORMAL) // if not - go on to the next PV name
                {   status = ca_pend_io(MCA_SEARCH_TIMEOUT);
                    if (status == ECA_NORMAL)
                    {   // Allocate persistent memory for the DataBuffer on this channel
                        // to hold all elements of the DBR_XXX type
                        // nearest to the native type
                        // RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        // Cnt=ca_element_count(CHNLS[HandlesUsed].CHID);
                        
                        
                        CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID);
                        CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].MonitorEventCount = 0;
                        
                        switch(CHNLS[HandlesUsed].NativeType2DBR)
                        {   case DBR_STRING:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t));
                                
                            break;
                        
                            case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                        
                            case DBR_FLOAT:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); 
                            break;
                
                            case DBR_ENUM:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); 
                            break;
                
                            case DBR_CHAR:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); 
                            break;
                    
                            case DBR_LONG:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                    
                            case DBR_DOUBLE:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); 
                            break;
                        }   
                        mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer);
                        
                                 
                        if(CHNLS[HandlesUsed].NativeType2DBR==DBR_STRING) // CACHE
                        {   if(CHNLS[HandlesUsed].NumElements==1) // Create MATLAB string - originally empty
                                CHNLS[HandlesUsed].CACHE = mxCreateString("");
                            else // Create MATLAB cell array of strings
                            {   CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements);
                                for(k=0;k<CHNLS[HandlesUsed].NumElements;k++)
                                {   mymxArray = mxCreateString("");
                                    mexMakeArrayPersistent(mymxArray);
                                    mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray);
                                }
                            }
                        }
                        else // Make CACHE a numeric mxArray 
                        {    CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL);  
                        }
                        
                        mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE);
                        
                        plhs[i-1]=mxCreateScalarDouble(++HandlesUsed);                        
                    
                    }
                    else
                        plhs[i-1]=mxCreateScalarDouble(0);

                }
                else
                    plhs[i-1]=mxCreateScalarDouble(0);
            } break;
            
        
        case 2:// MCAOPEN - add channel(s) by PV names. The arguments following prhs[0]
               // argument must be a cell array of strings - PV names
            
            L = mxGetM(prhs[1])*mxGetN(prhs[1]);
            plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL);
            myDblPr = mxGetPr(plhs[0]);
            
            for(i=0;i<L;i++)
            {   mymxArray = mxGetCell(prhs[1],i);
                mxGetString(mymxArray,PVName,PV_NAME_LENGTH_MAX+1);
                status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID));
                if(status == ECA_NORMAL) // if not - go on to the next PV name
                {   status = ca_pend_io(MCA_IO_TIMEOUT);
                    if (status == ECA_NORMAL)
                    {   // Allcate persistent memory for the DataBuffer on this channel
                        //RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID);
                        CHNLS[HandlesUsed].MonitorEventCount = 0;
                        //Cnt=ca_element_count(CHNLS[HandlesUsed].CHID);
                        switch(CHNLS[HandlesUsed].NativeType2DBR)
                        {   case DBR_STRING:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); 
                            break;
                        
                            case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                        
                            case DBR_FLOAT:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); 
                            break;
                
                        
                            case DBR_ENUM:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); 
                            break;
                
                            case DBR_CHAR:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); 
                            break;
                    
                            case DBR_LONG:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                    
                            case DBR_DOUBLE:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); 
                            break;
                        }   
                        mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer);   
                        
                        if(CHNLS[HandlesUsed].NativeType2DBR == DBR_STRING) // CACHE
                        {   CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements);
                            for(k=0;k<CHNLS[HandlesUsed].NumElements;k++)
                            {   mymxArray = mxCreateString(StrBuffer);
                                mexMakeArrayPersistent(mymxArray);
                                mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray);
                            }
                        }
                        else
                        {    CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL);  
                        }
                        
                        mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE);
                        
                        
                        myDblPr[i] = ++HandlesUsed;
                    }
                    else
                        myDblPr[i] = 0;
                }
                else
                    myDblPr[i] = 0;
            } break;
            
       case 3: // MCAOPEN Return names of connected channels as cell array of strings
            plhs[0] = mxCreateCellArray(1, &HandlesUsed);
            for(i=0;i<HandlesUsed;i++)
            {   if(CHNLS[i].CHID!=NULL)
                    {   mymxArray = mxCreateString(ca_name(CHNLS[i].CHID));
                        mxSetCell(plhs[0], i, mymxArray);
                    }
                else
                    {   mymxArray = mxCreateString("");
                        //mexPrintf("Handle: %d PV: %s\n",i+1, "Cleared Channel");
                        mxSetCell(plhs[0], i, mymxArray);
                    }
              } break;
        
        
         
        case 5: // MCACLOSE permanently clear channel
            Hndl = (int)mxGetScalar(prhs[1]);
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Handle out of range");  

            // If a monitor is installed, set the EVID pointer to NULL 
            // ca_clear_event dos not do it by itself

            if(CHNLS[Hndl-1].EVID) 
                CHNLS[Hndl-1].EVID = NULL;
                
            // If there is Callback String - destroy it
            if(CHNLS[Hndl-1].MonitorCBString)
            {   mxFree(CHNLS[Hndl-1].MonitorCBString); 
                CHNLS[Hndl-1].MonitorCBString =NULL;
            }    
            
            if(ca_state(CHNLS[Hndl-1].CHID)==3)
                mexWarnMsgTxt("Channel previously cleared");
            else
                if(ca_clear_channel(CHNLS[Hndl-1].CHID)!=ECA_NORMAL)
                    mexErrMsgTxt("ca_clear_channel failed");

            break;
            
        case 10: // MCAINFO return channels info as MATLAB structure array
            if(HandlesUsed>0)
            {   plhs[0] = mxCreateStructMatrix(1,HandlesUsed,6,MCAInfoFields);
                
                for(i=0;i<HandlesUsed;i++)
                {   mxSetFieldByNumber(plhs[0],i,0,mxCreateString(ca_name(CHNLS[i].CHID)));
                    mxSetFieldByNumber(plhs[0],i,1,mxCreateScalarDouble(ca_element_count(CHNLS[i].CHID)));
                    mxSetFieldByNumber(plhs[0],i,5,mxCreateString(ca_host_name(CHNLS[i].CHID)));
                    
                    switch(ca_state(CHNLS[i].CHID))
                    {   case 1: // Disconnected due to Server or Network - may reconnect 
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown"));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Disconnected due to server or network problem"));
                            break;
                        case 2: // Normal connection
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[i].CHID)]));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("connected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Normal connection"));
                            break;
                        case 3: // Disconnected by user
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown"));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Permanently disconnected (cleared) by the user"));                    
                            break;
                    }    
                }
            }
            else
            {   mexWarnMsgTxt("No connected PV's found"); 
                plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                
            }
            break;    
        
            
        case 11: // MCAINFO return info for 1 channel by handle number 
            Hndl = (int)mxGetScalar(prhs[1]);
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Handle out of range");  
                
            plhs[0] = mxCreateStructMatrix(1,1,6,MCAInfoFields);

            mxSetFieldByNumber(plhs[0],0,0,mxCreateString(ca_name(CHNLS[Hndl-1].CHID)));
            mxSetFieldByNumber(plhs[0],0,1,mxCreateScalarDouble(ca_element_count(CHNLS[Hndl-1].CHID)));
            mxSetFieldByNumber(plhs[0],0,5,mxCreateString(ca_host_name(CHNLS[Hndl-1].CHID)));
            
            switch(ca_state(CHNLS[Hndl-1].CHID))
            {  case 1: // Disconnected due to Server or Network - may reconnect 
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown"));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Disconnected due to server or network problem"));
                    break;
                case 2: // Normal connection
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[Hndl-1].CHID)]));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("connected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Normal connection"));
                    break;
                case 3: // Disconnected by user
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown"));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Permanently disconnected (cleared) by the user"));                    
                    break;
            };    
            
        break;    
        
        case 12: // MCASTATE return an array of status (1 - OK, 0 - disconnected or cleared) 
            if(HandlesUsed>0)
            {   plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL);
                myDblPr = mxGetPr(plhs[0]);
                for(i=0;i<HandlesUsed;i++)
                    myDblPr[i] = (double)(ca_state(CHNLS[i].CHID)==2);
            }
            else
            {   mexWarnMsgTxt("No connected PV's found"); 
                plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                
            }
            break;    
        
        
        case 30: // poll
            ca_poll();
        break;
            

        case 50: // MCAGET Get PV values by their MCA handles
            
            for(i=0;i<nrhs-1;i++) // First loop: place all ca_get requests in the buffer
            {   Hndl = (int)mxGetScalar(prhs[1+i]); //start from[1]:  [0] argument is the commnads switch
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Invalid Handle");
                
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                status = ca_array_get(RequestType,Cnt,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer);
                if(status!=ECA_NORMAL)
                    mexPrintf("Error in call to ca_array_get\n");
            }   
            
            status = ca_pend_io(MCA_GET_TIMEOUT);
            if(status!=ECA_NORMAL)
                mexErrMsgTxt("... ca_pend_io call timed out \n");
            
            
            for(i=0;i<nrhs-1;i++) // Another loop to copy data from temp structures to MATLAB
            
            {   Hndl = (int)mxGetScalar(prhs[1+i]);
                RequestType = RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                
                if(RequestType==DBR_STRING)
                {   if(Cnt==1)
                        plhs[i] = mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))));
                    else
                    {   plhs[i] = mxCreateCellMatrix(1,Cnt);
                        for(j=0;j<Cnt;j++)
                            mxSetCell(plhs[i], j, mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+j))));
                    }
                }
                
                else 
                {   plhs[i] = mxCreateDoubleMatrix(1,Cnt,mxREAL);
                    myDblPr = mxGetPr(plhs[i]);
                                        
                    switch(dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)))
                    
                    {   case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;    
                 
                        case DBR_FLOAT:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                
                        case DBR_ENUM:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                
                        case DBR_CHAR:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    
                        case DBR_LONG:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    
                        case DBR_DOUBLE:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    } 

                }
                
            } break;            

            case 51: // MCAGET Get scalar PV of the same type 
                     // second argument is an array of handles
                     // returns an array of values
            
            myDblPr = mxGetPr(prhs[1]);
            M = mxGetM(prhs[1]);
            N = mxGetN(prhs[1]);
            
            NumHandles = M*N;
            plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
            
            for(i=0;i<NumHandles;i++) // First loop: place all ca_get requests in the buffer
            {   Hndl = (int)myDblPr[i];
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Invalid Handle");
                
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                status = ca_array_get(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(plhs[0])+i);
                if(status!=ECA_NORMAL)
                    mexPrintf("Error in call to ca_array_get\n");
            }   
            
            status = ca_pend_io(MCA_GET_TIMEOUT);
            if(status!=ECA_NORMAL)
                mexErrMsgTxt("... ca_pend_io call timed out \n");
            
            break;            

        
       
        case 70: // MCAPUT
            NumHandles = (nrhs-1)/2;
            for(i=0;i<NumHandles;i++)
            {   j = 2+i*2;
                Hndl = (int)mxGetScalar(prhs[1+i*2]); 
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Handle out of range - no values written");
                // Set the status to 0 - mcaput_callback will write 1, if successful
                CHNLS[Hndl-1].LastPutStatus = 0;    
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));            
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                
                
                // If a value to write is passed as a string - the number of elements to write 
                //   is 1 , NOT the length of the string returned by mxGetNumberOfElements
                if(mxIsChar(prhs[j])) 
                    L=1;
                else
                    L = min(mxGetNumberOfElements(prhs[j]),Cnt);
                

                // Copy double or string data from MATLAB prhs[] to DataBuffer
                // on each channel 
                
                if(RequestType==DBR_STRING)
                {   // STRING type is is passed as a cell array of strings
                    // A a 1-row MATLAB character array (1 string) may also be passed as a value
                    
                    if(mxIsChar(prhs[j]))
                    {   mxGetString(prhs[j], StrBuffer, sizeof(dbr_string_t));
                        strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))),StrBuffer);
                        
                    }
                    else if(mxIsCell(prhs[j]))
                    {   for(k=0;k<L;k++)
                        {   mxGetString(mxGetCell(prhs[j],k), StrBuffer, sizeof(dbr_string_t));
                            strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+k)),StrBuffer);
                        }
                    }
                }
                else
                {   myDblPr = mxGetPr(prhs[j]); 
                    switch(RequestType)
                    {   
                        case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                        for(k=0;k<L;k++)
                            *((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_short_t)(myDblPr[k]);
                        break;    
                 
                        case DBR_FLOAT:
                        for(k=0;k<L;k++)
                            *((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_float_t)(myDblPr[k]);
                        break;
                
                        case DBR_ENUM:
                        for(k=0;k<L;k++)
                            *((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_enum_t)(myDblPr[k]);
                        break;
                
                        case DBR_CHAR:
                        for(k=0;k<L;k++)
                            *((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_char_t)(myDblPr[k]);
                        break;
                   
                        case DBR_LONG:
                        for(k=0;k<L;k++)
                            *((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_long_t)(myDblPr[k]);
                        break;
                    
                        case DBR_DOUBLE:
                        for(k=0;k<L;k++)
                            *((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_double_t)(myDblPr[k]);
                        break;
                    } 
                }            
 
                // place request in the que 
                status = ca_array_put_callback(RequestType,L,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer,
                                                   mcaput_callback,&(CHNLS[Hndl-1].LastPutStatus));

                 if(status!=ECA_NORMAL)
                    mexPrintf("ca_array_put_callback failed\n");
            }   
            
            status = ca_pend_event(MCA_PUT_TIMEOUT);
            
            plhs[0]=mxCreateDoubleMatrix(1,NumHandles,mxREAL);
            myDblPr = mxGetPr(plhs[0]);  
            
            for(i=0;i<NumHandles;i++)
            {   Hndl = (int)mxGetScalar(prhs[1+i*2]);
                myDblPr[i] = (double)CHNLS[Hndl-1].LastPutStatus;
                
            }
           
            break;
        
       case 80: // MCAPUT - fast unconfirmed put for scalar numeric PV's
        
            myDblPr = mxGetPr(prhs[1]);
            M = mxGetM(prhs[1]);
            N = mxGetN(prhs[1]);                
            NumHandles = M*N;
            
            plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
            myDblPr = mxGetPr(plhs[0]);  
            
            for(i=0;i<NumHandles;i++)
            {   myDblPr = mxGetPr(plhs[0]);
                Hndl = (int)(*(mxGetPr(prhs[1])+i)); 
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Handle out of range - no values written");

                status = ca_array_put(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(prhs[2])+i);

                if(status!=ECA_NORMAL)
                    {   myDblPr[i] = 0;
                        //mexPrintf("ca_array_put_callback failed\n");
                    }
                    else
                    {   myDblPr[i] = 1;
                    }
                    
            }   
            
            status = ca_pend_io(MCA_PUT_TIMEOUT);
            
            break;    
                 
            
        case 100: // MCAMON install Monitor or replace MonitorCBString
            
            Hndl = (int)mxGetScalar(prhs[1]); 
            
            // Check if the handle is within range 
            if(Hndl<1 || Hndl>HandlesUsed)
            {   plhs[0]=mxCreateScalarDouble(0);
                mexErrMsgTxt("Invalid Handle");
            }
            
            if(CHNLS[Hndl-1].EVID) // if VID is not NULL - another monitor is already installed - replace MonitorCBString
            {   if(CHNLS[Hndl-1].MonitorCBString) // Free memory for occupied by the old MonitorCBString
                {   mxFree(CHNLS[Hndl-1].MonitorCBString);
                    CHNLS[Hndl-1].MonitorCBString = NULL;
                }
                if(nrhs>2) // Check if the new string is specified
                {   if(mxIsChar(prhs[2]))
                    {   buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1;
                        CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen);
                        mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString);
                        mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); 
                    } 
                    else
                        mexErrMsgTxt("Third argument must be a string\n");
                }
                plhs[0]=mxCreateScalarDouble(1);
            }
            else // No monitor is presently installed;
            {   RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); // Closest to the native 
            
            
                if(nrhs>2)
                {   if(mxIsChar(prhs[2]))
                    {   buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1;
                        CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen);
                        mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString);
                        mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); 
                    } 
                    else
                        mexErrMsgTxt("Third argument must be a string\n");
                }
                else
                    CHNLS[Hndl-1].MonitorCBString = NULL;  // Set MonitorCBString to NULL so that mcaMonitorEventHandler only copies data to CACHE
            
                // Count argument set to 0 - native count
                status = ca_add_array_event(RequestType,0,CHNLS[Hndl-1].CHID, mcaMonitorEventHandler, &CHNLS[Hndl-1], 0.0, 0.0, 0.0, &(CHNLS[Hndl-1].EVID));
              
                if(status!=ECA_NORMAL)
                {   mexPrintf("ca_add_array_event failed\n");      
                    plhs[0]=mxCreateScalarDouble(0);
                }
                else
                {   ca_poll();
                    plhs[0]=mxCreateScalarDouble(1);
                }
            }   
            break;
            
        case 200: // Clear Monitor MCACLEARMON
            
            Hndl = (int)mxGetScalar(prhs[1]); 
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Invalid Handle");
            if(!CHNLS[Hndl-1].EVID) 
                mexErrMsgTxt("No monitor installed - can not clear");
                
            status = ca_clear_event(CHNLS[Hndl-1].EVID);
            if(status!=ECA_NORMAL)
                mexPrintf("ca_clear_event failed\n");
                
            // Set the EVID pointer to NULL (ca_clear_event dos not do it by itself)
            // to use as a FLAG that no monitors are installed 
            CHNLS[Hndl-1].EVID = NULL;
            // Reset
            CHNLS[Hndl-1].MonitorEventCount = 0;    
            // If there is Callback String - destroy it
            if(CHNLS[Hndl-1].MonitorCBString)
            {   mxFree(CHNLS[Hndl-1].MonitorCBString); 
                CHNLS[Hndl-1].MonitorCBString =NULL;
            }
                
          
        break;
          
        case 300: // MCACACHE Get Cached values of a monitored PV
            for(i=0;i<nrhs-1;i++)
            {   Hndl = (int)mxGetScalar(prhs[1+i]);
                // if(Hndl<1 || Hndl>HandlesUsed || !CHNLS[Hndl-1].CACHE)
                if(Hndl<1 || Hndl>HandlesUsed)
                    plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL);
                else
                    {   plhs[i] = mxDuplicateArray(CHNLS[Hndl-1].CACHE);
                        CHNLS[Hndl-1].MonitorEventCount = 0;
                    }
            }       
          
        break;
        
        case 500: // MCAMON Info on installed monitors
            L = 0;
            HndlArray = (int*)mxCalloc(HandlesUsed,sizeof(int));
            
            for(i=0;i<HandlesUsed;i++) // Count installed monitors
            {   if(CHNLS[i].EVID)
                HndlArray[L++]=i+1;
            }       
            
            if(L>0)
            {   plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL);
                myDblPr = mxGetPr(plhs[0]);
                plhs[1] = mxCreateCellMatrix(1,L);
                for(i=0;i<L;i++)
                {   myDblPr[i] = (double)HndlArray[i];
                    mxSetCell(plhs[1],i,mxCreateString(CHNLS[HndlArray[i]-1].MonitorCBString));
                }
            }
            else
            {   plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                plhs[1] = mxCreateCellMatrix(0,0);
            }
            
        break;
        
        case 510: // MCAMONEVENTS Event count fot monitors
                       
            plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL);
            myDblPr = mxGetPr(plhs[0]);
            for(i=0;i<HandlesUsed;i++)
                myDblPr[i]=(double)(CHNLS[i].MonitorEventCount);
            
        break;
        
        case 1000: // print timeout settings
            plhs[0] = mxCreateDoubleMatrix(3,1,mxREAL);
            mexPrintf("MCA timeout settings\n:");
            mexPrintf("mcaopen\t%f [s]\n",  MCA_SEARCH_TIMEOUT );
            mexPrintf("mcaget\t%f [s]\n",  MCA_GET_TIMEOUT ); 
            mexPrintf("mcaput\t%f [s]\n",  MCA_PUT_TIMEOUT );

            myDblPr = mxGetPr(plhs[0]);
            myDblPr[0] = MCA_SEARCH_TIMEOUT;
            myDblPr[1] = MCA_GET_TIMEOUT;
            myDblPr[2] = MCA_PUT_TIMEOUT;

            
        break;
        
        
        case 1001: // set MCA_SEARCH_TIMEOUT
            // return delay value
            MCA_SEARCH_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_SEARCH_TIMEOUT);
        break;
        
        case 1002: // set MCA_GET_TIMEOUT
            // return delay value
            MCA_GET_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_GET_TIMEOUT);
        break;
        
        case 1003: // set MCA_PUT_TIMEOUT
            // return delay value
            MCA_PUT_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_PUT_TIMEOUT);
        break;

    } 
}
コード例 #17
0
ファイル: caPutCallback.c プロジェクト: akazakov/epicstest
int main(int argc,char **argv)
{
    char   *pval;
    double sleepSecs = 0.0;
    int	    clearEvery = 0;
    int     indValue = 1;
    int     indNumberCallback = 1;

    while((argc>1) && (argv[1][0] == '-')) {
        int i;
        char option;
        int  narg;
        option = toupper((argv[1])[1]);
        pval = argv[2];
        argc -= 1; narg = 1;
        if(option=='S') {
            sscanf(pval,"%lf",&sleepSecs);
            argc -= 1; ++narg;
        } else if(option=='C') {
            sscanf(pval,"%d",&clearEvery);
            argc -= 1; ++narg;
        } else if(option=='V') {
            verbose = 1;
        } else {
            usageExit();
        }
        for(i=1; i<argc; i++) argv[i] = argv[i + narg];
    }

    if(argc != 4) usageExit();
    pvname = argv[1];
    pvalue1 = argv[2];
    pvalue2 = argv[3];
    pevent = epicsEventCreate(epicsEventEmpty);
    SEVCHK(ca_context_create(ca_enable_preemptive_callback),
        "ca_task_initialize");
    while(1) {
        SEVCHK(ca_search(pvname,&mychid),"ca_search_and_connect");
        if(ca_pend_io(3.0)!=ECA_NORMAL) {
            epicsThreadSleep(5.0);
            continue;
        }
        while(1) {
            epicsEventWaitStatus status;
            if(indValue==0) {
                indValue = 1; pvalue = pvalue2;
            } else {
                indValue = 0; pvalue=pvalue1;
            }
            if(++indNumberCallback >= MAXnumberCallback) indNumberCallback=0;
            numberCallback[indNumberCallback] = ++expectedCallback;
            status = ca_array_put_callback(DBR_STRING,1,mychid,
                pvalue,putCallback,&numberCallback[indNumberCallback]);
            if(status!=ECA_NORMAL) {
                printf("ca_array_put_callback %s\n",ca_message(status));
                epicsThreadSleep(2.0);
                continue;
            }
            if((clearEvery>0) 
            && ((expectedCallback % clearEvery)==0)) {
                ca_flush_io();
                epicsThreadSleep(sleepSecs);
                SEVCHK(ca_clear_channel(mychid),"ca_clear_channel");
                ca_flush_io();
                expectedCallback = 0;
                epicsThreadSleep(sleepSecs);
                if(verbose) {
                    printTime();
                    printf("Issued ca_clear_channel expectedCallback %d\n",
                        expectedCallback);
                }
                break;
            }
            ca_flush_io();
            if(verbose) {
                printTime();
                printf("Issued ca_put_callback expectedCallback %d\n",
                    expectedCallback);
            }
            while(1) {
                status = epicsEventWaitWithTimeout(pevent,10.0);
                if(status==epicsEventWaitTimeout) {
                    if(verbose) {
                        printTime();
                        printf("timeout after 10 seconds\n");
                    }
                    continue;
                }
                break;
            }
            if(status!=epicsEventWaitOK) {
                int i;
                printTime();
                printf("eventWait status %d\n",status);
                for(i=0; i<MAXnumberCallback; i++) numberCallback[i]=0;
            }
            epicsThreadSleep(sleepSecs);
        }
    }
    ca_task_exit();
    return(0);
}
コード例 #18
0
ファイル: caput.c プロジェクト: ISISComputingGroup/EPICS-base
int caget (pv *pvs, int nPvs, OutputT format,
           chtype dbrType, unsigned long reqElems)
{
    unsigned int i;
    int n, result;

    for (n = 0; n < nPvs; n++) {

                                /* Set up pvs structure */
                                /* -------------------- */

                                /* Get natural type and array count */
        pvs[n].nElems  = ca_element_count(pvs[n].chid);
        pvs[n].dbfType = ca_field_type(pvs[n].chid);
        pvs[n].dbrType = dbrType;

                                /* Set up value structures */
        pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */
        if (dbr_type_is_ENUM(pvs[n].dbrType))             /* Enums honour -n option */
        {
            if (enumAsNr) pvs[n].dbrType = DBR_TIME_INT;
            else          pvs[n].dbrType = DBR_TIME_STRING;
        }

        if (reqElems == 0 || pvs[n].nElems < reqElems)    /* Adjust array count */
            pvs[n].reqElems = pvs[n].nElems;
        else
            pvs[n].reqElems = reqElems;

                                /* Issue CA request */
                                /* ---------------- */

        if (ca_state(pvs[n].chid) == cs_conn)
        {
            nConn++;
            pvs[n].onceConnected = 1;
                                   /* Allocate value structure */
            pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].reqElems));
            if(!pvs[n].value){
                fprintf(stderr,"Allocation failed\n");
                exit(1);
            }
            result = ca_array_get(pvs[n].dbrType,
                                  pvs[n].reqElems,
                                  pvs[n].chid,
                                  pvs[n].value);
            pvs[n].status = result;
        } else {
            pvs[n].status = ECA_DISCONN;
        }
    }
    if (!nConn) return 1;              /* No connection? We're done. */

                                /* Wait for completion */
                                /* ------------------- */

    result = ca_pend_io(caTimeout);
    if (result == ECA_TIMEOUT)
        fprintf(stderr, "Read operation timed out: PV data was not read.\n");

                                /* Print the data */
                                /* -------------- */

    for (n = 0; n < nPvs; n++) {

        switch (format) {
        case plain:             /* Emulate old caput behaviour */
            if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
            else                                               printf("%s", pvs[n].name);
            printf("%c", fieldSeparator);
        case terse:
            if (pvs[n].status == ECA_DISCONN)
                printf("*** not connected\n");
            else if (pvs[n].status == ECA_NORDACCESS)
                printf("*** no read access\n");
            else if (pvs[n].status != ECA_NORMAL)
                printf("*** CA error %s\n", ca_message(pvs[n].status));
            else if (pvs[n].value == 0)
                printf("*** no data available (timeout)\n");
            else
            {
                if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
                    dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
                    int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
                    char *d = calloc(dlen+1, sizeof(char));
                    if(!d){
                        fprintf(stderr,"Allocation failed\n");
                        exit(1);
                    }
                    epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s));
                    printf("%s", d);
                    free(d);
                } else {
                    if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].reqElems, fieldSeparator);
                    for (i=0; i<pvs[n].reqElems; ++i) {
                        if (i) printf ("%c", fieldSeparator);
                        printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
                    }
                }
                printf("\n");
            }
            break;
        case all:
            print_time_val_sts(&pvs[n], reqElems);
            break;
        default :
            break;
        }
    }
    return 0;
}
コード例 #19
0
ファイル: caput.c プロジェクト: ISISComputingGroup/EPICS-base
int main (int argc, char *argv[])
{
    int i;
    int result;                 /* CA result */
    OutputT format = plain;     /* User specified format */
    RequestT request = get;     /* User specified request type */
    int isArray = 0;            /* Flag for array operation */
    int enumAsString = 0;       /* Force ENUM values to be strings */

    int count = 1;
    int opt;                    /* getopt() current option */
    chtype dbrType = DBR_STRING;
    char *pend;
    EpicsStr *sbuf;
    double *dbuf;
    char *cbuf = 0;
    char *ebuf = 0;
    void *pbuf;
    int len = 0;
    int waitStatus;
    struct dbr_gr_enum bufGrEnum;

    int nPvs;                   /* Number of PVs */
    pv* pvs;                /* Array of PV structures */

    LINE_BUFFER(stdout);        /* Configure stdout buffering */
    putenv("POSIXLY_CORRECT="); /* Behave correct on GNU getopt systems */

    while ((opt = getopt(argc, argv, ":cnlhatsS#:w:p:F:")) != -1) {
        switch (opt) {
        case 'h':               /* Print usage */
            usage();
            return 0;
        case 'n':               /* Force interpret ENUM as index number */
            enumAsNr = 1;
            enumAsString = 0;
            break;
        case 's':               /* Force interpret ENUM as menu string */
            enumAsString = 1;
            enumAsNr = 0;
            break;
        case 'S':               /* Treat char array as (long) string */
            charArrAsStr = 1;
            isArray = 0;
            break;
        case 't':               /* Select terse output format */
            format = terse;
            break;
        case 'l':               /* Select long output format */
            format = all;
            break;
        case 'a':               /* Select array mode */
            isArray = 1;
            charArrAsStr = 0;
            break;
        case 'c':               /* Select put_callback mode */
            request = callback;
            break;
        case 'w':               /* Set CA timeout value */
            if(epicsScanDouble(optarg, &caTimeout) != 1)
            {
                fprintf(stderr, "'%s' is not a valid timeout value "
                        "- ignored. ('caput -h' for help.)\n", optarg);
                caTimeout = DEFAULT_TIMEOUT;
            }
            break;
        case '#':               /* Array count */
            if (sscanf(optarg,"%d", &count) != 1)
            {
                fprintf(stderr, "'%s' is not a valid array element count "
                        "- ignored. ('caput -h' for help.)\n", optarg);
                count = 0;
            }
            break;
        case 'p':               /* CA priority */
            if (sscanf(optarg,"%u", &caPriority) != 1)
            {
                fprintf(stderr, "'%s' is not a valid CA priority "
                        "- ignored. ('caget -h' for help.)\n", optarg);
                caPriority = DEFAULT_CA_PRIORITY;
            }
            if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX;
            break;
        case 'F':               /* Store this for output and tool_lib formatting */
            fieldSeparator = (char) *optarg;
            break;
        case '?':
            fprintf(stderr,
                    "Unrecognized option: '-%c'. ('caput -h' for help.)\n",
                    optopt);
            return 1;
        case ':':
            fprintf(stderr,
                    "Option '-%c' requires an argument. ('caput -h' for help.)\n",
                    optopt);
            return 1;
        default :
            usage();
            return 1;
        }
    }

    nPvs = argc - optind;       /* Remaining arg list are PV names and values */

    if (nPvs < 1) {
        fprintf(stderr, "No pv name specified. ('caput -h' for help.)\n");
        return 1;
    }
    if (nPvs == 1) {
        fprintf(stderr, "No value specified. ('caput -h' for help.)\n");
        return 1;
    }

    nPvs = 1;                   /* One PV - the rest is value(s) */

    epId = epicsEventCreate(epicsEventEmpty);  /* Create empty EPICS event (semaphore) */

                                /* Start up Channel Access */

    result = ca_context_create(ca_enable_preemptive_callback);
    if (result != ECA_NORMAL) {
        fprintf(stderr, "CA error %s occurred while trying "
                "to start channel access.\n", ca_message(result));
        return 1;
    }
                                /* Allocate PV structure array */

    pvs = calloc (nPvs, sizeof(pv));
    if (!pvs) {
        fprintf(stderr, "Memory allocation for channel structure failed.\n");
        return 1;
    }
                                /* Connect channels */

    pvs[0].name = argv[optind] ;   /* Copy PV name from command line */

    result = connect_pvs(pvs, nPvs); /* If the connection fails, we're done */
    if (result) {
        ca_context_destroy();
        return result;
    }

                                /* Get values from command line */
    optind++;

    if (isArray) {
        optind++;               /* In case of array skip first value (nr
                                 * of elements) - actual number of values is used */
        count = argc - optind;

    } else {                    /* Concatenate the remaining line to one string
                                 * (sucks but is compatible to the former version) */
        for (i = optind; i < argc; i++) {
            len += strlen(argv[i]);
            len++;
        }
        cbuf = calloc(len, sizeof(char));
        if (!cbuf) {
            fprintf(stderr, "Memory allocation failed.\n");
            return 1;
        }
        strcpy(cbuf, argv[optind]);

        if (argc > optind+1) {
            for (i = optind + 1; i < argc; i++) {
                strcat(cbuf, " ");
                strcat(cbuf, argv[i]); 
            }
        }

        if ((argc - optind) >= 1)
            count = 1;
        argv[optind] = cbuf;
    }

    sbuf = calloc (count, sizeof(EpicsStr));
    dbuf = calloc (count, sizeof(double));
    if(!sbuf || !dbuf) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }

                                /*  ENUM? Special treatment */

    if (ca_field_type(pvs[0].chid) == DBR_ENUM) {

                                /* Get the ENUM strings */

        result = ca_array_get (DBR_GR_ENUM, 1, pvs[0].chid, &bufGrEnum);
        result = ca_pend_io(caTimeout);
        if (result == ECA_TIMEOUT) {
            fprintf(stderr, "Read operation timed out: ENUM data was not read.\n");
            return 1;
        }

        if (enumAsNr) {         /* Interpret values as numbers */

            for (i = 0; i < count; ++i) {
                dbuf[i] = epicsStrtod(*(argv+optind+i), &pend);
                if (*(argv+optind+i) == pend) { /* Conversion didn't work */
                    fprintf(stderr, "Enum index value '%s' is not a number.\n",
                            *(argv+optind+i));
                    return 1;
                }
                if (dbuf[i] >= bufGrEnum.no_str) {
                    fprintf(stderr, "Warning: enum index value '%s' may be too large.\n",
                            *(argv+optind+i));
                }
            }
            dbrType = DBR_DOUBLE;

        } else {                /* Interpret values as strings */

            for (i = 0; i < count; ++i) {
                epicsStrnRawFromEscaped(sbuf[i], sizeof(EpicsStr), *(argv+optind+i), sizeof(EpicsStr));
                *( sbuf[i]+sizeof(EpicsStr)-1 ) = '\0';
                dbrType = DBR_STRING;

                                /* Compare to ENUM strings */
                for (len = 0; len < bufGrEnum.no_str; len++)
                    if (!strcmp(sbuf[i], bufGrEnum.strs[len]))
                        break;

                if (len >= bufGrEnum.no_str) {
                                         /* Not a string? Try as number */
                    dbuf[i] = epicsStrtod(sbuf[i], &pend);
                    if (sbuf[i] == pend || enumAsString) {
                        fprintf(stderr, "Enum string value '%s' invalid.\n", sbuf[i]);
                        return 1;
                    }
                    if (dbuf[i] >= bufGrEnum.no_str) {
                        fprintf(stderr, "Warning: enum index value '%s' may be too large.\n", sbuf[i]);
                    }
                    dbrType = DBR_DOUBLE;
                }
            }
        }

    } else {                    /* Not an ENUM */

        if (charArrAsStr) {
            dbrType = DBR_CHAR;
            ebuf = calloc(len, sizeof(char));
            if(!ebuf) {
                fprintf(stderr, "Memory allocation failed\n");
                return 1;
            }
            count = epicsStrnRawFromEscaped(ebuf, len, cbuf, len-1) + 1;
        } else {
            for (i = 0; i < count; ++i) {
                epicsStrnRawFromEscaped(sbuf[i], sizeof(EpicsStr), *(argv+optind+i), sizeof(EpicsStr));
                *( sbuf[i]+sizeof(EpicsStr)-1 ) = '\0';
            }
            dbrType = DBR_STRING;
        }
    }

                                /* Read and print old data */
    if (format != terse) {
        printf("Old : ");
        result = caget(pvs, nPvs, format, 0, 0);
    }

                                /* Write new data */
    if (dbrType == DBR_STRING) pbuf = sbuf;
    else if (dbrType == DBR_CHAR) pbuf = ebuf;
    else pbuf = dbuf;

    if (request == callback) {
        /* Use callback version of put */
        pvs[0].status = ECA_NORMAL;   /* All ok at the moment */
        result = ca_array_put_callback (
            dbrType, count, pvs[0].chid, pbuf, put_event_handler, (void *) pvs);
    } else {
        /* Use standard put with defined timeout */
        result = ca_array_put (dbrType, count, pvs[0].chid, pbuf);
    }
    result = ca_pend_io(caTimeout);
    if (result == ECA_TIMEOUT) {
        fprintf(stderr, "Write operation timed out: Data was not written.\n");
        return 1;
    }
    if (request == callback) {   /* Also wait for callbacks */
        waitStatus = epicsEventWaitWithTimeout( epId, caTimeout );
        if (waitStatus)
            fprintf(stderr, "Write callback operation timed out\n");

        /* retrieve status from callback */
        result = pvs[0].status;
    }

    if (result != ECA_NORMAL) {
        fprintf(stderr, "Error occured writing data.\n");
        return 1;
    }

                                /* Read and print new data */
    if (format != terse)
        printf("New : ");

    result = caget(pvs, nPvs, format, 0, 0);

                                /* Shut down Channel Access */
    ca_context_destroy();

    return result;
}
コード例 #20
0
void SinglePlotThread::run()
{
#if 0
	// event gathering
	//printchannel();	//for Debug
	mutex.lock();
	mynode.plot	= m_plot;
	chid unit_chid;
	dbr_string_t units;
	QString unitch = m_pvname + ".EGU";
	ca_create_channel(unitch.toStdString().c_str(), 0, 0, 0, &unit_chid);
	ca_pend_io(0.1);
	ca_get(DBR_STRING, unit_chid, (void *)&units);
	ca_pend_io(0.1);
	m_plot->SetUnit(units);

	ca_create_channel(m_pvname.toStdString().c_str(), connectionCallback, &mynode, 0, (oldChannelNotify**)&mynode.mychid);
	ca_replace_access_rights_event(mynode.mychid, accessRightsCallback);
	ca_create_subscription (DBR_TIME_DOUBLE, 0, mynode.mychid, DBE_VALUE|DBE_ALARM, eventCallback, &mynode, &mynode.myevid);
	//ca_add_event(DBR_GR_DOUBLE, mynode.mychid, eventCallback, &mynode, &mynode.myevid);
	mutex.unlock();
	ca_pend_event(0.0);
#else
	//periodic gathering
	mutex.lock();
	chid unit_chid, val_chid;
	dbr_string_t units;

	QString unitch = m_pvname + ".EGU";
	ca_create_channel(unitch.toStdString().c_str(), 0, 0, 0, &unit_chid); ca_pend_io(0.2);
	ca_get(DBR_STRING, unit_chid, (void *)&units); ca_pend_io(0.2);
	m_plot->SetUnit(units);

	struct dbr_time_double data;
	ca_create_channel(m_pvname.toStdString().c_str(), 0, 0, 0, &val_chid);
	ca_pend_io(0.2);

	epicsTime  stamp;

	struct local_tm_nano_sec tm;
	int totsec = 0;
	//for periodic single plot local time
	int year, month, day, hour, min, sec;
	int factor = 1;
	switch(mperiodic)
	{
		case PointOne:
			factor *= 0.1;
			break;
		case PointFive:
			factor *= 0.5;
			break;
		case FiveSec:
			factor *= 5;
			break;
		case TenSec:
			factor *= 10;
			break;
		case OneSec:
		default:
			break;
	};
	while(getStop()==false)
	{
		ca_get(DBR_TIME_DOUBLE, val_chid, (void *)&data);
		ca_pend_io(0.2);
		//qDebug("%s : %f\n",ca_name(val_chid), data.value);
		Epoch2Datetime(year, month, day, hour, min, sec);
#if 0
		stamp = data.stamp;
		tm = (local_tm_nano_sec) stamp;
		totsec = tm.ansi_tm.tm_hour*3600+tm.ansi_tm.tm_min*60+tm.ansi_tm.tm_sec;
		m_plot->GetValue(data.value, totsec,tm.ansi_tm.tm_year,tm.ansi_tm.tm_mon, tm.ansi_tm.tm_mday );
#else
		totsec = hour*3600+min*60+sec;
		m_plot->GetValue(data.value, totsec, year, month, day);
#endif
		usleep(1000000*factor);
	};
	//ca_clear_channel(unit_chid);
	//ca_clear_channel(val_chid);
	ca_context_destroy();
	mutex.unlock();
	exit();
	qDebug("SinglePlot Exit");
#endif
}
コード例 #21
0
/* Find an unconnected PV and attempt to connect to it.  That should
 * restart the searches for all other unresolved PVs. */
void retryConnections(void)
{
    int i,j;
    const char *pvname=NULL;
    chid retryChid;
    int status;

#if DEBUG_RETRY
    print("retryConnections:\n");
    print(" freeListSize=%d freeListCount=%d\n",
      caTask.freeListSize,caTask.freeListCount);
    print(" pageSize=%d pageCount=%d\n",
      caTask.pageSize,caTask.pageCount);
    print(" nextpage=%d nextFree=%d\n",
      caTask.nextPage,caTask.nextFree);
    print(" channelCount=%d channelConnected=%d\n",
      caTask.channelCount,caTask.channelConnected);
    if(caTask.nextPage != caTask.pageCount-1) {
	print(" caTask.nextPage != caTask.pageCount-1\n");
    }
#else
  /* Check if all channels are connected */
    if(caTask.channelCount == caTask.channelConnected) {
	medmPostMsg(1,"retryConnections: All channels are connected\n");
	XBell(display, 50);
	return;
    }
#endif

  /* Find an unconnected PV */
    for(i=0; i < caTask.pageCount; i++) {
	int jmax=(i == caTask.nextPage)?caTask.nextFree:CA_PAGE_SIZE;
	for(j=0; j < jmax; j++) {
	    Channel *pCh=&caTask.pages[i][j];
	    if(pCh->chid && ca_state(pCh->chid) != cs_conn) {
		pvname=ca_name(pCh->chid);
		break;
	    }
	}
	if(pvname) break;
    }
#if DEBUG_RETRY
    print(" Found %s\n",pvname?pvname:"Not found");
    if(!pvname) return;
#else
    if(!pvname) {
	medmPostMsg(1,"retryConnections: Failed to find unconnected PV\n");
	return;
    }
#endif

  /* Search */
    status=ca_search_and_connect(pvname,&retryChid,NULL,NULL);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"retryConnections: ca_search failed for %s: %s\n",
	  pvname, ca_message(status));
    }

  /* Wait.  The searches will only continue for this time.  Keep the
   * time short as the interface is frozen, and most of the searches
   * occur at the start of the sequence.  Testing indicated:
   *
   * RETRY_TIMEOUT Searches
   *      30          15
   *       5          10
   *       3           9
   *       2           9
   *       1           8
   *
   * but this may vary owing to tuning and may change with new releases.
   */
    ca_pend_io(RETRY_TIMEOUT);

  /* Clear the channel */
    status = ca_clear_channel(retryChid);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"retryConnections: ca_clear_channel failed for %s: %s\n",
	  pvname, ca_message(status));
    }
}