g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014 
<== Date ==> <== Thread ==>

Subject: octave interface
From: "D. Peter Siddons" <siddons@bnl.gov>
To: tech-talk@aps.anl.gov
Date: Tue, 17 Jan 2006 17:52:50 -0500
Some time ago I posted a simple interface to CA from the Octave language. I just discovered a stupid typo which caused segfaults for some array puts. Attached is a revised version of the c++ file. The rest is OK.
Pete.


#include <octave/oct.h>
#include <malloc.h>
#include <tsDefs.h>
#include <cadef.h>
#include <ezca.h>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>

using namespace std;

extern "C" 
{
    extern int ezcaGet(char *pvname, char ezcatype, int nelem, void *data_buff);
    extern int ezcaGetNelem(char *pvname, int *nelem);
    extern int ezcaNewMonitorValue(char *pvname, char ezcatype);
    extern int ezcaClearMonitor(char *pvname, char ezcatype);
    extern int ezcaSetMonitor(char *pvname, char ezcatype);
    extern int ezcaPut(char *pvname, char ezcatype,int nelem, void *data_buff);
    extern int ezcaPvToChid(char *pvname, chid **cid);
    extern  short int ca_field_type ( chid );
    extern  long unsigned int ca_element_count ( chid );
    int Ca_types[7]= {1,2,4,6,0,3,5};

// ezca doesn't treat ENUMs, so fool it and use short, since this is what it resolves to.
#define ezcaEnum 6    

}


DEFUN_DLD(caput, args, ,
	  "caput('pvname',vals). Put values of vals[] to PV 'name'.")
{
     int b=0;
     char pv[255];
     int d,n,i,j,k;
     short int catype;
     int Nelem,Error;
     void *y;
     chid *ch;
     char *y1;
     char *y2;
     int *y3;
     long *y4;
     float *y5;
     double *y6;
     
// Copy data to vector
     if(args.length() >= 3)
     {
        cout << "Only PV name and one value array allowed" << endl;
	return octave_value(0);
	}
     RowVector x(args(1).vector_value());

// space for PV name
     charMatrix c(args(0).string_value());

// Copy name to C array     
     n=args(0).length();
     for (i = 0; i < n; i++) {
     	pv[i]= c(i);
	}
     pv[n]=(char)NULL;

// Get chid of channel
     j=ezcaPvToChid(pv, &ch);

// Use it to get field type     
     catype= Ca_types[ca_field_type(*ch)];

// Get number of elements from channel     
     ezcaGetNelem(pv, &Nelem);

// Allocate memory for C array, copy octave data to it and make the C call, 
// free the C array.
     
     Error=0;
     
     switch(catype){
     	case ezcaString:{
		cout << "Putting string" << endl;
		if (!args(1).is_string()){
			Error=1;
			break;
			}
		n = args(1).length();
		charMatrix y(args(1).string_value());
  		y1=(char *) calloc(n,sizeof(char));
		for(i=0;i<n;i++){
			y1[i]=y(i);
			}
		y1[n]=(char)(NULL);
		d=ezcaPut(pv, ezcaString, 1, (void *)y1);
		free(y1);
		}
		break;
		
	case ezcaByte:
		cout << "Putting bytes" << endl;
		n = args(1).length(); 
		// Check that data lengths match
		if(Nelem != n){
		Error=2;
		break;
		}

		y2=(char *) calloc(n,sizeof(char));
		for (i = 0; i < n; i++) {
			y2[i]= (char) x(i);
			}
		d=ezcaPut(pv,ezcaByte, n, y2);
		free(y2);
		break;
		  		  
	case ezcaShort:
		cout << "Putting shorts" << endl;
		n = args(1).length(); 
		// Check that data lengths match
		if(Nelem != n){
		Error=2;
		break;
		}
		y3=(int *) calloc(n,sizeof(int));
		for (i = 0; i < n; i++) {
			y3[i]= (int) x(i);
			}
		d=ezcaPut(pv, ezcaShort, n, y3);
		free(y3);
		break;

	case ezcaEnum:
		cout << "Putting enum" << endl;
		n = args(1).length(); 
		// Check that data lengths match
		if(Nelem != n){
		Error=2;
		break;
		}
		y3=(int *) calloc(n,sizeof(int));
		for (i = 0; i < n; i++) {
			y3[i]= (int) x(i);
			}
		d=ezcaPut(pv, ezcaShort, n, y3);
		free(y3);
		break;
		
	case ezcaLong:
		cout << "Putting long" << endl;
		n = args(1).length(); 
		// Check that data lengths match
		if(Nelem != n){
		Error=2;
		break;
		}
		y4=(long *) calloc(n,sizeof(long));
		for (i = 0; i < n; i++) {
			y4[i]=(long) x(i);
			}
		
		d=ezcaPut(pv, ezcaLong, n, y4);
		free(y4);
		break;
		
	case ezcaFloat:
		cout << "Putting float" << endl;
		n = args(1).length(); 
		// Check that data lengths match
		if(Nelem != n){
		Error=2;
		break;
		}
		cout << "Lengths OK" << endl;
		y5=(float *) calloc(n,sizeof(float));
		for (i = 0; i < n; i++) {
			y5[i]=(float) x(i);
			}
		
		d=ezcaPut(pv, ezcaFloat, n, y5);
		cout << "Data sent" << endl;
		free(y5);
		cout << "Memory freed" << endl;
		break;
		
	case ezcaDouble:
		cout << "Putting double" << endl;
		n = args(1).length(); 
		// Check that data lengths match
		if(Nelem != n){
		Error=2;
		break;
		}
		cout << "Lengths OK" << endl;
		y6=(double *) calloc(n,sizeof(double));
		for (i = 0; i < n; i++) {
			y6[i]=(double) x(i);
			}
		d=ezcaPut(pv, ezcaDouble, n, y6);
		cout << "Data sent" << endl;
		free(y6);
		cout << "Memory freed" << endl;
		break;
		
	default:
		Error=3;
		break;
	}
	switch(Error){
	case 1:
		cout << "Incorrect variable type" << endl;
		break;
	case 2:
		cout << "Incompatible array lengths" << endl;
		break;
	case 3:
		cout << "Unknown CA type" << endl;
		break;
	default: {}
	}
     if (d != 0) error("caput: Channel Access fault");
     
     return octave_value(Error);
}


DEFUN_DLD(caget, args, ,
	  "caget('pvname'). Get values from  PV 'name'.")
{
     int b=0;
     char pv[255];
     int d,n,i,j,k;
     short int catype;
//     void *y;
     chid *ch;
     char *y1;
     char *y2;
     int *y3;
     long *y4;
     float *y5;
     double *y6;
     octave_value_list answer;
     
     
     charMatrix c(args(0).string_value());
     
// Get PV name into C array
     n=args(0).length();
     for (i = 0; i < n; i++) {
     	pv[i]= c(i);
	}
     pv[n]=(char)NULL;

// Get channel ID so can access structures
     j=ezcaPvToChid(pv, &ch);

// like PV variable type     
     catype= Ca_types[ca_field_type(*ch)];

// Get number of elements in PV     
     ezcaGetNelem(pv, &n);

// Make vector to hold results
     octave_value retval;

// Allocate memory for C array, get data from PV, copy it to Octave vector,
// free up C array.
     switch(catype){

	case ezcaString: {
		  y2=(char *) calloc(256,sizeof(char));
		  d=ezcaGet(pv, catype, n, (void *)y2);
		  n=strlen(y2);
		  string y;
		  for (i = 0; i < n; i++) {
		  	y += (char) y2[i];
			}
		retval=y;
		free(y2);
		}
		break;
		  		  
     	case ezcaByte:{
		  y1=(char *) calloc(n,sizeof(char));
		  d=ezcaGet(pv, catype, n, (void *)y1);
		  RowVector y(n);
		  for (i = 0; i < n; i++) {
		  	y(i)=(char)y1[i];
			}
		retval=y;
		free(y1);
		}
		break;
		
	case ezcaShort: {
		  y3=(int *) calloc(n,sizeof(int));
		  d=ezcaGet(pv, catype, n, (void *)y3);
		  RowVector y(n);
		  for (i = 0; i < n; i++) {
		  	y(i) = (double) y3[i];
			}
		retval=y;
		free(y3);
		}
		break;
		
	case ezcaEnum: {
		  y3=(int *) calloc(n,sizeof(int));
		  d=ezcaGet(pv, ezcaShort, n, (void *)y3);
		  RowVector y(n);
		  for (i = 0; i < n; i++) {
		  	y(i) = (double) y3[i];
			}
		retval=y;
		free(y3);
		}
		break;
		
	case ezcaLong: {
		  y4=(long *) calloc(n,sizeof(long));
		  d=ezcaGet(pv, catype, n, (void *)y4);
		  RowVector y(n);
		  for (i = 0; i < n; i++) {
		  	y(i) = (double) y4[i];
			}
		retval=y;
		free(y4);
		}
		break;
		
	case ezcaFloat: {
		  y5=(float *) calloc(n,sizeof(float));
		  d=ezcaGet(pv, catype, n, (void *)y5);
		  RowVector y(n);
		  for (i = 0; i < n; i++) {
		  	y(i) = (double) y5[i];
			}
		retval=y;
		free(y5);
		}
		break;
		
	case ezcaDouble: {
		y6=(double *) calloc(n,sizeof(double));
		d=ezcaGet(pv, catype, n, (void *)y6);
		RowVector y(n);
		for (i = 0; i < n; i++) {
		    y(i)=y6[i];
		    }
		retval=y;
		free(y6);
		}
		break;
	default:
		cout << "Unknown CA type" << endl;
		return(octave_value(-1));
		break;
	}
	if(d != 0) error("caget: Channel Access fault"); 
     return retval;
}

