DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TimingController.cpp
Go to the documentation of this file.
1
9
15
16#include "appfwk/cmd/Nljs.hpp"
18#include "ers/Issue.hpp"
20#include "logging/Logging.hpp"
21
22#include <chrono>
23#include <cstdlib>
24#include <string>
25#include <thread>
26#include <vector>
27
28namespace dunedaq {
29
31DUNE_DAQ_SERIALIZABLE(nlohmann::json, "JSON");
32
33namespace timinglibs {
34
35TimingController::TimingController(const std::string& name, uint number_hw_commands)
36 : dunedaq::appfwk::DAQModule(name)
37 , m_hw_command_out_connection("timing_cmds")
38 , m_hw_cmd_out_timeout(100)
39 , m_hw_command_sender(nullptr)
40 , m_timing_device("")
41 , m_timing_session_name("")
42 , m_device_info_receiver(nullptr)
43 , m_number_hw_commands(number_hw_commands)
44 , m_sent_hw_command_counters(m_number_hw_commands)
45 , m_device_ready_timeout(10000)
46 , m_device_ready(false)
47 , m_device_infos_received_count(0)
48 , m_hardware_state_recovery_enabled(false)
49{
50 for (auto it = m_sent_hw_command_counters.begin(); it != m_sent_hw_command_counters.end(); ++it) {
51 it->atomic.store(0);
52 }
53
54 register_command("io_reset", &TimingController::do_io_reset);
55 register_command("print_status", &TimingController::do_print_status);
56}
57
58void
59TimingController::init(std::shared_ptr<appfwk::ConfigurationManager> mcfg)
60{
61 auto mod_config = mcfg->get_dal<dal::TimingController>(get_name());
62 m_params = mod_config->get_configuration();
63}
64
65void
66TimingController::do_configure(const CommandData_t& /*data*/)
67{
68 m_timing_device = m_params->get_device();
69 m_hardware_state_recovery_enabled = m_params->get_hardware_state_recovery_enabled();
70 m_timing_session_name = m_params->get_timing_session_name();
71
72 if (m_timing_device.empty()) {
73 throw UHALDeviceNameIssue(ERS_HERE, "Device name should not be empty");
74 }
75
76 if (!m_hw_command_out_connection.empty()) {
77 if (m_timing_session_name.empty()) {
78 m_hw_command_sender =
79 iomanager::IOManager::get()->get_sender<timingcmd::TimingHwCmd>(m_hw_command_out_connection);
80 } else {
81 m_hw_command_sender = iomanager::IOManager::get()->get_sender<timingcmd::TimingHwCmd>(iomanager::ConnectionId{
82 m_hw_command_out_connection, datatype_to_string<timingcmd::TimingHwCmd>(), m_timing_session_name });
83 }
84
85 if (m_timing_session_name.empty()) {
86 m_device_info_receiver = iomanager::IOManager::get()->get_receiver<nlohmann::json>(m_timing_device + "_info");
87 } else {
88 m_device_info_receiver = iomanager::IOManager::get()->get_receiver<nlohmann::json>(iomanager::ConnectionId{
89 m_timing_device + "_info", datatype_to_string<nlohmann::json>(), m_timing_session_name });
90 }
91 m_device_info_receiver->add_callback(
92 std::bind(&TimingController::process_device_info, this, std::placeholders::_1));
93 }
94}
95
96void
97TimingController::do_scrap(const CommandData_t&)
98{
99 if (m_device_info_receiver) {
100 m_device_info_receiver->remove_callback();
101 }
102 m_device_infos_received_count = 0;
103 m_device_ready = false;
104
105 for (auto it = m_sent_hw_command_counters.begin(); it != m_sent_hw_command_counters.end(); ++it) {
106 it->atomic.store(0);
107 }
108}
109
110void
111TimingController::send_hw_cmd(timingcmd::TimingHwCmd&& hw_cmd)
112{
113 if (!m_hw_command_sender) {
114 throw QueueIsNullFatalError(ERS_HERE, get_name(), m_hw_command_out_connection);
115 }
116 try {
117 m_hw_command_sender->send(std::move(hw_cmd), m_hw_cmd_out_timeout);
118 } catch (const dunedaq::iomanager::TimeoutExpired& excpt) {
119 std::ostringstream oss_warn;
120 oss_warn << "push to output queue \"" << m_hw_command_out_connection << "\"";
121 ers::warning(dunedaq::iomanager::TimeoutExpired(
122 ERS_HERE,
123 get_name(),
124 oss_warn.str(),
125 std::chrono::duration_cast<std::chrono::milliseconds>(m_hw_cmd_out_timeout).count()));
126 }
127}
128
129timingcmd::TimingHwCmd
130TimingController::construct_hw_cmd(const std::string& cmd_id)
131{
132 timingcmd::TimingHwCmd hw_cmd;
133 hw_cmd.id = cmd_id;
134 hw_cmd.device = m_timing_device;
135 return hw_cmd;
136}
137
138timingcmd::TimingHwCmd
139TimingController::construct_hw_cmd(const std::string& cmd_id, const nlohmann::json& payload)
140{
141 auto hw_cmd = construct_hw_cmd(cmd_id);
142 hw_cmd.payload = payload;
143 return hw_cmd;
144}
145
146void
147TimingController::do_io_reset(const CommandData_t& data)
148{
149 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("io_reset", data);
150
151 hw_cmd.payload["clock_source"] = m_params->get_clock_source();
152 hw_cmd.payload["soft"] = m_params->get_soft();
153
154 send_hw_cmd(std::move(hw_cmd));
155 ++(m_sent_hw_command_counters.at(0).atomic);
156}
157
158void
159TimingController::do_print_status(const CommandData_t&)
160{
161 timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("print_status");
162 send_hw_cmd(std::move(hw_cmd));
163 ++(m_sent_hw_command_counters.at(1).atomic);
164}
165
166} // namespace timinglibs
167} // namespace dunedaq
168
169// Local Variables:
170// c-basic-offset: 2
171// End:
#define ERS_HERE
The DUNE-DAQ namespace.
DUNE_DAQ_SERIALIZABLE(dfmessages::DataRequest, "DataRequest")
void warning(const Issue &issue)
Definition ers.hpp:150