You are on page 1of 7

Technical Note 029

Enabling Your NI-488.2M for UNIX ™

Applications to Interrupt on SRQ and Other


GPIB Events
Chip SaGomes

Introduction
Interrupt service routines provide fast, automatic responses to asynchronous events. You can use
an interrupt service routine to respond to specific events on the GPIB, such as the assertion of the
GPIB Service Request (SRQ) line. Applications that use interrupt service routines are
advantageous because you do not have to use periodic polling to check for the occurrence of an
asynchronous event, which is often inconvenient.

You can implement interrupt service routines using the NI-488.2M software and UNIX signals.
The National Instruments AT-GPIB, SB-GPIB (SBus-to-GPIB), MC-GPIB (MicroChannel-to-
GPIB), TC-GPIB (TURBOchannel-to-GPIB), and GPIB-1014 (VME-to-GPIB) interfaces and
their corresponding NI-488.2M/ NI-488M™ software drivers use UNIX signals so that
asynchronous events on the GPIB can cause hardware interrupts. This technical note describes
how you can enable your application to interrupt when a device requests service. It also
mentions other GPIB events that you can use to cause interrupts and presents a complete
program example.

Interrupting on SRQ
The GPIB SRQ Line and Serial Polling
IEEE 488 devices request service from the GPIB Controller by asserting the GPIB SRQ line.
When the Controller acknowledges the service request (SRQ), it serial polls each device on the
bus to determine which device requested service. Any device requesting service returns a status
byte with Bit 6 set and then unasserts the SRQ line after the serial poll. Devices not requesting
service return a status byte with Bit 6 cleared. Manufacturers of IEEE 488 devices use lower
order bits to indicate the reason for the service request or to summarize the state of the device.

The ANSI/IEEE Standard 488.2-1987 refined the bit assignments in the status byte. In addition
to setting Bit 6 when requesting service, IEEE 488.2 devices also set two other bits: Bit 4 and
Bit 5. Bit 4, the Message Available bit (MAV), is set when the device is ready to send
previously queried data. Bit 5, the Event Status bit (ESB), is set if one or more of the enabled
IEEE 488.2 events occur.

_____________________________
Product and company names are trademarks or trade names of their respective companies.

340549-01 © Copyright 1993 National Instruments Corporation. All rights reserved. August 1993
If you want more detailed information on serial polling, refer to National Instruments
Application Note 34, Serial Polling and SRQ Servicing with NI-488.2 Software (part number
340277-01).

UNIX Signals
The UNIX operating system defines a set of interrupt levels called signals that notify a process
that a particular event has occurred. Users interface to UNIX signals through the signal
system call. The signal call has two parameters: the UNIX signal level and the address of the
function to perform when the signal occurs. From an application standpoint, the signal
resembles a hardware interrupt. When UNIX reports a signal to a process, the process is
interrupted and control transfers to the function named in the signal call. The signal is
blocked until the service routine completes and transfers control back to the calling process.
For information about the different types of UNIX signals, refer to the UNIX man pages on
signal by typing man signal at the UNIX prompt. For an example of the signal call,
refer to the example program presented at the end of this technical note.

Implementing an SRQ Interrupt Service Routine


The following steps explain and demonstrate how to implement an SRQ interrupt service routine.
A complete program example is presented at the end of this technical note. This procedure is
based on the assumption that you already have your NI-488.2M software installed and you are
familiar with ibconf, the NI-488.2M driver configuration utility. You can refer to your
Getting Started manual for installation instructions and to the NI-488.2M Software Reference
Manual, (part number 320351-01), for information about ibconf.

2
1. Run ibconf, the NI-488.2M driver configuration utility. Locate the device map for gpib0
(or the GPIB interface you are using). Disable automatic serial polling and make a note of
the UNIX signal associated with the NI-488.2M driver, as shown in the following figure.

