This is a guide for getting the HP/Agilent 82350 A or B GPIB cards working on Linux.
There are other guides made by other people for a couple of other GPIB adapters here:
Unfortunately the mainline Linux kernel does not have any GPIB support. Even more unfortunate is that neither Ubuntu nor Debian appear to have packages for the kernel modules nor do any third-party apt repos appear to exist that are remotely up to date.
The project maintaining drivers for various GPIB adapters appears at first glance to be outdated and unmaintained due to being hosted on sourceforge and labeling their latest version as working for "3.x.x and 2.6.x kernels" but don't worry: It is actively maintained and works for 5.8.x kernels.
The biggest difference between the A and B models is that the A cards require loading a proprietary firmware (which someone has kindly hosted on github).
The cheapest way to get a working GPIB adapter might be to find a "HP 82350-66501 Rev B PCI Card". These are A cards despite the "Rev B" in their name. I've seen these go for $50 on ebay including shipping. If you don't have a PCI slot then you can find PCI-E to PCI adapters for around $10 to $15 on ebay or aliexpress by searching for "PCI-E PCI 32bit adapter". The slightly more expensive option is the Agilent/Keysight 82357B USB adapter which usually goes for around $80. Don't buy a "UGPlus" adapter as there is still no Linux support.
Interestingly it looks like the latest version of the GPIB drivers support GPIB on the Raspberry Pi via bitbanging. I haven't investigated this yet.
Download latest stable source code from here
Don't worry about the "for 3.x.x and 2.6.x kernels" part. This version works for newer kernels like 5.8.x as well.
If you have an A
card download the latest stable GPIB firmware:
sudo apt install git
git clone https://github.com/fmhess/linux_gpib_firmware
tar xvzf linux-gpib-4.3.4.tar.gz
cd linux-gpib-4.3.4.tar.gz/
tar xvzf linux-gpib-user-4.3.4.tar.gz
tar xvzf linux-gpib-kernel-4.3.4.tar.gz
sudo apt install build-essential
cd linux-gpib-user-4.3.4/
./configure
make
sudo make install
sudo ldconfig
It's probably a good idea to do a quick compile and install of the kernel modules to test things out:
cd ../
cd linux-gpib-kernel-4.3.4/
make
sudo make install
If using an Agilent 8350A card then you should still use the agilent_8350b
module. Note that the boards labeled "HP 82350-66501 Rev B" are actually Agilent 82350 A cards. The driver is the same but you need to load the firmware for this card after loading the kernel module (you do not need to load any firmware for the Agilent 82350 B cards).
First load the kernel module:
sudo modprobe agilent_82350b
You should see something like this in dmesg
:
[ 7064.440519] gpib: registered agilent_82350b_unaccel interface
[ 7064.440520] gpib: registered agilent_82350b interface
You need to use the gpib_config
utility to actually initialize your card,
First we need to modify the config file used by gpib_config
.
Edit /usr/local/etc/gpib.conf
changing the board_type =
line to:
board_type = "agilent_82350b"
The board type here will be the same as the kernel module name (without the .ko
) so even for a 82350 A card this will be "agilent_82350b".
If you have a card that doesn't require firmware, you can now just run sudo gpib_config
.
If you have a card that requires firmware then you should look at the README in the relevant directory of the linux_gpib_firmware
directory you downloaded earlier.
Go ahead and cd into the linux_gpib_firmware/hp_82350a/
directory, then:
sudo gpib-config -I ./agilent_82350a.bin
In dmesg you should now see something like:
[ 7567.569883] agilent_82350b: HP/Agilent 82350A board found
[ 7567.569903] agilent_82350b: plx base address remapped to 0x000000004010c097
[ 7567.569909] agilent_82350b: gpib base address remapped to 0x00000000048204c8
[ 7567.569915] agilent_82350b: sram base address remapped to 0x0000000075742a5f
[ 7567.569919] agilent_82350b: borg base address remapped to 0x000000009ce55d38
[ 7567.569923] agilent_82350b: Loading firmware...
[ 7567.669469] agilent_82350b: ...done.
[ 7567.768132] agilent_82350b: IRQ 19
Your GPIB card will appear as /dev/gpib0
unless you further modified the gpib.conf
file.
If you get some error, e.g. because you forgot to edit /usr/local/etc/gpib.conf
then it's possible that fixing your mistake and trying again will not be enough. In that case you might want to try unloading and reloading the module:
sudo modprobe -r agilent_82350a
sudo modprobe agilent_82350a
Once the card is initialized you can try to test it using the ibtest
utility but you'll probably need some GPIB device attached:
sudo ibtest
After testing that things work you should configure DKMS to automatically recompile and install this kernel module every time a new version of the linux kernel is installed (by normal system updates).
If you are going to do this then you should first unload and remove the previously installed drivers:
sudo modprobe -r agilent_82350a
sudo rm -rf /lib/modules/$(uname -r)/gpib
If you run lsmod | grep agilent_8235b
(or the name of the driver you're using) and you will see that three kernel modules are needed for this card:
gpib_common
tms9914
agilent_82350b
You will need to create a dkms configuration file for each of these.
First cd into linux-gpib-kernel-4.3.4/
, then create dkms-gpib_common.conf
with the content:
MAKE="make"
CLEAN="make clean"
BUILT_MODULE_NAME=gpib_common
BUILT_MODULE_LOCATION=drivers/gpib/sys/
PACKAGE_NAME=gpib_common
PACKAGE_VERSION=4.3.4
DEST_MODULE_LOCATION[0]="/kernel/drivers/gpib/sys/"
AUTOINSTALL=yes
and create dkms-tms9914.conf
with the content:
MAKE="make"
CLEAN="make clean"
BUILT_MODULE_NAME=tms9914
BUILT_MODULE_LOCATION=drivers/gpib/tms9914/
PACKAGE_NAME=tms9914
PACKAGE_VERSION=4.3.4
DEST_MODULE_LOCATION[0]="/kernel/drivers/gpib/tms9914/"
AUTOINSTALL=yes
and create dkms-agilent_8235b.conf
with the content:
MAKE="make"
CLEAN="make clean"
BUILT_MODULE_NAME=agilent_82350b
BUILT_MODULE_LOCATION=drivers/gpib/agilent_82350b/
PACKAGE_NAME=agilent_82350b
PACKAGE_VERSION=4.3.4
DEST_MODULE_LOCATION[0]="/kernel/drivers/gpib/agilent_82350b/"
AUTOINSTALL=yes
Change every instance of agilent_8350b
if you are using one of the other GPIB drivers.
Copy the linux-gpib-kernel-4.3.4
directory to /usr/src/
and make symlinks:
cd ../
sudo cp -a linux-gpib-kernel-4.3.4 /usr/src/agilent_82350b-4.3.4
cd /usr/src/
sudo ln -s gpib_common-4.3.4
sudo ln -s tms9914-4.3.4
It is important that the directory names match the PACKAGE_NAME
and PACKAGE_VERSION
from the dkms-*.conf
files.
Note that because make
compiles all modules, every time the kernel is updated you will effectively be recompiling all gpib modules three times, even the ones you don't use. This is not that big of a deal as it's a fairly quick operation but if you want to at least improve the situation a bit you could edit drivers/gpib/Makefile
to remove the lines for the drivers you don't use. You could also go one step further and make three copies of the directory instead of the symlinks and then edit drivers/gpib/Makefile
individually for each directory to prevent re-building of the same drivers multiple times.
Now to configure DKMS for the automatic recompile and install of these modules run:
cd /usr/src/agilent_82350b-4.3.4/
sudo dkms add -c dkms-agilent_82350b.conf -m agilent_82350b -v 4.3.4
sudo dkms build -c dkms-agilent_82350b.conf -m agilent_82350b -v 4.3.4
sudo dkms install -c dkms-agilent_82350b.conf -m agilent_82350b -v 4.3.4
sudo dkms add -c dkms-gpib_common.conf -m gpib_common -v 4.3.4
sudo dkms build -c dkms-gpib_common.conf -m gpib_common -v 4.3.4
sudo dkms install -c dkms-gpib_common.conf -m gpib_common -v 4.3.4
sudo dkms add -c dkms-tms9914.conf -m tms9914 -v 4.3.4
sudo dkms build -c dkms-tms9914.conf -m tms9914 -v 4.3.4
sudo dkms install -c dkms-tms9914.conf -m tms9914 -v 4.3.4
Verify that you can load the kernel module:
sudo modprobe agilent_82350a
Now these modules should be automatically recompiled and re-installed during kernel updates.
Add the following line at the bottom of /etc/modules
:
agilent_82350a
The last step is to configure the gpib_config
command to run automatically when the card is detected on boot.
You will have to create a directory for the firmware file and copy it.
First cd into the linux_gpib_firmware/
directory, then:
sudo mkdir -p /usr/local/share/gpib/firmware
sudo cp hp_82350a/agilent_82350a.bin /usr/local/share/gpib/firmware/
If you want to be able to communicate with GPIB devices without having to be root, create the group gpib
and add yourself to it:
sudo addgroup gpib
sudo usermod -a -G gpib $(whoami)
First we need to find some attributes for the card. First run lspci
and you should see a bunch of entries with one line like e.g:
06:00.0 Communication controller: PLX Technology, Inc. PCI <-> IOBus Bridge (rev 01)
Subsystem: Hewlett-Packard Company PCI <-> IOBus Bridge
Flags: medium devsel, IRQ 19
Memory at f7a04000 (32-bit, non-prefetchable) [size=128]
I/O ports at d000 [size=128]
Memory at f7a03000 (32-bit, non-prefetchable) [size=32]
Memory at f0000000 (32-bit, prefetchable) [size=32K]
Memory at f7a02000 (32-bit, non-prefetchable) [size=16]
Kernel modules: agilent_82350b
Yours may be different if you have a different revision of the card. If you have serious trouble finding the correct entry you can always shut down the computer, unplug the card, boot back up and see which entry disappears.
Take note of the "06:00.0".
Now run the following command, changing the "06:00.0" to what your own entry said:
sudo udevadm info /sys/bus/pci/devices/0000:06:00.0 --attribute-walk
Make sure you look only at the entry that says "looking at device ..." and ignore the following entries saying "looking at parent device ...".
Create the file /etc/udev/rules.d/99-gpib_agilent_82350b.rules
with the content:
SUBSYSTEM=="pci", ACTION=="add", ATTR{vendor}=="0x10b5", ATTR{device}=="0x9050", RUN+="/usr/local/sbin/gpib_config -I /usr/local/share/gpib/firmware/agilent_82350a.bin"
KERNEL=="gpib[0-9]*", MODE="660", GROUP="gpib"
but edit the 10b5
and 9050
to match what you found from the udevadm
command.
You can skip the line beginning with KERNEL==
if you don't want to allow users in the group gpib
to write to GPIB devices.
Do pay attention to whether the output from udevadm
says SUBSYSTEMS
or SUBSYSTEM
and ATTRS
or ATTR
and use whatever udevadm
said in your .rules
file.
Now make udev
reload its rules:
sudo udevadm control --reload-rules
Ensure the agilent_82350b
module is loaded but the gpib_config
command has not been run, then to test the udev
rules run the following command, changing the /sys/...
path to the same path you used in the udevadm info
command previously:
sudo udevadm test -a add /sys/bus/pci/devices/0000:06:00.0
Towards the end of the output you should see the line:
run: '/usr/local/sbin/gpib_config -I /usr/local/share/gpib/firmware/agilent_82350a.bin'
If you do, then you can now move on from simulation to actually triggering the rule:
sudo udevadm trigger -c add /sys/bus/pci/devices/0000:06:00.0
Check dmesg
output to ensure the gpib_config
ran correctly.
Of course the final test is to reboot and see if everything comes back up correctly :)
Thanks for these directions, very useful. I've found that on Linux Mint 20.2 (and possibly all Debian-like distros), during a kernel upgrade (or just running
$ sudo dkms autoinstall
), I get the error:Error! Could not locate dkms.conf file. File: /var/lib/dkms/gpib_common/4.3.4/source/dkms.conf does not exist.
To get around this, I did these steps (change
gpib_common
to other modules as needed):and
$ sudo dkms autoinstall
succeeds.