Line data Source code
1 : /**
2 : * @file CIBModule.hpp
3 : *
4 : * CIBModule is a DAQModule implementation that provides a command and readout interface of the Calibration Interface
5 : * Board hardware. This hardware focus on the control and operation of the ionization laser calibration system (IoLS).
6 : *
7 : * This is part of the DUNE DAQ Software Suite, copyright 2020.
8 : * Licensing/copyright details are in the COPYING file that you should have
9 : * received with this code.
10 : */
11 :
12 : #ifndef CIBMODULES_PLUGINS_CIBMODULE_HPP_
13 : #define CIBMODULES_PLUGINS_CIBMODULE_HPP_
14 :
15 : #include "appfwk/DAQModule.hpp"
16 : #include "appmodel/CIBModule.hpp"
17 : #include "hsilibs/HSIEventSender.hpp"
18 : #include "iomanager/Receiver.hpp"
19 : #include "iomanager/Sender.hpp"
20 : #include "utilities/WorkerThread.hpp"
21 :
22 : #include "cibmodules/opmon/CIBModule.pb.h"
23 :
24 : #include <deque>
25 : #include <fstream>
26 : #include <map>
27 : #include <memory>
28 : #include <shared_mutex>
29 : #include <string>
30 : #include <vector>
31 :
32 : #include <boost/array.hpp>
33 : #include <boost/asio.hpp>
34 :
35 : namespace dunedaq::cibmodules {
36 :
37 : // NFB: Do we need this?
38 : // typedef std::pair<uint64_t, uint64_t> ts_payload; // NOLINT
39 :
40 : class CIBModule : public dunedaq::hsilibs::HSIEventSender
41 : {
42 : public:
43 : /**
44 : * @brief CIBModule Constructor
45 : * @param name Instance name for this CIBModule instance
46 : */
47 : explicit CIBModule(const std::string& name);
48 : // destructor
49 : ~CIBModule();
50 :
51 : void init(std::shared_ptr<appfwk::ConfigurationManager> cfgMgr) override;
52 :
53 : /**
54 : * Disallow copy and move constructors and assignments
55 : */
56 : CIBModule(const CIBModule&) = delete;
57 : CIBModule& operator=(const CIBModule&) = delete;
58 : CIBModule(CIBModule&&) = delete;
59 : CIBModule& operator=(CIBModule&&) = delete;
60 :
61 : bool error_state() const { return m_error_state.load(); }
62 :
63 : protected:
64 : void generate_opmon_data() override;
65 :
66 : private:
67 : // control variables
68 : std::atomic<bool> m_is_running;
69 : std::atomic<bool> m_is_configured;
70 : std::atomic<bool> m_stop_requested;
71 :
72 : std::string m_receiver_host;
73 : /*const */ unsigned int m_receiver_port;
74 : std::chrono::microseconds m_receiver_timeout;
75 : std::atomic<bool> m_error_state;
76 :
77 : bool check_port_in_use(unsigned short port);
78 :
79 : boost::asio::io_service m_control_ios;
80 : boost::asio::ip::tcp::socket m_control_socket;
81 : boost::asio::ip::tcp::endpoint m_control_endpoint;
82 :
83 : boost::asio::io_service m_receiver_ios;
84 : boost::asio::ip::tcp::socket m_receiver_socket;
85 :
86 : std::shared_ptr<dunedaq::hsilibs::HSIEventSender::raw_sender_ct> m_cib_hsi_data_sender;
87 :
88 : // Commands
89 : void do_configure(const CommandData_t& obj) override;
90 : void do_start(const CommandData_t& startobj) override;
91 : void do_stop(const CommandData_t& obj) override;
92 0 : void do_scrap(const CommandData_t& /*obj*/) override {};
93 :
94 : // the CIB does not need reset, since the DAQ operation is
95 : // decoupled from the instrumentation operation
96 : void send_config(const std::string& config);
97 : bool send_message(const std::string& msg);
98 :
99 : // Configuration
100 : std::shared_ptr<appfwk::ConfigurationManager> m_cfg;
101 : using conf_t = appmodel::CIBModule;
102 : const conf_t* m_module = nullptr;
103 :
104 : std::atomic<daqdataformats::run_number_t> m_run_number;
105 :
106 : // Threading client
107 : dunedaq::utilities::WorkerThread m_thread_;
108 : void do_hsi_work(std::atomic<bool>&);
109 :
110 : // variables for geo_id to construct the HSI frame
111 : // These are defined as uint32 in the schema, but given the way the HSI frame is consctructed from this it is
112 : // unsusable. THe HSI frame uses 4 Bits for the slot and 10 Bits for the crate and 6 for the DetID. So here I'm
113 : // overiding the types
114 : uint16_t m_det; // NOLINT
115 : uint16_t m_crate; // NOLINT
116 : uint16_t m_slot; // NOLINT
117 :
118 : template<typename T>
119 : bool read(boost::asio::ip::tcp::socket& socket, T& obj);
120 :
121 : //
122 : // members related to calibration stream
123 : //
124 : void update_calibration_file();
125 : void init_calibration_file();
126 : bool set_calibration_stream(const std::string& prefix = "");
127 :
128 : bool m_calibration_stream_enable = false;
129 : std::string m_calibration_dir = "";
130 : std::string m_calibration_prefix = "";
131 : std::chrono::minutes m_calibration_file_interval;
132 : std::ofstream m_calibration_file;
133 : std::chrono::steady_clock::time_point m_last_calibration_file_update;
134 :
135 : //
136 : // metric utilities
137 : //
138 : // -- these have to match the protobuf definition in CIBModuleInfo.proto
139 : using general_metric_t = dunedaq::cibmodules::opmon::CIBModuleInfo;
140 : using const_message_counter_t =
141 : std::invoke_result<decltype(&general_metric_t::num_control_messages_sent), general_metric_t>::type;
142 :
143 : using message_counter_t = std::remove_const<const_message_counter_t>::type;
144 : std::atomic<message_counter_t> m_num_control_messages_sent = 0;
145 : std::atomic<message_counter_t> m_num_control_responses_received = 0;
146 :
147 : using const_total_trigger_counter_t =
148 : std::invoke_result<decltype(&general_metric_t::num_total_triggers_received), general_metric_t>::type;
149 : std::atomic<std::remove_const<const_total_trigger_counter_t>::type> m_num_total_triggers_received;
150 :
151 : using const_run_trigger_counter_t =
152 : std::invoke_result<decltype(&general_metric_t::num_run_triggers_received), general_metric_t>::type;
153 : std::atomic<std::remove_const<const_run_trigger_counter_t>::type> m_num_run_triggers_received;
154 :
155 : //
156 : //
157 : // monitoring data/information
158 : //
159 : std::deque<uint> m_buffer_counts; // NOLINT(build/unsigned)
160 : std::shared_mutex m_buffer_counts_mutex;
161 : void update_buffer_counts(uint new_count); // NOLINT(build/unsigned)
162 : double read_average_buffer_counts();
163 :
164 : //
165 : // DAQ-CIB communication statistics
166 : //
167 :
168 : //
169 : // trigger bit to be written into the HSI event
170 : //
171 : uint32_t m_trigger_bit;
172 : // flag to hold the start_run until the receiver is ready
173 : std::atomic<bool> m_receiver_ready;
174 : };
175 :
176 : } // namespace dunedaq::cibmodules
177 :
178 : #endif // CIBMODULES_PLUGINS_CIBMODULE_HPP_
|