Argonne National Laboratory

Experimental Physics and
Industrial Control System

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

Subject: Problem compiling EPICS ioc with libusb
From: Sam de Jong <srdejong@uvic.ca>
To: tech-talk@aps.anl.gov
Date: Thu, 22 Jun 2017 16:16:47 -0700

Hello EPICS tech-talk,

    I am trying to compile an EPICS IOC with libusb included (I am on a linux platform running ubuntu 14.04 and EPICS base 3.14-3.14.12.3 ).

    I created the ioc using

    makeBaseApp.pl -t example test   
    makeBaseApp.pl -t example -i -a linux-x86_64 test

and was able to run make with no issues.

I added the header files for a class I created which interfaces with a usb device (these are included in this email) by adding this line to /testAPP/src/testMain.cpp:

    #include "DI-2108-P.cpp"

when I try to make, I get this output:

make -C ./configure install
make[1]: Entering directory `/media/Extra_Space/work/testIOC/configure'
make -C O.linux-x86_64 -f ../Makefile TOP=../.. T_A=linux-x86_64 install
make[2]: Entering directory `/media/Extra_Space/work/testIOC/configure/O.linux-x86_64'
perl ../../../epics/epics3.14-3.14.12.3/bin/linux-x86_64/convertRelease.pl checkRelease
make[2]: Leaving directory `/media/Extra_Space/work/testIOC/configure/O.linux-x86_64'
make[1]: Leaving directory `/media/Extra_Space/work/testIOC/configure'
make -C ./testApp install
make[1]: Entering directory `/media/Extra_Space/work/testIOC/testApp'
make -C ./src install
make[2]: Entering directory `/media/Extra_Space/work/testIOC/testApp/src'
make -C O.linux-x86_64 -f ../Makefile TOP=../../.. T_A=linux-x86_64 install
make[3]: Entering directory `/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64'

/usr/bin/g++ -c  -D_POSIX_C_SOURCE=199506L -D_POSIX_THREADS -D_XOPEN_SOURCE=500           -D_X86_64_  -DUNIX  -D_BSD_SOURCE -Dlinux  -D_REENTRANT   -O3 -g   -Wall      -m64      -MMD -I. -I../O.Common -I. -I.. -I../../../include/os/Linux -I../../../include -I../../../../epics/epics3.14-3.14.12.3/include/os/Linux -I../../../../epics/epics3.14-3.14.12.3/include       ../testMain.cpp
In file included from ../testMain.cpp:14:0:
../DI-2108-P.cpp: In member function ‘std::vector<double> DI_2108_P::getReadings()’:
../DI-2108-P.cpp:202:7: warning: variable ‘r’ set but not used [-Wunused-but-set-variable]
   int r; //for return values
       ^
/usr/bin/g++ -o test  -L/media/Extra_Space/work/epics/epics3.14-3.14.12.3/lib/linux-x86_64 -L/media/Extra_Space/work/testIOC/lib/linux-x86_64        -m64              test_registerRecordDeviceDriver.o testMain.o    -ltestSupport -lrecIoc -lsoftDevIoc -lmiscIoc -lrsrvIoc -ldbtoolsIoc -lasIoc -ldbIoc -lregistryIoc -ldbStaticIoc -lca -lCom  
testMain.o: In function `DI_2108_P::Initialize()':
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:37: undefined reference to `libusb_init'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:42: undefined reference to `libusb_set_debug'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:44: undefined reference to `libusb_get_device_list'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:51: undefined reference to `libusb_open_device_with_vid_pid'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:56: undefined reference to `libusb_free_device_list'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:58: undefined reference to `libusb_kernel_driver_active'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:63: undefined reference to `libusb_claim_interface'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:60: undefined reference to `libusb_detach_kernel_driver'
testMain.o: In function `DI_2108_P::close()':
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:82: undefined reference to `libusb_release_interface'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:89: undefined reference to `libusb_close'
testMain.o: In function `DI_2108_P::sendMessage(std::string)':
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:114: undefined reference to `libusb_bulk_transfer'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:118: undefined reference to `libusb_bulk_transfer'
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:120: undefined reference to `libusb_strerror'
testMain.o: In function `DI_2108_P::getReadings()':
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:208: undefined reference to `libusb_bulk_transfer'
testMain.o: In function `DI_2108_P::reset()':
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:74: undefined reference to `libusb_reset_device'
testMain.o: In function `DI_2108_P::close()':
/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64/../DI-2108-P.cpp:90: undefined reference to `libusb_exit'
collect2: error: ld returned 1 exit status
make[3]: *** [test] Error 1
make[3]: Leaving directory `/media/Extra_Space/work/testIOC/testApp/src/O.linux-x86_64'
make[2]: *** [install.linux-x86_64] Error 2
make[2]: Leaving directory `/media/Extra_Space/work/testIOC/testApp/src'
make[1]: *** [src.install] Error 2
make[1]: Leaving directory `/media/Extra_Space/work/testIOC/testApp'
make: *** [testApp.install] Error 2


