Install linux-gpib-code and use it with National Instruments GPIB-USB-HS adapter

Page content

The National Instruments GPIB-USB-HS adapter

This is an old one, from 2007, built in hungary. Note that the ones you can usually buy on ebay are illegal clones. Some of these will not be 100% clones and behave differently. While this works ok on Windows, these will not work with Linux.

I had luck, and it seems that I did get a genuine one, but quite old one.

20250903_153857.jpg

20250903_153740.jpg

20250903_153536.jpg

20250903_153648(0).jpg

Small note: Many years ago I’ve created a DIY GPIB controller, based on a ATMega microcontroller and wrote the implementation for a GPIB controller myself. This even included advanced features like service request handling. Documentation of that old approach is still here

But some years later, I’ve sold all my GPIB devices and did not need that anymore.

Some more years later, a HP3455A came to my lab desk, and I decided to try the GPIB part again, just for fun, but now with off-the-shelf hardware and software.

Make it usable under Linux

We will need the package linux-gpib. This will create a set of kernel modules for various adapters and some tools.

% lsusb
...
Bus 005 Device 012: ID 3923:709b National Instruments Corp. GPIB-USB-HS
...

Get sources

svn checkout svn://svn.code.sf.net/p/linux-gpib/code/trunk linux-gpib-code

Will put code into new directory “linux-gpib-code”.

Installation

Libs to install prior installation:

  • libtool
  • linux headers for kernel (kernel-devel).

linux-gpib-kernel, make

There is a Makefile, just run make. Check also INSTALL file.

linux-gpib-kernel, make install

elite845g8:/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-kernel # make install
make -C /lib/modules/`uname -r`/build V=0 modules_install\
        M="/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-kernel/drivers/gpib" \
        GPIB_TOP_DIR=/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-kernel \
        INSTALL_MOD_DIR=gpib
make[1]: Verzeichnis „/usr/src/linux-6.4.0-150600.23.65-obj/x86_64/default“ wird betreten
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/agilent_82350b/agilent_82350b.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/cb7210/cb7210.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/cec/cec_gpib.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/fmh_gpib/fmh_gpib.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/gpio/gpib_bitbang.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/hp_82335/hp82335.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/hp_82341/hp_82341.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/ines/ines_gpib.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/nec7210/nec7210.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/sys/gpib_common.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/tms9914/tms9914.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/tnt4882/tnt4882.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/agilent_82357a/agilent_82357a.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/lpvo_usb_gpib/lpvo_usb_gpib.ko
  INSTALL /lib/modules/6.4.0-150600.23.65-default/gpib/ni_usb/ni_usb_gpib.ko
  DEPMOD  /lib/modules/6.4.0-150600.23.65-default
Warning: modules_install: missing 'System.map' file. Skipping depmod.
make[1]: Verzeichnis „/usr/src/linux-6.4.0-150600.23.65-obj/x86_64/default“ wird verlassen
/sbin/depmod -A

linux-gpib-user, make

Check INSTALL file. We need to create a “configure” file, by calling “./bootstrap” script.. Then “./configure –sysconfdir=/etc”. All described better in INSTALL file.

linux-gpib-user, make install

elite845g8:/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user # make install
Making install in include
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include“ wird betreten
Making install in gpib
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include/gpib“ wird betreten
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include/gpib“ wird betreten
make[3]: Für das Ziel „install-exec-am“ ist nichts zu tun.
 /usr/bin/mkdir -p '/usr/local/include/gpib'
 /usr/bin/install -c -m 644 gpib_user.h ib.h gpib_version.h '/usr/local/include/gpib'
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include/gpib“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include/gpib“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include“ wird betreten
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include“ wird betreten
make[3]: Für das Ziel „install-exec-am“ ist nichts zu tun.
make[3]: Für das Ziel „install-data-am“ ist nichts zu tun.
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/include“ wird verlassen
Making install in lib
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird betreten
make  install-recursive
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird betreten
Making install in .
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird betreten
make[4]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird betreten
 /usr/bin/mkdir -p '/usr/local/lib64'
 /bin/sh ../libtool   --mode=install /usr/bin/install -c   libgpib.la '/usr/local/lib64'
libtool: install: /usr/bin/install -c .libs/libgpib.so.0.4.0 /usr/local/lib64/libgpib.so.0.4.0
libtool: install: (cd /usr/local/lib64 && { ln -s -f libgpib.so.0.4.0 libgpib.so.0 || { rm -f libgpib.so.0 && ln -s libgpib.so.0.4.0 libgpib.so.0; }; })
libtool: install: (cd /usr/local/lib64 && { ln -s -f libgpib.so.0.4.0 libgpib.so || { rm -f libgpib.so && ln -s libgpib.so.0.4.0 libgpib.so; }; })
libtool: install: /usr/bin/install -c .libs/libgpib.lai /usr/local/lib64/libgpib.la
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/sbin" ldconfig -n /usr/local/lib64
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/lib64

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
 /usr/bin/mkdir -p '/usr/local/lib64/pkgconfig'
 /usr/bin/install -c -m 644 libgpib.pc '/usr/local/lib64/pkgconfig'
make[4]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird verlassen
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird verlassen
Making install in gpib_config
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib/gpib_config“ wird betreten
make[4]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib/gpib_config“ wird betreten
 /usr/bin/mkdir -p '/usr/local/sbin'
  /bin/sh ../../libtool   --mode=install /usr/bin/install -c gpib_config '/usr/local/sbin'
