Program Listing for File hardware_monitor.hpp
↰ Return to documentation for file (hardware_monitor.hpp)
#ifndef HW_MON_FRONTEND_H_
#define HW_MON_FRONTEND_H_
#include <cstdint>
#include <memory>
#include "config.hpp"
#include "hardware_monitor_backend.hpp"
#include "bus.hpp"
#include "publisher.hpp"
#include "network/utility.hpp"
#include "config/config_register.hpp"
#include "ers/ers.h"
using namespace std::chrono_literals;
template <class DEV>
class HwMonitor
{
public:
using device_pair = std::pair<std::shared_ptr<DEV>, std::shared_ptr<DEV>>;
HwMonitor(const std::vector<device_pair> & device_pairs, const ConfigRegister & c);
bool publish_monitor_info();
private:
HwMonBackend<DEV> m_backend;
Bus m_bus;
uint64_t m_fid;
std::unique_ptr<Publisher> m_publisher;
};
template <class DEV>
HwMonitor<DEV>::HwMonitor(const std::vector<HwMonitor<DEV>::device_pair> & device_pairs, const ConfigRegister &c)
: m_backend(device_pairs, c.extra_mon),
m_bus{c.bus_dir, c.bus_group, "register-mon-"+std::to_string(c.dconfs.at(0).dev_no), c.verbose_bus},
m_fid(c.fid_mon)
{
constexpr int net_pages{16};
constexpr int net_page_size{4096};
constexpr int net_page_timeout{0};
auto fid_mon = Elink(c.fid_mon);
unsigned int mon_interval_us = 1e6*c.mon_interval;
ERS_INFO(std::format("Hardware monitoring poll period {} s.", c.mon_interval));
m_publisher = network::utility::create_buffered_publisher(c.network_mode, c.local_ip, c.port_mon,
net_pages, net_page_size, net_page_timeout, UINT32_MAX, "HWMonitor", 0ms);
m_bus.publish(std::vector<felixbus::FelixBusElinkInfo>{felixbus::FelixBusElinkInfo{
.fid = fid_mon.fid,
.ip = c.local_ip,
.port = static_cast<std::uint16_t>(c.port_mon),
.unbuffered = false,
.pubsub = true,
.tcp = c.network_mode == NetworkMode::tcp,
.stream = fid_mon.has_streams,
.netio_pages = net_pages,
.netio_pagesize = net_page_size,
}});
m_publisher->set_periodic_callback(mon_interval_us, [this]{return publish_monitor_info();});
}
template <class DEV>
bool HwMonitor<DEV>::publish_monitor_info()
{
std::string msg = m_backend.get_monitor_data();
auto msg_ptr = reinterpret_cast<uint8_t*>(msg.data());
std::array<iovec, 2> net_msg;
uint8_t status = 0;
net_msg[0].iov_len = 1;
net_msg[0].iov_base = &status;
net_msg[1].iov_len = msg.length();
net_msg[1].iov_base = msg_ptr;
//The publish function that takes a pointer to the data message
//assumes that the first byte is the status byte.
std::ignore = m_publisher->publish(m_fid, net_msg, 0, 0, 0);
std::ignore = m_publisher->flush(m_fid);
//This function must return false otherwise the callback is invoked again.
//TODO: the publisher set_periodic_callback is designed for felix-tohost.
return false;
}
#endif /* HW_MON_FRONTEND_H_ */