42 template<
typename Tuple>
45 template<
typename... Ts>
47 using type = std::tuple<HistoricalMailboxFor<Ts>...>;
61 create_input_mailboxes_impl(std::make_index_sequence<InputCount>{});
70 start_input_mailboxes_impl(std::make_index_sequence<InputCount>{});
81 template<std::
size_t PrimaryIdx>
83 start_secondary_threads_impl<PrimaryIdx>(std::make_index_sequence<InputCount>{});
91 if (thread.joinable()) {
101 template<std::
size_t Index>
102 auto create_historical_mailbox_for_input() {
103 auto&
module = static_cast<ModuleType&>(*this);
104 using InputType = std::tuple_element_t<Index, InputTypesTuple>;
108 using OutputData =
typename ModuleType::OutputData;
110 uint32_t base_addr = commrat::calculate_base_address<OutputData, OutputTypesTuple, UserRegistry>(
111 module.config_.system_id(), module.config_.instance_id());
115 constexpr uint8_t num_outputs = std::tuple_size_v<OutputTypesTuple>;
116 uint8_t data_mbx_index =
get_data_mbx_base(num_outputs) +
static_cast<uint8_t
>(Index);
119 uint32_t data_mailbox_id = base_addr | data_mbx_index;
122 constexpr size_t input_message_size = get_data_mailbox_size<InputType>();
124 std::cout <<
"[" <<
module.config_.name << "] Creating DATA mailbox[" << Index
125 << "] at 0x" << std::hex << data_mailbox_id << std::dec
126 << " (base=0x" << std::hex << base_addr << std::dec
127 << ", index=" << static_cast<int>(data_mbx_index)
128 << ", size=" << input_message_size << " bytes)\n";
132 .message_slots =
module.config_.data_message_slots.value(),
133 .max_message_size = input_message_size,
134 .send_priority = static_cast<uint8_t>(module.config_.priority),
135 .realtime = module.config_.realtime,
136 .mailbox_name = module.config_.name + "_data_" + std::to_string(Index)
139 return HistoricalMailboxFor<InputType>(
141 module.config_.sync_tolerance()
148 template<std::size_t... Is>
149 void create_input_mailboxes_impl(std::index_sequence<Is...>) {
151 create_historical_mailbox_for_input<Is>()...
158 template<std::size_t... Is>
159 void start_input_mailboxes_impl(std::index_sequence<Is...>) {
160 auto&
module = static_cast<ModuleType&>(*this);
165 auto result = std::get<Is>(*input_mailboxes_).start();
167 std::cerr <<
"[" <<
module.config_.name << "] ERROR: Failed to start input mailbox "
168 << Is << " - error " << static_cast<int>(result.get_error()) << "\n";
177 template<std::size_t PrimaryIdx, std::size_t... Is>
178 void start_secondary_threads_impl(std::index_sequence<Is...>) {
179 auto&
module = static_cast<ModuleType&>(*this);
194 template<std::
size_t InputIdx>
196 auto&
module = static_cast<ModuleType&>(*this);
197 using InputType = std::tuple_element_t<InputIdx, InputTypesTuple>;
200 std::cout <<
"[" <<
module.config_.name << "] secondary_input_receive_loop[" << InputIdx << "] started\n";
202 int receive_count = 0;
203 while (module.running_) {
205 auto result = mailbox.template receive<InputType>();
206 if (!result.has_value()) {
207 std::cout <<
"[" <<
module.config_.name << "] secondary_input_receive_loop[" << InputIdx
208 << "] receive failed after " << receive_count << " messages\n";
212 if (receive_count <= 3) {
213 std::cout <<
"[" <<
module.config_.name << "] secondary_input_receive_loop[" << InputIdx
214 << "] received message #" << receive_count
215 << ", timestamp=" << result.value().header.timestamp << "\n";
219 std::cout <<
"[" <<
module.config_.name << "] secondary_input_receive_loop[" << InputIdx
220 << "] ended (total: " << receive_count << " messages)\n";