libtool: install: /usr/bin/install -c .libs/gpib_config /usr/local/sbin/gpib_config
make[4]: Für das Ziel „install-data-am“ ist nichts zu tun.
make[4]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib/gpib_config“ wird verlassen
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib/gpib_config“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/lib“ wird verlassen
Making install in drivers
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/drivers“ wird betreten
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/drivers“ wird betreten
make[2]: Für das Ziel „install-exec-am“ ist nichts zu tun.
make  install-data-hook
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/drivers“ wird betreten
test -e /etc/gpib.conf || \
        /usr/bin/install -c -m 644 -D ../util/templates/gpib.conf /etc/gpib.conf
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/drivers“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/drivers“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/drivers“ wird verlassen
Making install in examples
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/examples“ wird betreten
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/examples“ wird betreten
 /usr/bin/mkdir -p '/usr/local/bin'
  /bin/sh ../libtool   --mode=install /usr/bin/install -c ibtest ibterm findlisteners '/usr/local/bin'
libtool: install: /usr/bin/install -c .libs/ibtest /usr/local/bin/ibtest
libtool: install: /usr/bin/install -c .libs/ibterm /usr/local/bin/ibterm
libtool: install: /usr/bin/install -c .libs/findlisteners /usr/local/bin/findlisteners
make[2]: Für das Ziel „install-data-am“ ist nichts zu tun.
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/examples“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/examples“ wird verlassen
Making install in test
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/test“ wird betreten
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/test“ wird betreten
make[2]: Für das Ziel „install-exec-am“ ist nichts zu tun.
make[2]: Für das Ziel „install-data-am“ ist nichts zu tun.
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/test“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/test“ wird verlassen
Making install in doc
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/doc“ wird betreten
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/doc“ wird betreten
make[2]: Für das Ziel „install-exec-am“ ist nichts zu tun.
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/doc“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/doc“ wird verlassen
Making install in language
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language“ wird betreten
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language“ wird betreten
make -C perl all
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language/perl“ wird betreten
"/usr/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- LinuxGpib.bs blib/arch/auto/LinuxGpib/LinuxGpib.bs 644
Manifying 1 pod document
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language/perl“ wird verlassen
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language“ wird betreten
make[3]: Für das Ziel „install-exec-am“ ist nichts zu tun.
make[3]: Für das Ziel „install-data-am“ ist nichts zu tun.
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/language“ wird verlassen
Making install in usb
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb“ wird betreten
Making install in agilent_82357a
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/agilent_82357a“ wird betreten
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/agilent_82357a“ wird betreten
make[3]: Für das Ziel „install-exec-am“ ist nichts zu tun.
/usr/bin/install -c -d /usr/local/share/usb/agilent_82357a
test -d /etc/udev/rules.d && test -e /etc/udev/rules.d/99-agilent_82357a.rules ||\
        /usr/bin/install -c -m 644 -D 99-agilent_82357a.rules /etc/udev/rules.d/99-agilent_82357a.rules
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/agilent_82357a“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/agilent_82357a“ wird verlassen
Making install in ni_usb_gpib
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/ni_usb_gpib“ wird betreten
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/ni_usb_gpib“ wird betreten
make[3]: Für das Ziel „install-exec-am“ ist nichts zu tun.
/usr/bin/install -c -d /usr/local/share/usb/ni_usb_gpib
test -d /etc/udev/rules.d && test -e /etc/udev/rules.d/99-ni_usb_gpib.rules ||\
        /usr/bin/install -c -m 644 -D 99-ni_usb_gpib.rules /etc/udev/rules.d/99-ni_usb_gpib.rules
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/ni_usb_gpib“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/ni_usb_gpib“ wird verlassen
Making install in lpvo_usb_gpib
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/lpvo_usb_gpib“ wird betreten
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/lpvo_usb_gpib“ wird betreten
make[3]: Für das Ziel „install-exec-am“ ist nichts zu tun.
test -d /etc/udev/rules.d && test -e /etc/udev/rules.d/99-lpvo_usb_gpib.rules ||\
        /usr/bin/install -c -m 644 -D 99-lpvo_usb_gpib.rules /etc/udev/rules.d/99-lpvo_usb_gpib.rules
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/lpvo_usb_gpib“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb/lpvo_usb_gpib“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb“ wird betreten
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb“ wird betreten
/usr/bin/install -c -D ./udevadm.sh /usr/local/lib/udev/gpib_udevadm_wrapper
/usr/bin/install -c -D gpib_udev_fxloader /usr/local/lib/udev/gpib_udev_fxloader
/usr/bin/install -c -D ./gpib_udev_config /usr/local/lib/udev/gpib_udev_config
test -d /etc/udev/rules.d && test -e /etc/udev/rules.d/98-gpib-generic.rules ||\
        /usr/bin/install -c -m 644 -D ./98-gpib-generic.rules /etc/udev/rules.d/98-gpib-generic.rules
make[3]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb“ wird verlassen
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user/usb“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user“ wird betreten
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user“ wird betreten
make[2]: Für das Ziel „install-exec-am“ ist nichts zu tun.
make[2]: Für das Ziel „install-data-am“ ist nichts zu tun.
make[2]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user“ wird verlassen
make[1]: Verzeichnis „/home/dennis/national-instruments-gpib-usb-hs/linux-gpib-code/linux-gpib-user“ wird verlassen

Groups

Create group “gpib”. Add your user to that group.

/etc/gpib.conf

Below is default file content after installation. You have to edit this, add your interface and instruments there.

% cat /etc/gpib.conf

/***********************************************************************
GPIB.CONF IEEE488 library config file
-------------------

copyright            : (C) 2002 by Frank Mori Hess
(C) 1994 by C.Schroeter
email                : fmhess@users.sourceforge.net
***************************************************************************/
/***************************************************************************
*
*   Syntax:
*
*         interface { ... } starts new interface board section
*         device {...} device configuration
*
***************************************************************************/

/* This section configures the configurable driver characteristics
* for an interface board, such as board address, and interrupt level.
* minor = 0 configures /dev/gpib0, minor = 1 configures /dev/gpib1, etc.
  */

interface {
minor = 0       /* board index, minor = 0 uses /dev/gpib0, minor = 1 uses /dev/gpib1, etc. */
board_type = "ni_pci"   /* type of interface board being used */
name = "violet" /* optional name, allows you to get a board descriptor using ibfind() */
pad = 0 /* primary address of interface             */
sad = 0 /* secondary address of interface           */
timeout = T3s   /* timeout for commands */

        eos = 0x0a      /* EOS Byte, 0xa is newline and 0xd is carriage return */
        set-reos = yes  /* Terminate read if EOS */
        set-bin = no    /* Compare EOS 8-bit */
        set-xeos = no   /* Assert EOI whenever EOS byte is sent */
        set-eot = yes   /* Assert EOI with last byte on writes */

/* settings for boards that lack plug-n-play capability */
base = 0        /* Base io ADDRESS                  */
irq  = 0        /* Interrupt request level */
dma  = 0        /* DMA channel (zero disables)      */

/* pci_bus and pci_slot can be used to distinguish two pci boards supported by the same driver */
/*      pci_bus = 0 */
/*      pci_slot = 7 */

        master = yes    /* interface board is system controller */
}

/* This is how you might set up a pcIIa board on /dev/gpib1, uncomment to use. */
/*******************
interface {
minor = 1
board_type = "pcIIa"
pad = 0
sad = 0
timeout = T3s

        eos = 0x0a
        set-reos = yes
        set-bin = no

        base = 0x2e1
        irq  = 7
        dma  = 1

        master = yes
}
*********************/

/* Now the device sections define the device characteristics for each device.
* These are only used if you want to open the device using ibfind() (instead
* of ibdev() )
  */

device {
minor = 0       /* minor number for interface board this device is connected to */
name = "voltmeter"      /* device mnemonic */
pad = 7 /* The Primary Address */
sad = 0 /* Secondary Address */

        eos = 0xa       /* EOS Byte */
        set-reos = no /* Terminate read if EOS */
        set-bin = no /* Compare EOS 8-bit */
}

device {
minor = 0
name = "scope"
pad = 8
sad = 0
}

When trying to load the newly compiled kernel module, I get an error:

[133155.556359] usb 5-2: new high-speed USB device number 12 using xhci_hcd
[133155.711687] usb 5-2: New USB device found, idVendor=3923, idProduct=709b, bcdDevice= 1.01
[133155.711698] usb 5-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[133155.711703] usb 5-2: Product: GPIB-USB-HS
[133155.711707] usb 5-2: Manufacturer: National Instruments
[133155.711711] usb 5-2: SerialNumber: 018522D4
[133156.345458] Loading of unsigned module is rejected

Hm. So I need to sign that module.

Sign kernel modules: install signmod

Install signmod from here https://github.com/cipherswami/signmod. For OpenSuse, some paths need to be adjusted. Run install.sh .

##############################################################
#------------------------------------------------------------#
#                        signmod                             #
#------------------------------------------------------------#
################## Author: cipherswami #######################

