We recently developed some ASYN support for the National Instruments VISA library
https://github.com/ISISComputingGroup/EPICS-VISA so we could use Stream Device to control a GPIB device via an NI GPIB-ENET controller. There is the start of some very basic documentation at
http://epics.isis.stfc.ac.uk/doxygen/main/support/VISAdrv/ We have only used it ourselves on Windows 7 64bit, but it looks like NI VISA is available for 64bit Linux. Drop me an email
if you think it might be useful and I’ll put some better usage notes together for you.
[mailto:email@example.com] On Behalf Of Mark Rivers
Sent: 14 July 2017 19:50
To: 'Dennis Nicklaus'; firstname.lastname@example.org
Subject: RE: NI4882 GPIB support for Linux 64bit?
I don't really know anything about the linuxGpib driver in asyn. I am not sure who, if anyone, is using it.
That being said, I did a little research and found the following:
- This link in the asynDriver.html file
leads to this.
The latest version of that module is 3.1.101 from 2004. It is for 2.4.x Linux kernels.
There is a new home for the Linux GPIB package here
For linux kernel versions >= 2.4.x, use Linux-GPIB version 3.1.x. Earlier kernel versions are not supported.
For linux kernel versions >= 2.6.8, use Linux-GPIB version 3.2.x or later.
The linux 3.x.x and 4.x.x series kernels are also supported by Linux-GPIB version 3.2.x or later.
The 4.x.x Linux-GPIB release series is being maintained to keep it in working condition with new kernel releases. Currently there are no plans to further develop the library beyond keeping it in a functioning state.
The 3.1.x series for 2.4.x kernels is no longer actively maintained. All boards supported by the current 4.x.x. release are listed here.
The documentation is here:
The NI4882 is one of the modules that is supported in the 4.x.x release.
I first suspected the problem was that the API had changed between the old 3.1.x release that asyn was written for and the new 4.x.x release.
However, ibfind, ibtmo, and ibsre are documented functions in the 4.0.1 release:
ibcnt is a documented global variable.
gpib_error_string is not documented there. There is an iberr global variable from which is should be easy to implement gpib_error_string().
So it looks to me like NI has a library which is not really compatible with the LinuxGPIB driver. Note that NI says this on their Web page
The legacy GPIB API, libgpibapi.so, is still available for compatibility with
existing applications. It provides only 32-bit support, and is not recommended
for new development.
Perhaps you should not be using the NI library, but should be using the driver from Sourceforge instead?
Thanks for your help, Mark. Yes I am using the NI supplied gpib-enet drivers.
The gpibapi library is one that I have to add to the makefile for it to find these symbols.
That's where I want them from. I did this all like 8 years ago and it worked, but I realized today that it worked then because I was on a 32bit system then and 64bit now.
Reading what you quoted from NI below, I realize that they have moved *most* of the API functions into libni4882 for 64bit.
But not all. Because now my build winds up with this:
make: Entering directory `/usr/local/epics/support/asyn-master/testApp/src/O.linux-x86_64'
/usr/bin/g++ -o test -L/usr/local/epics/support/asyn-master/lib/linux-x86_64 -L/usr/local/epics/base-3.16.1/lib/linux-x86_64 -Wl,-rpath,/usr/local/epics/support/asyn-master/lib/linux-x86_64 -Wl,-rpath,/usr/local/epics/base-3.16.1/lib/linux-x86_64
-rdynamic -m64 test_registerRecordDeviceDriver.o testMain.o -ltestSupport -lasyn -ldbRecStd -ldbCore -lca -lCom
/usr/local/epics/support/asyn-master/lib/linux-x86_64/libasyn.so: undefined reference to `ibtmo'
/usr/local/epics/support/asyn-master/lib/linux-x86_64/libasyn.so: undefined reference to `ibfind'
/usr/local/epics/support/asyn-master/lib/linux-x86_64/libasyn.so: undefined reference to `ibsre'
/usr/local/epics/support/asyn-master/lib/linux-x86_64/libasyn.so: undefined reference to `gpib_error_string'
/usr/local/epics/support/asyn-master/lib/linux-x86_64/libasyn.so: undefined reference to `ibcnt'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
make: Leaving directory `/usr/local/epics/support/asyn-master/testApp/src/O.linux-x86_64'
make: *** [install.linux-x86_64] Error 2
So I went back and rebuilt everything for 32bit -- linux-x86.
And even there, I get similar errors
usr/bin/g++ -o test -L/usr/local/epics/support/asyn-master/lib/linux-x86 -L/usr/local/epics/base-3.16.1/lib/linux-x86 -Wl,-rpath,/usr/local/epics/support/asyn-master/lib/linux-x86 -Wl,-rpath,/usr/local/epics/base-3.16.1/lib/linux-x86
-rdynamic -m32 test_registerRecordDeviceDriver.o testMain.o -ltestSupport -lasyn -ldbRecStd -ldbCore -lca -lCom
/usr/local/epics/support/asyn-master/lib/linux-x86/libasyn.so: undefined reference to `ibfind'
/usr/local/epics/support/asyn-master/lib/linux-x86/libasyn.so: undefined reference to `gpib_error_string'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
make: Leaving directory `/usr/local/epics/support/asyn-master/testApp/src/O.linux-x86'
Investigation with 'nm' shows that there ibtmo, ibsre, and ibcnt are not in the 64bit libraries at all.
Now, ibfind is an interesting one. nm shows no ibfind in the libraries, even in the 32 bit one and even in the older
version (2.3.1) that I successfully used 8 years ago. They do (both 32 and 64, new and old) have an ibfindA and ibfindW
$nm -D *.so* | grep ibfind
0000000000044d10 T ibfindA
0000000000044d00 T ibfindW
which are for Ascii (8bit) and Wide (16bit) character usage. So
1) How did this ever work? Was there something special in the older versions of gcc?
2) How should I proceed? Edit the Asyn source to change ibfind to ibfindA?
And what about this 'gpib_error_string' undefined symbol? I don't find it in any of the NI GPIB libs either. Where is it supposed to come from? (32 or 64 bit).
Do I need to get both those from the epics linux-gpib stuff?
Can you give a quick summary of how I install and link to the gpib stuff?
You asked about:
>When I search the asyn Makefiles for references to the gpibapi library I don't find any.
I added these lines to the asyn/asyn Makefile to link with the NI GPIB-Enet drivers
gpibapi_DIR = /usr/local/natinst/ni4882/lib
gpibapi_LIBS = gpibapi
One final note: I do get the same undefined symbols when I try to build my IOC linking to the asyn library, as to be expected.
Thanks for your help and suggestions!
On 7/13/17 12:38 PM, Mark Rivers wrote:
If you don't have a 64-bit NI library then yes, you can only build for linux-x86, not linux-x86_64.
However, on National Instruments downloads site I found the following:
What is new in NI-488.2 for Linux 3.2
General enhancements and bug fixes.
Updated Linux distribution support.
Modified the integer types used in ni4882.h and libni4882.so. All uses of 'unsigned long' have been replaced with 'unsigned int' to improve compatibility with 64-bit compilers. This
API has never been documented with prior versions of NI-488.2 for Linux, but ni4882.h and a 32-bit version of libni4882.so were installed on the system. Any user utilizing these files should update their applications according to the updated function prototypes
in ni4882.h. This change does not impact ni488.h or libgpibapi.so.
Added 64-bit Application Interface. NI-488.2 for Linux, Version 3.2, adds a 64-bit application interface that allows users to create 64-bit applications using libni4882.so. Using
the 32-bit version of libni4882.so, users can use the same NI4882 API to build corresponding 32-bit applications with no source code changes. For more information about the new NI4882 API, refer to the NI-488.2 Help. You can access NI-488.2 Help from GPIB
Explorer. To start GPIB Explorer from a terminal, enter the following command, /usr/local/bin/gpibexplorer. In GPIB Explorer, select Help>>NI-488.2 Help from the menu bar.
So this says that version 3.2 has a 64-bit API.
I'm trying to build asyn support for arch = linux-x86_64 to use with GPIB over ethernet.
I seem to be bumping into a problem where it is looking for libgpibapi.a and that library only exists in the 32bit NI library:
$ ls /usr/local/natinst/ni4882/lib
cib.o liblvgpibconf.so.15.1.0* libniGPIBsys.so.15.1.0*
libgpibapi.so.15.1.0* libni4882.so.15.1.0* ni4882.o
libni4882.so.15.1.0* libni488config.so.15.1.0* libniGPIBsys.so.15.1.0* ni4882.o
If I point the asyn Makefile at /usr/local/natinst/ni4882/lib64, it complains it can't find libgpibapi.a and if I point it at /usr/local/natinst/ni4882/lib (32 bit version), it rightly complains that libgpibapi.so is incompatible.
Am I forced to build everything for 32bit if I need GPIB asyn?