GSI-CS-CO / saftlib

GSI Timing Service
GNU Lesser General Public License v3.0
5 stars 5 forks source link

Saftlib v3 - Simplified API for Timing

GSI timing receiver hardware includes a large collection of slave devices. Saftlib provides a user-friendly software interface for controlling these devices. In a typcal use case, one process (saftbusd) shares access to these hardware resources on behalf of multiple client programs. Clients connect to saftbusd using a C++ library of proxy objects which represent the shared resources. The user API of for shared resources hides device register access and provides high-level functionality.

Table of Contents

Saftlib

API documentation

Generated with Doxygen from the master branch, the Saftlib Documentation is available here: https://gsi-cs-co.github.io/saftlib.

Compile and install

./autogen.sh
./configure
make install

Default installation directory prefix is /usr/local. It can be changed (for example to $HOME/.local), by running configure with the --prefix option like this

./configure --prefix=$HOME/.local

Etherbone

You might encounter this error:

checking for etherbone >= 2.1.0... no
configure: error: Package requirements (etherbone >= 2.1.0) were not met:

Package 'etherbone', required by 'virtual:world', not found

To solve this, you need to provide a folder that contains an etherbone.pc file:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

Quickstart

If saftbusd (or any client program) is started by non root users, the socket directory (where the socket for inter process communication is located) should be changed by setting the SAFTBUS_SOCKET_PATH environment variable. For example

export SAFTBUS_SOCKET_PATH=/tmp/saftbus # only for non-root user
export LD_LIBRARY_PATH=$HOME/.local/lib # only if installation prefix was changed to $HOME/.local
saftbusd libsaft-service.so tr0:dev/wbm0 # this blocks the terminal. Interact with saftbusd from another terminal

The following command (in a different terminal) shows all services registered on saftbusd.

export SAFTBUS_SOCKET_PATH=/tmp/saftbus # only for non-root user
export LD_LIBRARY_PATH=$HOME/.local/lib # only if installation prefix was changed to $HOME/.local
saftbus-ctl -s

Using saftbusd like this is useful for tests and development. For use in production it is recommended to do a proper installation and launch saftbusd as a systemd unit.

Version 3 changes

Version 3 of saftlib has major internal changes compared to version 2, but aims to keep the user API unchanged.

Saftlib user guide

The package contains two libraries

And a set of command line tools to control and interact with attached hardware devices.

Start saftbusd and load the saftlib-service.so plugin

The most common use case for saftlib, is to be used over saftbus. A running saftbusd with the libsaft-servcie.so plugin is needed and a TimingReceiver_Service has to be attached to SAFTd. This can be achieve by launching saftbusd like this (assuming that a FAIR Timing Receiver is attached to the system under /dev/wmb0):

saftbusd libsaft-service.so tr0:dev/wbm0 tr1:dev/wbm1 tr2:dev/ttyUSB0

Wildcard character * is allowed, so the following line is equivalent to the previous one (if only dev/wbm0 and dev/wbm1 exist)

saftbusd libsaft-service.so tr*:dev/wbm* tr2:dev/ttyUSB0

Alternatively, saftbusd can be launched without any plugins and libsaft-service.so can be loaded later using saftbus-ctl

saftbus-ctl -l libsaft-service.so tr0:dev/wbm0 tr1:dev/wbm1 tr2:dev/ttyUSB0

In order to see, which plugins are loaded, which services are available on saftbusd, and which processes are connected to saftbus, saftbus-ctl can be used:

$ saftbus-ctl -s
objects:
  object-path                        ID [owner] sig-fd/use-count interface-names
  /saftbus                           1 [-1]  11/1 Container
  /de/gsi/saftlib                    2 [-1]d SAFTd
  /de/gsi/saftlib/tr0/acwbm          3 [-1]  WbmActionSink ActionSink Owned
  /de/gsi/saftlib/tr0/embedded_cpu   4 [-1]  EmbeddedCPUActionSink ActionSink Owned
  /de/gsi/saftlib/tr0/outputs/LED1   5 [-1]  Output ActionSink Owned
  [...]
  /de/gsi/saftlib/tr0/inputs/LVDSi2  33 [-1]  Input EventSource Owned
  /de/gsi/saftlib/tr0/inputs/LVDSi3  34 [-1]  Input EventSource Owned
  /de/gsi/saftlib/tr0                35 [-1]d TimingReceiver BuildIdRom ECA ECA_Event ECA_TLU LM32Cluster Mailbox OpenDevice Reset TempSensor Watchdog WhiteRabbit