[#] NOT! Installing Req. Packages

[#] Generating a new private key and self-signed certificate...
.....+.........+.+...........+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+.....+.........+..........+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.........+...+...+......+.........+.....................+...+...+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......+...+...+....+...+............+...........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+..+...+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*............+.+............+.....+....+...+............+......+...+..+...+......+......+............+.......+......+........+....+..+.+..................+.....+....+..+.........+......+....+..+...+......+...+..........+..+...+.......+...+............+........+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----

[#] Setting permissions...

[#] Registering the certificate with MOK (reboot required) ...

[#] Set a password for MOK enrollment now, and use the same password during enrollment after the reboot.
input password: 
input password again: 
[#] Certificate registered successfully.

[#] Installing signmod script ...
[#] signmod script installed successfully at /usr/local/bin/signmod

[#] signmod installation completed. Reboot your system to complete the key enrollment.

pw was “signmod”. After a reboot, we can enroll new key from BIOS level and continue to boot into Linux. Linux now knows that new key and we can use it for code signing.

Check if new certificates/keys are enrolled in UEFI:

% mokutil --list-enrolled
...
[key 3]
SHA1 Fingerprint: f0:5e:12:ec:96:a4:7c:f2:4b:11:b2:4b:be:40:8d:cc:e2:af:ec:7c
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            15:2f:7c:49:2c:25:6d:b1:7a:af:49:ee:81:53:ca:c0:63:62:ea:5e
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=IN, ST=AndhraPradesh, L=Visakhapatnam, O=fCoderSociety, CN=signmod
        Validity
            Not Before: Sep  3 14:01:02 2025 GMT
            Not After : Sep  1 14:01:02 2035 GMT
        Subject: C=IN, ST=AndhraPradesh, L=Visakhapatnam, O=fCoderSociety, CN=signmod
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cf:f0:1e:b8:d3:0c:11:43:a9:3d:d5:ee:1a:7e:
                    df:39:ae:a4:7b:8d:e5:35:03:0b:d0:b3:bb:17:f1:
                    a7:cf:10:4c:c0:e1:f9:dd:7f:fc:9c:c0:72:de:c4:
                    bd:9f:a0:d9:52:5e:72:5b:39:76:b0:29:ef:2b:97:
                    d5:5a:98:21:a4:c6:c6:98:8d:d7:eb:bf:c4:77:25:
                    47:86:8d:05:65:24:5c:d0:a2:33:f1:2d:b3:1a:9a:
                    61:27:85:37:5e:8b:c6:6a:96:b5:d3:94:50:43:ac:
                    68:ab:36:64:a5:8e:eb:51:68:a1:8b:4f:27:23:ec:
                    e0:02:38:e4:77:38:2f:e9:a0:ad:86:ec:be:4f:df:
                    3d:92:8e:38:7b:d1:1a:cb:80:d4:6f:85:80:be:0a:
                    72:de:0d:e6:2a:38:9e:fc:42:45:25:19:cf:2c:58:
                    4b:80:30:ba:24:8a:ef:38:72:28:0d:cc:e6:b6:16:
                    22:ee:b7:e4:6a:b5:ca:00:b6:cd:33:de:39:37:19:
                    27:2a:7d:a3:b0:ca:40:96:3f:28:a8:46:49:16:35:
                    f8:69:f6:b1:75:e7:ff:15:d9:b2:75:ce:41:80:c9:
                    a9:df:54:ad:08:c6:09:ac:3d:fb:98:6f:f3:5a:03:
                    93:25:03:e2:a9:05:52:32:4b:30:d3:00:df:28:01:
                    8e:4b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                C9:5E:A4:15:B7:6F:77:A0:FA:75:E6:9D:84:F8:34:A7:E0:B0:AD:85
            X509v3 Authority Key Identifier: 
                C9:5E:A4:15:B7:6F:77:A0:FA:75:E6:9D:84:F8:34:A7:E0:B0:AD:85
            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        1e:6c:b5:a2:4d:ff:0c:4a:7d:92:70:d3:ba:97:38:41:f2:c5:
        3c:c4:ba:8c:3c:af:3b:60:ce:a2:56:d1:0a:72:06:94:41:9e:
        17:20:57:fa:46:9e:22:e2:a4:88:2b:fe:a4:b7:ba:dc:b8:e4:
        f3:ae:ad:a2:4b:59:9b:2c:fd:2a:ae:aa:3b:b7:f0:39:02:5b:
        bc:43:73:fa:4f:9b:7f:a7:e5:63:55:72:c7:11:54:9a:ec:51:
        38:45:e3:dc:81:d5:af:39:4a:43:22:c1:ee:e7:f9:60:75:69:
        c6:d0:a5:5f:2c:0a:35:a8:61:17:64:14:28:95:ad:ef:24:b1:
        8e:d7:26:64:4c:18:4e:71:fc:53:f1:86:49:cd:b7:a4:d8:f2:
        d1:18:b6:36:5b:ac:b7:82:13:a4:34:fb:33:24:c4:f0:20:6c:
        58:d5:db:1e:c4:5b:32:5e:b6:9f:ec:3d:f2:57:99:4a:5b:f6:
        84:2a:10:b6:5c:a1:e7:c6:ab:39:f3:15:dc:cf:53:ce:52:c5:
        6d:62:4b:07:fc:6e:d9:28:a8:dd:02:ba:f5:8d:ab:a6:eb:c9:
        80:68:c9:bc:60:68:1a:fb:c6:7c:46:b4:f2:24:ab:20:94:92:
        23:a7:a3:20:d8:4f:3c:39:6f:82:01:20:b2:8b:7b:74:9d:35:
        eb:44:6d:ff

Yes, that worked.

Now do the actual signing:

# signmod ni_usb_gpib.ko
[#] Module 'ni_usb_gpib.ko' signed successfully.

Check if module was signed:

# modinfo ni_usb_gpib.ko
filename:       /lib/modules/6.4.0-150600.23.65-default/gpib/ni_usb/ni_usb_gpib.ko
license:        GPL
suserelease:    SLE15-SP6
srcversion:     01145208B2106C5346843DD
alias:          usb:v3923p725Dd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v3923p725Cd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v3923p7618d*dc*dsc*dp*ic*isc*ip*in00*
alias:          usb:v3923p709Bd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v3923p702Ad*dc*dsc*dp*ic*isc*ip*in*
depends:        usbcore,gpib_common
retpoline:      Y
name:           ni_usb_gpib
vermagic:       6.4.0-150600.23.65-default SMP preempt mod_unload modversions 
sig_id:         PKCS#7
signer:         signmod
sig_key:        15:2F:7C:49:2C:25:6D:B1:7A:AF:49:EE:81:53:CA:C0:63:62:EA:5E
sig_hashalgo:   sha256
signature:      3B:CB:C8:88:60:54:CE:A6:B0:EC:D4:82:0F:7C:E5:F2:A1:D1:46:5E:
                C1:D1:99:0D:FC:24:4B:FC:5E:2F:AB:00:6B:FB:19:A2:27:07:7F:F9:
                B5:CE:87:0C:17:9E:9B:90:CB:F0:4D:1A:1B:2E:C3:4E:C4:02:43:19:
                58:28:AF:0B:26:AA:70:1A:1C:11:E1:AB:26:B5:DB:92:C8:DD:24:7B:
                7C:09:D6:F5:2B:72:40:01:89:7C:DB:2F:03:C4:DC:4D:86:03:3C:F2:
                73:65:A1:32:1C:E2:D7:09:04:1D:D4:DF:E3:DA:87:2F:DE:8D:9E:9C:
                D8:67:C7:AA:30:11:62:47:A6:53:1C:E1:96:64:8F:15:2D:F0:55:27:
                FE:DF:C0:D5:DE:E8:45:7E:94:97:0E:87:B3:40:D6:93:C7:E6:D7:D8:
                BB:8E:7A:ED:DC:BB:40:68:B8:E6:99:2B:DF:87:71:0F:75:1F:CA:5D:
                C7:C9:58:4D:2B:6E:FA:4D:8C:01:DC:33:C1:2C:4D:0E:23:60:0A:B5:
                9C:E1:3D:49:D0:56:F6:FA:94:16:C2:80:75:98:08:21:27:F6:13:D1:
                39:FD:EE:B0:C8:3F:A5:13:98:C4:1C:E2:86:15:F0:A8:9D:B4:0A:92:
                9E:01:62:F2:BF:C0:11:F8:DF:16:05:1E:9C:00:2A:B7

Looks good.

Try to load module:

# insmod ni_usb_gpib.ko
insmod: ERROR: could not insert module ni_usb_gpib.ko: Key was rejected by service
# modprobe ni_usb_gpib
modprobe: ERROR: could not insert 'ni_usb_gpib': Key was rejected by service

Hm, this still is failing, despite module is signed with a key known to UEFI. What is still wrong? Deep search brought this up (maybe valid for Opensuse only):

The EKU codeSigning setting is required for latest kernel releases of 
openSUSE Leap/Tumbleweed to accept the certificate for signature verification 
of kernel modules. The -addext option requires OpenSSL version 1.1.1 or later. 

More Info:

Related issues: https://sourceforge.net/p/linux-gpib/mailman/linux-gpib-general/thread/44219D64.6070406@ll.mit.edu/ How it should work: https://gist.github.com/ochococo/8362414fff28fa593bc8f368ba94d46a Some additional infos: https://www.cl.cam.ac.uk/~osc22/tutorials/gpib_usb_linux.html Also related: https://tomverbeure.github.io/2023/01/29/Installing-Linux-GPIB-Drivers-for-the-Agilent-82357B.html

So I adjusted the key creation part of install.sh to have that additional option -addext "extendedKeyUsage=codeSigning". See changed excerpt from script file below:

...
# Function to generate a new private key and self-signed certificate
generate_keys() {
    echo "[#] Generating a new private key and self-signed certificate..."

    # Generate private key and certificate in DER format
    openssl req -new -x509 -newkey rsa:$KEY_SIZE -sha256 -keyout "$PRIVATE_KEY" -out "$CERTIFICATE_DER" -outform der -nodes -nodes -days $DAYS_VALID -subj "$CERT_SUBJECT" -addext "extendedKeyUsage=codeSigning" || { echo "[!] Failed to generate keys"; exit 1; }
...    

Keys were recreated then, and accepted via BIOS and reboot again.

Below is a dump of new key. Note the new X509v3 Extended Key Usage: section:

[key 4]
SHA1 Fingerprint: e7:2b:cc:6c:db:8c:1a:0e:02:b9:45:7d:41:48:14:b9:67:6b:13:41
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0f:f1:1b:5f:dc:85:61:ca:c6:0d:3a:c1:09:88:01:d3:e6:06:d9:54
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=DE, ST=DennisD, L=Spurtikus, O=fCoderSociety, CN=signmod
        Validity
            Not Before: Sep  3 14:52:37 2025 GMT
            Not After : Sep  1 14:52:37 2035 GMT
        Subject: C=DE, ST=DennisD, L=Spurtikus, O=fCoderSociety, CN=signmod
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b3:f2:ef:12:d3:69:b6:64:6c:97:c7:3c:1a:3f:
                    eb:e0:dc:13:11:71:e9:ec:1e:44:db:e6:97:33:b3:
                    8e:d0:0e:28:3f:7d:b6:a4:f4:26:fc:8f:68:99:02:
                    8a:20:32:64:5d:e2:48:c9:e0:56:90:74:f4:d4:ac:
                    cc:cf:95:96:79:ac:2f:4f:78:3c:fd:c3:bd:ad:9c:
                    aa:fa:8b:b6:71:ad:c8:4b:83:e5:dc:9d:f6:34:ff:
                    3d:e3:c6:2c:f2:36:a0:53:30:03:b1:71:9e:89:9d:
                    fb:bc:0a:84:78:2d:fb:ff:1f:c8:1d:b6:cf:b0:de:
                    a9:bf:4b:5c:da:f0:bb:c2:41:6b:86:c7:2b:c9:92:
                    3d:f2:66:cd:7e:00:9f:cf:64:6d:d4:90:3b:9b:fd:
                    28:cc:f8:dd:77:f6:a8:cb:54:93:8a:fb:c3:85:bf:
                    12:76:13:f1:c9:38:1b:06:9c:ec:1e:ad:28:44:bc:
                    c2:b8:47:7e:7f:28:8a:d0:df:b0:e2:0a:17:69:b8:
                    06:3b:b9:44:77:f4:22:74:17:2a:ca:43:65:71:8e:
                    fd:49:15:24:08:a1:c5:50:ce:b1:30:41:d0:64:e0:
                    33:e9:76:1b:26:05:52:e3:46:f9:69:61:69:53:9d:
                    2c:0e:a8:4a:7d:39:1b:83:c5:1b:46:78:91:2e:b5:
                    9e:f9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                AE:DB:17:98:22:E1:77:65:CE:B7:3D:FB:DF:41:B4:61:AF:8D:36:5E
            X509v3 Authority Key Identifier: 
                AE:DB:17:98:22:E1:77:65:CE:B7:3D:FB:DF:41:B4:61:AF:8D:36:5E
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Extended Key Usage: 
                Code Signing
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        23:ec:6b:cd:47:22:bc:c7:10:82:fb:de:ba:42:71:df:aa:31:
        f0:d3:65:78:ff:99:b7:5e:cc:21:81:47:77:4a:bb:99:22:6c:
        a6:ea:e5:e0:39:4f:2c:83:4c:c4:ef:a0:fd:1b:fe:b0:cb:62:
        33:f7:8e:dc:bf:a1:2d:f7:2d:73:ce:fd:f6:57:e3:7c:2e:e0:
        74:d7:a3:8a:23:a0:66:7b:4a:ec:14:f2:f8:b8:1e:dd:0f:b8:
        b7:e5:22:ad:f3:79:24:a7:4f:76:90:c6:1e:bf:16:37:b5:e1:
        aa:fb:dc:f1:11:cf:f8:b2:cb:0a:b1:91:b5:48:25:7b:8a:78:
        a7:95:a3:95:c3:41:50:9f:f5:2f:1b:b2:c8:7a:93:80:09:e4:
        7e:4b:65:e3:bd:77:40:a9:c0:94:68:f8:3e:fd:2a:f9:c3:8b:
        b6:02:1d:22:7d:8c:bc:04:d9:77:f8:ef:b6:a8:17:27:ac:aa:
        10:83:35:a5:40:1e:65:f7:f4:e2:48:c5:a0:39:02:17:88:85:
        78:f7:e8:20:ce:bd:ed:e9:a8:2b:37:a4:fb:c4:15:6c:be:e6:
        57:67:f4:94:cf:73:23:c4:b3:1c:66:83:6c:1d:c4:cf:3a:a0:
        67:7a:b2:e1:d6:3c:84:5c:6c:c7:c4:da:ac:94:c6:e9:6a:a4:
        de:c5:27:3f

With that key, I signed again the kernel module.

And this module is finally accepted. There is some dependency to other modules from Linux-GPIB package, therefore we get unknown symbol error when loading the module. So I signed ALL the other newly compiled modules with same mechanism (signmod) and these modules could be loaded too.

Errors when some dependent modules cannot be loaded (from dmesg):

[  221.764007] ni_usb_gpib: Unknown symbol gpib_register_driver (err -2)
[  221.764118] ni_usb_gpib: Unknown symbol gpib_unregister_driver (err -2)
[  221.764169] ni_usb_gpib: Unknown symbol gpib_match_device_path (err -2)
[  547.304357] usb 5-2: new high-speed USB device number 12 using xhci_hcd
[  547.455741] usb 5-2: New USB device found, idVendor=3923, idProduct=709b, bcdDevice= 1.01
[  547.455752] usb 5-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  547.455758] usb 5-2: Product: GPIB-USB-HS
[  547.455762] usb 5-2: Manufacturer: National Instruments
[  547.455766] usb 5-2: SerialNumber: 018522D4
[  548.092483] Loading of unsigned module is rejected

[  573.300199] ni_usb_gpib: Unknown symbol gpib_register_driver (err -2)
[  573.300435] ni_usb_gpib: Unknown symbol gpib_unregister_driver (err -2)
[  573.300538] ni_usb_gpib: Unknown symbol gpib_match_device_path (err -2)
[  656.631106] ni_usb_gpib: Unknown symbol gpib_register_driver (err -2)
[  656.631206] ni_usb_gpib: Unknown symbol gpib_unregister_driver (err -2)
[  656.631252] ni_usb_gpib: Unknown symbol gpib_match_device_path (err -2)

And loading, when we have signed dependent modules (I signed all modules):

[  779.108426] Linux-GPIB 4.3.6 Driver
[  792.427583] ni_usb_gpib driver loading
[  792.541118] ni_usb_gpib: probe succeeded for path: usb-0000:04:00.4-2
[  792.541166] usbcore: registered new interface driver ni_usb_gpib
[  792.541170] gpib: registered ni_usb_b interface

When having no feasible modules, the Adapter shows no activity. When I was able to load the modules, the “READY” LED was lighting.

By the way, The installation of linux-gpib package added some udev rule files, file /etc/udev/rules.d/99-ni_usb_gpib.rules contains the specific udev rule for NI USB adapters:

# more /etc/udev/rules.d/99-ni_usb_gpib.rules
#gpib-usb-b without firmware
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="3923", ATTR{idProduct}=="702b", ENV{DEVICE}="$devnode", RUN+="/usr/lo
cal/lib/udev/gpib_udev_fxloader"
#device id 713b is a keithley kusb-488 before we load it with firmware
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="3923", ATTR{idProduct}=="713b", ENV{DEVICE}="$devnode", RUN+="/usr/lo
cal/lib/udev/gpib_udev_fxloader"

#automatically set the correct --board-type option
ACTION=="add|change", SUBSYSTEM=="usb", DRIVER=="ni_usb_gpib", ATTRS{serial}=="*", ENV{GPIB_CONFIG_OPTIONS}+="--board-t
ype ni_usb_b", ENV{SERIAL}="$attr{serial}"
#devices ready to be configured with gpib_config
SUBSYSTEM=="usb", ACTION=="add|change", DRIVER=="ni_usb_gpib", ATTRS{idVendor}=="3923", ATTRS{idProduct}=="702a", RUN+=
"/usr/local/lib/udev/gpib_udev_config"
SUBSYSTEM=="usb", ACTION=="add|change", DRIVER=="ni_usb_gpib", ATTRS{idVendor}=="3923", ATTRS{idProduct}=="709b", RUN+=
"/usr/local/lib/udev/gpib_udev_config"
SUBSYSTEM=="usb", ACTION=="add|change", DRIVER=="ni_usb_gpib", ATTRS{idVendor}=="3923", ATTRS{idProduct}=="7618", RUN+=
"/usr/local/lib/udev/gpib_udev_config"
SUBSYSTEM=="usb", ACTION=="add|change", DRIVER=="ni_usb_gpib", ATTRS{idVendor}=="3923", ATTRS{idProduct}=="725[cd]", RU
N+="/usr/local/lib/udev/gpib_udev_config"

#this rule generates new "change" udev events for devices supported by the
#driver after the module is loaded.
#it is needed because if the driver is not already loaded when the hardware is plugged in,
#then the initial hardware "add" event will not be able to accomplish anything.
SUBSYSTEM=="module", ACTION=="add", DEVPATH=="/module/ni_usb_gpib", RUN+="/usr/local/lib/udev/gpib_udevadm_wrapper trig
ger --property-match DRIVER=ni_usb_gpib"

Accessing the GPIB-USB-HS adapter

linux-gpib package calls the hardware adapter an “interface”.

Attaching device after reboot (dmesg):

[   98.900349] usb 5-1.3.4: new high-speed USB device number 12 using xhci_hcd
[   99.003701] usb 5-1.3.4: New USB device found, idVendor=3923, idProduct=709b, bcdDevice= 1.01
[   99.003712] usb 5-1.3.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[   99.003716] usb 5-1.3.4: Product: GPIB-USB-HS
[   99.003720] usb 5-1.3.4: Manufacturer: National Instruments
[   99.003724] usb 5-1.3.4: SerialNumber: 018522D4
[   99.656078] Linux-GPIB 4.3.6 Driver
[   99.666402] ni_usb_gpib driver loading
[   99.666443] ni_usb_gpib: probe succeeded for path: usb-0000:04:00.4-1.3.4
[   99.666468] usbcore: registered new interface driver ni_usb_gpib
[   99.666470] gpib: registered ni_usb_b interface
[   99.804646] ni_usb_gpib: attach
[   99.804658] usb 5-1.3.4: bus 5 dev num 12 attached to gpib minor 0, NI usb interface 0
[   99.890871] ni_usb_hs_wait_for_ready: board serial number is 0x18522d4

On this page I found how to check an interface: https://epics-controls.org/resources-and-support/documents/howto-documents/gpib-ports-linux-streamdevice/#Verify_connection_to_GPIB_board

After adding a name for the interface, I could talk to the interface and see the activity LED flashing:

interface {
        minor = 0
        name = "niusb"
        board_type = "ni_usb_b"
        pad = 0
        master = yes
}

More info on gpib.conf: https://linux-gpib.sourceforge.io/doc_html/configuration-gpib-conf.html

With executable “ibtest” from Linux-gpib package we can manually try gpib commands and such. With that tool, I could access my interface board and get the bus line status:

# ibtest
Do you wish to open a (d)evice or an interface (b)oard?
        (you probably want to open a device): b
enter name of interface board (or device) you wish to open: niusb
trying to open board named 'niusb'
You can:
        w(a)it for an event
        write (c)ommand bytes to bus (system controller only)
        send (d)evice clear (device only)
        change remote (e)nable line (system controller only)
        (g)o to standby (release ATN line, system controller only)
        send (i)nterface clear (system controller only)
        ta(k)e control (assert ATN line, system controller only)
        get bus (l)ine status (board only)
        go to local (m)ode
        change end (o)f transmission configuration
        (q)uit
        (r)ead string
        perform (s)erial poll (device only)
        change (t)imeout on io operations
        request ser(v)ice (board only)
        (w)rite data string
        send group e(x)ecute trigger (device only)
: l
DAV off
NDAC on
NRFD off
IFC off
REN on
SRQ off
ATN on
EOI off
gpib status is: 
ibsta = 0x130  < CMPL CIC ATN >
iberr= 0

ibcntl = 0
...

Accessing a GPIB device

Now I added a device description for my HP3455A. Its device address was set to 4 using the switches at its backside. My complete gpib.conf now looks like this:

interface {
        minor = 0
        name = "niusb"
        board_type = "ni_usb_b"
        pad = 0
        master = yes
}

device {
        minor = 0
        name = "hp3455"
        pad = 4
        sad = 0
}

After that addition (or any change to gpib.conf), gpib_config needs to be executed again. And immediately after that, I could communicate with my HP3455A. Below, two voltage values are read from the device.

# ibtest
Do you wish to open a (d)evice or an interface (b)oard?
        (you probably want to open a device): d
enter primary gpib address for device you wish to open [0-30]: 4
trying to open pad = 4 on /dev/gpib0 ...
You can:
        w(a)it for an event
        write (c)ommand bytes to bus (system controller only)
        send (d)evice clear (device only)
        change remote (e)nable line (system controller only)
        (g)o to standby (release ATN line, system controller only)
        send (i)nterface clear (system controller only)
        ta(k)e control (assert ATN line, system controller only)
        get bus (l)ine status (board only)
        go to local (m)ode
        change end (o)f transmission configuration
        (q)uit
        (r)ead string
        perform (s)erial poll (device only)
        change (t)imeout on io operations
        request ser(v)ice (board only)
        (w)rite data string
        send group e(x)ecute trigger (device only)
: r
enter maximum number of bytes to read [1024]: 
trying to read 1024 bytes from device...
received string: '-1.357350E+00
'
Number of bytes read: 15
gpib status is: 
ibsta = 0x2100  < END CMPL >
iberr= 0

ibcntl = 15
You can:
(bla bla suppressed ...)

: r
enter maximum number of bytes to read [1024]: 
trying to read 1024 bytes from device...
received string: '-1.326420E+00
'
Number of bytes read: 15
gpib status is: 
ibsta = 0x2100  < END CMPL >
iberr= 0

ibcntl = 15
...

Infos for HP3455A GPIB implementation can be found in Operating and Service Manual. Addressing at page 3-7, details on commands page 3-7 - 3-14. HP3455A is an older guy, so it has only few commands, and the command syntax is very basic.

Using the “HP3455A Multimeter Command Line Control Tool”

Someone else already has written some cool code for HP3455A:

https://hackaday.io/project/200870-hp3455a-multimeter-command-line-control-tool

I’ve downloaded, compiled and executed that for testing. Works well.

Compilation

Compilation steps after download:

% cd ~/src/HP3455A_ctl_05_07_2025/
% ls
AA_README        gpib_error_strings.c  gpib_stuff.h   HP3455A_ctl.h  Makefile_MINGW    sleep_ms.c       text_utils.c
engr_notation.c  gpib_error_strings.h  HP3455A.c      HP3455A.h      parse_and_exec.c  sleep_ms.h       text_utils.h
engr_notation.h  gpib_stuff.c          HP3455A_ctl.c  Makefile       parse_and_exec.h  std_constants.h
% make
gcc -c -Wall HP3455A_ctl.c
gcc -c -Wall gpib_stuff.c
gcc -c -Wall sleep_ms.c
gcc -c -Wall text_utils.c
gcc -c -Wall HP3455A.c
gcc -c -Wall parse_and_exec.c
gcc -c -Wall engr_notation.c
gcc -Wall HP3455A_ctl.o gpib_stuff.o HP3455A.o sleep_ms.o \
text_utils.o parse_and_exec.o engr_notation.o -lm -lgpib \
-o HP3455A_ctl

Trying it out

Basic read of a single measurement:

% ./HP3455A_ctl
Usage: HP3455A_ctl [-d dev_addr] CMD1 [arg1] [CMD2]...
where CMDn [argn] is one of:

HELP                   cmd_name
READ_CMDFILE           cmdfilename
INTERACTIVE            [TOLERANT]
SLEEP_MS               NmilliSeconds
GET_MEAS               No Parameters
SET_MODE               DC_VOLTS/AC_VOLTS/AC_VOLTS_FAST/OHMS_2W/OHMS_4W/VDC/VAC/VACF/OHMS2/OHMS4/TEST
SET_RANGE              0.1/1/10/100/1000/10000/1K/10K/AUTO
SET_TRIGGER_SOURCE     INTERNAL/EXTERNAL/MANUAL
SET_MATH               SCALE/ERROR/OFF
SET_Y_Z_VAL            Y/Z val.xxx
STORE_Y_Z              Y/Z
GET_Y_Z_VAL            Y/Z
SET_DISPLAY_REG_A      No Parameters
AUTOCAL                ON/OFF
HI_RES                 ON/OFF
DATA_RDY_RQS           ON/OFF
GET_CONFIG             [DISP]
RESTORE_CONFIG         NO Parameters
FETCH_TO_FILE          Num dwell_ms Filename
FETCH_TO_FILE_HS       Num dwell_ms Filename    EXPERIMENTAL
SHOW_MSG_BLOCK         No Parameters
DEV_CLR                No Parameters
DEV_LOCAL              No Parameters
GRP_TRIGGER            No Parameters
SERIAL_POLL            [DISP]
SHOW_RESPONSE          cmdstring
SEND_CMD               cmdstring


The configuration options (starting with -) must all
be before the first command.

% ./HP3455A_ctl GET_MEAS
[0] Value: -1.408410e+0

Now 100 values at given time steps, into a file:

% ./HP3455A_ctl FETCH_TO_FILE 100 100 test1
** Internal message block is not valid. ***
** Retrieve Configuration from 3455A. ***
Config: DC Volts, Range: 1.0, Autorange EN, Autocal EN, HiRes DIS, Trigger: INT, Math OFF, Raw config values: 0x3B 0x4E 0x3D 0x3E
Force off AUTORANGE mode

INFO, calculated measurement time: 160 mS
NOTE: requested dwell time less than calculated measurement time.
Using Calculated Measurement time as dwell time: 160 mS
[0] Get: 100 samples dwell_time: 160 mS to file: test1
Index,VALUE
1,-1.398350e+0
2,-1.417360e+0
3,-1.389100e+0
... (lines ommitted)
98,-1.395760e+0
99,-1.399900e+0
100,-1.418970e+0

% more test1
Index,VALUE
1,-1.398350e+0
2,-1.417360e+0
3,-1.389100e+0
... (lines ommitted)

Nice.

Add Kernel lock to keep module usable

The new module is compiled against some kernel version. When updating the system, the kernel could be overwritten. To keep a steady state, I added a kernel lock:

# zypper al 'kernel*'
Die angegebene Sperre wurde erfolgreich hinzugefügt.

More info on that, see here: https://ehowton.livejournal.com/875646.html

See also

Installation:

Linux GPIB Package, more general info:

Linux issues: