Add utilization messages for more debbuging
This commit is contained in:
parent
377fb3417e
commit
5f0e71b13d
@ -3,18 +3,59 @@ syntax = "proto3";
|
||||
import "nanopb.proto";
|
||||
package utilization;
|
||||
|
||||
message Utilization
|
||||
enum Error {
|
||||
NoError = 0;
|
||||
}
|
||||
|
||||
message UtilizationSummary
|
||||
{
|
||||
string name = 1 [ (nanopb).max_size = 32 ];
|
||||
uint32 stackSize = 2;
|
||||
uint32 stackUsed = 3;
|
||||
uint32 utilization = 4;
|
||||
};
|
||||
uint32 avg_cpu_percent = 1;
|
||||
uint32 max_stack_percent = 2;
|
||||
uint32 thread_count = 3;
|
||||
uint32 cpu_idle = 4;
|
||||
}
|
||||
|
||||
message SystemStats
|
||||
{
|
||||
uint32 cpu_utilization_percent = 1;
|
||||
uint32 max_stack_utilization_percent = 2; // e.g., worst stack usage
|
||||
uint32 heap_free_percent = 3; // if heap used
|
||||
uint32 num_threads_over_threshold = 4; // e.g., stack over 80%
|
||||
}
|
||||
|
||||
message UtilizationBroadcastConfigRequest
|
||||
{
|
||||
uint32 period_ms = 1;
|
||||
}
|
||||
|
||||
message UtilizationBroadcastConfigResponse
|
||||
{
|
||||
}
|
||||
|
||||
message UtilizationSummaryRequest
|
||||
{
|
||||
}
|
||||
|
||||
message UtilizationSummaryResponse
|
||||
{
|
||||
UtilizationSummary utilization_summary = 1;
|
||||
Error error = 2;
|
||||
}
|
||||
|
||||
message UtilizationBroadcast
|
||||
{
|
||||
SystemStats system_stats = 1;
|
||||
}
|
||||
|
||||
// only those messages are send through wire at temperature endpoint
|
||||
message IngressMessage
|
||||
{
|
||||
uint32 request_id = 255;
|
||||
oneof data
|
||||
{
|
||||
UtilizationBroadcastConfigRequest utilization_broadcast_config_request = 1;
|
||||
UtilizationSummaryRequest utilization_summary_request = 2;
|
||||
}
|
||||
};
|
||||
|
||||
message EgressMessage
|
||||
@ -22,7 +63,9 @@ message EgressMessage
|
||||
optional uint32 request_id = 255;
|
||||
oneof data
|
||||
{
|
||||
UtilizationBroadcastConfigResponse utilization_broadcast_config_response = 1;
|
||||
UtilizationSummaryResponse utilization_summary_response = 2;
|
||||
// broadcast
|
||||
Utilization utilization = 16;
|
||||
UtilizationBroadcast utilization = 16;
|
||||
}
|
||||
};
|
||||
|
||||
@ -44,7 +44,7 @@ template <typename RequestT> struct global_ipc_request<RequestT, std::enable_if_
|
||||
|
||||
static std::optional<ResponseT> call(const RequestT &request) {
|
||||
static zephyr::semaphore::sem sem{0, 1};
|
||||
return defaultIpcHandler(ctrlIngressQueue, temperature_receiver_tag, sem, request);
|
||||
return defaultIpcHandler(ctrlIngressQueue, ctrl_receiver_tag, sem, request);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ using namespace rims;
|
||||
/// exception handling takes ~800 bytes from the stack when thrown, we need to make sure there is at least this much stack left for each thread
|
||||
/// We need to drop exceptions ;( most of the stack space seems to be used for stack unwinding and other stuff
|
||||
///
|
||||
static K_THREAD_STACK_DEFINE(k_messengerStack, 1200);
|
||||
static K_THREAD_STACK_DEFINE(k_messengerStack, 1500);
|
||||
TStack messengerStack{k_messengerStack, K_THREAD_STACK_SIZEOF(k_messengerStack)};
|
||||
|
||||
static K_THREAD_STACK_DEFINE(k_uartStack, 1300);
|
||||
@ -38,7 +38,7 @@ TStack temperatureSamplerStack{k_temperatureSamplerStack, K_THREAD_STACK_SIZEOF(
|
||||
static K_THREAD_STACK_DEFINE(k_zeroCrossDetectionStack, 1300);
|
||||
TStack zeroCrossDetectionStack{k_zeroCrossDetectionStack, K_THREAD_STACK_SIZEOF(k_zeroCrossDetectionStack)};
|
||||
|
||||
static K_THREAD_STACK_DEFINE(k_phaseModulationStack, 1500);
|
||||
static K_THREAD_STACK_DEFINE(k_phaseModulationStack, 1700);
|
||||
TStack phaseModulationStack{k_phaseModulationStack, K_THREAD_STACK_SIZEOF(k_phaseModulationStack)};
|
||||
|
||||
static K_THREAD_STACK_DEFINE(k_gpioStack, 700);
|
||||
@ -79,7 +79,7 @@ gpio_dt_spec status = GPIO_DT_SPEC_GET(DT_NODELABEL(status_led), gpios);
|
||||
|
||||
int main() {
|
||||
using namespace rims;
|
||||
auto littlesleep = []() { std::this_thread::sleep_for(std::chrono::milliseconds{100}); };
|
||||
auto littlesleep = []() { std::this_thread::sleep_for(std::chrono::milliseconds{200}); };
|
||||
|
||||
messengerTread.init(messengerStack);
|
||||
uartThread.init(uartStack);
|
||||
@ -137,4 +137,7 @@ int main() {
|
||||
threadAnalyzer->start();
|
||||
littlesleep();
|
||||
}
|
||||
while(true){
|
||||
littlesleep();
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,5 +16,6 @@ constexpr int operation_receiver_tag = 6;
|
||||
constexpr int messenger_receiver_tag = 7;
|
||||
constexpr int uart_receiver_tag = 8;
|
||||
constexpr int cobs_receiver_tag = 9;
|
||||
constexpr int utilization_receiver_tag = 10;
|
||||
|
||||
} // namespace rims
|
||||
|
||||
@ -7,10 +7,11 @@
|
||||
#include "operation.hpp"
|
||||
|
||||
#include "config.hpp"
|
||||
#include "gpio.hpp"
|
||||
#include "ctrl.hpp"
|
||||
#include "gpio.hpp"
|
||||
#include "temperature_measurements.hpp"
|
||||
#include "uart.hpp"
|
||||
#include "utilization.hpp"
|
||||
|
||||
#include "pb.h"
|
||||
#include "pb_decode.h"
|
||||
@ -23,6 +24,7 @@
|
||||
#include "proto/message.pb.h"
|
||||
#include "proto/operation.pb.h"
|
||||
#include "proto/temperature.pb.h"
|
||||
#include "proto/utilization.pb.h"
|
||||
|
||||
#include "id.hpp"
|
||||
|
||||
@ -217,6 +219,7 @@ void MessengerThread::threadMain() {
|
||||
logEgressQueue.k_event_init(_events.at(4));
|
||||
gpioEgressQueue.k_event_init(_events.at(5));
|
||||
operationEgressQueue.k_event_init(_events.at(6));
|
||||
utilizationEgressQueue.k_event_init(_events.at(7));
|
||||
|
||||
while (1) {
|
||||
auto ret = zephyr::event_pool::k_poll_forever(_events);
|
||||
@ -228,6 +231,7 @@ void MessengerThread::threadMain() {
|
||||
zephyr::event_pool::k_poll_handle(_events[4], std::bind(&MessengerThread::event_logEgress, this));
|
||||
zephyr::event_pool::k_poll_handle(_events[5], std::bind(&MessengerThread::event_gpioEgress, this));
|
||||
zephyr::event_pool::k_poll_handle(_events[6], std::bind(&MessengerThread::event_operation, this));
|
||||
zephyr::event_pool::k_poll_handle(_events[7], std::bind(&MessengerThread::event_utilization, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,6 +313,10 @@ void MessengerThread::event_dataArrived() {
|
||||
CHECK(handle_opIngressMsg(id, stream, buf.device));
|
||||
break;
|
||||
}
|
||||
case utilization_receiver_tag: {
|
||||
CHECK(handle_utilizationIngressMsg(id, stream, buf.device));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
std::span<std::byte> b{(std::byte *)buf.data.data(), buf.data.size()};
|
||||
AsyncUART::transmit(buf.device, b);
|
||||
@ -353,40 +361,45 @@ void MessengerThread::event_dataArrived() {
|
||||
}
|
||||
|
||||
void MessengerThread::event_temperatureEgress() {
|
||||
temperatureEgressQueue.try_consume([&](temperature_EgressMessage &out) { //
|
||||
temperatureEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, temperature_receiver_tag, out.request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
void MessengerThread::event_ctrlEgress() {
|
||||
ctrlEgressQueue.try_consume([&](ctrl_EgressMessage &out) { //
|
||||
ctrlEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, ctrl_receiver_tag, out.has_request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
void MessengerThread::event_configEgress() {
|
||||
configEgressQueue.try_consume([&](config_EgressMessage &out) { //
|
||||
configEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, config_receiver_tag, out.has_request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
void MessengerThread::event_logEgress() {
|
||||
logEgressQueue.try_consume([&](log_EgressMessage &out) { //
|
||||
logEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, logging_receiver_tag, out.has_request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
void MessengerThread::event_gpioEgress() {
|
||||
gpioEgressQueue.try_consume([&](gpio_EgressMessage &out) { //
|
||||
gpioEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, gpio_receiver_tag, out.has_request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
void MessengerThread::event_operation() {
|
||||
operationEgressQueue.try_consume([&](op_EgressMessage &out) { //
|
||||
operationEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, operation_receiver_tag, out.has_request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
void MessengerThread::event_utilization() {
|
||||
utilizationEgressQueue.try_consume([&](auto &out) { //
|
||||
push({(std::byte *)&out, sizeof(out)}, utilization_receiver_tag, out.has_request_id ? std::optional{out.request_id} : std::nullopt);
|
||||
});
|
||||
}
|
||||
|
||||
struct SubsystemMessages {
|
||||
uint32_t subsystem_id;
|
||||
@ -395,13 +408,14 @@ struct SubsystemMessages {
|
||||
uint32_t tag;
|
||||
};
|
||||
|
||||
constexpr std::array<SubsystemMessages, 6> subsystems = { //
|
||||
constexpr std::array<SubsystemMessages, 7> subsystems = { //
|
||||
SubsystemMessages{temperature_receiver_tag, temperature_IngressMessage_msg, temperature_EgressMessage_msg, temperature_IngressMessage_request_id_tag},
|
||||
SubsystemMessages{ctrl_receiver_tag, ctrl_IngressMessage_msg, ctrl_EgressMessage_msg, ctrl_IngressMessage_request_id_tag},
|
||||
SubsystemMessages{config_receiver_tag, config_IngressMessage_msg, config_EgressMessage_msg, config_IngressMessage_request_id_tag},
|
||||
SubsystemMessages{logging_receiver_tag, log_IngressMessage_msg, log_EgressMessage_msg, log_IngressMessage_request_id_tag},
|
||||
SubsystemMessages{gpio_receiver_tag, gpio_IngressMessage_msg, gpio_EgressMessage_msg, gpio_IngressMessage_request_id_tag},
|
||||
SubsystemMessages{operation_receiver_tag, op_IngressMessage_msg, op_EgressMessage_msg, op_IngressMessage_request_id_tag}
|
||||
SubsystemMessages{operation_receiver_tag, op_IngressMessage_msg, op_EgressMessage_msg, op_IngressMessage_request_id_tag},
|
||||
SubsystemMessages{utilization_receiver_tag, utilization_IngressMessage_msg, utilization_EgressMessage_msg, utilization_IngressMessage_request_id_tag}
|
||||
};
|
||||
|
||||
constexpr const pb_msgdesc_t &ingress(uint32_t tag) {
|
||||
@ -455,28 +469,32 @@ std::expected<void, Error> MessengerThread::defaultHandler(uint32_t subsystem_id
|
||||
}
|
||||
|
||||
std::expected<void, Error> MessengerThread::handle_temperatureIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev) {
|
||||
// try to decode stream, and put it to IngressQueue
|
||||
if (not temperatureIngressQueue.try_produce([&](temperature_IngressMessage &request) { return defaultHandler(temperature_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
if (not temperatureIngressQueue.try_produce([&](auto &request) { return defaultHandler(temperature_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Error> MessengerThread::handle_ctrlIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev) {
|
||||
if (not ctrlIngressQueue.try_produce([&](ctrl_IngressMessage &request) { return defaultHandler(ctrl_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
if (not ctrlIngressQueue.try_produce([&](auto &request) { return defaultHandler(ctrl_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Error> MessengerThread::handle_configIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev) {
|
||||
if (not configIngressQueue.try_produce([&](config_IngressMessage &request) { return defaultHandler(config_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
if (not configIngressQueue.try_produce([&](auto &request) { return defaultHandler(config_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Error> MessengerThread::handle_gpioIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev) {
|
||||
if (not gpioIngressQueue.try_produce([&](gpio_IngressMessage &request) { return defaultHandler(gpio_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
if (not gpioIngressQueue.try_produce([&](auto &request) { return defaultHandler(gpio_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Error> MessengerThread::handle_opIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev) {
|
||||
if (not operationIngressQueue.try_produce([&](op_IngressMessage &request) { return defaultHandler(operation_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
if (not operationIngressQueue.try_produce([&](auto &request) { return defaultHandler(operation_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Error> MessengerThread::handle_utilizationIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev) {
|
||||
if (not utilizationIngressQueue.try_produce([&](auto &request) { return defaultHandler(utilization_receiver_tag, &request, id, stream, dev); })) return std::unexpected{messenger::request_queue_full{}};
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -159,6 +159,7 @@ class MessengerThread : public ZephyrThread {
|
||||
void event_logEgress();
|
||||
void event_gpioEgress();
|
||||
void event_operation();
|
||||
void event_utilization();
|
||||
|
||||
using handler_ret_t = std::expected<void, Error>;
|
||||
|
||||
@ -169,10 +170,11 @@ class MessengerThread : public ZephyrThread {
|
||||
NDIS handler_ret_t handle_configIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev);
|
||||
NDIS handler_ret_t handle_gpioIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev);
|
||||
NDIS handler_ret_t handle_opIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev);
|
||||
NDIS handler_ret_t handle_utilizationIngressMsg(WireFormatID id, pb_istream_t &stream, AsyncUART *dev);
|
||||
|
||||
void push(std::span<std::byte> bytes, uint32_t subsystem_id, std::optional<uint32_t> requestid);
|
||||
|
||||
std::array<k_poll_event, 7> _events;
|
||||
std::array<k_poll_event, 8> _events;
|
||||
|
||||
public:
|
||||
// a pair of subsystem_id and request requestId
|
||||
|
||||
@ -6,10 +6,12 @@
|
||||
#include <proto/message.pb.h>
|
||||
#include <proto/operation.pb.h>
|
||||
#include <proto/temperature.pb.h>
|
||||
#include <proto/utilization.pb.h>
|
||||
|
||||
static_assert(CONFIG_PROTO_CONFIGURATION_PB_H_MAX_SIZE <= sizeof(messenger_Message::data.bytes));
|
||||
static_assert(LOG_PROTO_LOG_PB_H_MAX_SIZE <= sizeof(messenger_Message::data.bytes));
|
||||
static_assert(TEMPERATURE_PROTO_TEMPERATURE_PB_H_MAX_SIZE <= sizeof(messenger_Message::data.bytes));
|
||||
static_assert(CTRL_PROTO_CTRL_PB_H_MAX_SIZE <= sizeof(messenger_Message::data.bytes));
|
||||
static_assert(GPIO_PROTO_GPIO_PB_H_MAX_SIZE <= sizeof(messenger_Message::data.bytes));
|
||||
static_assert(UTILIZATION_PROTO_UTILIZATION_PB_H_MAX_SIZE <= sizeof(messenger_Message::data.bytes));
|
||||
// static_assert(OP_PROTO_OPERATION_PB_H_MAX_SIZE <= sizeof(Message::data.bytes));
|
||||
|
||||
@ -1,17 +1,99 @@
|
||||
#include "utilization.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include "log.hpp"
|
||||
#include <cstdint>
|
||||
#include <thread>
|
||||
#include <zephyr/debug/thread_analyzer.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
namespace rims {
|
||||
|
||||
void mythread_analyzer_cb(struct thread_analyzer_info *info) {
|
||||
ULOG_DEBUG(
|
||||
"thread name, memfree, cpu : %s, %d, %d",
|
||||
info->name,
|
||||
info->stack_size - info->stack_used,
|
||||
info->utilization // cpu usage in %
|
||||
);
|
||||
K_FIFO_DEFINE(utilizationIngress);
|
||||
K_FIFO_DEFINE(utilizationEggress);
|
||||
|
||||
fifo_queue<utilization_IngressMessage, 2> utilizationIngressQueue{utilizationIngress};
|
||||
fifo_queue<utilization_EgressMessage, 2> utilizationEgressQueue{utilizationEggress};
|
||||
|
||||
struct StatsAccumulator {
|
||||
uint32_t total_cpu = 0;
|
||||
uint32_t total_threads = 0;
|
||||
uint32_t max_stack_percent = 0;
|
||||
uint32_t threads_over_stack_threshold = 0;
|
||||
uint32_t idle_thread_cpu = 0;
|
||||
uint32_t heap_free_percent = 0; // Optional, left as placeholder
|
||||
};
|
||||
|
||||
// Threshold for stack usage warning (e.g. 80%)
|
||||
constexpr uint32_t STACK_WARN_THRESHOLD = 80;
|
||||
|
||||
// We'll store intermediate values here
|
||||
static StatsAccumulator stats{};
|
||||
|
||||
// Simple utility to calculate percent with safety
|
||||
static uint32_t percent(uint32_t used, uint32_t total) {
|
||||
if (total == 0) return 0;
|
||||
return (used * 100) / total;
|
||||
}
|
||||
|
||||
// Called once per thread by thread_analyzer_run()
|
||||
extern "C" void mythread_analyzer_cb(struct thread_analyzer_info *info) {
|
||||
if (!info || info->stack_size == 0) return;
|
||||
|
||||
if (strcmp(info->name, "idle") == 0) {
|
||||
stats.idle_thread_cpu = info->utilization;
|
||||
return;
|
||||
}
|
||||
|
||||
stats.total_threads++;
|
||||
|
||||
uint32_t stack_used = info->stack_size - info->stack_used;
|
||||
uint32_t stack_used_percent = percent(stack_used, info->stack_size);
|
||||
|
||||
if (stack_used_percent > stats.max_stack_percent) {
|
||||
stats.max_stack_percent = stack_used_percent;
|
||||
}
|
||||
|
||||
if (stack_used_percent >= STACK_WARN_THRESHOLD) {
|
||||
stats.threads_over_stack_threshold++;
|
||||
}
|
||||
stats.total_cpu += info->utilization;
|
||||
}
|
||||
|
||||
// Call after `thread_analyzer_run(mythread_analyzer_cb)`
|
||||
void finalize_utilization(utilization_UtilizationSummary &summary, utilization_SystemStats &sysstats) {
|
||||
summary.avg_cpu_percent = percent(stats.total_cpu, stats.total_threads * 100);
|
||||
summary.max_stack_percent = stats.max_stack_percent;
|
||||
summary.thread_count = stats.total_threads;
|
||||
summary.cpu_idle = stats.idle_thread_cpu;
|
||||
|
||||
sysstats.cpu_utilization_percent = stats.total_cpu;
|
||||
sysstats.max_stack_utilization_percent = stats.max_stack_percent;
|
||||
sysstats.heap_free_percent = stats.heap_free_percent; // Fill from heap stats if available
|
||||
sysstats.num_threads_over_threshold = stats.threads_over_stack_threshold;
|
||||
|
||||
// Reset accumulator if reused
|
||||
stats = StatsAccumulator{};
|
||||
}
|
||||
|
||||
// void mythread_analyzer_cb(struct thread_analyzer_info *info) {
|
||||
// ULOG_DEBUG(
|
||||
// "thread name, memfree, cpu : %s, %d, %d",
|
||||
// info->name,
|
||||
// info->stack_size - info->stack_used,
|
||||
// info->utilization // cpu usage in %
|
||||
// );
|
||||
// }
|
||||
|
||||
void run_stats_collection() {
|
||||
thread_analyzer_run(mythread_analyzer_cb, 0);
|
||||
|
||||
utilization_UtilizationSummary summary{};
|
||||
utilization_SystemStats sysstats{};
|
||||
|
||||
finalize_utilization(summary, sysstats);
|
||||
|
||||
// Now encode with nanopb and send
|
||||
// pb_encode(..., &summary);
|
||||
// pb_encode(..., &sysstats);
|
||||
}
|
||||
|
||||
void ThreadAnalyzer::loop() {
|
||||
|
||||
@ -3,8 +3,14 @@
|
||||
#include "common.hpp"
|
||||
#include <zephyr/debug/thread_analyzer.h>
|
||||
|
||||
#include "fifo_queue.hpp"
|
||||
#include "utilization_pb_helpers.hpp"
|
||||
|
||||
namespace rims {
|
||||
|
||||
extern fifo_queue<utilization_IngressMessage, 2> utilizationIngressQueue;
|
||||
extern fifo_queue<utilization_EgressMessage, 2> utilizationEgressQueue;
|
||||
|
||||
class ThreadAnalyzer {
|
||||
public:
|
||||
ThreadAnalyzer() = default;
|
||||
|
||||
55
rims_app/src/utilization_pb_helpers.hpp
Normal file
55
rims_app/src/utilization_pb_helpers.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "message_type_id.hpp"
|
||||
#include "traits_helpers.hpp"
|
||||
#include <proto/utilization.pb.h>
|
||||
|
||||
namespace rims {
|
||||
|
||||
template <> constexpr int tag<utilization_UtilizationBroadcastConfigRequest>() {
|
||||
return utilization_IngressMessage_utilization_broadcast_config_request_tag;
|
||||
}
|
||||
|
||||
template <> constexpr int tag<utilization_UtilizationSummaryRequest>() {
|
||||
return utilization_IngressMessage_utilization_summary_request_tag;
|
||||
}
|
||||
|
||||
|
||||
template <> constexpr int tag<utilization_UtilizationBroadcastConfigResponse>() {
|
||||
return utilization_EgressMessage_utilization_broadcast_config_response_tag;
|
||||
}
|
||||
|
||||
template <> constexpr int tag<utilization_UtilizationSummaryResponse>() {
|
||||
return utilization_EgressMessage_utilization_summary_response_tag;
|
||||
}
|
||||
|
||||
template <> constexpr int tag<utilization_UtilizationBroadcast>() {
|
||||
return utilization_EgressMessage_utilization_broadcast_config_response_tag;
|
||||
}
|
||||
|
||||
template <typename MsgT>
|
||||
constexpr bool is_utilization_ingress_msg_v = is_any_of_v<
|
||||
MsgT, //
|
||||
utilization_UtilizationBroadcastConfigRequest,
|
||||
utilization_UtilizationSummaryRequest>;
|
||||
|
||||
template <typename MsgT>
|
||||
constexpr bool is_utilization_egress_msg_v = is_any_of_v<
|
||||
MsgT, //
|
||||
utilization_UtilizationBroadcastConfigResponse,
|
||||
utilization_UtilizationSummaryResponse,
|
||||
utilization_UtilizationBroadcast>;
|
||||
|
||||
template <> struct ResponseSelector<utilization_UtilizationBroadcastConfigRequest> {
|
||||
using response_t = utilization_UtilizationBroadcastConfigResponse;
|
||||
};
|
||||
|
||||
template <> struct ResponseSelector<utilization_UtilizationSummaryRequest> {
|
||||
using response_t = utilization_UtilizationSummaryResponse;
|
||||
};
|
||||
|
||||
template <> struct EgressSelector<utilization_IngressMessage> {
|
||||
using egress_t = utilization_EgressMessage;
|
||||
};
|
||||
|
||||
} // namespace rims
|
||||
Loading…
Reference in New Issue
Block a user