DEFUN_DLD(cagetnelem, args, ,
	  "cagetnelem('pvname'). Get number of values for PV 'name'.")
{
     char pv[255];
     int n,i,j;
     chid *ch;
     
     
     charMatrix c(args(0).string_value());
     
     n=args(0).length();
     for (i = 0; i < n; i++) {
     	pv[i]= c(i);
	}
     pv[n]=(char)NULL;
     ezcaGetNelem(pv, &n);
     return octave_value(n);
}

DEFUN_DLD(casetmonitor, args, ,
	  "casetmonitor('pvname'). Set a monitor on PV 'name'.")
{
     char pv[255];
     int n,i,j;
     chid *ch;
     
     
     charMatrix c(args(0).string_value());
     
     n=args(0).length();
     for (i = 0; i < n; i++) {
     	pv[i]= c(i);
	}
     pv[n]=(char)NULL;
     j=ezcaPvToChid(pv, &ch);
     n = Ca_types[ca_field_type(*ch)];
     ezcaSetMonitor(pv, (char)n);
     return octave_value(0);
}

DEFUN_DLD(caclrmonitor, args, ,
	  "caclrmonitor('pvname'). Clear a monitor on PV 'name'.")
{
     char pv[255];
     int n,i,j;
     chid *ch;
     
     
     charMatrix c(args(0).string_value());
     
     n=args(0).length();
     for (i = 0; i < n; i++) {
     	pv[i]= c(i);
	}
     pv[n]=(char)NULL;
     j=ezcaPvToChid(pv, &ch);
     n = Ca_types[ca_field_type(*ch)];
     ezcaClearMonitor(pv,(char)n);
     return octave_value(0);
}

DEFUN_DLD(canewmonval, args, ,
	  "canewmonval('pvname'). check for a new value of PV 'name'.\n If no monitors are set, always returns 1, i.e. new data available.")
{
     char pv[255];
     int n,i,j;
     chid *ch;
     octave_value retval;
     
     charMatrix c(args(0).string_value());
     
     n=args(0).length();
     for (i = 0; i < n; i++) {
     	pv[i]= c(i);
	}
     pv[n]=(char)NULL;
     j=ezcaPvToChid(pv, &ch);
     n = Ca_types[ca_field_type(*ch)];
     retval=ezcaNewMonitorValue(pv, (char)n);
     return retval;
}

Navigate by Date:
Prev: RE: vxStats Gurd, Pamela A.
Next: NTP time server problems liushu
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014 
Navigate by Thread:
Prev: Beam Extracted from SNS Ring Gurd, David P.
Next: NTP time server problems liushu
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·