Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Does VISA have VXI-11 Server implement to serve the interrupt channel for SRQ?

Hi,
 
I implemented both the VXI-11 Client (for Interrupt Channel), and VXI-11 Server (for Core and Abort channels).  Both work fine in Linux.  But not with NI-VISA.
 
I have tested the NI-VISA for VXI-11 using MAX Explorer, and it works for the Core Channel which is the "VXI-11 Client" that VISA has,  but when I send the SRQ thru VXI-11 interrupt channel, which is the VXI-11 server that VISA SHOULD have,  but there is no response !!!.
 
Here are the step that I've tested using MAX Explorer.
1. Open VISA Test Panel using VISA TCP/IP Resourses.
2. Create a resource with IP Address, and LAN Device Name.  My VXI-11 Server received "device_link_1_svc" to reate a link
3. Send viEnableEvent with Event Type VI_EVENT_SERVICE_REQ, Mechanism is Queue.  My VXI-11 Server received functions "create_intr_chan_1_svc", and "device_enable_srq_1_svc" with 40 bytes package, and I saved into memory.
4. When my device STB has changed (I emulate the STB changes every 1 minute), and it sends 40 bytes saved in step 3 back to VISA thru interrupt channel (VXI-11 Client).
5. Send viWaitOnEvent with Event Type VI_EVENT_SERVICE_REQ, Timeout = 30 (I tried with many number from 0 to 3000).  This function always return error
 
 
How do I test the NI-VISA SRQ?  Please help.
 
 
Thanks,
Dominator
0 Kudos
Message 1 of 21
(9,116 Views)
Hey Dominator,
 
Can you let me know what version of NI-VISA you have installed?
 

Regards,

Nick D.


0 Kudos
Message 2 of 21
(9,085 Views)
I'm using VISA version 2.8, Windows 2000 Professional.
0 Kudos
Message 3 of 21
(9,068 Views)

Hey Dominator,

Would you be able to implement a 3rd party program to monitor the packets being sent? One such program is:

http://www.ethereal.com/

Can you try to verify that your are sending the same message in both linux and VISA? is they same message is being sent, then I'd be curious why it's not responding the same.

Regards,

Nick D.

0 Kudos
Message 4 of 21
(9,048 Views)
The function "create_intr_chan_1_svc" received the parameters.  Here is the print out.
 
 argp->progNum=395185,
 argp->progVers=1,
 argp->hostAddr=0xAC101A31,
 argp->hostPort=1099,
 argp->progFamily=0,
 rqstp->rq_proc=25,
 rqstp->rq_prog=0x607AF,
 rqstp->rq_vers=1,
 rqstp->rq_clntcred=0x0xb766111c,
 rqstp->rq_cred.oa_flavor=0,
 rqstp->rq_cred.oa_length=0,
 rqstp->rq_cred.oa_base=0x0xb7660dfc,
 rqstp->rq_xprt->xp_addrlen=16,
 rqstp->rq_xprt->xp_port=0,
 rqstp->rq_xprt->xp_sock=26
 rqstp->rq_xprt->xp_p1=0x0x8115290,
 rqstp->rq_xprt->xp_p2=0x(nil),
 rqstp->rq_xprt->xp_pad=0x0x811518c,
 rqstp->rq_xprt->xp_raddr.sin_family=2,
 rqstp->rq_xprt->xp_raddr.sin_port=14341,
 rqstp->rq_xprt->xp_raddr.sin_zero=0x0x8115170,
 rqstp->rq_xprt->xp_raddr.sin_addr.s_addr=0x311A10AC
Then I tried to create the Interrupt CLIENT, but failed (3 attempts):    s_pclientInterrupt = clnt_create (pcAddr, DEVICE_INTR, DEVICE_INTR_VERSION, "tcp");
[29805-LXI]: [DEBUG  ]  99 : f=vxi11_server.cpp l=1855. <2007/07/19 15:27:24>Create interrupt channel for host 172.16.26.49
Create Interrupt Channel: 172.16.26.49: RPC: Remote system error - Connection refused
[29805-LXI]: [DEBUG  ] 100 : f=vxi11_server.cpp l=1855. <2007/07/19 15:27:25>Create interrupt channel for host 172.16.26.49
Create Interrupt Channel: 172.16.26.49: RPC: Remote system error - Connection refused
[29805-LXI]: [DEBUG  ] 101 : f=vxi11_server.cpp l=1855. <2007/07/19 15:27:26>Create interrupt channel for host 172.16.26.49
Create Interrupt Channel: 172.16.26.49: RPC: Remote system error - Connection refused
 
Is the VISA Interrupt Channel SERVER running?
 
 
Regards,
Dominator
 
 

 
0 Kudos
Message 5 of 21
(9,015 Views)

This is my PC SYSTEM INFORMATION

