Tags database design

The ability to associate ASCII labels with data points evolved during the term of the project. Initially, there was no requirement for it — as long as adios put the samples into shared memory, everyone was happy. When the time came to configure the analog and digital I/O ports, we decided we needed a way of saving that configuration. The tags database was really a text-file-based configuration database initially. Then I added the tag keyword, and the tags database was born.

Before we proceed with the details of the software, it's a good idea to explain the tags database because it's common to the drivers, adios, and the tag utility.

At a high level, the tags database is a flat ASCII text file. The default name is adios.cfg, and the utilities search for it in /etc first and then in the local directory (unless you override the name).

Configuration (and tag) information is presented card-by-card and spans multiple lines. It's important to keep in mind that this information is used by both the drivers and utilities. The drivers use it to configure their I/O ports, and the utilities use it to make sense of the shared memory region maintained by adios.

The device keyword indicates the beginning of configuration for a particular card. Recall that the dio144, pcl711, and iso813 drivers create device names of the form /dev/driver-port (e.g., /dev/pcl711-0220 for a PCL-711 card at port address 0x220). The device keyword uses the same format.

Once a device keyword has been read, all further configuration information in the file applies to that device, until another device keyword (or the end of file). Here's the formal grammar (I've broken the ccfga and cfgd keyword definitions over two lines):

cfgfile  :: [devdirs]... ["#" comment]

devdirs  :: devs [chandirs]...

devs     :: "device" devicename

chandirs :: "channel" channum [ [portspec] [cfg]... ]...

portspec :: "port" <"A" | "B" | "C">

cfg      :: <cfga | cfgd>

cfga     :: <"ain" | "aout"> ["span" loval","hival]
            ["gain" gainval] ["tag" tagname]

cfgd     :: "bit" bitnum [<"din" | "dout">]
            [<"positive" | "negative">] ["tag" tagname]

So, as a short example:

device /dev/pcl711-0220
  channel 1 ain span 0,70 tag BOILER_TEMPERATURE
  channel 2
    ain
    span -3,+4.2285
    gain 2
    tag VOLTAGE_1
  channel 3 ain span +100,-100 tag PRESSURE_1
  # channels 4 and 5 are not used here
  channel 6 ain tag RAW_ANALOG_1
  channel
    7 ain
      span 0,1 tag spud

  # Channel 8 is not used

  # Channel 9 is the output channel
  channel 9 aout span 0,8191 tag OUTPUT_TEMPERATURE_1

  # Channel 10 is the digital input channel with 8 bits
  channel 10
    bit 0 din negative tag CHECK_1
    bit 1 din positive tag CHECK_2
    din bit 2 positive tag SWITCH_1
    din bit 3 positive tag SWITCH_2
    # bits 4 through 7 are not used

  # Channel 11 is the digital output channel with 8 bits
  channel 11
    bit 0 dout positive tag CONVEYOR_MOTOR_1
    bit 1 negative tag CONVEYOR_START
    bit 2 negative tag ALARM_1_LED
    bit 3 dout negative tag ALARM_2_LED
    # bits 4 through 7 are not used

This configures a PCL-711 driver at port 0x220.

The gain settings are simply numbers passed directly to the driver. So, a gain setting of 2 doesn't mean that the gain setting is 2 ×, it simply means that the PCL-711 driver will receive the constant 2 and interpret it accordingly (i.e., in this case it means gain setting number 2, which is actually a 4 × gain setting.)