LCOV - code coverage report
Current view: top level - timinglibs/src - TimingMasterControllerBase.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 110 0
Test Date: 2026-10-11 15:05:20 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/ConfigurationManager.hpp"
      16              : #include "appfwk/DAQModule.hpp"
      17              : #include "appfwk/cmd/Nljs.hpp"
      18              : #include "ers/Issue.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            0 :     TLOG() << get_name() << " conf: master, will send delays with period [ms] " << m_endpoint_scan_period;
      72              :   } else {
      73            0 :     TLOG() << get_name() << " conf: master, will not send delays";
      74              :   }
      75            0 : }
      76              : 
      77              : void
      78            0 : TimingMasterControllerBase::do_start(const CommandData_t& data)
      79              : {
      80            0 :   TimingController::do_start(data); // set sent cmd counters to 0
      81            0 :   if (m_endpoint_scan_period)
      82            0 :     endpoint_scan_thread.start_working_thread();
      83            0 :   TLOG() << "Endpoint monitoring started";
      84            0 : }
      85              : 
      86              : void
      87            0 : TimingMasterControllerBase::do_stop(const CommandData_t& /*data*/)
      88              : {
      89            0 :   if (endpoint_scan_thread.thread_running())
      90            0 :     endpoint_scan_thread.stop_working_thread();
      91            0 :   TLOG() << "Endpoint monitoring stopped";
      92            0 : }
      93              : 
      94              : void
      95            0 : TimingMasterControllerBase::send_configure_hardware_commands(const CommandData_t& data)
      96              : {
      97            0 :   do_io_reset(data);
      98            0 :   do_master_set_timestamp(data);
      99            0 : }
     100              : 
     101              : void
     102            0 : TimingMasterControllerBase::do_master_set_timestamp(const CommandData_t&)
     103              : {
     104            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("set_timestamp");
     105              : 
     106            0 :   auto mdal = m_params->cast<dal::TimingMasterControllerConf>();
     107            0 :   hw_cmd.payload["timestamp_source"] = mdal->get_timestamp_source();
     108              : 
     109            0 :   send_hw_cmd(std::move(hw_cmd));
     110            0 :   ++(m_sent_hw_command_counters.at(1).atomic);
     111            0 : }
     112              : 
     113              : void
     114            0 : TimingMasterControllerBase::do_master_set_endpoint_delay(const CommandData_t& data)
     115              : {
     116            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("set_endpoint_delay", data);
     117              : 
     118            0 :   TLOG_DEBUG(2) << "set ept delay data: " << data.dump();
     119              : 
     120            0 :   send_hw_cmd(std::move(hw_cmd));
     121            0 :   ++(m_sent_hw_command_counters.at(3).atomic);
     122            0 : }
     123              : 
     124              : void
     125            0 : TimingMasterControllerBase::do_master_send_fl_command(const CommandData_t& data)
     126              : {
     127            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("send_fl_command", data);
     128              : 
     129            0 :   TLOG_DEBUG(2) << "send fl cmd data: " << data.dump();
     130              : 
     131            0 :   send_hw_cmd(std::move(hw_cmd));
     132            0 :   ++(m_sent_hw_command_counters.at(4).atomic);
     133            0 : }
     134              : 
     135              : void
     136            0 : TimingMasterControllerBase::do_master_measure_endpoint_rtt(const CommandData_t& data)
     137              : {
     138            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("master_measure_endpoint_rtt");
     139              : 
     140            0 :   TLOG_DEBUG(2) << "measure endpoint rtt data: " << data.dump();
     141              : 
     142            0 :   send_hw_cmd(std::move(hw_cmd));
     143            0 :   ++(m_sent_hw_command_counters.at(5).atomic);
     144            0 : }
     145              : 
     146              : void
     147            0 : TimingMasterControllerBase::do_master_endpoint_scan(const CommandData_t& data)
     148              : {
     149            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("master_endpoint_scan");
     150              : 
     151            0 :   TLOG_DEBUG(2) << "endpoint scan data: " << data.dump();
     152              : 
     153            0 :   send_hw_cmd(std::move(hw_cmd));
     154            0 :   ++(m_sent_hw_command_counters.at(6).atomic);
     155            0 : }
     156              : 
     157              : // void
     158              : // TimingMasterControllerBase::get_info(opmonlib::InfoCollector& ci, int /*level*/)
     159              : //{
     160              : //  send counters internal to the module
     161              : //  timingmastercontrollerinfo::Info module_info;
     162              : //  module_info.sent_master_io_reset_cmds = m_sent_hw_command_counters.at(0).atomic.load();
     163              : //  module_info.sent_master_print_status_cmds = m_sent_hw_command_counters.at(1).atomic.load();
     164              : //  module_info.sent_master_set_timestamp_cmds = m_sent_hw_command_counters.at(2).atomic.load();
     165              : //  module_info.sent_master_set_endpoint_delay_cmds = m_sent_hw_command_counters.at(3).atomic.load();
     166              : //  module_info.sent_master_send_fl_command_cmds = m_sent_hw_command_counters.at(4).atomic.load();
     167              : 
     168              : //   // for (uint i = 0; i < m_number_hw_commands; ++i) {
     169              : //   //  module_info.sent_hw_command_counters.push_back(m_sent_hw_command_counters.at(i).atomic.load());
     170              : //   //}
     171              : //   ci.add(module_info);
     172              : // }
     173              : 
     174              : // cmd stuff
     175              : void
     176            0 : TimingMasterControllerBase::endpoint_scan(std::atomic<bool>& running_flag)
     177              : {
     178              : 
     179            0 :   std::ostringstream starting_stream;
     180            0 :   starting_stream << ": Starting endpoint_scan() method.";
     181            0 :   TLOG_DEBUG(0) << get_name() << starting_stream.str();
     182              : 
     183            0 :   while (running_flag.load() && m_endpoint_scan_period) {
     184              : 
     185            0 :     timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("master_endpoint_scan");
     186              : 
     187            0 :     timingcmd::TimingMasterEndpointScanPayload cmd_payload;
     188            0 :     cmd_payload.endpoints = m_monitored_endpoint_locations;
     189              : 
     190              :     // dal::TimingMasterController::TimingMasterEndpointScanPayload cmd_payload;
     191              :     // cmd_payload.endpoints = m_monitored_endpoint_locations;
     192              : 
     193            0 :     hw_cmd.payload = cmd_payload;
     194            0 :     send_hw_cmd(std::move(hw_cmd));
     195              : 
     196            0 :     ++(m_sent_hw_command_counters.at(3).atomic);
     197            0 :     if (m_endpoint_scan_period) {
     198            0 :       auto prev_gather_time = std::chrono::steady_clock::now();
     199            0 :       auto next_gather_time = prev_gather_time + std::chrono::milliseconds(m_endpoint_scan_period);
     200              : 
     201              :       // check running_flag periodically
     202            0 :       auto slice_period = std::chrono::microseconds(10000);
     203            0 :       auto next_slice_gather_time = prev_gather_time + slice_period;
     204              : 
     205            0 :       bool break_flag = false;
     206            0 :       while (next_gather_time > next_slice_gather_time + slice_period) {
     207            0 :         if (!running_flag.load()) {
     208            0 :           TLOG_DEBUG(0) << "while waiting to send delays, negative run gatherer flag detected.";
     209            0 :           break_flag = true;
     210            0 :           break;
     211              :         }
     212            0 :         std::this_thread::sleep_until(next_slice_gather_time);
     213            0 :         next_slice_gather_time = next_slice_gather_time + slice_period;
     214              :       }
     215            0 :       if (break_flag == false) {
     216            0 :         std::this_thread::sleep_until(next_gather_time);
     217              :       }
     218              :     } else {
     219            0 :       TLOG() << "m_endpoint_scan_period is 0 and send delays thread is running! breaking loop!";
     220            0 :       break;
     221              :     }
     222            0 :   }
     223              : 
     224            0 :   std::ostringstream exiting_stream;
     225            0 :   exiting_stream << ": Exiting endpoint_scan() method. Received " << m_sent_hw_command_counters.at(3).atomic.load()
     226            0 :                  << " commands";
     227            0 :   TLOG_DEBUG(0) << get_name() << exiting_stream.str();
     228            0 : }
     229              : 
     230              : } // namespace timinglibs
     231              : } // namespace dunedaq
     232              : 
     233              : // Local Variables:
     234              : // c-basic-offset: 2
     235              : // End:
        

Generated by: LCOV version 2.0-1