From 56d32553113ea42a40d5a0715f5e735433c38205 Mon Sep 17 00:00:00 2001 From: "A. Hahn" Date: Mon, 22 Jul 2024 09:56:08 +0200 Subject: [PATCH] v3.1.1 --- README.md | 135 ++++++++++++++++++++++++++++++++++++++------------- configure.ac | 2 +- 2 files changed, 102 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index a4b6362..d81b29a 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,95 @@ # Saftlib v3 - Simplified API for Timing -GSI timing receiver hardware includes a large collection of slave devices. +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. +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. -#### API documentation +# Table of Contents + +- [Saftlib](#saftlib) + * [API documentation](#api-documentation) + * [Compile and install](#compile-and-install) + + [Etherbone](#etherbone) + + [Quickstart](#quickstart) + * [Version 3 changes](#version-3-changes) + * [Saftlib user guide](#saftlib-user-guide) + + [Start saftbusd and load the saftlib-service.so plugin](#start-saftbusd-and-load-the-saftlib-serviceso-plugin) + + [Firmware drivers](#firmware-drivers) + - [Burst generator](#burst-generator) + - [Function generator](#function-generator) + + [Developing software using saftlib Driver or Proxy classes](#developing-software-using-saftlib-driver-or-proxy-classes) + - [Best practices](#best-practices) + - [Limitations](#limitations) + - [Shared access or exclusive access](#shared-access-or-exclusive-access) + - [Examples](#examples) + * [Example 1: [A simple event snoop tool](examples/EventSnoopTool/README.md)](#example-1---a-simple-event-snoop-tool--examples-eventsnooptool-readmemd-) + * [Example 2: [A serial transceiver using an IO of a TimingReceiver](examples/SerialTransceiver/README.md)](#example-2---a-serial-transceiver-using-an-io-of-a-timingreceiver--examples-serialtransceiver-readmemd-) + + [Develop plugins to add new services](#develop-plugins-to-add-new-services) + * [Example 1: [A simple LM32 firmware driver](examples/SimpleFirmware/README.md)](#example-1---a-simple-lm32-firmware-driver--examples-simplefirmware-readmemd-) + +# Saftlib + +## API documentation + Generated with Doxygen from the master branch, the Saftlib Documentation is available here: [https://gsi-cs-co.github.io/saftlib](https://gsi-cs-co.github.io/saftlib). -#### Compile and install +## Compile and install + ```bash ./autogen.sh -./configure +./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 ```bash ./configure --prefix=$HOME/.local ``` -#### Quickstart + +### 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: + +```bash +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 + ```bash 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. + ```bash 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. - - Rewrite of the inter process communication system ([saftbus](saftbus/README.md)) + - Rewrite of the inter process communication system ([saftbus](saftbus/README.md)) - Better stability and performance. - Use fewer file descriptors. - Give up compatibility with Gio::Dbus-API for simpler code. @@ -93,40 +144,47 @@ And a set of command line tools to control and interact with attached hardware d ### 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): + ```bash 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) + ```bash 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 + ```bash 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: + ```bash $ 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 + /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 + /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: +active plugins: libsaft-service.so connected client processes: 10 (pid=432932) ``` -If the libsaft-service plugin is running, additional devices can be attached using +If the libsaft-service plugin is running, additional devices can be attached using ```bash saft-ctl tr5 attach dev/wbm5 ``` @@ -141,71 +199,85 @@ saft-ctl tr5 quit The saftbus tool `saftbus-ctl` also allows to remove services. See ([saftbus](saftbus/README.md)) for details. ### Firmware drivers -Two firmware drivers are contained in the saftlib package. + +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 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 { [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. +When loading the driver plugin `libbg-firmware-service.so { [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: + ```bash 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: + ```bash 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 +Before using the burst generator, the firmware has to be put into a working state with + ```bash 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: + ```bash 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 +If individual channel interfaces are needed, a call to + ```bash 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 + +Will initiate the firmware to rescan the available function generator channels and provide the FunctionGenerator interface for each of them. Calling + ```bash saft-fg-ctl -d tr0 -sm ``` -Will initiate the firmware to rescan the available function generator channels and provide the default interface (MasterFunctionGenerator). +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 +#### Best practices + In order to get the best performance out of saftlib, users should follow some basic rules: - - If a Proxy objects is used frequently int the program it should be stored instead of recreated if it is needed. For example, when new ECA conditions are frequently defined, the corresponding ActionSink Proxy should be stored instead of calling ActionSink::create() whenever an ActionSink_Proxy is needed. Reason: Creating a Proxy object has some overhead, it loads the program as well as the saftbusd server. + - If a Proxy objects is used frequently int the program it should be stored instead of recreated if it is needed. For example, when new ECA conditions are frequently defined, the corresponding ActionSink Proxy should be stored instead of calling ActionSink::create() whenever an ActionSink_Proxy is needed. Reason: Creating a Proxy object has some overhead, it loads the program as well as the saftbusd server. - Configuring the ECA takes relatively long. If many conditions should be changed, the fastest way is to create a complete new set of conditions in an inactive state, then call ToggleActive which will deactivate all active conditions and activate all inactive conditions. Then remove all inactive conditions. This results in only one reconfiguration of the ECA hardware. #### Limitations + There are some limitations that users should be aware of. - It is not possible to create or destroy Proxy objects on a saftbus::SignalGroup inside a Signal callback function from the same saftbus::SignalGroup. +#### Shared access or exclusive access -#### Shared access or exclusive access There are two fundamentally different ways of writing code that uses saftlib: - The classes from saftlib can be used remotely through Proxy objects, this is shown in the first code example. In this case many processes can share the hardware resources at the same time. A saftbusd server has to be available with the saftd-service plugin loaded and a TimingReceiver hardware attached. This is probably the most common use case. - Alternatively, the driver classes can also be used directly for lower latency (standalone, without running saftbusd). In this case the program connects directly to the hardware and no saftbusd server can run connect to the same hardware at the same time. But the program can be written in a way to provide the same functionality as saftbusd. This option might be useful when extra low latency in the hardware communication is needed. Both options are implemented in the simple event snoop tool of the [Examples](#examples) section. -#### Examples +#### Examples ##### Example 1: [A simple event snoop tool](examples/EventSnoopTool/README.md) @@ -224,8 +296,3 @@ It shows how to reuse existing conditions and react on the Destroy signal. 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. - - - - - diff --git a/configure.ac b/configure.ac index 1814491..57f44c3 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Set these variables before each release: m4_define(MAJOR,3) dnl Increment if removed/changed properties/signals/methods since previous release m4_define(MINOR,1) dnl Increment if added properties/signals/methods; reset to 0 if MAJOR changed -m4_define(REVISION,0) dnl Increment on each release; reset to 0 if MAJOR/MINOR changed +m4_define(REVISION,1) dnl Increment on each release; reset to 0 if MAJOR/MINOR changed m4_define(SONAME,10) dnl Whenever MAJOR is incremented, add MINOR+1 to this variable