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 Board hardware.
5 : * 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 "iomanager/Receiver.hpp"
18 : #include "iomanager/Sender.hpp"
19 : #include "utilities/WorkerThread.hpp"
20 : #include "hsilibs/HSIEventSender.hpp"
21 :
22 : #include "cibmodules/opmon/CIBModule.pb.h"
23 :
24 : #include <memory>
25 : #include <string>
26 : #include <vector>
27 : #include <fstream>
28 : #include <shared_mutex>
29 : #include <map>
30 : #include <deque>
31 :
32 : #include <boost/asio.hpp>
33 : #include <boost/array.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 :
62 : bool error_state() const { return m_error_state.load(); }
63 :
64 : protected:
65 : void generate_opmon_data() override;
66 :
67 : private:
68 :
69 : // control variables
70 : std::atomic<bool> m_is_running;
71 : std::atomic<bool> m_is_configured;
72 : std::atomic<bool> m_stop_requested;
73 :
74 : std::string m_receiver_host;
75 : /*const */ unsigned int m_receiver_port;
76 : std::chrono::microseconds m_receiver_timeout;
77 : std::atomic<bool> m_error_state;
78 :
79 : bool check_port_in_use(unsigned short port);
80 :
81 : boost::asio::io_service m_control_ios;
82 : boost::asio::ip::tcp::socket m_control_socket;
83 : boost::asio::ip::tcp::endpoint m_control_endpoint;
84 :
85 : boost::asio::io_service m_receiver_ios;
86 : boost::asio::ip::tcp::socket m_receiver_socket;
87 :
88 : std::shared_ptr<dunedaq::hsilibs::HSIEventSender::raw_sender_ct> m_cib_hsi_data_sender;
89 :
90 : // Commands
91 : void do_configure(const CommandData_t &obj) override;
92 : void do_start(const CommandData_t &startobj) override;
93 : void do_stop(const CommandData_t &obj) override;
94 0 : void do_scrap(const CommandData_t & /*obj*/) override {};
95 :
96 : // the CIB does not need reset, since the DAQ operation is
97 : // decoupled from the instrumentation operation
98 : void send_config(const std::string &config);
99 : bool send_message(const std::string &msg);
100 :
101 : // Configuration
102 : std::shared_ptr<appfwk::ConfigurationManager> m_cfg;
103 : using conf_t = appmodel::CIBModule;
104 : const conf_t *m_module = nullptr;
105 :
106 : std::atomic<daqdataformats::run_number_t> m_run_number;
107 :
108 : // Threading client
109 : dunedaq::utilities::WorkerThread m_thread_;
110 : void do_hsi_work(std::atomic<bool> &);
111 :
112 : // variables for geo_id to construct the HSI frame
113 : // These are defined as uint32 in the schema, but given the way the HSI frame is consctructed from this it is unsusable.
114 : // THe HSI frame uses 4 Bits for the slot and 10 Bits for the crate and 6 for the DetID. So here I'm overiding the types
115 : uint16_t m_det; // NOLINT
116 : uint16_t m_crate; // NOLINT
117 : uint16_t m_slot; // NOLINT
118 :
119 : template <typename T>
120 : bool read(boost::asio::ip::tcp::socket &socket, T &obj);
121 :
122 : //
123 : // members related to calibration stream
124 : //
125 : void update_calibration_file();
126 : void init_calibration_file();
127 : bool set_calibration_stream(const std::string &prefix = "");
128 :
129 : bool m_calibration_stream_enable = false;
130 : std::string m_calibration_dir = "";
131 : std::string m_calibration_prefix = "";
132 : std::chrono::minutes m_calibration_file_interval;
133 : std::ofstream m_calibration_file;
134 : std::chrono::steady_clock::time_point m_last_calibration_file_update;
135 :
136 : //
137 : // metric utilities
138 : //
139 : // -- these have to match the protobuf definition in CIBModuleInfo.proto
140 : using general_metric_t = dunedaq::cibmodules::opmon::CIBModuleInfo;
141 : using const_message_counter_t = 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 = std::invoke_result<decltype(&general_metric_t::num_total_triggers_received), general_metric_t>::type;
148 : std::atomic<std::remove_const<const_total_trigger_counter_t>::type> m_num_total_triggers_received;
149 :
150 : using const_run_trigger_counter_t = std::invoke_result<decltype(&general_metric_t::num_run_triggers_received), general_metric_t>::type;
151 : std::atomic<std::remove_const<const_run_trigger_counter_t>::type> m_num_run_triggers_received;
152 :
153 : //
154 : //
155 : // monitoring data/information
156 : //
157 : std::deque<uint> m_buffer_counts; // NOLINT(build/unsigned)
158 : std::shared_mutex m_buffer_counts_mutex;
159 : void update_buffer_counts(uint new_count); // NOLINT(build/unsigned)
160 : double read_average_buffer_counts();
161 :
162 : //
163 : // DAQ-CIB communication statistics
164 : //
165 :
166 : //
167 : // trigger bit to be written into the HSI event
168 : //
169 : uint32_t m_trigger_bit;
170 : // flag to hold the start_run until the receiver is ready
171 : std::atomic<bool> m_receiver_ready;
172 : };
173 :
174 : } // namespace dunedaq::cibmodules
175 :
176 : #endif // CIBMODULES_PLUGINS_CIBMODULE_HPP_
|