The showsamp utility

Before we dive into the code for showsamp, here is an example of what the output looks like. I'm running this with a simulated device, called /dev/sim000-0220, which generates patterns of data.

# showsamp

SHOWSAMP
Shared memory region:  /adios
Size:          40960 bytes
Devices: (1)
    [0] "/dev/sim000-0220" 8 x AI, 16 x DI
HEAD 206 TAIL 999 ELEMENT_SIZE 36 NUM_ELEMS 1000
Data Set 202, acquired 2003 10 09 14:25:50.73824624 (delta 0 ns)
CARD /dev/sim000-0220, 8 AI, (1 AO), 16 DI, (16 DO)
  AI: 0651 0652 0653 0654 0655 0656 0657 0658
  DI: 00CB

Data Set 203, acquired 2003 10 09 14:25:50.83914604 (delta 0 ns)
CARD /dev/sim000-0220, 8 AI, (1 AO), 16 DI, (16 DO)
  AI: 0659 065A 065B 065C 065D 065E 065F 0660
  DI: 00CC

Data Set 204, acquired 2003 10 09 14:25:50.94004585 (delta 0 ns)
CARD /dev/sim000-0220, 8 AI, (1 AO), 16 DI, (16 DO)
  AI: 0661 0662 0663 0664 0665 0666 0667 0668
  DI: 00CD

Data Set 205, acquired 2003 10 09 14:25:51.04096166 (delta 0 ns)
CARD /dev/sim000-0220, 8 AI, (1 AO), 16 DI, (16 DO)
  AI: 0669 066A 066B 066C 066D 066E 066F 0670
  DI: 00CE

Data Set 206, acquired 2003 10 09 14:25:51.14186147 (delta 0 ns)
CARD /dev/sim000-0220, 8 AI, (1 AO), 16 DI, (16 DO)
  AI: 0671 0672 0673 0674 0675 0676 0677 0678
  DI: 00CF

The showsamp utility starts up and tells me that it's using a shared memory region identified as /adios, that it's 40 KB in size, and that there is only one device present, called /dev/sim000-0220. It then tells me that this device has 8 analog inputs and 16 digital inputs and dumps the default 5 samples, showing the analog and the digital values.

The showsamp utility has a rather large main() function. That's because, as stated above, it was written initially to be a quick hack to test ADIOS's shared memory. Basically, it opens the shared memory segment, calls mmap() to map the shared memory segment to a pointer, and then verifies the signature.

If this all succeeds, then main() creates a series of pointers into the various data structures of interest, and dumps out the last N samples (where N defaults to 5 and can be overridden on the command line with -n):

for (i = head - optn + 1; i <= head; i++) {
  if (i < 0) {
    do_data_set (i + sig -> num_elems);
  } else {
    do_data_set (i);
  }
}

The code above starts at N positions before the current head and goes until the head. Notice that the result of the subtraction may be negative, and that's fine—we handle it by adding in the number of elements from the num_elems member in shared memory.

To actually get one data set's worth of samples:

static void
do_data_set (int ds)
{
  int                   i, j;
  adios_data_header_t   *dhead;
  uint16_t              *u16;
  struct tm             *tm;
  char                  buf [BUFSIZ];

  dhead = (adios_data_header_t *) (database
        + ds * daq -> element_size);
  i = dhead -> t0ns / 1000000000LL;
  tm = localtime (&i);
  strftime (buf, sizeof (buf), "%Y %m %d %H:%M:%S", tm);

  printf ("Data Set %d, acquired %s.%09lld (delta %" PRId64 " ns)\n", 
          ds, buf, dhead -> t1ns % 1000000000LL, 
          dhead -> t1ns - dhead -> t0ns);
  u16 = (uint16_t *) (dhead + 1);
  for (i = 0; i < sig -> num_cis; i++) {
    printf ("CARD %s, %d AI, (%d AO), %d DI, (%d DO)\n",
            cis [i].name,
            cis [i].nai, cis [i].nao,
            cis [i].ndi, cis [i].ndo);
    if (cis [i].nai) {
      printf ("  AI: ");
      for (j = 0; j < cis [i].nai; j++) {
        printf ("%04X ", *u16++);
      }
      printf ("\n");
    }
    if (cis [i].ndi) {
      printf ("  DI: ");
      for (j = 0; j < (cis [i].ndi + 15) / 16; j++) {
        printf ("%04X ", *u16++);
      }
      printf ("\n");
    }
  }
  printf ("\n");
}

The ds parameter is the data set number, and the first line of code does pointer arithmetic to get the pointer dhead to point to the appropriate data set. We adjust and format the time that the sample was acquired, and then dump out all of the data elements. The CIS tells us how many samples we are expecting. Note that the CIS does not tell us the formatting of the digital I/O—whether they are “naturally” presented as 8-bit or 16-bit samples, or how they are grouped (e.g., on the DIO-144 they are grouped as three sets of 8-bit samples). There are other assumptions in this code, like that all analog samples will be 16 bits or less, and that all digital samples will be printed as 16-bit quantities. You can easily change this by adding more information into the CIS and then examining that information here.