Do you have any idea what might be causing this issue? I've tried googling around and haven't found anything helpful.

Thank you for your assistance,
-Sam de Jong

   

   

#include <bitset>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <unistd.h>
#include <vector>
#include </usr/include/libusb-1.0/libusb.h>

#include "DI-2108-P.h"

using namespace std;


DI_2108_P::DI_2108_P(){
  nChan=1;
  ranges.resize(nChan);
  multiplier.resize(nChan);
  divisor.resize(nChan);
}

DI_2108_P::DI_2108_P(int nChannels){
  nChan=nChannels;
  ranges.resize(nChan);
  multiplier.resize(nChan);
  divisor.resize(nChan);
}


void DI_2108_P::Initialize(){
  
  libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
  //libusb_device_handle *dev_handle; //a device handle
  ctx = NULL; //a libusb session
  int r; //for return values
  ssize_t cnt; //holding number of devices in list
  r = libusb_init(&ctx); //initialize the library for the session we just declared
  if(r < 0) {
    cout<<"Init Error "<<r<<endl; //there was an error
    //return error;
  }
  libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
  
  cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
  if(cnt < 0) {
    cout<<"Get Device Error"<<endl; //there was an error
    //return error;
  }
  cout<<cnt<<" Devices in list."<<endl;
  
  dev_handle = libusb_open_device_with_vid_pid(ctx, vID, pID); //these are vendorID and productID I found for my usb device
  if(dev_handle == NULL)
    cout<<"Cannot open device"<<endl;
  else
    cout<<"Device Opened"<<endl;
  libusb_free_device_list(devs, 1); //free the list, unref the devices in it
  
  if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
    cout<<"Kernel Driver Active"<<endl;
    if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
      cout<<"Kernel Driver Detached!"<<endl;
  }
  r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
  if(r < 0) {
    cout<<"Cannot Claim Interface"<<endl;
    
  }
  cout<<"Claimed Interface"<<endl;
    
    
}

void DI_2108_P::reset(){
  libusb_reset_device(dev_handle);	
}


void DI_2108_P::close(){
  int r;
  //libusb_context *ctx = NULL; //a libusb session
  
  r = libusb_release_interface(dev_handle, 0); //release the claimed interface
  if(r!=0) {
    cout<<"Cannot Release Interface"<<endl;
    return;
  }
  cout<<"Released Interface"<<endl;
  
  libusb_close(dev_handle); //close the device we opened
  libusb_exit(ctx); //needs to be called to end the
 

}


string DI_2108_P::sendMessage(string message){
  //libusb_context *ctx = NULL; //a libusb session
  int r; //for return values

  string error = "error";

  message = message+"\r";
  

  unsigned char recieved[1000000];
  unsigned char sent[50];
  strcpy((char*) sent, message.c_str());
  

  int actual; //used to find out how many bytes were written
  
  //cout<<"Data->"<<message<<"<-"<<endl; //just to see the data we want to write : abcd
  cout<<"Writing Data..."<<endl;
  r = libusb_bulk_transfer(dev_handle, (1 | LIBUSB_ENDPOINT_OUT), sent, sizeof(sent), &actual, 0); //my device's out endpoint was 1, found with trial- the device had 2 endpoints: 2 and 129
  if(r == 0 && actual == sizeof(sent)){ //we wrote the 4 bytes successfully
    cout<<"Writing Successful!"<<endl;
    sleep(0.1);
    r = libusb_bulk_transfer(dev_handle, (1 | LIBUSB_ENDPOINT_IN), recieved, sizeof(recieved), &actual, 0);
    cout<<actual<<endl;
    cout<<libusb_strerror((libusb_error)r)<<endl;
  }else
    cout<<"Write Error"<<endl;
  
  std::string sName(reinterpret_cast<char*>(recieved));
  return sName;


}

void DI_2108_P::setNChannels(int nChannels){
  nChan = nChannels;
  ranges.resize(nChan);
  multiplier.resize(nChan);
  divisor.resize(nChan);
}

void DI_2108_P::setRange(int channel, int range){
  if(channel>nChan) return;
  if(range>4) return;
  ranges[channel] = range;

  if(range==0){
    multiplier[channel]=10;
    divisor[channel] = 1./32768;
  }else if(range==1){
    multiplier[channel]=5;
    divisor[channel] = 1./32768;
  }else if(range==2){
    multiplier[channel]=2.5;
    divisor[channel] = 1./32768;
  }else if(range==3){
    multiplier[channel]=10;
    divisor[channel] = 1./65536;
  }else if(range==4){
    multiplier[channel]=5;
    divisor[channel] = 1./65536;
  }
}


void DI_2108_P::startScan(){


  this->sendMessage("ps 1");

  stringstream ss;
  for(int i=0; i<nChan; i++){
    ss<<i;
    string slistString = "slist "+ss.str()+" ";;
    ss.str("");

    int b=ranges[i]<<8;
    
    int channelMask = i+b;
    ss<<channelMask;
    slistString = slistString+ss.str();
    ss.str("");
    
    this->sendMessage(slistString);

    cout<<slistString<<endl;
        
  }





  this->sendMessage("start 0");
}

void DI_2108_P::stopScan(){
  this->sendMessage("stop 0");
}


vector<double> DI_2108_P::getReadings(){

  vector<double> readings;
  readings.resize(nChan);
  
  int r; //for return values

  unsigned char recieved[1000000];
    
  int actual; //used to find out how many bytes were written
  
  r = libusb_bulk_transfer(dev_handle, (1 | LIBUSB_ENDPOINT_IN), recieved, 1000000, &actual, 0);

  for(int i=0; i<nChan; i++){
    short combined = (recieved[2*i+1] << 8 ) | (recieved[2*i] & 0xff);
    
    double add = 0;
    if(ranges[i]>2) add=multiplier[i]/2;
    
    readings[i] = multiplier[i]*(double)combined*divisor[i]+add;
   

  }

  return readings;

  
}
 
#include <bitset>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <unistd.h>
#include <vector>
#include </usr/include/libusb-1.0/libusb.h>


//#include "DI-2108-P.cpp"

using namespace std;

class DI_2108_P{
  
 public:
  
  DI_2108_P();
  DI_2108_P(int nChannels);
  // DI_2108_P(int vendorID, int productID);
  void Initialize();
  void close();
  string sendMessage(string message);
  void startScan();
  void stopScan();
  void reset();
  vector<double> getReadings();
  
  void setNChannels(int nChannels);
  void setRange(int channel, int range);


 private:

  static const int vID = 0x0683;
  static const int pID = 0x2109;
  libusb_context *ctx;
  libusb_device_handle *dev_handle;
  
  vector<int> ranges;
  vector<double> multiplier;
  vector<double> divisor;
  int nChan;

};

Replies:
RE: Problem compiling EPICS ioc with libusb Mark Rivers

Navigate by Date:
Prev: RE: waveform arrays within SNL Al Honey
Next: RE: Problem compiling EPICS ioc with libusb Mark Rivers
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
Navigate by Thread:
Prev: SIS3302 digitizer driver based on Transient Recorder Framework ambroz . bizjak
Next: RE: Problem compiling EPICS ioc with libusb Mark Rivers
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
ANJ, 22 Jun 2017 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·