active plugins:
  libsaft-service.so

connected client processes:
  10 (pid=432932)

If the libsaft-service plugin is running, additional devices can be attached using

saft-ctl tr5 attach dev/wbm5

Devices can be removed (only if none of their child services are owned by a client process) with

saft-ctl tr5 remove

The SAFTd service can be removed (only if none of their child services are owned by a client process) with

saft-ctl tr5 quit

The saftbus tool saftbus-ctl also allows to remove services. See (saftbus) for details.

Firmware drivers

Two firmware drivers are contained in the saftlib package. They are be compiled by the build system into separate shared libraries (libbg-firmware-service.so and libfg-firmware-service.so) and are installed together with libsaft-service.so.

Burst generator

The burst generator service is not part of the libsaft-service.so. The service has to be loaded as a plugin into saftbusd. The service requires a matching firmware running on one of the user LM32 cores. The firmware binary is installed at ${prefix}/share/saftlib/firmware/burstgen.bin and can be automatically loaded with the driver plugin. When loading the driver plugin libbg-firmware-service.so { <saftlib-device> [lm32-core-index] } and optional lm32-core-index is provided, the plugin loader will write the firmware binary to the requested core index. There are no checks if another firmware is already running on that core. The plugin can be loaded into a running saftbusd using saftbus-ctl, for example:

saftbus-ctl -l libbg-firmware-service.so tr0 0

This will install the driver on device tr0 after loading the firmware into lm32-core 0 on this device.

The plugin can be loaded when saftbusd is started, for example:

saftbusd libsaft-service.so tr0:dev/wbm0 libbg-firmware-service.so tr0 0

Before using the burst generator, the firmware has to be put into a working state with

saft-burst-ctl tr0 -i 1

Function generator

The function generator service is not part of libsaft-service.so. The service has to be loaded as a plugin into saftbusd. The service requires a matching firmware running on one of the user LM32 cores. SCU timing receivers are already preloaded with the function generator firmware binary. This service is meant to be used only on SCU timing receivers. The plugin can be loaded into a running saftbusd using saftbus-ctl, for example:

saftbus-ctl -l libfg-firmware-service.so tr0

This will install the driver on device tr0. By default, the driver will provide two services /de/gsi/saftlib/tr0/fg-firmware and the MasterFunctionGenerator interface /de/gsi/saftlib/tr0/fg-firmware/master_fg which bundles all available function generator channels behind one interface. If individual channel interfaces are needed, a call to

saft-fg-ctl -d tr0 -si

Will initiate the firmware to rescan the available function generator channels and provide the FunctionGenerator interface for each of them. Calling

saft-fg-ctl -d tr0 -sm

Will initiate the firmware to rescan the available function generator channels and provide the default interface (MasterFunctionGenerator).

Developing software using saftlib Driver or Proxy classes

Best practices

In order to get the best performance out of saftlib, users should follow some basic rules:

Limitations

There are some limitations that users should be aware of.

Shared access or exclusive access

There are two fundamentally different ways of writing code that uses saftlib:

Both options are implemented in the simple event snoop tool of the Examples section.

Examples

Example 1: A simple event snoop tool

A simple program that can be used to monitor timing events. The program configures the ECA to effectively call the function "on_action" whenever an event matches the specified event id. There are two versions of this example, showing both, shared and exclusive access to the hardware.

Example

Example 2: A serial transceiver using an IO of a TimingReceiver

An example with multiple threads and different saftbus::SignalGroups. It shows how to reuse existing conditions and react on the Destroy signal.

Example

Develop plugins to add new services

Example 1: A simple LM32 firmware driver

TimingReceiver hardware provides LM32 soft-core CPUs. These can be programmed with use case specific firmware. Saftlib3 allows to extend the functionality of the TimingReceiver driver with plugins.

Example