Skip to content

Step by step instructions for creating your own DAQModule package under v2.0.0

Marco Roda edited this page Nov 24, 2020 · 9 revisions

[Under development]

Introduction

This page is intended to provide a step-by-step guide to setting up a work area in which you create software modules that run within the DUNE DAQ software application framework (appfwk). These modules are often called DAQModules since that is the C++ base class that they inherit from. If you are impatient to get started, you can jump to the Step-by-step Instructions now.
New users should probably continue reading this introduction, though, to learn a little bit of background information.

This page draws from, and references, several other Wiki pages in the appfwk repository. Links to these pages are listed in the text in the relevant places, and they are a good source of additional information for interested readers. Here are some of these references collected for you in one place on this page:

and last, but certainly not least

A brief recap of the main idea behind appfwk the can be found in a presentation about v1 This snipped provides a quick summary.

As a refresher: * a *DAQProcess* contains one or more *DAQModules* * when multiple *DAQModules* are present within a *DAQProcess*, they communicate with each other via *Queues* (the diagrams that are included later on this page might help explain this) * there are two classes that wrap *Queues* to provide the ability to push data onto the queue (*DAQSink*) or pull data from a queue (*DAQSource*). An individual *DAQModule* will only access one side of each *Queue*. If the module pushes data onto the queue, it will use an instance of the *DAQSink* class (which wraps the desired *Queue*), and if the module pops data from the queue, it will use an instance of the *DAQSource* class. * the *DAQModules* that run within a given process (and the *Queues* between them) are specified in a JSON *process configuration* file. An example of one such file is given below. The creation of the *DAQModules* and *Queues* is handled by the *appfwk*. * at this point in time, we expect that most users will be developing *DAQModules* and simply using existing *Queues* from the *appfwk*. * at the moment, there aren't any centrally-provided libraries, tools, or recommendations for inter-process communication. We expect to address this topic soon, but for now, developers can either focus on single-process examples, or use other software for inter-process communication. The instructions on this page focus on single-process examples. * please remember that there have been a number of compromises or simplifications in the functionality that is provided by *appfwk* v1. We have made a good faith attempt to provide a good start on the internal interfaces and layout of *DAQProcesses*, but things will definitely change over time, and we will be gathering feedback from everyone on ways that things might be improved. (Of course, we already have a fairly good list based on the experience of creating v1.)

Since DAQ Suite v2, the system has been enriched with automated generated code tools. References to this can be found at these links

  • Presentations by Brett from previous meeting
  • Schema
  • Moo

Step-by-step Installation instructions

Instructions on setting up a work area in which you can create your new package can be found here. After you've created your own working area, for our purposes the first things to do is to add the packages your new package will depend on and compile them. Most likely your dependencies will include appfwk and cmdlib as per the installation instructions. For future reference we'll call your working area WORK_DIR, which is the directory that at this point should contain the following automatic generated sub-directories: build, dbt-pyvenv, install, log and sourcecode.

Create your own software package

File locations

How to write a DAQModule

Planning your DAQ Module

How to create the inputs for the automatically generated code

How to create a schema file

How to create a command file

How to write the C++ code of the DAQModule

From the C++ point of view, DAQ modules are implementation of a DAQ Module interface. That means that apart from the constructor (that receives a name) only one method has to be implemented: init().
The function has to handle all those configuration items that are not supposed to be reconfigurable during the run. Optionally it can configure all those variables that can be overridden during run time.

The most important thing that init has to do is to call register_command in order to associate functions to each command that the module is expected to support. Each function has to be a set of operations that changes the internal status of the module according to the command that it is implementing. The prototype of each function is in the form

void do_something( const nlohmann::json & ) ;

The function can be virtual and the system is able to pick the most downstream specification.

Assuming that the name of the module you are developing is MyNewDAQModule a call to associate the command "start" to a function called do_start will be

register_command("start",  & MyNewDAQModule::do_start);

It is expected that the operations of the DAQ Module are carried on in other threads under the control of the DAQModule itself.

How to make your DAQModule a plugin of the appfmw

DAQModules need to be created with a factory pattern simply via their name. In the application framework this is done using CETlib. In order to do that, each implementation (cpp file) needs to have a call to the macro DEFINE_DUNE_DAQ_MODULE(<name_including_namespace>) for example

DEFINE_DUNE_DAQ_MODULE(dunedaq::appfwk::DummyModule)

In order to generate a shared object library that is linkable in runtime from the application framework, the name of the library has to be the in the form <package>_<module_name_no_namespace>_duneDAQModule. This can be achieved simply adding a line in the CMakeLists.txt file of your project in the form daq_add_plugin(<module_name_no_namespace> duneDAQModule LINK_LIBRARIES ers::ers appfwk <...>). After the command LINK_LIBRARIES you list all the dependencies necessary for your plugin. For example:

daq_add_plugin( DummyModule  duneDAQModule LINK_LIBRARIES ers::ers appfwk )  

Running examples

Clone this wiki locally