MIDAS - The Multiple Instance Data Acquisition System

Data Acquisition - Shared Data Area access procedures (DataSpyLib)

These procedures provide a simple method for a user data acquisition/analysis program to access realtime data held in Shared Memory by the MIDAS Tape Server (or equivalent server).
The method used does not require or allow the user program to interact with the flow of data to storage.
The first 24 bytes of the returned data contain a block header (see below) which is the same as the block header used when data is written to disc.


Usage

   To initialise and establish connection

      int dataSpyOpen(int ID);          /* ID = 0 => n */

   To close connection

      int dataSpyClose(int ID);
      
   To retrieve a data block
   
      int dataSpyRead (int ID, char *data, int length); 
    
      This procedure returns the length (in bytes) of the data returned or 0 if no data is available. 
   

ID is the identifier of the shared data area to be used
data is the buffer to be used for the retrieved data
length is the length of this buffer in bytes

Implementation

The realtime data is held in Shared Memory Segments (1 segment for each TCP data connection). Each segment current holds a maximum of 64 data buffers and each buffer is normally 64 Kbytes. This is managed as a FIFO. The dataSpyRead procedure returns the oldest buffer in the segment.
Since the FIFO segment is dynamic a check is performed when the selected buffer has been copied into the user area and if this buffer is no longer valid action is retried. It is possible that there is no data available (if new data is not being received) in which case dataSpyRead returns length=0 and it is up to the user software to decide what to do (possibly wait a short while and retry).

The DataSpy library is normally installed as /MIDAS/Linux/lib64/libdataspy.so (for 64 bit Linux).

Following is the 24 byte block header

typedef struct s_data_header {
    char   header_id[8];              //   contains the string  EBYEDATA
    long   header_sequence;           //   within the file
    short  header_stream;             //   data acquisition stream number (in the range 1=>4)
    short  header_tape;               //   =1
    short  header_MyEndian;           //   written as a native 1 by the tape server
    short  header_DataEndian;         //   written as a native 1 in the hardware structure of the data following
    long   header_dataLen;            //   total length of useful data following the header in bytes
} DATA_HEADER;
Following is a simple example of use of the library.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern int dataSpyOpen   (int id);
extern int dataSpyClose  (int id);
extern int dataSpyRead   (int id, char *data, int length);


main (int argc, char **argv)
{
     	int buffer32 [16*1024];

	int i,j,k;
        int x;
	int ID = 0;

	i = dataSpyOpen (ID);
	printf ("open = %d\n", i);

        x = dataSpyRead (ID, (char*)buffer32, 64*1024);

	if (x > 0)
	{
 
		printf ("read %d\n", x);

                k=0;
                for (i = 0; i < 64; i++) {
                   for (j = 0; j < 8; j++) {
                     printf(" 0x%08lx", buffer32[k] & 0x00000000ffffffff);
                     k++;
                   }
                   printf ("\n");
                }
                printf ("\n");
        } else {printf ("no data\n");}

	i = dataSpyClose (ID);
	printf ("\nclose\n");
}

 

Return to documentation index documentation index


© Jan 2015 NPG - STFC