===============================================================================
National Instruments | Board characteristics |
===============================================================================
Board: gpib0 | SELECT (use h or l key):
----------------------------------------+--------------------------------------
Primary gpib address .......... 00H |
Secondary gpib address ........ NONE |
Timeout setting ............... T10s |
EOS byte ...................... 00H |
Terminate read on EOS ......... no |
Set EOI with EOS on write ..... no |
Type of compare on EOS ........ 7-bit |
Set EOI w/last byte of write .. yes |
|
Board is system controller .... yes |
Disable auto serial polling ... no | <- Change
Change this field
this field to yes
to yes
Local parallel poll ........... no |
Timing ........................ veryhi |
UNIX signal ................... 230 | <- Note this
Note this value
value
DMA mode ...................... yes |
|
(Use j or k key to change fields) |
-------------------------------------------------------------------------------
^Q: help ^W: explain field ^Y: reset value ^O: return to map

Example ibconf Screen

2. Write the interrupt routine in your application code. This routine depends on your
application. For example, if your application interrupts when a device asserts SRQ, you
should conduct a serial poll to find the devices requesting service. Your application should
then decode the returned status bytes and service the devices appropriately. The following
code is an example service routine for a one-device system.
void int_serv_func() { /* SRQ interrupt service routine
*/
unsigned char status; /* Store serial poll response byte.
*/
printf("SRQ asserted on GPIB\n");
ibrsp(ud,&status); /* Perform serial poll of device.
*/
/* ud is the device handle for the device.
*/
/* Device handles are returned from calls to ibfind.
*/
if (status & 0x40) service_device ();
/* service_device is the device service routine.
*/
}

3
3. Issue the UNIX system call signal to associate your service routine with the UNIX signal
used by the GPIB driver. Use the UNIX signal level value associated with the GPIB driver
(noted in step 1) and the address of your service routine as parameters for signal. The
following example in C shows a typical call to signal.
signal(SIGUSR1,int_serv_func);
/* SIGUSR1 is defined in <signal.h>. It is the
*/
/* same as the UNIX signal found in ibconf.
*/
/* int_serv_func is called when SIGUSR1 is delivered.
*/

4. Issue the NI-488.2M function call ibsgnl. The parameters you use set the criteria that the
NI-488.2M driver uses to deliver the signal to your application. The following example uses
the function ibsgnl to deliver a signal when the GPIB SRQ line is asserted.
ibsgnl(brd,0xSRQ1);
/* brd is the unit descriptor returned by ibfind
*/
/* (gpib0). NOTE: ibsgnl is a board level call.
*/
/* You cannot use the unit descriptor for a device.
*/
/* SRQ1 is defined in the gpib header file ugpib.h and
*/
/* causes the driver to deliver the signal when SRQ is
*/
/* asserted.
*/

Refer to the example program at the end of this technical note to see the implementation of an
SRQ interrupt service routine.

Interrupting on Other GPIB Events


This section discusses GPIB events other than SRQ that you can use to cause interrupts. To
implement an interrupt service routine for GPIB conditions other than SRQ, follow the steps in
the previous section Implementing an SRQ Interrupt Service Routine. However, you do not need
to disable auto-serial polling in ibconf unless you are interrupting on SRQ.

Selecting Different Mask Variables in ibsgnl


You can configure your NI-488.2M software to interrupt on GPIB events other than SRQ by
selecting different mask variables in ibsgnl. Refer to the following table to see the layout of
the mask variable.

Except for SRQI, a signal is sent to your application on any transition into or out of a specific
state (for example, from TACS to non-TACS). The SRQI event signals only the assertion of the
SRQ line, not its unassertion. You can issue the ibwait call with a parameter of 0 in your
interrupt service routine. The ibwait function updates ibsta, which contains the current
state of the GPIB board. For example, if you used a value of 0x4 hex in the ibsgnl function
call, an interrupt would occur when the GPIB board was listen addressed or unaddressed. A call
to the function ibwait updates ibsta and reveals the exact state of the board (listen addressed

4
or unaddressed). The information returned in ibsta could then determine the action taken in
the interrupt service routine.

Signal Mask Layout

