Skip to content

Instantly share code, notes, and snippets.

@Juul
Last active October 27, 2023 10:11
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Juul/997ee7feb11e20c0dfa7eaf00cc43b07 to your computer and use it in GitHub Desktop.
Save Juul/997ee7feb11e20c0dfa7eaf00cc43b07 to your computer and use it in GitHub Desktop.
Guide for setting up GPIB support in Linux for the HP/Agilent 82350 A and B PCI cards

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).

Buying a GPIB card

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.

Downloading the source code

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

Extracting the source code

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

Compile and install userland utilities

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).

Initializing the card

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

Testing the card

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

Configuring auto-recompile with DKMS

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.

Automatically loading the kernel module on boot

Add the following line at the bottom of /etc/modules:

agilent_82350a

Automatically initializing the card on boot

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 :)

@mdclemen
Copy link

mdclemen commented Jan 10, 2022

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):

cd /usr/src
sudo mkdir gpib_common-4.3.4
cd gpib_common-4.3.4
sudo ln -s </path/to>/linux-gpib-kernel/* ./
sudo rm *.conf
sudo ln -s </path/to>/linux-gpib-kernel/dkms-gpib_common.conf ./dkms.conf
sudo dkms add -c dkms.conf -m gpib_common -v 4.3.4
sudo dkms build -c dkms.conf -m gpib_common -v 4.3.4
sudo dkms install -c dkms.conf -m gpib_common -v 4.3.4

and $ sudo dkms autoinstall succeeds.

@Skroder
Copy link

Skroder commented Oct 14, 2022

Can anybody point me to a Fedora based version of these instructions? I am getting stuck with no build-essentials and .configure.
I have an HP 82350A PCI card. I have a bunch of 488 stuff that works on Windows that I am trying to port to Fedora 36. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment