APIs, concepts, guides, and more
PrintRTTasksSummary.cpp
1#include <thread>
2#include <chrono>
3#include <csignal>
4#include <atomic>
5#include <iostream>
6#include <sstream>
7#include <string>
8#include <string_view>
9#include <vector>
10#include <memory>
11
12#include "SampleAppsHelper.h" // Import our helper functions.
13#include "rsi.h" // Import our RapidCode Library.
14#include "rttask.h" // Import the RTTask library
15
16using namespace RSI::RapidCode; // Import the RapidCode namespace
17using namespace RSI::RapidCode::RealTimeTasks; // Import the RealTimeTasks namespace
18
19/* CONSTANTS - Use these to customize the output */
20constexpr bool LOOP_FOREVER = false; // If false, it will only run once
21constexpr int64_t LOOP_PERIOD_MS = 1000;
22
23constexpr bool PRINT_DETAILED_INFO = true;
24constexpr bool PRINT_TIMING_METRICS = true;
25
26constexpr int32_t SEPARATOR_LENGTH = 80; // Length of the separator lines in the output
27
28// Setup signal handler for Ctrl+C
29std::atomic<bool> stopRequested(false);
30void SignalHandler(int signal)
31{
32 if (signal == SIGINT)
33 {
34 stopRequested.store(true);
35 }
36}
37
38// Helpers for converting RapidCode types to STL types
39template<typename T, typename U = std::shared_ptr<T>>
40std::vector<U> ConvertToSTLVector(const RapidVector<T*>& src) {
41 std::vector<U> dst;
42 dst.reserve(src.Size());
43 for (auto* p : src) dst.emplace_back(p);
44 return dst;
45}
46
47std::vector<std::string> ConvertToSTLVector(const RapidVector<const char*>& src) {
48 std::vector<std::string> dst;
49 dst.reserve(src.Size());
50 for (const char* p : src) {
51 dst.emplace_back(std::string(p));
52 }
53 return dst;
54}
55
56// Helper functions for converting RapidCode enums to strings
57std::string ToString(const RTTaskState& state)
58{
59 switch (state)
60 {
61 case RTTaskState::Dead: return "Dead";
62 case RTTaskState::Disabled: return "Disabled";
63 case RTTaskState::Waiting: return "Waiting";
64 case RTTaskState::Running: return "Running";
65 default: return "Unknown State";
66 }
67}
68
69std::string ToString(const RTTaskManagerState& state)
70{
71 switch (state)
72 {
73 case RTTaskManagerState::Dead: return "Dead";
74 case RTTaskManagerState::Running: return "Running";
75 case RTTaskManagerState::Stopped: return "Stopped";
76 default: return "Unknown State";
77 }
78}
79
80std::string ToString(const PlatformType& platformType)
81{
82 switch (platformType)
83 {
84 case PlatformType::Native: return "Native";
85 case PlatformType::INtime: return "INtime";
86 case PlatformType::Linux: return "Linux";
87 case PlatformType::Windows: return "Windows";
88 default: return "Unknown Platform";
89 }
90}
91
92std::string FormatUserLabel(std::string_view userLabel, std::string_view autoGenerated = "")
93{
94 if (userLabel.empty() || (!autoGenerated.empty() && userLabel == autoGenerated))
95 return std::string();
96 return std::string(userLabel) + " ";
97}
98
99void AppendTaskSummary(std::ostream& os, const std::shared_ptr<RTTask>& task)
100{
101 const RTTaskInfo& taskInfo = task->InfoGet();
102 const RTTaskStatus& taskStatus = task->StatusGet();
103 const RTTaskCreationParameters& taskParams = taskInfo.CreationParameters;
104
105 // Basic task information
106 std::string userLabel = FormatUserLabel(taskParams.UserLabel);
107 std::string executionCount =
108 taskStatus.ExecutionCount == RTTaskStatus::InvalidExecutionCount ?
109 "N/A" : std::to_string(taskStatus.ExecutionCount);
110
111 os << " Task " << userLabel
112 << "(ID: " << task->IdGet() << ")"
113 << " - State: " << ToString(taskStatus.State)
114 << " [Execution Count: " << executionCount << "]\n";
115
116 // Task creation parameters
117 if (PRINT_DETAILED_INFO)
118 {
119 os << " Function: " << taskParams.FunctionName << "\n";
120
121 if (taskParams.LibraryName != nullptr && taskParams.LibraryName[0] != '\0')
122 {
123 os << " Library: " << taskParams.LibraryName << "\n";
124 }
125
126 if (taskParams.LibraryDirectory != nullptr && taskParams.LibraryDirectory[0] != '\0')
127 {
128 os << " Library Directory: " << taskParams.LibraryDirectory << "\n";
129 }
130
131 os << " Priority: " << static_cast<int32_t>(taskParams.Priority) << "\n";
132
133 auto repeatsOrForever = [](int64_t repeats) { return repeats == RTTaskCreationParameters::RepeatForever ? "Forever" : std::to_string(repeats); };
134 os << " Repeats: " << repeatsOrForever(taskParams.Repeats) << "\n";
135 os << " Period: " << taskParams.Period << " samples\n";
136 os << " Phase: " << taskParams.Phase << " samples\n";
137 }
138
139 // Timing information
140 if (PRINT_TIMING_METRICS)
141 {
142 if (taskParams.EnableTiming)
143 {
144 auto timeOrInvalid = [](uint64_t time) { return time == RTTaskStatus::InvalidExecutionTime ? "N/A" : std::to_string(time); };
145 os << " Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeLast) << " ns\n";
146 os << " Max Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeMax) << " ns\n";
147 os << " Min Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeMin) << " ns\n";
148 os << " Mean Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeMean) << " ns\n";
149 }
150 else
151 {
152 os << " Timing: Disabled\n";
153 }
154 }
155}
156
157void AppendTaskManagerSummary(std::ostream& os, const std::shared_ptr<RTTaskManager>& taskManager)
158{
159 const RTTaskManagerInfo& taskManagerInfo = taskManager->InfoGet();
160 const RTTaskManagerStatus& taskManagerStatus = taskManager->StatusGet();
161 const RTTaskManagerCreationParameters& taskManagerParams = taskManagerInfo.CreationParameters;
162
163 os << std::string(SEPARATOR_LENGTH, '-') << "\n";
164
165 // Task manager information
166 std::string autoGeneratedLabel = "TaskManager_" + std::to_string(taskManager->IdGet());
167 std::string managerLabel = FormatUserLabel(taskManagerParams.UserLabel, autoGeneratedLabel);
168
169 os << "Task Manager " << managerLabel
170 << "(ID: " << taskManager->IdGet() << ")"
171 << " - State: " << ToString(taskManagerStatus.State)
172 << " [Cycle Count: " << taskManagerStatus.CycleCount << "]\n";
173
174 // Task manager creation parameters
175 if (PRINT_DETAILED_INFO)
176 {
177 os << "Platform: " << ToString(taskManagerParams.Platform);
178 if (taskManagerParams.Platform == PlatformType::INtime)
179 {
180 os << " - " << taskManagerParams.NodeName;
181 }
182 else if (taskManagerParams.Platform == PlatformType::Linux || taskManagerParams.Platform == PlatformType::Windows)
183 {
184 if (taskManagerParams.CpuCore != -1)
185 {
186 os << " - CPU Core: " << taskManagerParams.CpuCore;
187 }
188 }
189 os << "\n";
190
191 if (taskManagerParams.RTTaskDirectory != nullptr && taskManagerParams.RTTaskDirectory[0] != '\0')
192 {
193 os << "RTTask Directory: " << taskManagerParams.RTTaskDirectory << "\n";
194 }
195 }
196
197 // Task manager status information
198 if (PRINT_TIMING_METRICS)
199 {
200 os << "Cycle Time Mean: " << taskManagerStatus.CycleTimeMean << " ns\n";
201 os << "Cycle Time Last: " << taskManagerStatus.CycleTimeLast << " ns\n";
202 os << "Cycle Time Max: " << taskManagerStatus.CycleTimeMax << " ns\n";
203 os << "Cycle Time Min: " << taskManagerStatus.CycleTimeMin << " ns\n";
204 }
205
206 // Task summary information
207 std::vector<std::shared_ptr<RTTask>> tasks = ConvertToSTLVector(taskManager->TasksGet());
208
209 // Format the count of tasks
210 if (taskManagerStatus.TaskSubmissionCount != 0)
211 {
212 os << "\nTasks submitted: " << taskManagerStatus.TaskSubmissionCount;
213 if (tasks.size() != 0)
214 {
215 os << ", Current tasks: " << tasks.size();
216 }
217 os << "\n";
218 }
219
220 // Add the info about each task to the string
221 for (const auto& task : tasks)
222 {
223 AppendTaskSummary(os, task);
224 }
225}
226
227void AppendGlobalTagSummary(std::ostream& os, const std::shared_ptr<RTTaskManager>& taskManager)
228{
229 std::vector<std::string> globalTagNames = ConvertToSTLVector(taskManager->GlobalNamesGet());
230
231 os << "Global Tags Count: " << globalTagNames.size() << "\n";
232 for (const auto& tagName : globalTagNames)
233 {
234 RSI::RapidCode::FirmwareValue tag = taskManager->GlobalValueGet(tagName.c_str());
235 os << " " << tagName << ": " << tag.UInt64 << "\n";
236 }
237}
238
239int main()
240{
241 // Print a start message to indicate that the sample app has started
242 const std::string SAMPLE_APP_NAME = "Utilities: Print Real-Time Tasks Summary";
243 SampleAppsHelper::PrintHeader(SAMPLE_APP_NAME);
244
245 // Register the signal handler for Ctrl+C
246 std::signal(SIGINT, SignalHandler);
247
248 // Set the exit code to an error value.
249 int exitCode = -1;
250 try
251 {
252 /* SAMPLE APP BODY */
253 std::ostringstream rtTasksSummary;
254 auto nextWakeupTime = std::chrono::steady_clock::now();
255 while (!stopRequested.load())
256 {
257 rtTasksSummary.str(""); rtTasksSummary.clear();
258 rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
259
260 // Discover the task managers that are running, and convert to STL containers for easier memory management.
261 std::vector<std::shared_ptr<RTTaskManager>> taskManagers = ConvertToSTLVector(RTTaskManager::Discover());
262 rtTasksSummary << "Discovered " << taskManagers.size() << " task managers:\n";
263
264 if (taskManagers.size() != 0)
265 {
266 // Loop through each task manager and add its information to the string
267 for (const auto& taskManager : taskManagers)
268 {
269 AppendTaskManagerSummary(rtTasksSummary, taskManager);
270 }
271 rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
272
273 // Add the global tags to the string
274 // AppendGlobalTagSummary(rtTasksSummary, taskManagers[0]);
275 // rtTasksSummary << std::string(SEPARATOR_LENGTH, '-') << "\n";
276 }
277
278 // Print the accumulated string
279 std::cout << rtTasksSummary.str() << std::endl;
280
281 if (!LOOP_FOREVER) break;
282 // Sleep for the specified period before the next iteration
283 nextWakeupTime += std::chrono::milliseconds(LOOP_PERIOD_MS);
284 std::this_thread::sleep_until(nextWakeupTime);
285 };
286
287 exitCode = 0; // Set the exit code to success.
288 }
289 catch (const std::exception &ex)
290 {
291 std::cerr << ex.what() << std::endl;
292 exitCode = -1;
293 }
294 // Print a message to indicate the sample app has finished and if it was successful or not
295 SampleAppsHelper::PrintFooter(SAMPLE_APP_NAME, exitCode);
296
297 return exitCode;
298}
static RapidVector< RTTaskManager * > Discover()
Discover all active RTTaskManager instances.
RTTaskManagerState
Enum representing the possible states of an RTTaskManager.
Definition rttask.h:74
RTTaskState
Enum representing the possible states of a real-time task.
Definition rttask.h:62
PlatformType
Enum representing the platform type for an RTTaskManager.
Definition rttask.h:85
static void PrintFooter(std::string sampleAppName, int exitCode)
Print a message to indicate the sample app has finished and if it was successful or not.
static void PrintHeader(std::string sampleAppName)
Print a start message to indicate that the sample app has started.
RTTaskCreationParameters specifies all the information required to create and configure a real-time t...
Definition rttask.h:124
static constexpr int32_t RepeatForever
Special value to indicate the task should repeat forever.
Definition rttask.h:138
RTTaskInfo provides information about a real-time task, including its creation parameters....
Definition rttask.h:228
RTTaskManagerCreationParameters specifies all the information required to create and configure an RTT...
Definition rttask.h:318
Information about RTTaskManager firmware, including its creation parameters and ID....
Definition rttask.h:348
RTTaskManagerStatus provides status information for RTTaskManager firmware, including its current sta...
Definition rttask.h:282
RTTaskStatus provides status information for a real-time task, including its current state,...
Definition rttask.h:237
static constexpr uint64_t InvalidExecutionTime
Invalid value for execution time, indicating timing is not enabled or the task has not executed.
Definition rttask.h:272
static constexpr int64_t InvalidExecutionCount
Invalid value for execution count, indicating the task has not executed.
Definition rttask.h:269
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