Bit Hex
Mnemonic Description
Position Value
SRQI 12 1000 SRQ on
LOK 7 80 GPIB board is in Lockout state
REM 6 40 GPIB board is in Remote state
CIC 5 20 GPIB board is Controller-In-Charge
TACS 3 8 GPIB board is Talker
LACS 2 4 GPIB board is Listener
DTAS 1 2 GPIB board is in Device Trigger State
DCAS 0 1 GPIB board is in Device Clear State

Using a Master and Slave Application


Another example of a useful interrupt service routine is in a master and slave application. You
can set up the application so that it is interrupted when the slave computer enters the Talker
Active or Listener Active state. When the slave is Talker Active, the interrupt routine can write
data to the master computer. When the slave is Listener Active, it can read data from the master.
If no signal is received, the application continues to process data or performs other necessary
tasks.
The next section contains an example program that demonstrates how to implement an SRQ
service routine.

5
Example Program
/* This program shows the implementation of a simple SRQ interrupt
* service routine. It was written to control a National Instruments
* GPIB device emulator.
*/
#include <stdio.h>
#include "ugpib.h"

#define SIGUSR1 30 /* UNIX signal associated with GPIB driver */

/* Application program variables passed to GPIB functions */


char rd[1024]; /* read data buffer */
int brd; /* board handle */
int emul; /* device handle */
int NO_SRQ; /* flag for while loop */

/* The following routine is called when the SRQ line is asserted */


void SRQ_service() { /* SRQ interrupt service routine */
unsigned char status; /* stores serial poll response byte */
printf("SRQ asserted on GPIB\n");
ibrsp(emul,&status); /* performs serial poll of device */
printf("Value of SPR byte = %x\n",status);
NO_SRQ = 0; /* stops while loop */
}

main() {
NO_SRQ = 1; /* initiate flag for while loop */

if ((brd = ibfind ("gpib0")) < 0) finderr();


/* obtain unit descriptor for board */

if (ibsic(brd) & ERR) error();


/* reset board & become controller-in-charge */

if ((emul = ibfind ("dev1")) < 0) finderr();


/* obtain unit descriptor for device */

signal(SIGUSR1,SRQ_service);
/* associate SRQ_service routine with signal SIGUSR1 */

if (ibsgnl(brd,0x1000)& ERR) error();


/* configure driver to issue signal on SRQ */

if (ibclr (emul) & ERR) error();


/* reset device */
if (ibwrt (emul,"g0 e0x40 w1",11) & ERR) error();
/* request a sine wave from device and configure it to */
/* assert SRQ when it is done generating data */

while (NO_SRQ);
/* wait in loop until SRQ_service changes NO_SRQ */
/* Now the program is free to do other tasks while */
/* device is generating data. */

if (ibrd (emul,rd,1024L) & ERR) error();


else printf("Number of bytes read = %d\n",ibcnt);
/* read data from device, it will assert EOI on last byte */

if (ibonl (emul,0) & ERR) error();


/* free unit descriptor for device */

if (ibonl (brd,0) & ERR) error();


/* free unit descriptor for board */

6
}
finderr() {
/* This routine would notify you that the ibfind call failed, and
* refer you to the driver software configuration procedures.
*/
printf("Ibfind error; does device or board\n");
printf("name given match configuration name?\n");
exit();
}

error() {
/* An error checking routine at this location would, among other
* things, check iberr to determine the exact cause of the error
* condition and then take action appropriate to the application.
* For errors during data transfers, you can examine ibcnt to
* determine the actual number of bytes transferred.
*/
printf("ibsta=0x%x, iberr=%d, ibcnt=%ld\n\n",ibsta,iberr,ibcnt);
exit();
}

Summary
For fast, automatic responses to asynchronous events, you can set up your GPIB application to
use interrupt routines. You can use the NI-488M function call ibsgnl to designate the
interrupt event. When interrupted, your program passes control to the service routine named in
the UNIX signal call. The interrupt routine is code you create that responds to the interrupt
and takes whatever action is appropriate for your application.

You might also like