LCOV - code coverage report
Current view: top level - flxlibs/plugins - FelixReaderModule.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 96 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 14 0

            Line data    Source code
       1              : /**
       2              :  * @file FelixReaderModule.cc FelixReaderModule DAQModule implementation
       3              :  *
       4              :  * This is part of the DUNE DAQ Application Framework, copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : #include "confmodel/Connection.hpp"
       9              : #include "confmodel/QueueWithSourceId.hpp"
      10              : #include "confmodel/DetDataSender.hpp"
      11              : #include "confmodel/DetectorStream.hpp"
      12              : #include "confmodel/GeoId.hpp"
      13              : 
      14              : #include "appmodel/DataReaderModule.hpp"
      15              : #include "appmodel/FelixDetectorToDaqConnection.hpp"
      16              : #include "appmodel/FelixInterface.hpp"
      17              : #include "appmodel/FelixDataSender.hpp"
      18              : 
      19              : #include "CreateElink.hpp"
      20              : #include "FelixReaderModule.hpp"
      21              : #include "FelixIssues.hpp"
      22              : 
      23              : #include "logging/Logging.hpp"
      24              : 
      25              : #include "flxcard/FlxException.h"
      26              : 
      27              : #include <chrono>
      28              : #include <memory>
      29              : #include <string>
      30              : #include <thread>
      31              : #include <utility>
      32              : #include <vector>
      33              : 
      34              : /**
      35              :  * @brief Name used by TRACE TLOG calls from this source file
      36              :  */
      37              : #define TRACE_NAME "FelixReaderModule" // NOLINT
      38              : 
      39              : /**
      40              :  * @brief TRACE debug levels used in this source file
      41              :  */
      42              : enum
      43              : {
      44              :   TLVL_ENTER_EXIT_METHODS = 5,
      45              :   TLVL_WORK_STEPS = 10,
      46              :   TLVL_BOOKKEEPING = 15
      47              : };
      48              : 
      49              : namespace dunedaq {
      50              : namespace flxlibs {
      51              : 
      52            0 : FelixReaderModule::FelixReaderModule(const std::string& name)
      53              :   : DAQModule(name)
      54            0 :   , m_configured(false)
      55            0 :   , m_card_id(0)
      56            0 :   , m_logical_unit(0)
      57            0 :   , m_links_enabled()
      58            0 :   , m_num_links(0)
      59            0 :   , m_block_size(0)
      60            0 :   , m_block_router(nullptr)
      61              : //, block_ptr_sinks_{ }
      62              : 
      63              : {
      64              :  
      65            0 :   register_command("conf", &FelixReaderModule::do_configure);
      66            0 :   register_command("start", &FelixReaderModule::do_start);
      67            0 :   register_command("stop_trigger_sources", &FelixReaderModule::do_stop);
      68            0 : }
      69              : 
      70              : void
      71            0 : FelixReaderModule::init(const std::shared_ptr<appfwk::ConfigurationManager> mcfg)
      72              : {
      73              :   //auto ini = args.get<appfwk::app::ModInit>();
      74              :   
      75            0 :   auto modconf = mcfg->get_dal<appmodel::DataReaderModule>(get_name());
      76            0 :   auto session = mcfg->get_session();
      77              : 
      78            0 :   if (modconf->get_connections().size() != 1) {
      79            0 :     throw InitializationError(ERS_HERE, "FLX Data Reader does not have a unique associated flx_if");
      80              :   }
      81              : 
      82            0 :   const auto  det_conn = modconf->get_connections()[0]->cast<appmodel::FelixDetectorToDaqConnection>();
      83              : 
      84              : // Create a source_id to local elink map
      85            0 :   std::map<uint, uint> src_id_to_elink_map;
      86            0 :   auto flx_if = det_conn->receiver()->cast<appmodel::FelixInterface>();
      87            0 :   auto det_senders = det_conn->get_felix_senders();
      88              : 
      89            0 :   if (!det_senders.empty()) { // Redundant test as schema forbids 0 senders
      90            0 :     for (const auto& data_sender : det_senders) {
      91              :       // Check if sender enabled
      92            0 :       if (data_sender->is_disabled(*session)) {
      93            0 :         continue;
      94              :       }
      95            0 :       for (const auto& stream : data_sender->get_streams()) {
      96            0 :         src_id_to_elink_map[stream->get_source_id()] = data_sender->get_link();
      97              :       }
      98              : 
      99            0 :       TLOG(TLVL_BOOKKEEPING) << "Registering link: " << (uint32_t)data_sender->get_link() << " / " << m_links_enabled.size();
     100            0 :       m_links_enabled.push_back(data_sender->get_link());
     101              : 
     102              :     }
     103              :   }
     104            0 :   m_num_links = m_links_enabled.size();
     105            0 :   if (flx_if != nullptr) {
     106            0 :         m_card_wrapper = std::make_unique<CardWrapper>(flx_if, m_links_enabled);
     107            0 :         m_card_id = flx_if->get_card();
     108            0 :         m_logical_unit = flx_if->get_slr();
     109            0 :         m_block_size = flx_if->get_dma_block_size() * m_1kb_block_size;
     110            0 :         m_chunk_trailer_size = flx_if->get_chunk_trailer_size();
     111              :   }
     112              :   
     113              : 
     114            0 :   for (auto qi : modconf->get_outputs()) {
     115            0 :     auto q_with_id = qi->cast<confmodel::QueueWithSourceId>();
     116            0 :     if (q_with_id == nullptr) continue;
     117            0 :     TLOG_DEBUG(TLVL_WORK_STEPS) << ": CardReader output queue is " << q_with_id->UID();
     118            0 :     TLOG_DEBUG(TLVL_WORK_STEPS) << "Creating ElinkModel for target queue: " << q_with_id->UID() << " DLH number: " << q_with_id->get_source_id();
     119            0 :     auto elink = src_id_to_elink_map[q_with_id->get_source_id()];
     120            0 :     auto link_ptr = m_elinks[elink] = createElinkModel(q_with_id->UID());
     121            0 :     if ( ! link_ptr ) {
     122            0 :       ers::fatal(InitializationError(ERS_HERE, "CreateElink failed to provide an appropriate model for queue!"));
     123              :     }
     124            0 :     register_node( q_with_id->UID(), link_ptr);
     125            0 :     link_ptr->init(m_block_queue_capacity);
     126              :     //m_elinks[q_with_id->get_source_id()]->init(args, m_block_queue_capacity);
     127            0 :   }
     128              : 
     129              :   // Router function of block to appropriate ElinkHandlers
     130            0 :   m_block_router = [&](uint64_t block_addr) { // NOLINT
     131              :     // block_counter++;
     132            0 :     const auto* block = const_cast<felix::packetformat::block*>(
     133            0 :       felix::packetformat::block_from_bytes(reinterpret_cast<const char*>(block_addr)) // NOLINT
     134              :     );
     135            0 :     auto elink = block->elink;
     136            0 :     if (m_elinks.count(elink) != 0) {
     137            0 :       m_elinks[elink]->queue_in_block_address(block_addr);
     138              :     } else {
     139              :       // Really bad -> unexpeced ELINK ID in Block.
     140              :       // This check is needed in order to avoid dynamically add thousands
     141              :       // of ELink parser implementations on the fly, in case the data
     142              :       // corruption is extremely severe.
     143              :       //
     144              :       // Possible causes:
     145              :       //   -> enabled links that don't connect to anything
     146              :       //   -> unexpected format (fw/sw version missmatch)
     147              :       //   -> data corruption from FE
     148              :       //   -> data corruption from CR (really rare, last possible cause)
     149              : 
     150              :       // NO TLOG_DEBUG, but should count and periodically report corrupted DMA blocks.
     151              :     }
     152            0 :   };
     153              : 
     154              :   // Set function for the CardWrapper's block processor.
     155            0 :   m_card_wrapper->set_block_addr_handler(m_block_router);
     156            0 : }
     157              : 
     158              : void
     159            0 : FelixReaderModule::do_configure(const CommandData_t& /*args*/)
     160              : {
     161              :    
     162            0 :     bool is_32b_trailer = false;
     163              : 
     164            0 :     TLOG(TLVL_BOOKKEEPING) << "Number of felix links specified in configuration: " << m_links_enabled.size();
     165            0 :     TLOG(TLVL_BOOKKEEPING) << "Number of data link handlers: " << m_elinks.size();
     166              : 
     167              :     // Config checks
     168            0 :     if (m_num_links != m_elinks.size()) {
     169            0 :       ers::fatal(ElinkConfigurationInconsistency(ERS_HERE, m_links_enabled.size()));
     170              :     }
     171            0 :     if (m_block_size % m_1kb_block_size != 0) {
     172            0 :       ers::fatal(BlockSizeConfigurationInconsistency(ERS_HERE, m_block_size));
     173            0 :     } else if (m_block_size != m_1kb_block_size && m_chunk_trailer_size != m_32b_trailer_size) {
     174            0 :       ers::fatal(BlockSizeConfigurationInconsistency(ERS_HERE, m_block_size));
     175            0 :     } else if (m_chunk_trailer_size == m_32b_trailer_size) {
     176            0 :       is_32b_trailer = true;
     177              :     }
     178              : 
     179              :     // Configure components
     180            0 :     TLOG(TLVL_WORK_STEPS) << "Card ID: " << m_card_id;
     181            0 :     TLOG(TLVL_WORK_STEPS) << "Configuring components with Block size:" << m_block_size
     182            0 :                           << " & trailer size: " << m_chunk_trailer_size;
     183            0 :     m_card_wrapper->configure();
     184              :     // get linkids defined by queues
     185            0 :     std::vector<int> linkids;
     186            0 :     for(auto& [id, elink] : m_elinks) {
     187            0 :       linkids.push_back(id);
     188              :     }
     189              :     // loop through all elinkmodels, change the linkids to link tags and configure
     190            0 :     for (unsigned i = 0; i < m_num_links; ++i) {
     191            0 :       auto elink = m_elinks.extract(linkids[i]);
     192            0 :       auto tag = m_links_enabled[i] * m_elink_multiplier;
     193            0 :       elink.key() = tag;
     194            0 :       m_elinks.insert(std::move(elink));
     195            0 :       m_elinks[tag]->set_ids(m_card_id, m_logical_unit, m_links_enabled[i], tag);
     196            0 :       m_elinks[tag]->conf(m_block_size, is_32b_trailer);
     197            0 :     }
     198            0 : }
     199              : 
     200              : void
     201            0 : FelixReaderModule::do_start(const CommandData_t& /*args*/)
     202              : {
     203            0 :     m_card_wrapper->start();
     204            0 :     for (auto& [tag, elink] : m_elinks) {
     205            0 :       elink->start();
     206              :     }
     207            0 : }
     208              : 
     209              : void
     210            0 : FelixReaderModule::do_stop(const CommandData_t& /*args*/)
     211              : {
     212            0 :     m_card_wrapper->stop();
     213            0 :     for (auto& [tag, elink] : m_elinks) {
     214            0 :       elink->stop();
     215              :     }
     216            0 : }
     217              : 
     218              : 
     219              : } // namespace flxlibs
     220              : } // namespace dunedaq
     221              : 
     222            0 : DEFINE_DUNE_DAQ_MODULE(dunedaq::flxlibs::FelixReaderModule)
        

Generated by: LCOV version 2.0-1