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