dabelknap / VMEStream

0 stars 1 forks source link

Using VMEController.h #6

Closed dabelknap closed 11 years ago

dabelknap commented 11 years ago

@ekfriis I'm a bit confused about what is going on in the VME code.

virtual bool read(unsigned long address, size_t size, void* value) = 0;
virtual bool write(unsigned long address, size_t size, void* value) = 0;
virtual bool multiread(unsigned int *addresses, size_t size, unsigned short *data, int dataCounter) = 0;
virtual bool multiwrite(unsigned int *addresses, size_t size, unsigned short *data, int dataCounter) = 0;

Do you (or perhaps Mathias), have a suggestion of how to handle this? I am tempted to start over from the original CAEN VME libraries, which is probably overkill.

I started a caen branch of VMEStream, which has the code I've written so far involving the VME stuff.

ekfriis commented 11 years ago

Hi Austin,

So VMEController [1] is the "abstract interface base class". Note how all of the methods in the header are not defined in the .cc, and have the form

virtual bool reset() = 0;

the =0 means this function is pure-abstract, and is only defined in the derived classes. So then there are two terribly named derived classes caen and null which define:

//   in null.h
virtual bool reset() {
    Logger logger = Logger::getInstance("VMEController::null");
    static int rst_counter=0;
    if (rst_counter<10) 
    {
        LOG4CPLUS_WARN(logger, "null::reset() called");
        //cerr << "null::reset() called" << endl;
        rst_counter++;
    }
  }

// in caen.cc
bool
caen::reset()
{
  CVErrorCodes status = CAENVME_SystemReset(handle);
  if(status != cvSuccess)
    {
      return false;
    }
  return true;
}

So the null class is a VMEController that just logs all the calls but does nothing. The caen class is a VMEController that actually goes and does stuff via the low-level CAEN libs. This lets you do something in your application like:

VMEController* controller = NULL;
if (is_test_mode) {
   controller = new null();
} else {
   controller = new caen();
}

// controller = new VMEController();
// NB the above will not compile since VMEController has pure-virtual (abstract) methods.

controller->reset();
controller->blockWrite(...);
// other stuff

This way you can put your program in test mode, and it will work even if you don't have a CAEN card in your PC, and will log the calls to screen, etc. This is a common way of abstracting interfaces/testing stuff in OO languages. Another example you use every day [2].

You are correct that the width is architecture dependent, but this is only a problem if the data type is too small, or you are doing unholy things (see patternTest/*.cc). Since these just refer to the VME (memory) addresses, I think they should be fine, but feel free to convert to the specific-width types where you think it is appropriate and commit it to SVN. If it was broken, I think it would have happened during the 64bit transition (SLC4->SLC5).

I would resist the urge to rewrite from scratch, until you are positive that it is broken.

Evan

[1] https://svnweb.cern.ch/trac/cactus/browser/trunk/cactusprojects/rct/VME/VMEController.h [2] https://cmssdt.cern.ch/SDT/lxr/source/FWCore/Framework/interface/EDAnalyzer.h#058

dabelknap commented 11 years ago

It seems like vme->read(...) is most often called with cvD16 for the datawidth, and an unsigned short is passed as the input data. https://svnweb.cern.ch/trac/cactus/browser/trunk/cactusprojects/rct/RCTCore/RCTReceiverCard.cc#L39

dabelknap commented 11 years ago

I added the read/write functions rather than the multiread/multiwrite assuming (for the time being) cvD32 (3390c3b). However, I am getting a compiler error:

[dbelknap@rctslc6 VMEStream]$ make
g++ -g -Wall -Iinclude -I/afs/cern.ch/user/d/dbelknap/softipbus/include -I/opt/xdaq/include/ -std=c99 -DLINUX -o bin/vme2fd src/vme2fd.cc lib/libvmestream.a
cc1plus: warning: command line option "-std=c99" is valid for C/ObjC but not for C++
src/vme2fd.cc: In function ‘int main(int, char**)’:
src/vme2fd.cc:51: warning: unused variable ‘vme_tx_data’
src/vme2fd.cc:52: warning: unused variable ‘vme_rx_data’
src/vme2fd.cc:54: warning: unused variable ‘vme_tx_address’
src/vme2fd.cc:55: warning: unused variable ‘vme_rx_address’
/tmp/dbelknap/ccdILlYW.o: In function `main':
/afs/cern.ch/user/d/dbelknap/VMEStream/src/vme2fd.cc:44: undefined reference to `cbuffer_new()'
/afs/cern.ch/user/d/dbelknap/VMEStream/src/vme2fd.cc:45: undefined reference to `cbuffer_new()'
...

I don't understand how I can have an undefined reference error when the proper header files and libraries have been included.

ekfriis commented 11 years ago

Can you check using nm to see if the symbols are in libvmestream.a?

On Wed, Sep 11, 2013 at 4:56 PM, Austin Belknap notifications@github.comwrote:

I added the read/write functions rather than the multiread/multiwrite assuming (for the time being) cvD32 (3390c3bhttps://github.com/dabelknap/VMEStream/commit/3390c3b). However, I am getting a compiler error:

[dbelknap@rctslc6 VMEStream]$ make g++ -g -Wall -Iinclude -I/afs/cern.ch/user/d/dbelknap/softipbus/include -I/opt/xdaq/include/ -std=c99 -DLINUX -o bin/vme2fd src/vme2fd.cc lib/libvmestream.a cc1plus: warning: command line option "-std=c99" is valid for C/ObjC but not for C++ src/vme2fd.cc: In function ‘int main(int, char**)’: src/vme2fd.cc:51: warning: unused variable ‘vme_tx_data’ src/vme2fd.cc:52: warning: unused variable ‘vme_rx_data’ src/vme2fd.cc:54: warning: unused variable ‘vme_tx_address’ src/vme2fd.cc:55: warning: unused variable ‘vme_rx_address’ /tmp/dbelknap/ccdILlYW.o: In function main': /afs/cern.ch/user/d/dbelknap/VMEStream/src/vme2fd.cc:44: undefined reference tocbuffer_new()' /afs/cern.ch/user/d/dbelknap/VMEStream/src/vme2fd.cc:45: undefined reference to `cbuffer_new()' ...

I don't understand how I can have an undefined reference error when the proper header files and libraries have been included.

— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24247042 .

dabelknap commented 11 years ago

nm shows the symbols to be there.

ekfriis commented 11 years ago

Hi Austin,

I can compile it/run the tests in my SLC5 VM. Have you done a make clean? Is your area completely pushed to dabelknap/VMEStream? If so, maybe it is some problem with SLC6.

Evan

dabelknap commented 11 years ago

I did do a make clean, and it didn't help. Also, are you using the caen branch rather than master?

dabelknap commented 11 years ago

@ekfriis Just wanted to follow up: should I try switching to SLC5? Although, the fact that this compiler error is present in the first place troubles me. I can't think of any reason why it should be there.

ekfriis commented 11 years ago

I can reproduce your problem in SLC5 as well, so that won't fix it. I'm very confused too :). I did test that if you just compile all of the src files together (not building+linking in library) it works, so I would propose you just do this instead for the time being and we can come back to this later.

On Fri, Sep 13, 2013 at 5:40 PM, Austin Belknap notifications@github.comwrote:

@ekfriis https://github.com/ekfriis Just wanted to follow up: should I try switching to SLC5? Although, the fact that this compiler error is present in the first place troubles me. I can't think of any reason why it should be there.

— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24403358 .

dabelknap commented 11 years ago

How did you build it exactly? I tried creating all the .o files by hand and linking them, and I am getting the same 'undefined' errors.

ekfriis commented 11 years ago

g++ $FLAGSETC vme2fd.cc $SOME_PATH/circular_buffer.cc [other .cc]

On Mon, Sep 16, 2013 at 8:35 AM, Austin Belknap notifications@github.comwrote:

How did you build it exactly? I tried creating all the .o files by hand and linking them, and I am getting the same 'undefined' errors.

— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24491116 .

dabelknap commented 11 years ago

Are there a .cc versions of circular_buffer and buffer? g++ doesn't like the implicit cast from void* (from malloc) to uint32_t*.

ekfriis commented 11 years ago

Ah, maybe this is the source of the link problem as well. Weren't you already compiling to buffer.o with g++ as well?

On Mon, Sep 16, 2013 at 8:59 AM, Austin Belknap notifications@github.comwrote:

Are there a .cc versions of circular_buffer and buffer? g++ doesn't like the implicit cast from void* (from malloc) to uint32_t*.

— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24491735 .

dabelknap commented 11 years ago

Those were compiled using gcc. I figured it would be safe considering the caen vme libs were originally c libraries.

ekfriis commented 11 years ago

You may need to wrap the header defintiions to the C files in

extern "C" {
}

, see http://msdn.microsoft.com/en-us/library/0603949d.aspx

On Mon, Sep 16, 2013 at 9:08 AM, Austin Belknap notifications@github.comwrote:

Those were compiled using gcc. I figured it would be safe considering the caen vme libs were originally c libraries.

— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24492020 .

dabelknap commented 11 years ago

Do I just redefine the header definitions for the functions I need in vme2fd.cc?

ekfriis commented 11 years ago

Sorry, I was unclear. You need to wrap the #includes, not definitions.

On Mon, Sep 16, 2013 at 9:21 AM, Austin Belknap notifications@github.comwrote:

Do I just redefine the header definitions for the functions I need in vme2fd.cc?

— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24492491 .

dabelknap commented 11 years ago

Okay, it compiles. I cast the malloc statements in VMEStream, circular_buffer, and buffer. The changes haven been committed to git/svn.