Closed dabelknap closed 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
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
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.
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 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.
— Reply to this email directly or view it on GitHubhttps://github.com/dabelknap/VMEStream/issues/6#issuecomment-24247042 .
nm
shows the symbols to be there.
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
I did do a make clean, and it didn't help. Also, are you using the caen
branch rather than master
?
@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.
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 .
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.
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 .
Are there a .cc versions of circular_buffer and buffer? g++ doesn't like the implicit cast from void*
(from malloc) to uint32_t*
.
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 .
Those were compiled using gcc. I figured it would be safe considering the caen vme libs were originally c libraries.
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 .
Do I just redefine the header definitions for the functions I need in vme2fd.cc
?
Sorry, I was unclear. You need to wrap the #include
s, 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 .
Okay, it compiles. I cast the malloc statements in VMEStream, circular_buffer, and buffer. The changes haven been committed to git/svn.
@ekfriis I'm a bit confused about what is going on in the VME code.
caen
class inherits fromVMEController
, andmultiread
,multiwrite
, etc. are actually implemented incaen.cc
. However, it seems that theVMEController
class is what is actually called when doing read/write operations. Not sure why it is done this way.unsigned int
instead ofuint32_t
, for instance. The definition of the former is architecture-dependent, which means it might not work properly on SLC6, correct?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.