APIs, concepts, guides, and more
print-rttasks-summary.cpp
#include <thread>
#include <chrono>
#include <csignal>
#include <atomic>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <memory>
#include "helpers.h" // import our helper functions.
#include "config.h" // import our configuration.
#include "rsi.h" // import our RapidCode Library.
#include "rttask.h" // import the RTTask library
using namespace RSI::RapidCode; // Import the RapidCode namespace
using namespace RSI::RapidCode::RealTimeTasks; // Import the RealTimeTasks namespace
/* CONSTANTS - Use these to customize the output */
constexpr bool LOOP_FOREVER = false; // If false, it will only run once
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; // Length of the separator lines in the output
// setup signal handler for Ctrl+C
std::atomic<bool> stopRequested(false);
void SignalHandler(int signal)
{
if (signal == SIGINT)
{
stopRequested.store(true);
}
}
// helpers for converting RapidCode types to STL types
template<typename T>
std::vector<T> ConvertToSTLVector(const RapidVector<T>& src) {
std::vector<T> dst;
dst.reserve(src.Size());
for (auto& p : src) dst.emplace_back(std::move(p));
return dst;
}
std::vector<std::string> ConvertToSTLVector(const RapidVector<const char*>& src) {
std::vector<std::string> dst;
dst.reserve(src.Size());
for (const char* p : src) {
dst.emplace_back(std::string(p));
}
return dst;
}
// helper functions for converting RapidCode enums to strings
std::string ToString(const RTTaskState& state)
{
switch (state)
{
case RTTaskState::Dead: return "Dead";
case RTTaskState::Disabled: return "Disabled";
case RTTaskState::Waiting: return "Waiting";
case RTTaskState::Running: return "Running";
default: return "Unknown State";
}
}
std::string ToString(const RTTaskManagerState& state)
{
switch (state)
{
case RTTaskManagerState::Dead: return "Dead";
case RTTaskManagerState::Running: return "Running";
case RTTaskManagerState::Stopped: return "Stopped";
default: return "Unknown State";
}
}
std::string ToString(const PlatformType& platformType)
{
switch (platformType)
{
case PlatformType::Native: return "Native";
case PlatformType::INtime: return "INtime";
case PlatformType::Linux: return "Linux";
case PlatformType::Windows: return "Windows";
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)
{
const RTTaskInfo& taskInfo = task.InfoGet();
const RTTaskStatus& taskStatus = task.StatusGet();
const RTTaskCreationParameters& taskParams = taskInfo.CreationParameters;
// Basic task information
std::string userLabel = FormatUserLabel(taskParams.UserLabel);
std::string executionCount =
"N/A" : std::to_string(taskStatus.ExecutionCount);
os << " Task " << userLabel
<< "(ID: " << task.IdGet() << ")"
<< " - State: " << ToString(taskStatus.State)
<< " [Execution Count: " << executionCount << "]\n";
// Task creation parameters
if (PRINT_DETAILED_INFO)
{
os << " Function: " << taskParams.FunctionName << "\n";
if (taskParams.LibraryName != nullptr && taskParams.LibraryName[0] != '\0')
{
os << " Library: " << taskParams.LibraryName << "\n";
}
if (taskParams.LibraryDirectory != nullptr && taskParams.LibraryDirectory[0] != '\0')
{
os << " Library Directory: " << taskParams.LibraryDirectory << "\n";
}
os << " Priority: " << static_cast<int32_t>(taskParams.Priority) << "\n";
auto repeatsOrForever = [](int64_t repeats) { return repeats == RTTaskCreationParameters::RepeatForever ? "Forever" : std::to_string(repeats); };
os << " Repeats: " << repeatsOrForever(taskParams.Repeats) << "\n";
os << " Period: " << taskParams.Period << " samples\n";
os << " Phase: " << taskParams.Phase << " samples\n";
}
// timing information
if (PRINT_TIMING_METRICS)
{
if (taskParams.EnableTiming)
{
auto timeOrInvalid = [](uint64_t time) { return time == RTTaskStatus::InvalidExecutionTime ? "N/A" : std::to_string(time); };
os << " Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeLast) << " ns\n";
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)
{
const RTTaskManagerInfo& taskManagerInfo = taskManager.InfoGet();
const RTTaskManagerStatus& taskManagerStatus = taskManager.StatusGet();
const RTTaskManagerCreationParameters& taskManagerParams = taskManagerInfo.CreationParameters;
os << std::string(SEPARATOR_LENGTH, '-') << "\n";
// Task manager information
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";
// Task manager creation parameters
if (PRINT_DETAILED_INFO)
{
os << "Platform: " << ToString(taskManagerParams.Platform);
if (taskManagerParams.Platform == PlatformType::INtime)
{
os << " - " << taskManagerParams.NodeName;
}
else if (taskManagerParams.Platform == PlatformType::Linux || taskManagerParams.Platform == PlatformType::Windows)
{
if (taskManagerParams.CpuCore != -1)
{
os << " - CPU Core: " << taskManagerParams.CpuCore;
}
}
os << "\n";
if (taskManagerParams.RTTaskDirectory != nullptr && taskManagerParams.RTTaskDirectory[0] != '\0')
{
os << "RTTask Directory: " << taskManagerParams.RTTaskDirectory << "\n";
}
}
// Task manager status information
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";
}
// Task summary information
std::vector<RTTask> tasks = ConvertToSTLVector(taskManager.TasksGet());
// Format the count of tasks
if (taskManagerStatus.TaskSubmissionCount != 0)
{
os << "\nTasks submitted: " << taskManagerStatus.TaskSubmissionCount;
if (tasks.size() != 0)
{
os << ", Current tasks: " << tasks.size();
}
os << "\n";
}
// add the info about each task to the string
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)
{
RSI::RapidCode::FirmwareValue tag = taskManager->GlobalValueGet(tagName.c_str());
os << " " << tagName << ": " << tag.UInt64 << "\n";
}
}
int main()
{
// Print a start message to indicate that the sample app has started
const std::string SAMPLE_APP_NAME = "📜 Utilities: Print Real-Time Tasks Summary";
Helpers::PrintHeader(SAMPLE_APP_NAME);
// register the signal handler for Ctrl+C
std::signal(SIGINT, SignalHandler);
// set the exit code to an error value.
int exitCode = -1;
try
{
/* SAMPLE APP BODY */
std::ostringstream rtTasksSummary;
auto nextWakeupTime = std::chrono::steady_clock::now();
while (!stopRequested.load())
{
rtTasksSummary.str(""); rtTasksSummary.clear();
rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
// Discover the task managers that are running, and convert to STL containers for easier memory management.
std::vector<RTTaskManager> taskManagers = ConvertToSTLVector(RTTaskManager::Discover());
rtTasksSummary << "Discovered " << taskManagers.size() << " task managers:\n";
if (taskManagers.size() != 0)
{
// Loop through each task manager and add its information to the string
for (auto& taskManager : taskManagers)
{
AppendTaskManagerSummary(rtTasksSummary, taskManager);
}
rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
// Add the global tags to the string
// AppendGlobalTagSummary(rtTasksSummary, taskManagers[0]);
// rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
}
// Print the accumulated string
std::cout << rtTasksSummary.str() << std::endl;
if (!LOOP_FOREVER) break;
// Sleep for the specified period before the next iteration
nextWakeupTime += std::chrono::milliseconds(LOOP_PERIOD_MS);
std::this_thread::sleep_until(nextWakeupTime);
};
exitCode = 0; // Set the exit code to success.
}
catch (const std::exception &ex)
{
std::cerr << ex.what() << std::endl;
exitCode = -1;
}
// print a message to indicate the sample app has finished and if it was successful or not
Helpers::PrintFooter(SAMPLE_APP_NAME, exitCode);
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....
Definition rsi.h:12412
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...
Definition rttask.h:435
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.
Definition rttask.h:559
RTTaskManagerState
Enum representing the possible states of an RTTaskManager.
Definition rttask.h:76
@ Dead
Manager firmware is not initialized or has been terminated.
Definition rttask.h:77
@ Running
Manager firmware is currently running.
Definition rttask.h:78
@ Stopped
Manager firmware is initialized but not currently running.
Definition rttask.h:79
RTTaskState
Enum representing the possible states of a real-time task.
Definition rttask.h:64
@ Dead
Task is not initialized or has been terminated.
Definition rttask.h:65
@ Waiting
Task is active but waiting for its next scheduled execution time.
Definition rttask.h:67
@ Running
Task is currently executing.
Definition rttask.h:68
@ Disabled
Task is initialized but not currently executing.
Definition rttask.h:66
PlatformType
Enum representing the platform type for an RTTaskManager.
Definition rttask.h:87
@ Native
Native platform (where the library is running, Windows or Linux).
Definition rttask.h:88
@ Windows
Standard Windows (useful for debugging tasks before running on INtime).
Definition rttask.h:91
void PrintHeader(std::string sampleAppName)
[NetworkShutdown]
Definition helpers.h:146
void PrintFooter(std::string sampleAppName, int exitCode)
[PrintHeader]
Definition helpers.h:162
The RealTimeTasks namespace.
Definition rttask.h:36
RTTaskCreationParameters specifies all the information required to create and configure a real-time t...
Definition rttask.h:126
static constexpr int32_t RepeatForever
Special value to indicate the task should repeat forever.
Definition rttask.h:140
char FunctionName[NameLengthMaximum]
Name of the task function to execute.
Definition rttask.h:155
char LibraryName[NameLengthMaximum]
Name of the library containing the task function.
Definition rttask.h:158
char UserLabel[NameLengthMaximum]
User-defined label for the task. Empty UserLabels will default to the FunctionName....
Definition rttask.h:164
int32_t Repeats
Number of times the task should execute (RepeatForever for infinite, 0 for none (one-shot)).
Definition rttask.h:170
TaskPriority Priority
Priority of the task (coming soon).
Definition rttask.h:167
char LibraryDirectory[DirectoryLengthMaximum]
Path to the directory containing the library with the task function.
Definition rttask.h:161
int32_t Period
Execution period of the task in RMP sample periods.
Definition rttask.h:173
int32_t Phase
Phase offset for task execution. For example, if you have 4 tasks with a period of 4,...
Definition rttask.h:178
bool EnableTiming
Whether to enable timing measurements for the task. Keep in mind, enabling timing does add a small am...
Definition rttask.h:182
RTTaskInfo provides information about a real-time task, including its creation parameters....
Definition rttask.h:230
RTTaskCreationParameters CreationParameters
Creation parameters used to create the task.
Definition rttask.h:232
char UserLabel[NameLengthMaximum]
User-defined label for the manager.
Definition rttask.h:359
RTTaskManagerCreationParameters specifies all the information required to create and configure an RTT...
Definition rttask.h:320
int32_t CpuCore
[Linux] CPU core to which the manager should be pinned (-1 for no pinning).
Definition rttask.h:349
PlatformType Platform
Platform on which the manager firmware will run.
Definition rttask.h:342
char NodeName[NameLengthMaximum]
[INtime] Name of the node on which the manager will run. By default, this is set to (and verified as)...
Definition rttask.h:346
char RTTaskDirectory[DirectoryLengthMaximum]
Path to the directory containing the real-time task libraries.
Definition rttask.h:339
Information about RTTaskManager firmware, including its creation parameters and ID....
Definition rttask.h:369
RTTaskManagerCreationParameters CreationParameters
Creation parameters used to create the manager.
Definition rttask.h:371
RTTaskManagerStatus provides status information for RTTaskManager firmware, including its current sta...
Definition rttask.h:284
uint64_t CycleTimeMax
Maximum execution time of a cycle in nanoseconds.
Definition rttask.h:295
uint64_t TaskSubmissionCount
Number of tasks submitted to the manager.
Definition rttask.h:289
RTTaskManagerState State
Current state of the manager.
Definition rttask.h:286
uint64_t CycleTimeLast
Execution time of the last cycle in nanoseconds.
Definition rttask.h:304
double CycleTimeMean
Mean execution time of cycles in nanoseconds.
Definition rttask.h:301
uint64_t CycleTimeMin
Minimum execution time of a cycle in nanoseconds.
Definition rttask.h:298
int64_t CycleCount
Number of cycles executed by the manager.
Definition rttask.h:292
RTTaskStatus provides status information for a real-time task, including its current state,...
Definition rttask.h:239
RTTaskState State
Current state of the task.
Definition rttask.h:241
static constexpr uint64_t InvalidExecutionTime
Invalid value for execution time, indicating timing is not enabled or the task has not executed.
Definition rttask.h:274
uint64_t ExecutionTimeMin
Minimum execution time of the task in nanoseconds.
Definition rttask.h:250
uint64_t ExecutionTimeMax
Maximum execution time of the task in nanoseconds.
Definition rttask.h:247
int64_t ExecutionCount
Number of times the task has executed.
Definition rttask.h:244
double ExecutionTimeMean
Mean execution time of the task in nanoseconds.
Definition rttask.h:253
uint64_t ExecutionTimeLast
Last execution time of the task in nanoseconds.
Definition rttask.h:256
static constexpr int64_t InvalidExecutionCount
Invalid value for execution count, indicating the task has not executed.
Definition rttask.h:271
Union representing a generic RMP firmware value with multiple data types, stored in 64-bits.
Definition rsi.h:468
uint64_t UInt64
64-bit unsigned integer.
Definition rsi.h:479