Line data Source code
1 : /**
2 : * @file TimingHardwareManagerBase.hpp
3 : *
4 : * TimingHardwareManagerBase is a DAQModule implementation that
5 : * provides the interface to the timing system hardware.
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 TIMINGLIBS_SRC_TIMINGHARDWAREMANAGER_HPP_
13 : #define TIMINGLIBS_SRC_TIMINGHARDWAREMANAGER_HPP_
14 :
15 : #include "InfoGatherer.hpp"
16 : #include "timinglibs/TimingHardwareInterface.hpp"
17 : #include "timinglibs/TimingIssues.hpp"
18 : #include "timinglibs/timingcmd/Nljs.hpp"
19 : #include "timinglibs/timingcmd/Structs.hpp"
20 : #include "timinglibs/timingcmd/msgp.hpp"
21 :
22 : #include "appfwk/DAQModule.hpp"
23 : #include "ers/Issue.hpp"
24 : #include "iomanager/Receiver.hpp"
25 : #include "logging/Logging.hpp"
26 :
27 : #include "timinglibs/dal/TimingHardwareManagerConf.hpp"
28 : #include "confmodel/Connection.hpp"
29 :
30 : #include "timing/TimingNode.hpp"
31 : #include "timing/EndpointDesignInterface.hpp"
32 : #include "timing/HSIDesignInterface.hpp"
33 : #include "timing/MasterDesignInterface.hpp"
34 : #include "timing/TopDesignInterface.hpp"
35 :
36 : #include "uhal/ConnectionManager.hpp"
37 : #include "utilities/ReusableThread.hpp"
38 :
39 : #include <map>
40 : #include <memory>
41 : #include <regex>
42 : #include <string>
43 : #include <vector>
44 :
45 : namespace dunedaq {
46 : namespace timinglibs {
47 :
48 : /**
49 : * @brief TimingHardwareManagerBase creates vectors of ints and writes
50 : * them to the configured output queues.
51 : */
52 : class TimingHardwareManagerBase : public dunedaq::appfwk::DAQModule, public timinglibs::TimingHardwareInterface
53 : {
54 : public:
55 : /**
56 : * @brief TimingHardwareManagerBase Constructor
57 : * @param name Instance name for this TimingHardwareManagerBase instance
58 : */
59 : explicit TimingHardwareManagerBase(const std::string& name);
60 :
61 : TimingHardwareManagerBase(const TimingHardwareManagerBase&) = delete; ///< TimingHardwareManagerBase is not copy-constructible
62 : TimingHardwareManagerBase& operator=(const TimingHardwareManagerBase&) =
63 : delete; ///< TimingHardwareManagerBase is not copy-assignable
64 : TimingHardwareManagerBase(TimingHardwareManagerBase&&) = delete; ///< TimingHardwareManagerBase is not move-constructible
65 : TimingHardwareManagerBase& operator=(TimingHardwareManagerBase&&) = delete; ///< TimingHardwareManagerBase is not move-assignable
66 0 : virtual ~TimingHardwareManagerBase() {}
67 :
68 : void init(std::shared_ptr<appfwk::ConfigurationManager> mcfg) override;
69 : virtual void conf(const CommandData_t& data);
70 :
71 : protected:
72 : // Commands
73 : // virtual void do_configure(const CommandData_t&);
74 : // virtual void do_start(const CommandData_t&);
75 : // virtual void do_stop(const CommandData_t&);
76 : virtual void do_scrap(const CommandData_t&);
77 :
78 :
79 : virtual void process_hardware_command(timingcmd::TimingHwCmd& timing_hw_cmd);
80 :
81 : // Configuration
82 : std::string m_hw_cmd_connection;
83 : using source_t = dunedaq::iomanager::ReceiverConcept<timingcmd::TimingHwCmd>;
84 : std::shared_ptr<source_t> m_hw_command_receiver;
85 :
86 : // hardware polling intervals [us]
87 : // TODO change to duration::milliseconds
88 : uint m_gather_interval;
89 : uint m_gather_interval_debug;
90 :
91 : // uhal members
92 : std::map<std::string, std::unique_ptr<uhal::HwInterface>> m_hw_device_map;
93 : std::mutex m_hw_device_map_mutex;
94 :
95 : // managed timing devices
96 : std::string m_monitored_device_name_master;
97 : std::map<uint, std::string> m_monitored_device_names_fanout;
98 : std::string m_monitored_device_name_endpoint;
99 : std::string m_monitored_device_name_hsi;
100 :
101 : virtual void register_common_hw_commands_for_design() = 0;
102 : virtual void register_master_hw_commands_for_design() = 0;
103 : virtual void register_endpoint_hw_commands_for_design() = 0;
104 : virtual void register_hsi_hw_commands_for_design() = 0;
105 :
106 : // retrieve top level/design object for a timing device
107 : template<class TIMING_DEV>
108 : TIMING_DEV get_timing_device(const std::string& device_name);
109 : const timing::TimingNode* get_timing_device_plain(const std::string& device_name);
110 :
111 : // timing hw cmds stuff
112 : std::map<timingcmd::TimingHwCmdId, std::function<void(const timingcmd::TimingHwCmd&)>> m_timing_hw_cmd_map_;
113 :
114 : template<typename Child>
115 : void register_timing_hw_command(const std::string& hw_cmd_id, void (Child::*f)(const timingcmd::TimingHwCmd&));
116 :
117 : // timing common commands
118 : void io_reset(const timingcmd::TimingHwCmd& hw_cmd);
119 : void print_status(const timingcmd::TimingHwCmd& hw_cmd);
120 :
121 : // timing master commands
122 : void set_timestamp(const timingcmd::TimingHwCmd& hw_cmd);
123 : void set_endpoint_delay(const timingcmd::TimingHwCmd& hw_cmd);
124 : void send_fl_cmd(const timingcmd::TimingHwCmd& hw_cmd);
125 : void master_endpoint_scan(const timingcmd::TimingHwCmd& hw_cmd);
126 :
127 : // timing partition commands
128 : virtual void partition_configure(const timingcmd::TimingHwCmd& hw_cmd) = 0;
129 :
130 : // timing endpoint commands
131 : void endpoint_enable(const timingcmd::TimingHwCmd& hw_cmd);
132 : void endpoint_disable(const timingcmd::TimingHwCmd& hw_cmd);
133 : void endpoint_reset(const timingcmd::TimingHwCmd& hw_cmd);
134 :
135 : // hsi
136 : void hsi_reset(const timingcmd::TimingHwCmd& hw_cmd);
137 : void hsi_configure(const timingcmd::TimingHwCmd& hw_cmd);
138 : void hsi_start(const timingcmd::TimingHwCmd& hw_cmd);
139 : void hsi_stop(const timingcmd::TimingHwCmd& hw_cmd);
140 : void hsi_print_status(const timingcmd::TimingHwCmd& hw_cmd);
141 :
142 : // opmon stuff
143 : std::atomic<uint64_t> m_received_hw_commands_counter; // NOLINT(build/unsigned)
144 : std::atomic<uint64_t> m_accepted_hw_commands_counter; // NOLINT(build/unsigned)
145 : std::atomic<uint64_t> m_rejected_hw_commands_counter; // NOLINT(build/unsigned)
146 : std::atomic<uint64_t> m_failed_hw_commands_counter; // NOLINT(build/unsigned)
147 :
148 : // monitoring
149 : std::map<std::string, std::unique_ptr<InfoGatherer>> m_info_gatherers;
150 :
151 : void register_info_gatherer(uint gather_interval, const std::string& device_name, int op_mon_level);
152 : void gather_monitor_data(InfoGatherer& gatherer);
153 :
154 : virtual void start_hw_mon_gathering(const std::string& device_name = "");
155 : virtual void stop_hw_mon_gathering(const std::string& device_name = "");
156 : virtual std::vector<std::string> check_hw_mon_gatherer_is_running(const std::string& device_name);
157 :
158 : std::mutex m_command_threads_map_mutex;
159 : std::map<std::string, std::unique_ptr<std::thread>> m_command_threads;
160 : std::mutex master_sfp_mutex;
161 : virtual void perform_endpoint_scan(const timingcmd::TimingHwCmd& hw_cmd);
162 : virtual void clean_endpoint_scan_threads();
163 : std::unique_ptr<dunedaq::utilities::ReusableThread> m_endpoint_scan_threads_clean_up_thread;
164 : std::atomic<bool> m_run_endpoint_scan_cleanup_thread;
165 : const timinglibs::dal::TimingHardwareManagerConf* m_params;
166 : std::map<uint,int> m_monitored_endpoints_round_trip_times;
167 : };
168 :
169 : } // namespace timinglibs
170 : } // namespace dunedaq
171 :
172 : #include "detail/TimingHardwareManagerBase.hxx"
173 :
174 : #endif // TIMINGLIBS_SRC_TIMINGHARDWAREMANAGER_HPP_
175 :
176 : // Local Variables:
177 : // c-basic-offset: 2
178 : // End:
|