Exemple #1
0
ec_master_t *ecrt_open_master(unsigned int master_index)
{
    char path[MAX_PATH_LEN];
    ec_master_t *master = NULL;
    ec_ioctl_module_t module_data;
    int ret;

    master = malloc(sizeof(ec_master_t));
    if (!master) {
        fprintf(stderr, "Failed to allocate memory.\n");
        return 0;
    }

    master->process_data = NULL;
    master->process_data_size = 0;
    master->first_domain = NULL;
    master->first_config = NULL;

    snprintf(path, MAX_PATH_LEN - 1,
#ifdef USE_RTDM
            "EtherCAT%u",
#else
            "/dev/EtherCAT%u",
#endif
            master_index);

#ifdef USE_RTDM
    master->fd = rt_dev_open(path, O_RDWR);
#else
    master->fd = open(path, O_RDWR);
#endif
    if (EC_IOCTL_IS_ERROR(master->fd)) {
        fprintf(stderr, "Failed to open %s: %s\n", path,
                strerror(EC_IOCTL_ERRNO(master->fd)));
        goto out_clear;
    }

    ret = ioctl(master->fd, EC_IOCTL_MODULE, &module_data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to get module information from %s: %s\n",
                path, strerror(EC_IOCTL_ERRNO(ret)));
        goto out_clear;
    }

    if (module_data.ioctl_version_magic != EC_IOCTL_VERSION_MAGIC) {
        fprintf(stderr, "ioctl() version magic is differing:"
                " %s: %u, libethercat: %u.\n",
                path, module_data.ioctl_version_magic,
                EC_IOCTL_VERSION_MAGIC);
        goto out_clear;
    }

    return master;