National Instruments Technical Support Form (Version 4.0.2.3002)
Generated: Thursday, July 19, 2007 4:30 PM Eastern Daylight Time


System Information:

Operating System(OS): Microsoft Windows 2000
OS Version: 5.00.2195
OS Info: Service Pack 4
Processor: Intel(R) Pentium(R) 4 CPU 2.80GHz / x86 Family 15 Model 3 Stepping 4 / GenuineIntel / 2793 MHz
Number of Processors: 1
Physical Memory: 1,046,516 KB RAM
Drive C:\ 5,990,440 of 38,989,752 KB free
Drive E:\ 3,736,783 of 19,936,633 KB free


NI Software Information:

CVI Run-Time 7.1.0.307
LabVIEW Run-Time 8.0
Measurement & Automation Explorer 4.0.2.3002
Measurement Studio for VS2003 7.1
.NET Languages Hardware Support 7.1.0
Common 8.0.11.194
NI-VISA 8.0.11.138
NI-PAL Software 1.10.3f0
NI Spy 2.3.2.49152
NI-VISA 3.5
visa32.dll 3.5.0.49152
NiVisaServer.exe 3.5.0.49152
NIvisaic.exe 3.5.0.49152

MAX Summary:

  • Devices and Interfaces
    • PXI System (Unidentified)
    • Serial & Parallel
      • COM1
      • LPT1
    • VISA TCP/IP Resources
      • TCPIP::ottdev04::OPM8::INSTR
      • TCPIP::ottdev04::inst8::INSTR
      • TCPIP::ottdev04::inst1::INSTR
  • Software
    • CVI Run-Time
    • LabVIEW Run-Time
    • Measurement & Automation Explorer
    • Measurement Studio for VS2003
      • .NET Languages Hardware Support
        • Common
        • NI-VISA
    • NI Spy
    • NI-PAL
    • NI-VISA
      • visa32.dll
      • NiVisaServer.exe
      • NIvisaic.exe
0 Kudos
Message 6 of 21
(9,010 Views)

Hi,

Look like NI-VISA does not have Port Mapper running.  So I have to create the raw socket to talk thru the interrupt channel instead of using RPC clnt_create (pcAddr, DEVICE_INTR, DEVICE_INTR_VERSION, "tcp").

 

Let me try the raw socket, and I'll let you know.

Regards,

Dominator.

0 Kudos
Message 7 of 21
(8,993 Views)

Unlike DEVICE_CORE and DEVICE_ASYNC, the DEVICE_INTR is not intended for the application side to create.  The only difference of DEVICE_INTR against others is, its RPC functions are "reverse direction" call.  Therefore the client for DEVICE_INTR is the instrument side.  The server is VISA or application side.

More different part is, the Port Mapper for VXI-11 is normally provided only for DEVICE_CORE channel at the instrument side.  Although DEVICE_ASYNC is similar condition for RPC's caller/callee relationship, its actual port# is informed by create_link() response (through the abortPort field on Create_LinkParms) rather than Port Mapper service which asks for prog# 395184.  As for DEVICE_INTR channel, it is also unrelated to Port Mapper, because the server (VISA or app) teaches its IP address and Port# when the app invokes create_intr_chan() function.  Then the instrument will learn enough knowledge about the DEVICE_INTR server (= VISA app side) such as IP address and Port#. This is why DEVICE_INTR is unrelated to Port Mapper.

If your test environment is running under Win32, it is recommended to install a network capture tool in order to spy the traffic.  (I personally prefer "Squeezer"  but it may not have English gui... it always appears in Japanese on my pc.)  Then try VISA call viOpen() and viEnableEvent( SRQ).  Then create_intr_chan() will be invoked and immediately the "reverse direction" RPC call will be invoked.  Hereafter whenever your instrument generates an SRQ, device_intr_srq() will be invoked from the instrument.  Its server entity is normally embedded inside the VISA, but the call will be visible by a network spy tool.

> Look like NI-VISA does not have Port Mapper running

I think it is very normal implementation.  In VXI-11 architecture, the port mapper is only needed for establishing DEVICE_CORE channel. 

このメッセージは 07-23-2007 02:03 PMに Makoto が編集しています。

0 Kudos
Message 8 of 21
(8,972 Views)
I implemented the VXI-11 function for both RPC (support port mapper i.e. Unix, Linux) and TCP raw socket (port mapper is not available i.e. Windows)
 
//Convert Bytes to/from Big/Little Endian or vise versa
#define BYTES_ORDER(b)    (s_bIsNetworkOrdered) ? (b) : EndianConvertInt32((b))
struct DeviceSrqParms
{
 struct
 {
  u_int handle_len;
  char handle_val[40];
 } handle;
};
typedef struct DeviceSrqParms DeviceSrqParms;
typedef struct rcphdr
{
 uint32_t length;  /*with MSB must be set 0x80 00 00 00*/
 uint32_t xid;   /* Transaction Identifier */
 uint32_t msg_type;  /* Message Type */
 uint32_t rpcvers;  /* RPC Version No. */
 uint32_t prog;   /* Program No. */
 uint32_t vers;   /* Program Version No. */
 uint32_t proc;   /* Procedure No. */
 uint32_t auth[4];  /*authentication data*/
} RPCHDR;
typedef struct intr_srq_data
{
 RPCHDR    tdsRPC_Header;
 DeviceSrqParms  tdsDevSrqData;
} INTR_SRQ_DATA;
 
 
void *
device_intr_srq_1(Device_SrqParms *argp, CLIENT *clnt)
{
    static char  *clnt_res;
    static uint32_t ui32XId = 1;
 
    //For RPC
    if ( s_ptdsRpcClientInterrupt ) //CLIENT handle created from clnt_creat()
    {
        memset((char *)&clnt_res, 0, sizeof(clnt_res));
        if (clnt_call (clnt, device_intr_srq,
            (xdrproc_t) xdr_Device_SrqParms, (caddr_t) argp,
            (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
            s_tdsTimeValTimeout) != RPC_SUCCESS)
        {
            DEBUG_INFO("device_intr_srq_1: Fail to sent package Device_SrqParms");
            return (NULL);
        }
        DEBUG_INFO("device_intr_srq_1: clnt_call() success");
    }
    //For TCP Raw Socket
    if ( s_pobjTcpClientInterrupt ) //Socket object created earlier
    { 
        INTR_SRQ_DATA    tdsIntrSrqData;
        uint32_t     ui32Length = (sizeof( INTR_SRQ_DATA ) - 4) | 0X80000000;
 
        //Create RPC Header
        tdsIntrSrqData.tdsRPC_Header.length = BYTES_ORDER(ui32Length);
        tdsIntrSrqData.tdsRPC_Header.xid = BYTES_ORDER(ui32XId++);
        tdsIntrSrqData.tdsRPC_Header.msg_type = 0; 
        tdsIntrSrqData.tdsRPC_Header.rpcvers = BYTES_ORDER(2);
        tdsIntrSrqData.tdsRPC_Header.prog = BYTES_ORDER(DEVICE_INTR);
        tdsIntrSrqData.tdsRPC_Header.vers = BYTES_ORDER(DEVICE_INTR_VERSION);
        tdsIntrSrqData.tdsRPC_Header.proc = BYTES_ORDER(device_intr_srq);
        memset(tdsIntrSrqData.tdsRPC_Header.auth, 0, sizeof(tdsIntrSrqData.tdsRPC_Header.auth));
        //Append stored SRQ data
        memcpy(&tdsIntrSrqData.tdsDevSrqData.handle.handle_val, argp->handle.handle_val, sizeof(DeviceSrqParms));
        tdsIntrSrqData.tdsDevSrqData.handle.handle_len = BYTES_ORDER(argp->handle.handle_len);

        //TCP Socket accept data as std::string, so convert data structure to std::string
        char *pcData = (char *) &tdsIntrSrqData;
        try
        {
            std::string sData = "", sHexData = "";
            char acTemp[10];
            for ( int i = 0; i < (int) sizeof(tdsIntrSrqData); i++)
            {
                sData += pcData[i];
                sprintf(acTemp, "%02X", pcData[i]);
                if ( i % 4 == 0 )
                    sHexData += "\n\t";
                sHexData += acTemp;
            }
            DEBUG_INFO("device_intr_srq_1: sData to send to NI-VISA: >>>>>>>>>>>>>>>>>>>>>>>>>>>>%s",
                sHexData.c_str());
            //Send data to TCP Socket
            *s_pobjTcpClientInterrupt << sData;
        }
        catch ( SocketException& )
        {
            std::cout << "Send data failed\n";
        }
        clnt_res = tdsIntrSrqData.tdsDevSrqData.handle.handle_val;
    }
    return ((void *)&clnt_res);
} // End device_intr_srq_1
 
Any suggestions, please let me know
Dominator.
0 Kudos
Message 9 of 21
(8,913 Views)

As for Raw-socket sender routine, it looks like bit strange.

The contents of tdsIntrSrqData (INTR_SRQ_DATA type) are looking okay.

The strange point that I feel is:

//Send data to TCP Socket
*s_pobjTcpClientInterrupt << sData
;

I believe the above stream I/O (?) operator does send the given data (sData in this case) over the TCP/IP raw socket.  However in your code, the sData is string type and looks like contain human-readable "hex-dump" of the tdsIntrSrqData content.  It must be sent out as raw binary, not as formatted string. Or, the above socket stream I/O call does eat a hex-dump string then convert it back to binary when send??? 

0 Kudos
Message 10 of 21
(8,885 Views)