LCOV - code coverage report
Current view: top level - timinglibs/src - TimingMasterControllerBase.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 114 0
Test Date: 2026-02-16 10:18:04 Functions: 0.0 % 24 0

            Line data    Source code
       1              : /**
       2              :  * @file TimingMasterControllerBase.cpp TimingMasterControllerBase class
       3              :  * implementation
       4              :  *
       5              :  * This is part of the DUNE DAQ Software Suite, copyright 2020.
       6              :  * Licensing/copyright details are in the COPYING file that you should have
       7              :  * received with this code.
       8              :  */
       9              : 
      10              : #include "TimingMasterControllerBase.hpp"
      11              : #include "timinglibs/dal/EndpointLocation.hpp"
      12              : #include "timinglibs/timingcmd/Nljs.hpp"
      13              : #include "timinglibs/timingcmd/Structs.hpp"
      14              : 
      15              : #include "appfwk/cmd/Nljs.hpp"
      16              : #include "ers/Issue.hpp"
      17              : #include "appfwk/ConfigurationManager.hpp"
      18              : #include "appfwk/DAQModule.hpp"
      19              : 
      20              : #include <chrono>
      21              : #include <cstdlib>
      22              : #include <string>
      23              : #include <thread>
      24              : #include <vector>
      25              : 
      26              : namespace dunedaq {
      27              : namespace timinglibs {
      28              : 
      29            0 : TimingMasterControllerBase::TimingMasterControllerBase(const std::string& name)
      30              :   : dunedaq::timinglibs::TimingController(name, 7) // 2nd arg: how many hw commands can this module send?
      31            0 :   , m_endpoint_scan_period(0)
      32            0 :   , endpoint_scan_thread(std::bind(&TimingMasterControllerBase::endpoint_scan, this, std::placeholders::_1))
      33              : {
      34            0 :   register_command("conf", &TimingMasterControllerBase::do_configure);
      35            0 :   register_command("scrap", &TimingMasterControllerBase::do_scrap);
      36              : 
      37            0 :   register_command("start_scanning_endpoints", &TimingMasterControllerBase::do_start);
      38            0 :   register_command("stop_scanning_endpoints", &TimingMasterControllerBase::do_stop);
      39              : 
      40              :   // timing master hardware commands
      41            0 :   register_command("master_set_timestamp", &TimingMasterControllerBase::do_master_set_timestamp);
      42            0 :   register_command("master_set_endpoint_delay", &TimingMasterControllerBase::do_master_set_endpoint_delay);
      43            0 :   register_command("master_send_fl_command", &TimingMasterControllerBase::do_master_send_fl_command);
      44            0 :   register_command("master_measure_endpoint_rtt", &TimingMasterControllerBase::do_master_measure_endpoint_rtt);
      45            0 :   register_command("master_endpoint_scan", &TimingMasterControllerBase::do_master_endpoint_scan);
      46            0 : }
      47              : 
      48              : void
      49            0 : TimingMasterControllerBase::do_configure(const CommandData_t& data)
      50              : {
      51            0 :   auto mdal = m_params->cast<dal::TimingMasterControllerConf>();
      52              : 
      53            0 :   auto monitored_endpoints = mdal->get_monitored_endpoints();
      54              : 
      55            0 :    for (auto endpoint : monitored_endpoints) {
      56            0 :     timingcmd::EndpointLocation endpoint_location;
      57            0 :     endpoint_location.address = endpoint->get_address();
      58            0 :     endpoint_location.fanout_slot = endpoint->get_fanout_slot();
      59            0 :     endpoint_location.sfp_slot = endpoint->get_sfp_slot();
      60            0 :     m_monitored_endpoint_locations.push_back(endpoint_location);
      61              :    }
      62              : 
      63            0 :   TimingController::do_configure(data); // configure hw command connection
      64              : 
      65            0 :   configure_hardware_or_recover_state<TimingMasterNotReady>(data, "Timing master");
      66              : 
      67            0 :   TLOG() << get_name() << " conf done on master, device: " << m_timing_device;
      68              :   
      69            0 :   m_endpoint_scan_period = mdal->get_endpoint_scan_period();
      70            0 :   if (m_endpoint_scan_period)
      71              :   {
      72            0 :     TLOG() << get_name() << " conf: master, will send delays with period [ms] " << m_endpoint_scan_period;    
      73              :   }
      74              :   else
      75              :   {
      76            0 :     TLOG() << get_name() << " conf: master, will not send delays";
      77              :   }
      78            0 : }
      79              : 
      80              : void
      81            0 : TimingMasterControllerBase::do_start(const CommandData_t& data)
      82              : {
      83            0 :   TimingController::do_start(data); // set sent cmd counters to 0
      84            0 :   if (m_endpoint_scan_period) endpoint_scan_thread.start_working_thread();
      85            0 :   TLOG() << "Endpoint monitoring started";
      86            0 : }
      87              : 
      88              : void
      89            0 : TimingMasterControllerBase::do_stop(const CommandData_t& /*data*/)
      90              : {
      91            0 :   if (endpoint_scan_thread.thread_running()) endpoint_scan_thread.stop_working_thread();
      92            0 :   TLOG() << "Endpoint monitoring stopped";
      93            0 : }
      94              : 
      95              : void
      96            0 : TimingMasterControllerBase::send_configure_hardware_commands(const CommandData_t& data)
      97              : {
      98            0 :   do_io_reset(data);
      99            0 :   do_master_set_timestamp(data);
     100            0 : }
     101              : 
     102              : void
     103            0 : TimingMasterControllerBase::do_master_set_timestamp(const CommandData_t&)
     104              : {
     105            0 :   timingcmd::TimingHwCmd hw_cmd =
     106            0 :   construct_hw_cmd( "set_timestamp");
     107              : 
     108            0 :   auto mdal = m_params->cast<dal::TimingMasterControllerConf>();
     109            0 :   hw_cmd.payload["timestamp_source"] = mdal->get_timestamp_source();
     110              : 
     111            0 :   send_hw_cmd(std::move(hw_cmd));
     112            0 :   ++(m_sent_hw_command_counters.at(1).atomic);
     113            0 : }
     114              : 
     115              : void
     116            0 : TimingMasterControllerBase::do_master_set_endpoint_delay(const CommandData_t& data)
     117              : {
     118            0 :   timingcmd::TimingHwCmd hw_cmd =
     119            0 :   construct_hw_cmd( "set_endpoint_delay", data);
     120              :   
     121            0 :   TLOG_DEBUG(2) << "set ept delay data: " << data.dump();
     122              :   
     123            0 :   send_hw_cmd(std::move(hw_cmd));
     124            0 :   ++(m_sent_hw_command_counters.at(3).atomic);
     125            0 : }
     126              : 
     127              : void
     128            0 : TimingMasterControllerBase::do_master_send_fl_command(const CommandData_t& data)
     129              : {
     130            0 :   timingcmd::TimingHwCmd hw_cmd =
     131            0 :   construct_hw_cmd( "send_fl_command", data);
     132              :   
     133            0 :   TLOG_DEBUG(2) << "send fl cmd data: " << data.dump();
     134              : 
     135            0 :   send_hw_cmd(std::move(hw_cmd));
     136            0 :   ++(m_sent_hw_command_counters.at(4).atomic);
     137            0 : }
     138              : 
     139              : void
     140            0 : TimingMasterControllerBase::do_master_measure_endpoint_rtt(const CommandData_t& data)
     141              : {
     142            0 :   timingcmd::TimingHwCmd hw_cmd =
     143            0 :   construct_hw_cmd( "master_measure_endpoint_rtt");
     144              :   
     145            0 :   TLOG_DEBUG(2) << "measure endpoint rtt data: " << data.dump();
     146              : 
     147            0 :   send_hw_cmd(std::move(hw_cmd));
     148            0 :   ++(m_sent_hw_command_counters.at(5).atomic);
     149            0 : }
     150              : 
     151              : void
     152            0 : TimingMasterControllerBase::do_master_endpoint_scan(const CommandData_t& data)
     153              : {
     154            0 :   timingcmd::TimingHwCmd hw_cmd =
     155            0 :   construct_hw_cmd( "master_endpoint_scan");
     156              :   
     157            0 :   TLOG_DEBUG(2) << "endpoint scan data: " << data.dump();
     158              : 
     159            0 :   send_hw_cmd(std::move(hw_cmd));
     160            0 :   ++(m_sent_hw_command_counters.at(6).atomic);
     161            0 : }
     162              : 
     163              : //void
     164              : //TimingMasterControllerBase::get_info(opmonlib::InfoCollector& ci, int /*level*/)
     165              : //{
     166              :   // send counters internal to the module
     167              : //  timingmastercontrollerinfo::Info module_info;
     168              : //  module_info.sent_master_io_reset_cmds = m_sent_hw_command_counters.at(0).atomic.load();
     169              : //  module_info.sent_master_print_status_cmds = m_sent_hw_command_counters.at(1).atomic.load();
     170              : //  module_info.sent_master_set_timestamp_cmds = m_sent_hw_command_counters.at(2).atomic.load();
     171              : //  module_info.sent_master_set_endpoint_delay_cmds = m_sent_hw_command_counters.at(3).atomic.load();
     172              : //  module_info.sent_master_send_fl_command_cmds = m_sent_hw_command_counters.at(4).atomic.load();
     173              : 
     174              : //   // for (uint i = 0; i < m_number_hw_commands; ++i) {
     175              : //   //  module_info.sent_hw_command_counters.push_back(m_sent_hw_command_counters.at(i).atomic.load());
     176              : //   //}
     177              : //   ci.add(module_info);
     178              : // }
     179              : 
     180              : // cmd stuff
     181              : void
     182            0 : TimingMasterControllerBase::endpoint_scan(std::atomic<bool>& running_flag)
     183              : {
     184              : 
     185            0 :   std::ostringstream starting_stream;
     186            0 :   starting_stream << ": Starting endpoint_scan() method.";
     187            0 :   TLOG_DEBUG(0) << get_name() << starting_stream.str();
     188              : 
     189            0 :   while (running_flag.load() && m_endpoint_scan_period) {
     190              : 
     191            0 :     timingcmd::TimingHwCmd hw_cmd =
     192            0 :     construct_hw_cmd( "master_endpoint_scan");
     193              : 
     194            0 :     timingcmd::TimingMasterEndpointScanPayload cmd_payload;
     195            0 :     cmd_payload.endpoints = m_monitored_endpoint_locations;
     196              : 
     197              :     // dal::TimingMasterController::TimingMasterEndpointScanPayload cmd_payload;
     198              :     // cmd_payload.endpoints = m_monitored_endpoint_locations;
     199              : 
     200            0 :     hw_cmd.payload = cmd_payload;
     201            0 :     send_hw_cmd(std::move(hw_cmd));
     202              : 
     203            0 :     ++(m_sent_hw_command_counters.at(3).atomic);
     204            0 :     if (m_endpoint_scan_period)
     205              :     {
     206            0 :       auto prev_gather_time = std::chrono::steady_clock::now();
     207            0 :       auto next_gather_time = prev_gather_time + std::chrono::milliseconds(m_endpoint_scan_period);
     208              : 
     209              :       // check running_flag periodically
     210            0 :       auto slice_period = std::chrono::microseconds(10000);
     211            0 :       auto next_slice_gather_time = prev_gather_time + slice_period;
     212              : 
     213            0 :       bool break_flag = false;
     214            0 :       while (next_gather_time > next_slice_gather_time + slice_period) {
     215            0 :         if (!running_flag.load()) {
     216            0 :           TLOG_DEBUG(0) << "while waiting to send delays, negative run gatherer flag detected.";
     217            0 :           break_flag = true;
     218            0 :           break;
     219              :         }
     220            0 :         std::this_thread::sleep_until(next_slice_gather_time);
     221            0 :         next_slice_gather_time = next_slice_gather_time + slice_period;
     222              :       }
     223            0 :       if (break_flag == false) {
     224            0 :         std::this_thread::sleep_until(next_gather_time);
     225              :       }
     226              :     }
     227              :     else
     228              :     {
     229            0 :       TLOG() << "m_endpoint_scan_period is 0 and send delays thread is running! breaking loop!";
     230            0 :       break;
     231              :     }
     232            0 :   }
     233              : 
     234            0 :   std::ostringstream exiting_stream;
     235            0 :   exiting_stream << ": Exiting endpoint_scan() method. Received " <<  m_sent_hw_command_counters.at(3).atomic.load()
     236            0 :                  << " commands";
     237            0 :   TLOG_DEBUG(0) << get_name() << exiting_stream.str();
     238            0 : }
     239              : 
     240              : } // namespace timinglibs
     241              : } // namespace dunedaq
     242              : 
     243              : // Local Variables:
     244              : // c-basic-offset: 2
     245              : // End:
        

Generated by: LCOV version 2.0-1