#include <thread>
#include <chrono>
#include <csignal>
#include <atomic>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <memory>
#include "helpers.h"
#include "config.h"
#include "rsi.h"
#include "rttask.h"
constexpr bool LOOP_FOREVER = false;
constexpr int64_t LOOP_PERIOD_MS = 1000;
constexpr bool PRINT_DETAILED_INFO = true;
constexpr bool PRINT_TIMING_METRICS = true;
constexpr int32_t SEPARATOR_LENGTH = 80;
std::atomic<bool> stopRequested(false);
void SignalHandler(int signal)
{
if (signal == SIGINT)
{
stopRequested.store(true);
}
}
template<typename T>
std::vector<T> dst;
for (auto& p : src) dst.emplace_back(std::move(p));
return dst;
}
std::vector<std::string> dst;
for (const char* p : src) {
dst.emplace_back(std::string(p));
}
return dst;
}
{
switch (state)
{
default: return "Unknown State";
}
}
{
switch (state)
{
default: return "Unknown State";
}
}
{
switch (platformType)
{
default: return "Unknown Platform";
}
}
std::string FormatUserLabel(std::string_view userLabel, std::string_view autoGenerated = "")
{
if (userLabel.empty() || (!autoGenerated.empty() && userLabel == autoGenerated))
return std::string();
return std::string(userLabel) + " ";
}
void AppendTaskSummary(std::ostream& os,
RTTask& task)
{
std::string userLabel = FormatUserLabel(taskParams.
UserLabel);
std::string executionCount =
os << " Task " << userLabel
<<
"(ID: " << task.
IdGet() <<
")"
<<
" - State: " << ToString(taskStatus.
State)
<< " [Execution Count: " << executionCount << "]\n";
if (PRINT_DETAILED_INFO)
{
{
}
{
}
os <<
" Priority: " <<
static_cast<int32_t
>(taskParams.
Priority) <<
"\n";
os <<
" Repeats: " << repeatsOrForever(taskParams.
Repeats) <<
"\n";
os <<
" Period: " << taskParams.
Period <<
" samples\n";
os <<
" Phase: " << taskParams.
Phase <<
" samples\n";
}
if (PRINT_TIMING_METRICS)
{
{
os <<
" Max Execution Time: " << timeOrInvalid(taskStatus.
ExecutionTimeMax) <<
" ns\n";
os <<
" Min Execution Time: " << timeOrInvalid(taskStatus.
ExecutionTimeMin) <<
" ns\n";
os <<
" Mean Execution Time: " << timeOrInvalid(taskStatus.
ExecutionTimeMean) <<
" ns\n";
}
else
{
os << " Timing: Disabled\n";
}
}
}
void AppendTaskManagerSummary(std::ostream& os,
RTTaskManager& taskManager)
{
os << std::string(SEPARATOR_LENGTH, '-') << "\n";
std::string autoGeneratedLabel =
"TaskManager_" + std::to_string(taskManager.
IdGet());
std::string managerLabel = FormatUserLabel(taskManagerParams.
UserLabel, autoGeneratedLabel);
os << "Task Manager " << managerLabel
<<
"(ID: " << taskManager.
IdGet() <<
")"
<<
" - State: " << ToString(taskManagerStatus.
State)
<<
" [Cycle Count: " << taskManagerStatus.
CycleCount <<
"]\n";
if (PRINT_DETAILED_INFO)
{
os <<
"Platform: " << ToString(taskManagerParams.
Platform);
{
os <<
" - " << taskManagerParams.
NodeName;
}
{
if (taskManagerParams.
CpuCore != -1)
{
os <<
" - CPU Core: " << taskManagerParams.
CpuCore;
}
}
os << "\n";
{
}
}
if (PRINT_TIMING_METRICS)
{
os <<
"Cycle Time Mean: " << taskManagerStatus.
CycleTimeMean <<
" ns\n";
os <<
"Cycle Time Last: " << taskManagerStatus.
CycleTimeLast <<
" ns\n";
os <<
"Cycle Time Max: " << taskManagerStatus.
CycleTimeMax <<
" ns\n";
os <<
"Cycle Time Min: " << taskManagerStatus.
CycleTimeMin <<
" ns\n";
}
std::vector<RTTask> tasks = ConvertToSTLVector(taskManager.
TasksGet());
{
if (tasks.size() != 0)
{
os << ", Current tasks: " << tasks.size();
}
os << "\n";
}
for (auto& task : tasks)
{
AppendTaskSummary(os, task);
}
}
void AppendGlobalTagSummary(std::ostream& os, const std::shared_ptr<RTTaskManager>& taskManager)
{
std::vector<std::string> globalTagNames = ConvertToSTLVector(taskManager->GlobalNamesGet());
os << "Global Tags Count: " << globalTagNames.size() << "\n";
for (const auto& tagName : globalTagNames)
{
os <<
" " << tagName <<
": " << tag.
UInt64 <<
"\n";
}
}
int main()
{
const std::string SAMPLE_APP_NAME = "📜 Utilities: Print Real-Time Tasks Summary";
std::signal(SIGINT, SignalHandler);
int exitCode = -1;
try
{
std::ostringstream rtTasksSummary;
auto nextWakeupTime = std::chrono::steady_clock::now();
while (!stopRequested.load())
{
rtTasksSummary.str(""); rtTasksSummary.clear();
rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
rtTasksSummary << "Discovered " << taskManagers.size() << " task managers:\n";
if (taskManagers.size() != 0)
{
for (auto& taskManager : taskManagers)
{
AppendTaskManagerSummary(rtTasksSummary, taskManager);
}
rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
}
std::cout << rtTasksSummary.str() << std::endl;
if (!LOOP_FOREVER) break;
nextWakeupTime += std::chrono::milliseconds(LOOP_PERIOD_MS);
std::this_thread::sleep_until(nextWakeupTime);
};
exitCode = 0;
}
catch (const std::exception &ex)
{
std::cerr << ex.what() << std::endl;
exitCode = -1;
}
return exitCode;
}
const size_t Size() const
Returns the number of elements in the vector.
A wrapper class for the C++ STL vector class that aims to maintain application binary interface....
int32_t IdGet()
Get the ID of the task.
RTTaskInfo InfoGet()
Get information about the task.
RTTaskStatus StatusGet()
Get the current status of the task.
Interface for controlling and monitoring a single real-time task. See RTTaskManager::TaskSubmit and R...
RapidVector< RTTask > TasksGet()
Get all tasks managed by this RTTaskManager.
int32_t IdGet()
Get the ID of the manager.
static RapidVector< RTTaskManager > Discover()
Discover all active RTTaskManager instances.
RTTaskManagerInfo InfoGet()
Get information about the manager.
RTTaskManagerStatus StatusGet()
Get the current status of the manager.
Interface for managing real-time tasks firmware. See Real-Time Tasks for more information.
RTTaskManagerState
Enum representing the possible states of an RTTaskManager.
@ Dead
Manager firmware is not initialized or has been terminated.
@ Running
Manager firmware is currently running.
@ Stopped
Manager firmware is initialized but not currently running.
RTTaskState
Enum representing the possible states of a real-time task.
@ Dead
Task is not initialized or has been terminated.
@ Waiting
Task is active but waiting for its next scheduled execution time.
@ Running
Task is currently executing.
@ Disabled
Task is initialized but not currently executing.
PlatformType
Enum representing the platform type for an RTTaskManager.
@ Native
Native platform (where the library is running, Windows or Linux).
@ Windows
Standard Windows (useful for debugging tasks before running on INtime).
@ Linux
Linux with PREEMPT_RT.
void PrintHeader(std::string sampleAppName)
[NetworkShutdown]
void PrintFooter(std::string sampleAppName, int exitCode)
[PrintHeader]
The RealTimeTasks namespace.
RTTaskCreationParameters specifies all the information required to create and configure a real-time t...
static constexpr int32_t RepeatForever
Special value to indicate the task should repeat forever.
char FunctionName[NameLengthMaximum]
Name of the task function to execute.
char LibraryName[NameLengthMaximum]
Name of the library containing the task function.
char UserLabel[NameLengthMaximum]
User-defined label for the task. Empty UserLabels will default to the FunctionName....
int32_t Repeats
Number of times the task should execute (RepeatForever for infinite, 0 for none (one-shot)).
TaskPriority Priority
Priority of the task (coming soon).
char LibraryDirectory[DirectoryLengthMaximum]
Path to the directory containing the library with the task function.
int32_t Period
Execution period of the task in RMP sample periods.
int32_t Phase
Phase offset for task execution. For example, if you have 4 tasks with a period of 4,...
bool EnableTiming
Whether to enable timing measurements for the task. Keep in mind, enabling timing does add a small am...
RTTaskInfo provides information about a real-time task, including its creation parameters....
RTTaskCreationParameters CreationParameters
Creation parameters used to create the task.
char UserLabel[NameLengthMaximum]
User-defined label for the manager.
RTTaskManagerCreationParameters specifies all the information required to create and configure an RTT...
int32_t CpuCore
[Linux] CPU core to which the manager should be pinned (-1 for no pinning).
PlatformType Platform
Platform on which the manager firmware will run.
char NodeName[NameLengthMaximum]
[INtime] Name of the node on which the manager will run. By default, this is set to (and verified as)...
char RTTaskDirectory[DirectoryLengthMaximum]
Path to the directory containing the real-time task libraries.
Information about RTTaskManager firmware, including its creation parameters and ID....
RTTaskManagerCreationParameters CreationParameters
Creation parameters used to create the manager.
RTTaskManagerStatus provides status information for RTTaskManager firmware, including its current sta...
uint64_t CycleTimeMax
Maximum execution time of a cycle in nanoseconds.
uint64_t TaskSubmissionCount
Number of tasks submitted to the manager.
RTTaskManagerState State
Current state of the manager.
uint64_t CycleTimeLast
Execution time of the last cycle in nanoseconds.
double CycleTimeMean
Mean execution time of cycles in nanoseconds.
uint64_t CycleTimeMin
Minimum execution time of a cycle in nanoseconds.
int64_t CycleCount
Number of cycles executed by the manager.
RTTaskStatus provides status information for a real-time task, including its current state,...
RTTaskState State
Current state of the task.
static constexpr uint64_t InvalidExecutionTime
Invalid value for execution time, indicating timing is not enabled or the task has not executed.
uint64_t ExecutionTimeMin
Minimum execution time of the task in nanoseconds.
uint64_t ExecutionTimeMax
Maximum execution time of the task in nanoseconds.
int64_t ExecutionCount
Number of times the task has executed.
double ExecutionTimeMean
Mean execution time of the task in nanoseconds.
uint64_t ExecutionTimeLast
Last execution time of the task in nanoseconds.
static constexpr int64_t InvalidExecutionCount
Invalid value for execution count, indicating the task has not executed.
Union representing a generic RMP firmware value with multiple data types, stored in 64-bits.
uint64_t UInt64
64-bit unsigned integer.