out_clear:
    ec_master_clear(master);
    free(master);
    return 0;
}
Exemple #2
0
///================================================= FUNCTION HEADER==================================================
/// Name        : Q8TimerStart
/// Input       : iCardNum     - PCI memory region that is mapped to Q8 card memory
/// Output      : None
/// Return      : None
/// Description : Deacctivates the timer to stop counting
///===================================================================================================================
void Q8TimerStop(int cardNum) {
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=41;
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #3
0
///============================================FUNCTION HEADER=========================================================
/// Name        : Q8WatchdogTimer
/// Input       : iCardNum  - PCI memory region that is mapped to Q8 card memory
///               fInterval - Timeout interval needed  analog output channnels to be set
/// Output      : None
/// Return      : None
/// Description : Configures  and enables Watchdog timer
///
///=====================================================================================================================
void Q8WatchdogTimer(int iCardNum,float fInterval) {
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=28;
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    q8Str.udwPeriod=(uint32_t)(fInterval/ 60e-9)-1;
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #4
0
void Q8EncoderReset(int   iCardNum,int iChannelNum) {
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    struct_Q8_Config q8Str;
    q8Str.iCardNum=iCardNum;
    q8Str.uiFuncIndex=iChannelNum+31;
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #5
0
///============================================== FUNCTION HEADER=======================================================
/// Name        : Q8EncoderInput
/// Input       : iCardNum    - PCI memory region that is mapped to Q8 card memory
///               iChannelNum - Encoder channel number
/// Output      : None
/// Return      : an int32_t value that is read
/// Description : Reads the specified channel of encoder.Actually the value read is the counter value of the specified
///               channel
///
///=====================================================================================================================
int32_t Q8EncoderInput(int iCardNum,int iChannelNum) {
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=iChannelNum+16;
    rt_dev_read(fd,&q8Str,sizeof(struct_Q8_Config));
    return q8Str.dwNvalue;
}
Exemple #6
0
///================================================= FUNCTION HEADER====================================================
/// Name        : Q8TimerSet
/// Input       : iCardNum     - PCI memory region that is mapped to Q8 card memory
///               fPeriod      - Timer set period in seconds
/// Output      : None
/// Return      : None
/// Description : Configures  32 bit counter as timer interrupt source
///
///=====================================================================================================================
void Q8TimerSet(int cardNum,float fPeriod) {
    struct_Q8_Config q8Str;
    q8Str.udwPeriod=(uint32_t)(fPeriod / 60e-9)-1;
    q8Str.uiFuncIndex=39;
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #7
0
///================================================= FUNCTION HEADER==================================================
/// Name        : Q8GetIrq
/// Input       : iCardNum     - PCI memory region that is mapped to Q8 card memory
/// Output      : None
/// Return      : Q8 IRQ Line number
/// Description : This function fetches irq line number assigned to Q8 card.
///===================================================================================================================
uint8_t Q8GetIrq(int cardNum) {

    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=42;
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    rt_dev_read(fd,&q8Str,sizeof(struct_Q8_Config));
    return q8Str.irq;
}
Exemple #8
0
///==========================================FUNCTION HEADER============================================================
/// Name        : Q8AnalogInput
/// Input       : iCardNum    - PCI memory region that is mapped to Q8 card memory
///               iCahnnelNum - D/A input channel number
/// Output      : None
/// Return      : None
/// Description : Reads the  voltage value from the specified channel.
///
///=====================================================================================================================
int16_t Q8AnalogInput(int iCardNum,int iChannelNum) {

    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    struct_Q8_Config q8Str;
    q8Str.iCardNum=iCardNum;
    q8Str.uiFuncIndex=iChannelNum+8;
    rt_dev_read(fd,&q8Str,sizeof(struct_Q8_Config));
    return q8Str.wValueSigned;
}
Exemple #9
0
///=============================================== FUNCTION HEADER =====================================================
/// Name        : Q8CounterOutput
/// Input       : iCardNum     - PCI memory region that is mapped to Q8 card memory
///               iClockSource - ClockSource selection,WATCHDOG or COUNTER
///               fPeriod      - Square wave period
///               iCntrlEn     - Not used
/// Output      : None
/// Return      : None
/// Description : Configures counter output and generates periodic square wave
///
///=====================================================================================================================
void Q8CounterOutput(int iCardNum,int iClockSource, float fPeriod,int iCntrlEn )
{
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=26;
    q8Str.iClockSource=iClockSource;
    q8Str.udwPeriod=(uint32_t)(fPeriod / 60e-9)-1;
    q8Str.iCntrlEn=iCntrlEn;
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #10
0
///=============================================== FUNCTION HEADER =====================================================
/// Name        : Q8PwmOutput
/// Input       : iCardNum     - PCI memory region that is mapped to Q8 card memory
///               iClockSource - ClockSource selection,WATCHDOG or COUNTER
///               fPeriod      - PWM period
///               iCntrlEn     - Not used
///               fPulseWidth  - PWM pulse width,0...100
/// Output      : None
/// Return      : None
/// Description : Configures counter output and generates PWM based periodic wave.
///
///=====================================================================================================================
void Q8PwmOutput(int iCardNum,int iClockSource, float fPeriod,float fPulseWidth,int iCntrlEn) {
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=27;
    q8Str.iClockSource=iClockSource;
    q8Str.udwLow=(uint32_t)( ((100-fPulseWidth)*fPeriod/100) / 30e-9) -1;
    q8Str.udwHigh=(uint32_t)( ((fPulseWidth)*fPeriod/100) / 30e-9)-1;
    q8Str.iCntrlEn=iCntrlEn;
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #11
0
/*!*****************************************************************************
 *******************************************************************************
\note  open_serial
\date  Oct 2000
   
\remarks 

        opens a specific serial port

 *******************************************************************************
 Function Parameters: [in]=input,[out]=output

 \param[in]     fname : name of serial port
 \param[in]     baud  : baudrate (choose from termios.h, e.g., B38400)
 \param[in]     mode  : O_RDONLY or O_RDWR

 return serial_fd, i.e., the file descriptor, or FALSE

 ******************************************************************************/
int
open_serial(char *fname, int baud, int mode)
{
  int serial_fd;
  struct rtser_config get_config;
  int rc;

  serial_fd = rt_dev_open( fname, mode  | O_NOCTTY | O_NDELAY );

  if (serial_fd < 0) {
    printf("Can't open serial port %s for mode %d (err=%d)\n",fname,mode,serial_fd);
    return FALSE;
  }

  // get settings of the serial port
  rc = rt_dev_ioctl(serial_fd, RTSER_RTIOC_GET_CONFIG, &get_config);
  if (rc) {
    printf("ERROR: cannot get RTSER_RTIOC_GET_CONFIG, status = %d, errno = %d, strerror = %s \n",
	   rc,errno,strerror(errno));
    return FALSE;
  }

  // set baud rate
  get_config.baud_rate = baud;

  // set parity and bits
  get_config.parity        = RTSER_NO_PARITY;
  get_config.data_bits     = RTSER_8_BITS;
  get_config.stop_bits     = RTSER_DEF_STOPB;
  get_config.rx_timeout    = 50*1000; // in ns
  get_config.tx_timeout    = 50*1000; // in ns
  get_config.event_timeout = 50*1000; // in ns
  get_config.event_mask    = RTSER_EVENT_RXPEND;

  get_config.config_mask = 
    RTSER_SET_BAUD | RTSER_SET_PARITY | RTSER_SET_DATA_BITS | RTSER_SET_STOP_BITS |
    RTSER_SET_TIMEOUT_RX | RTSER_SET_TIMEOUT_TX | RTSER_SET_TIMEOUT_EVENT | RTSER_SET_EVENT_MASK;

  // and update the serial line
  rc = rt_dev_ioctl(serial_fd, RTSER_RTIOC_SET_CONFIG, &get_config);
  if (rc) {
    printf("ERROR: cannot get RTSER_RTIOC_SET_CONFIG, status = %d, errno = %d, strerror = %s \n",
	   rc,errno,strerror(errno));
    return FALSE;
  }

  // clear the buffer
  clear_serial(serial_fd);

  return serial_fd;
  
}
Exemple #12
0
///================================================= FUNCTION HEADER====================================================
/// Name        : Q8AnalogConfig
/// Input       : iCardNum     - PCI memory region that is mapped to Q8 card memory
///               iChannelNum  - D/A Output channel number
///               iMode        - Output voltage range selection
/// Output      : None
/// Return      : None
/// Description : Configures  the specified analog output channel
///
///=====================================================================================================================
void    Q8AnalogConfig(int iCardNum,int iChannelNum,int iMode) {
//update process of configuration of analogoutput mode
    dacCon[iChannelNum]=iMode;
    struct_Q8_Config q8Str;
    q8Str.iCardNum=iCardNum;
    q8Str.uiFuncIndex=iChannelNum;
    q8Str.ubDacMode=iMode;
    q8Str.iChannelNum=iChannelNum;
    q8Str.uiFuncIndex=30;
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
Exemple #13
0
///============================================== FUNCTION HEADER=======================================================
/// Name        : Q8DigitalOutput
/// Input       : iCardNum        - PCI memory region that is mapped to Q8 card memory.
///               iPtrChannelNums - Array address.In this array numbers of channels written are defined and stored.
///               iArraySİze      - Array size.
/// Output      : None
/// Return      : None
/// Description : Configures  the specified channel(s) as output(s) and writes the specified channel(s)
///=====================================================================================================================
void  Q8DigitalOutput(int iCardNum,uint32_t channel,uint32_t data,int writeOnly) {
    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }


    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=24;
    q8Str.onlyDigitalData=writeOnly;
    q8Str.udwDataDirection=0;
    q8Str.udwDataDirection|=channel;
    q8Str.udwDataRegister=data;
    q8Str.iCardNum=iCardNum;

    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
}
int main(int argc, char *argv[])
{
	char buf[1024];
	ssize_t size;
	int device;
	int ret;

	/* open the device */
	device = rt_dev_open(DEVICE_NAME, 0);
	if (device < 0) {
		printf("ERROR : can't open device %s (%s)\n",
		       DEVICE_NAME, strerror(-device));
		fflush(stdout);
		exit(1);
	}

	/* first read */
	size = rt_dev_read (device, (void *)buf, 1024);
	printf("Read in device %s\t: %d bytes\n", DEVICE_NAME, size);

	/* first write */
	sprintf(buf, "HelloWorld!");
	size = rt_dev_write (device, (const void *)buf, strlen(buf) + 1);
	printf("Write from device %s\t: %d bytes\n", DEVICE_NAME, size);

	/* second read */
	size = rt_dev_read (device, (void *)buf, 1024);
	printf("Read in device %s\t: %s\n", DEVICE_NAME, buf);

	/* third read */
	size = rt_dev_read (device, (void *)buf, 1024);
	printf("Read in device %s\t: %d bytes\n", DEVICE_NAME, size);

	/* close the device */
	ret = rt_dev_close(device);
	if (ret < 0) {
		printf("ERROR : can't close device %s (%s)\n",
		       DEVICE_NAME, strerror(-ret));
		fflush(stdout);
		exit(1);
	}

	return 0;
}
Exemple #15
0
///================================================FUNCTION HEADER=====================================================
/// Name        : Q8EncoderConfig
/// Input       : iCardNum        - PCI memory region that is mapped to Q8 card memory
///               iChannelNum     - Encoder channel number
///               iCountMode      - Count mode to use
///               iBcd            - Bcd or binary counting
///               iQuadrature     - Quadrature  type selection
///               iIndexEn        - Enable or disable index feature
///               iIndexPol       - Select index polarity
/// Output      : None
/// Return      : None
/// Description : Configures  the encoder channel
///
///=====================================================================================================================
int Q8EncoderConfig(int iCardNum, int iChannelNum,int iCountMode,
                    int iBcd, int iQuadrature, int iIndexEn, int iIndexPol)
{
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=29;
    q8Str.iCardNum=iCardNum;
    q8Str.iChannelNum=iChannelNum;
    q8Str.ubEcountMode=iCountMode;
    q8Str.ubEbcdMode=iBcd;
    q8Str.ubEquadratureMode=iQuadrature;
    q8Str.ubIndexEnable=iIndexEn;
    q8Str.ubIndexPolarity=iIndexPol;
    if(fd < 0) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }
    rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));

    return fd;
}
Exemple #16
0
///================================================ FUNCTION HEADER======================================================
/// Name        : Q8DigitalInput
/// Input       : iCardNum        - PCI memory region that is mapped to Q8 card memory.
///               iPtrChannelNums - Array address.In this array numbers of channels read are defined and stored.
///               iArraySİze      - Array size.
/// Output      : None
/// Return      : an unint32_t value
/// Description : Configures  the specified channel(s) as input(s) and reads the specified channel(s)
///
///=====================================================================================================================
uint32_t  Q8DigitalInput(int iCardNum,uint32_t channel,int readonly) {


    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }

    uint32_t udwDigitalRead=0;
    struct_Q8_Config q8Str;
    q8Str.uiFuncIndex=25;
    q8Str.onlyDigitalData=readonly;
    q8Str.udwDataDirection=0xFFFFFFFF;
    q8Str.udwDataDirection&=channel;
    q8Str.iCardNum=iCardNum;
    int i;
    uint32_t udwDataBuffer;
    uint32_t udwDataReg;
    rt_dev_read(fd,&q8Str,sizeof(struct_Q8_Config));
    return q8Str.udwDataRegister;
}
Exemple #17
0
///============================================ FUNCTION HEADER=========================================================
/// Name        : Q8AnalogOutput
/// Input       : iCardNum    - PCI memory region that is mapped to Q8 card memory
///               iChannelNum - D/A Output channel number
///               fValue      - User defined voltage which is wanted to see at output of the specified channel
/// Output      : None
/// Return      : None
/// Description : Writes user defined voltage value to the specified channel.
///
///=====================================================================================================================
void Q8AnalogOutput(int iCardNum,int iChannelNum,real_T dacValue) {

    if(fd==-1) {
        fd = rt_dev_open(DEV_NAME, O_RDWR);
    }

    struct_Q8_Config q8Str;
    q8Str.iCardNum=iCardNum;
    q8Str.uiFuncIndex=iChannelNum;

    if (dacValue <=0) {
        if(dacCon[iChannelNum]==BIPOLAR_10V) {
            q8Str.uwValueUnsigned=(DAC_BIPOLAR_ZERO-(uint16_t)((-dacValue)*4096/20));
            rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
            return;
        }
        else if(dacCon[iChannelNum]==BIPOLAR_5V) {
            q8Str.uwValueUnsigned=(DAC_BIPOLAR_ZERO-(uint16_t)((-dacValue)*4096/10));
            rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
            return;
        }
        else
            return;
    }//if

    if(dacCon[iChannelNum]==BIPOLAR_10V) {
        q8Str.uwValueUnsigned=(DAC_BIPOLAR_ZERO+(uint16_t)(dacValue*4096/20));
        rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
        return;
    }
    else if(dacCon[iChannelNum]==BIPOLAR_5V) {
        q8Str.uwValueUnsigned=(DAC_BIPOLAR_ZERO+(uint16_t)(dacValue*4096/10));
        rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
        return;
    }
    else if(dacCon[iChannelNum]==UNIPOLAR_10V) {
        q8Str.uwValueUnsigned=(uint16_t)(dacValue*4096/10);
        rt_dev_write(fd,&q8Str,sizeof(struct_Q8_Config));
        return;
    }
} // end of function
int main (int argc, char * argv[])
{
	int fd;
	int i;

	if (argc < 2) {
		fprintf(stderr, "usage: %s rtdm_device\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	
	fd = rt_dev_open(argv[1], O_WRONLY);
	if (fd < 0) {
		fprintf(stderr, "%s: %s\n", argv[1], strerror(-fd));
		exit(EXIT_FAILURE);
	}
	
	for (i = 2; i < argc; i ++)
		rt_dev_write(fd, argv[i], strlen(argv[i]));
		
	rt_dev_close(fd);
	exit(EXIT_SUCCESS);
}
Exemple #19
0
/**
 * This function is called when the control program is loaded to zenom.
 * Use this function to register control parameters, to register log variables
 * and to initialize control parameters.
 *
 * @return Return non-zero to indicate an error.
 */
int ZenomMatlab::initialize()
{
    
    int paramIdx, sigIdx;
    int nBlockParams, nSignals;
    const char* status;
    
    // İsmi gözükmeyen parametrelerin sayısını tutar.
    unknown_param_counter = 0;

    /* Here is where Q8 dirver is  loaded to kernel space */
     
    //system(STR(sudo insmod DQ8));
    fd = rt_dev_open(DEV_NAME, O_RDWR);

    if(fd < 0)
        fprintf(stderr, "target:Q8 device open error!\n");
    
    
    init_xenomai();

    rtM = MODEL();

    if (rtmGetErrorStatus(rtM) != NULL) {
        (void)fprintf(stderr,"Error during model registration: %s\n",
                      rtmGetErrorStatus(rtM));
        exit(EXIT_FAILURE);
    }
    
    MdlInitializeSizes();
    MdlInitializeSampleTimes();

    status = rt_SimInitTimingEngine(rtmGetNumSampleTimes(rtM),
                                    rtmGetStepSize(rtM),
                                    rtmGetSampleTimePtr(rtM),
                                    rtmGetOffsetTimePtr(rtM),
                                    rtmGetSampleHitPtr(rtM),
                                    rtmGetSampleTimeTaskIDPtr(rtM),
                                    rtmGetTStart(rtM),
                                    &rtmGetSimTimeStep(rtM),
                                    &rtmGetTimingData(rtM));


    if (status != NULL) {
        (void)fprintf(stderr, "Failed to initialize sample time engine: %s\n", status);
        exit(EXIT_FAILURE);
    }

    rt_CreateIntegrationData(rtM);

    mmi = &(rtmGetDataMapInfo(rtM).mmi);

    if (mmi!=NULL){
        //exception here 
    }    

    bp = rtwCAPI_GetBlockParameters(mmi);
    sig = rtwCAPI_GetSignals(mmi);

    nBlockParams = rtwCAPI_GetNumBlockParameters(mmi);
    nSignals = rtwCAPI_GetNumSignals(mmi);

    xrtpi = new XrtTargetParamInfo[nBlockParams];
    xtsi = new XrtTargetSignalInfo[nSignals];

    /** Get parameter and register */      
    
    Xrt_GetParameterInfo(mmi);
    Xrt_GetSignalInfo(mmi);

    /**************** ZENOM PART  ***************/
    
    for(paramIdx = 0; paramIdx < rtwCAPI_GetNumBlockParameters(mmi); paramIdx++){
        
        std::string paramName(xrtpi[paramIdx].paramName);
        std::string blockName(xrtpi[paramIdx].blockName);

        if(paramName.empty()){
            paramName = std::string("unknownBlock");
        }
            

        for (std::size_t found = paramName.find_first_of(" "); 
            found != std::string::npos ; 
            found = paramName.find_first_of(" "))
        {
            paramName.erase (found);
        }

        for (std::size_t found = blockName.find_first_of(" "); 
            found != std::string::npos ; 
            found = blockName.find_first_of(" "))
        {
            blockName.erase (found);
        }

        paramName = blockName + "-" + paramName;
        
        registerControlVariable( xrtpi[paramIdx].dataValue, 
                                 paramName, 
                                 xrtpi[paramIdx].numRows, 
                                 xrtpi[paramIdx].numColumns );
    }

    for (sigIdx = 0; sigIdx < rtwCAPI_GetNumSignals(mmi); ++sigIdx){

        std::string sigName(xtsi[sigIdx].signalName);  

        if(sigName.empty()){
            sigName = std::string("unknownSignal");
            sigName += unknown_param_counter;
        }

        for (std::size_t found = sigName.find_first_of(" "); 
            found != std::string::npos ; 
            found = sigName.find_first_of(" "))
        {
            sigName.erase (found);
        }

        registerLogVariable(xtsi[sigIdx].dataValue,
                        sigName,
                        xtsi[sigIdx].numRows,
                        xtsi[sigIdx].numColumns);
    }

    setFrequency( (double)rtmGetStepSize(rtM) );
    setDuration ( (double)rtmGetTFinal(rtM) );

    fprintf(stderr, "init done!");
    
    return 0;
}
Exemple #20
0
static int __init klat_mod_init(void)
{
	char devname[RTDM_MAX_DEVNAME_LEN + 1];
	unsigned dev_nr;
	int err;

	err = rt_pipe_create(&klat_pipe, "klat_pipe", pipe, 4096);
	if (err) {
		printk("rt_pipe_create(klat_pipe): %d\n", err);
		return err;
	}

	err = rt_task_create(&klat_srvr, "klat_srvr", 0, 0, 0);
	if (err) {
		printk("rt_task_create(klat_srvr): %d\n", err);
		goto err_close_pipe;
	}

	pkt.config.mode = mode;
	pkt.config.priority = priority;
	pkt.config.period = period * 1000;
	pkt.config.warmup_loops = 1;
	pkt.config.histogram_size = 0;
	pkt.config.freeze_max = freeze_max;

	for (dev_nr = 0; dev_nr < DEV_NR_MAX; dev_nr++) {
		snprintf(devname, sizeof(devname),
			 "rttest-timerbench%d",
			 dev_nr);
		fd = rt_dev_open(devname, O_RDONLY);
		if (fd < 0)
			continue;

		err = rt_dev_ioctl(fd, RTTST_RTIOC_TMBENCH_START, &pkt.config);
		if (err == -ENOTTY) {
			rt_dev_close(fd);
			continue;
		}

		if (err < 0) {
			printk("rt_dev_ioctl(RTTST_RTIOC_TMBENCH_START): %d\n",
			       err);
			goto err_destroy_task;
		}

		break;
	}
	if (fd < 0) {
		printk("rt_dev_open: could not find rttest device\n"
		       "(modprobe timerbench?)");
		err = fd;
		goto err_destroy_task;
	}

	err = rt_task_start(&klat_srvr, &klat_server, NULL);
	if (err) {
		printk("rt_task_start: %d\n", err);
		goto err_close_dev;
	}

	return 0;

  err_close_dev:
	rt_dev_close(fd);
  err_destroy_task:
	rt_task_delete(&klat_srvr);
  err_close_pipe:
	rt_pipe_delete(&klat_pipe);
	return err;
}
Exemple #21
0
TPCANStatus __stdcall CAN_Initialize(TPCANHandle Channel,
		TPCANBaudrate Btr0Btr1, TPCANType HwType, DWORD IOPort, WORD Interrupt) {

	PCAN_DESCRIPTOR *desc = NULL;
	errno = 0;
	TPCANStatus Result = PCAN_ERROR_OK;

	try {

		// logging
		char szLog[MAX_LOG];
		LOG_EnteringTo("CAN_Initialize");
		sprintf(
				szLog,
				"Channel: 0x%02X, Btr0Btr1: %d, HwType: 0x%08X, IOPort: 0x%08X, Interrupt: 0x%08X",
				Channel, Btr0Btr1, IOPort, HwType, Interrupt);
		LOG_Parameters("CAN_Initialize", szLog);

		// device name and falgs
		char *szDeviceName = CAN_Get_Device_Name(Channel, HwType, IOPort,
				IOPort);
		int nFlag = O_RDWR | O_NONBLOCK;

		// allocate for descriptors
		if (ppDescriptors == NULL) {
			if ((ppDescriptors = (PCAN_DESCRIPTOR **) malloc(
					sizeof(PCAN_DESCRIPTOR *) * 0x100)) == NULL) {
				Result = PCAN_ERROR_RESOURCE;
				goto fail;
			}
			memset(ppDescriptors, 0, sizeof(PCAN_DESCRIPTOR *) * 0x100);
		}

		// check if descriptor allready existing
		desc = ppDescriptors[Channel];
		if (ppDescriptors[Channel] != NULL) {
			Result = PCAN_ERROR_INITIALIZE;
			goto fail;
		}

		// create desciptor
		if ((ppDescriptors[Channel] = (PCAN_DESCRIPTOR *) malloc(
				sizeof(PCAN_DESCRIPTOR))) == NULL) {
			Result = PCAN_ERROR_RESOURCE;
			goto fail;
		}

		// fill descriptor
		desc = ppDescriptors[Channel];
		desc->szDevicePath[0] = 0;
		desc->nFileNo = -1;
		desc->nFilter = PCAN_FILTER_OPEN;
		desc->nListenOnly = 0;
		desc->Btr0Btr1 = Btr0Btr1;
		strncpy(desc->szDevicePath, szDeviceName, LOCAL_STRING_LEN);

#ifndef NO_RT
		char DeviceName[256];
		sscanf(szDeviceName, "/dev/%s", DeviceName);
		if ((desc->nFileNo = rt_dev_open(DeviceName, nFlag)) == -1)
#else
		if ((desc->nFileNo = open(szDeviceName, nFlag)) == -1)
#endif
		{
			Result = PCAN_ERROR_NODRIVER;
			goto fail;
		}

		// initialize
		TPCANInit init;
		init.wBTR0BTR1 = desc->Btr0Btr1; // combined BTR0 and BTR1 register of the SJA100
		init.ucCANMsgType = MSGTYPE_EXTENDED; // 11 or 29 bits
		init.ucListenOnly = desc->nListenOnly; // listen only mode when != 0
		if (__ioctl(desc->nFileNo, PCAN_INIT, &init) < 0) {
			Result = PCAN_ERROR_NODRIVER;
			goto fail;
		}
		goto leave;

		// error handling
		fail: if (desc) {
			if (desc->nFileNo > -1)
				__close(desc->nFileNo);
			free(desc);
			ppDescriptors[Channel] = NULL;
		}

		leave: LOG_LeavingFrom("CAN_Initialize", Result);
		return Result;
	} catch (...) {
		Result = PCAN_ERROR_UNKNOWN;
		LOG_Exception("CAN_Initialize");
	}
	return Result;

}
int main (int ac, char **av)
{
    int err;
    char *cp, *progname = (char*)basename(av[0]), *rtdm_driver;
    struct sched_param param_square = {.sched_priority = 99 };
    struct sched_param param_irq = {.sched_priority = 98 };
    pthread_attr_t thattr_square, thattr_irq;

    period_ns = PERIOD; /* ns */

    signal(SIGINT, cleanup_upon_sig);
    signal(SIGTERM, cleanup_upon_sig);
    signal(SIGHUP, cleanup_upon_sig);
    signal(SIGALRM, cleanup_upon_sig);

    while (--ac) {
        if ((cp = *++av) == NULL)
            break;
        if (*cp == '-' && *++cp) {
            switch(*cp) {
            case 'p' :
                period_ns = (unsigned long)atoi(*++av);
                break;

            case 'r' :
                rtdm_driver = *++av;
                break;

            default:
                usage(progname);
                break;
            }
        }
        else
            break;
    }

    // Display every 2 sec
    loop_prt = 2000000000 / period_ns;

    printf ("Using driver \"%s\" and period %d ns\n", rtdm_driver, period_ns);

    // Avoid paging: MANDATORY for RT !!
    mlockall(MCL_CURRENT|MCL_FUTURE);

    // Init rt_printf() system
    rt_print_auto_init(1);

    // Open RTDM driver
    if ((fd = rt_dev_open(rtdm_driver, 0)) < 0) {
        perror("rt_open");
        exit(EXIT_FAILURE);
    }

    // Thread attributes
    pthread_attr_init(&thattr_square);

    // Joinable
    pthread_attr_setdetachstate(&thattr_square, PTHREAD_CREATE_JOINABLE);

    // Priority, set priority to 99
    pthread_attr_setinheritsched(&thattr_square, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&thattr_square, SCHED_FIFO);
    pthread_attr_setschedparam(&thattr_square, &param_square);

    // Create thread(s)
    err = pthread_create(&thid_square, &thattr_square, &thread_square, NULL);

    if (err)
    {
        fprintf(stderr,"square: failed to create square thread, code %d\n",err);
        return 0;
    }

    // Thread attributes
    pthread_attr_init(&thattr_irq);

    // Priority, set priority to 98
    pthread_attr_setinheritsched(&thattr_irq, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&thattr_irq, SCHED_FIFO);
    pthread_attr_setschedparam(&thattr_irq, &param_irq);

    err = pthread_create(&thid_irq, &thattr_irq, &thread_irq, NULL);

    if (err)
    {
        fprintf(stderr,"square: failed to create IRQ thread, code %d\n",err);
        return 0;
    }

    pause();

    return 0;
}
Exemple #23
0
int main(int argc, char **argv)
{
	int cpu = 0, c, err, sig;
	struct sigaction sa;
	char task_name[16];
	sigset_t mask;

	while ((c = getopt(argc, argv, "g:hp:l:T:qH:B:sD:t:fc:P:b")) != EOF)
		switch (c) {
		case 'g':
			do_gnuplot = strdup(optarg);
			break;

		case 'h':

			do_histogram = 1;
			break;

		case 's':

			do_stats = 1;
			break;

		case 'H':

			histogram_size = atoi(optarg);
			break;

		case 'B':

			bucketsize = atoi(optarg);
			break;

		case 'p':

			period_ns = atoi(optarg) * 1000LL;
			break;

		case 'l':

			data_lines = atoi(optarg);
			break;

		case 'T':

			test_duration = atoi(optarg);
			alarm(test_duration + WARMUP_TIME);
			break;

		case 'q':

			quiet = 1;
			break;

		case 'D':

			benchdev_no = atoi(optarg);
			break;

		case 't':

			test_mode = atoi(optarg);
			break;

		case 'f':

			freeze_max = 1;
			break;

		case 'c':
			cpu = T_CPU(atoi(optarg));
			break;

		case 'P':
			priority = atoi(optarg);
			break;

		case 'b':
			stop_upon_switch = 1;
			break;

		default:

			fprintf(stderr,
"usage: latency [options]\n"
"  [-h]                         # print histograms of min, avg, max latencies\n"
"  [-g <file>]                  # dump histogram to <file> in gnuplot format\n"
"  [-s]                         # print statistics of min, avg, max latencies\n"
"  [-H <histogram-size>]        # default = 200, increase if your last bucket is full\n"
"  [-B <bucket-size>]           # default = 1000ns, decrease for more resolution\n"
"  [-p <period_us>]             # sampling period\n"
"  [-l <data-lines per header>] # default=21, 0 to supress headers\n"
"  [-T <test_duration_seconds>] # default=0, so ^C to end\n"
"  [-q]                         # supresses RTD, RTH lines if -T is used\n"
"  [-D <testing_device_no>]     # number of testing device, default=0\n"
"  [-t <test_mode>]             # 0=user task (default), 1=kernel task, 2=timer IRQ\n"
"  [-f]                         # freeze trace for each new max latency\n"
"  [-c <cpu>]                   # pin measuring task down to given CPU\n"
"  [-P <priority>]              # task priority (test mode 0 and 1 only)\n"
"  [-b]                         # break upon mode switch\n"
);
			exit(2);
		}

	if (!test_duration && quiet) {
		fprintf(stderr,
			"latency: -q only works if -T has been given.\n");
		quiet = 0;
	}

	if ((test_mode < USER_TASK) || (test_mode > TIMER_HANDLER)) {
		fprintf(stderr, "latency: invalid test mode.\n");
		exit(2);
	}

	time(&test_start);

	histogram_avg = calloc(histogram_size, sizeof(long));
	histogram_max = calloc(histogram_size, sizeof(long));
	histogram_min = calloc(histogram_size, sizeof(long));

	if (!(histogram_avg && histogram_max && histogram_min))
		cleanup();

	if (period_ns == 0)
		period_ns = CONFIG_XENO_DEFAULT_PERIOD;	/* ns */

	if (priority <= T_LOPRIO)
		priority = T_LOPRIO + 1;
	else if (priority > T_HIPRIO)
		priority = T_HIPRIO;

	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGTERM);
	sigaddset(&mask, SIGHUP);
	sigaddset(&mask, SIGALRM);
	pthread_sigmask(SIG_BLOCK, &mask, NULL);

	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = sigdebug;
	sa.sa_flags = SA_SIGINFO;
	sigaction(SIGDEBUG, &sa, NULL);

	if (freeze_max) {
		/* If something goes wrong, we want to freeze the current
		   trace path to help debugging. */
		signal(SIGSEGV, faulthand);
		signal(SIGBUS, faulthand);
	}

	setlinebuf(stdout);

	printf("== Sampling period: %Ld us\n"
	       "== Test mode: %s\n"
	       "== All results in microseconds\n",
	       period_ns / 1000, test_mode_names[test_mode]);

	mlockall(MCL_CURRENT | MCL_FUTURE);

	if (test_mode != USER_TASK) {
		char devname[RTDM_MAX_DEVNAME_LEN];

		snprintf(devname, RTDM_MAX_DEVNAME_LEN, "rttest-timerbench%d",
			 benchdev_no);
		benchdev = rt_dev_open(devname, O_RDWR);

		if (benchdev < 0) {
			fprintf(stderr,
				"latency: failed to open benchmark device, code %d\n"
				"(modprobe RTAI_timerbench?)\n", benchdev);
			return 0;
		}
	}

	rt_timer_set_mode(TM_ONESHOT);	/* Force aperiodic timing. */

	snprintf(task_name, sizeof(task_name), "display-%d", getpid());
	err = rt_task_create(&display_task, task_name, 0, 0, T_FPU);

	if (err) {
		fprintf(stderr,
			"latency: failed to create display task, code %d\n",
			err);
		return 0;
	}

	err = rt_task_start(&display_task, &display, NULL);

	if (err) {
		fprintf(stderr,
			"latency: failed to start display task, code %d\n",
			err);
		return 0;
	}

	if (test_mode == USER_TASK) {
		snprintf(task_name, sizeof(task_name), "sampling-%d", getpid());
		err =
		    rt_task_create(&latency_task, task_name, 0, priority,
				   T_FPU | cpu | T_WARNSW);

		if (err) {
			fprintf(stderr,
				"latency: failed to create latency task, code %d\n",
				err);
			return 0;
		}

		err = rt_task_start(&latency_task, &latency, NULL);

		if (err) {
			fprintf(stderr,
				"latency: failed to start latency task, code %d\n",
				err);
			return 0;
		}
	}

	sigwait(&mask, &sig);
	finished = 1;

	cleanup();

	return 0;
}
static void sync_task_func(void *arg)
{
    int             ret;
    rtdm_lockctx_t  lock_ctx;
    nanosecs_abs_t  timestamp;
    nanosecs_abs_t  timestamp_master;
    rtser_event_t   ser_rx_event;

    can_frame_t can_frame = {
        .can_id = clock_sync_can_id,
        .can_dlc = sizeof(timestamp),
    };
    struct iovec iov = {
        .iov_base = &can_frame,
        .iov_len = sizeof(can_frame_t),
    };
    struct msghdr msg = {
        .msg_name = NULL,
        .msg_namelen = 0,
        .msg_iov = &iov,
        .msg_iovlen = 1,
        .msg_control = NULL,
        .msg_controllen = 0,
    };

    if (clock_sync_mode == SYNC_CAN_SLAVE) {
        msg.msg_control = &timestamp;
        msg.msg_controllen = sizeof(timestamp);
    }

    while (1) {
        switch (clock_sync_mode) {
            case SYNC_SER_MASTER:
                timestamp = cpu_to_be64(rtdm_clock_read());

                ret = sync_dev_ctx->ops->write_rt(sync_dev_ctx, NULL,
                    &timestamp, sizeof(timestamp));
                if (ret != sizeof(timestamp)) {
                    tims_error("[CLOCK SYNC]: can't write serial time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                rtdm_task_wait_period();
                break;

            case SYNC_SER_SLAVE:
                ret = sync_dev_ctx->ops->ioctl_rt(sync_dev_ctx, NULL,
                    RTSER_RTIOC_WAIT_EVENT, &ser_rx_event);
                if (ret < 0) {
                    tims_error("[CLOCK SYNC]: can't read serial time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                ret = sync_dev_ctx->ops->read_rt(sync_dev_ctx, NULL,
                    &timestamp_master, sizeof(timestamp_master));
                if (ret != sizeof(timestamp_master)) {
                    tims_error("[CLOCK SYNC]: can't read serial time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                timestamp_master = be64_to_cpu(timestamp_master);

                rtdm_lock_get_irqsave(&sync_lock, lock_ctx);
                clock_offset =
                    timestamp_master - ser_rx_event.rxpend_timestamp;
                rtdm_lock_put_irqrestore(&sync_lock, lock_ctx);
                break;

            case SYNC_CAN_MASTER:
                // workaround for kernel working on user data
                iov.iov_len = sizeof(can_frame_t);
                iov.iov_base = &can_frame;
                // workaround end
                *(nanosecs_abs_t *)can_frame.data =
                    cpu_to_be64(rtdm_clock_read());

                ret = sync_dev_ctx->ops->sendmsg_rt(sync_dev_ctx, NULL,
                                                    &msg, 0);
                if (ret < 0) {
                    tims_error("[CLOCK SYNC]: can't send CAN time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                rtdm_task_wait_period();
                break;

            case SYNC_CAN_SLAVE:
                // workaround for kernel working on user data
                iov.iov_len = sizeof(can_frame_t);
                iov.iov_base = &can_frame;
                // workaround end

                ret = sync_dev_ctx->ops->recvmsg_rt(sync_dev_ctx, NULL,
                                                    &msg, 0);
                if (ret < 0) {
                    tims_error("[CLOCK SYNC]: can't receive CAN time stamp, "
                               "code = %d\n", ret);
                    return;
                }

                timestamp_master =
                    be64_to_cpu(*(nanosecs_abs_t *)can_frame.data);

                rtdm_lock_get_irqsave(&sync_lock, lock_ctx);
                clock_offset = timestamp_master - timestamp;
                rtdm_lock_put_irqrestore(&sync_lock, lock_ctx);
                break;
        }
    }

 exit_task:
    rtdm_context_unlock(sync_dev_ctx);
}


static __initdata char *mode_str[] = {
    "Local Clock", "RTnet", "CAN Master", "CAN Slave",
    "Serial Master", "Serial Slave"
};

static __initdata struct rtser_config sync_serial_config = {
    .config_mask        = RTSER_SET_BAUD | RTSER_SET_FIFO_DEPTH |
                          RTSER_SET_TIMESTAMP_HISTORY | RTSER_SET_EVENT_MASK,
    .baud_rate          = 115200,
    .fifo_depth         = RTSER_FIFO_DEPTH_8,
    .timestamp_history  = RTSER_RX_TIMESTAMP_HISTORY,
    .event_mask         = RTSER_EVENT_RXPEND,
};

int __init tims_clock_init(void)
{
    struct can_filter   filter;
    int                 nr_filters = 1;
    struct ifreq        can_ifr;
    struct sockaddr_can can_addr;
    int                 ret;

    if (clock_sync_mode < SYNC_NONE || clock_sync_mode > SYNC_SER_SLAVE) {
        tims_error("invalid clock_sync_mode %d", clock_sync_mode);
        return -EINVAL;
    }

    printk("TIMS: clock sync mode is %s\n", mode_str[clock_sync_mode]);
    printk("TIMS: clock sync dev is %s\n", clock_sync_dev);

    rtdm_lock_init(&sync_lock);

    switch(clock_sync_mode) {
        case SYNC_NONE:
            return 0;

        case SYNC_RTNET:
            sync_dev_fd = rt_dev_open(clock_sync_dev, O_RDONLY);
            if (sync_dev_fd < 0)
                goto sync_dev_error;
            set_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags);
            break;

        case SYNC_CAN_MASTER:
        case SYNC_CAN_SLAVE:
            sync_dev_fd = rt_dev_socket(PF_CAN, SOCK_RAW, 0);
            if (sync_dev_fd < 0) {
                tims_error("[CLOCK SYNC]: error opening CAN socket: %d\n",
                           sync_dev_fd);
                return sync_dev_fd;
            }
            set_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags);

            strcpy(can_ifr.ifr_name, clock_sync_dev);
            ret = rt_dev_ioctl(sync_dev_fd, SIOCGIFINDEX, &can_ifr);
            if (ret) {
                tims_info("[CLOCK SYNC]: error resolving CAN interface: %d\n",
                          ret);
                return ret;
            }

            if (clock_sync_mode == SYNC_CAN_MASTER)
                nr_filters = 0;
            else {
                filter.can_id   = clock_sync_can_id;
                filter.can_mask = 0xFFFFFFFF;
            }

            ret = rt_dev_setsockopt(sync_dev_fd, SOL_CAN_RAW, CAN_RAW_FILTER,
                                    &filter, nr_filters*sizeof(can_filter_t));
            if (ret < 0)
                goto config_error;

            /* Bind socket to default CAN ID */
            can_addr.can_family  = AF_CAN;
            can_addr.can_ifindex = can_ifr.ifr_ifindex;

            ret = rt_dev_bind(sync_dev_fd, (struct sockaddr *)&can_addr,
                              sizeof(can_addr));
            if (ret < 0)
                goto config_error;

            /* Enable timestamps for incoming packets */
            ret = rt_dev_ioctl(sync_dev_fd, RTCAN_RTIOC_TAKE_TIMESTAMP,
                               RTCAN_TAKE_TIMESTAMPS);
            if (ret < 0)
                goto config_error;

            /* Calculate transmission delay */
            ret = rt_dev_ioctl(sync_dev_fd, SIOCGCANBAUDRATE, &can_ifr);
            if (ret < 0)
                goto config_error;

            /* (47+64 bit) * 1.000.000.000 (ns/sec) / baudrate (bit/s) */
            sync_delay = 1000 * (111000000 / can_ifr.ifr_ifru.ifru_ivalue);
            break;

        case SYNC_SER_MASTER:
        case SYNC_SER_SLAVE:
            sync_dev_fd = rt_dev_open(clock_sync_dev, O_RDWR);
            if (sync_dev_fd < 0)
                goto sync_dev_error;
            set_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags);

            ret = rt_dev_ioctl(sync_dev_fd, RTSER_RTIOC_SET_CONFIG,
                               &sync_serial_config);
            if (ret < 0)
                goto config_error;

            /* (80 bit) * 1.000.000.000 (ns/sec) / baudrate (bit/s) */
            sync_delay = 1000 * (80000000 / sync_serial_config.baud_rate);
            break;
    }

    sync_dev_ctx = rtdm_context_get(sync_dev_fd);

    if (clock_sync_mode != SYNC_RTNET) {
        ret = rtdm_task_init(&sync_task, "TIMSClockSync", sync_task_func,
                             NULL, CLOCK_SYNC_PRIORITY, CLOCK_SYNC_PERIOD);
        if (ret < 0)
            return ret;
        set_bit(TIMS_INIT_BIT_SYNC_TASK, &init_flags);
    }

    return 0;

 sync_dev_error:
    tims_error("[CLOCK SYNC]: cannot open %s\n", clock_sync_dev);
    return sync_dev_fd;

 config_error:
    tims_info("[CLOCK SYNC]: error configuring sync device: %d\n", ret);
    return ret;
}


void tims_clock_cleanup(void)
{
    if (test_and_clear_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags))
        rt_dev_close(sync_dev_fd);

    if (test_and_clear_bit(TIMS_INIT_BIT_SYNC_TASK, &init_flags))
        rtdm_task_join_nrt(&sync_task, 100);
}