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