APIs, concepts, guides, and more
rttask.h
1#pragma once
2
3#ifndef RTTASK_H
4#define RTTASK_H
5
6#include <atomic> // for std::atomic
7#include <cstdint> // for int32_t, int64_t
8#include <cstddef> // for size_t
9#include <cstdio> // for std::snprintf
10#include <cstring> // for std::memset
11#include <limits> // for std::numeric_limits
12#include <stdexcept> // for std::invalid_argument
13
14#if defined(WIN32)
15#undef max
16#endif // defined(WIN32)
17
18#if !defined(RSI_INTERNAL)
19#include "rsi.h"
20#endif // defined(RSI_INTERNAL)
21
22#define RSI_GLOBAL(type, name) \
23 static_assert(sizeof(std::atomic<type>) == sizeof(type), "Expected size of "#type" to be equal to std::atomic<"#type">."); \
24 alignas(uint64_t) std::atomic<type> name
25
26#define REGISTER_GLOBAL(name) \
27 { #name, offsetof(GlobalData, name), sizeof(GlobalData::name), RSIDataTypeGet<decltype(GlobalData::name.load())>::type }
28
29namespace RSI
30{
31namespace RapidCode
32{
33namespace RealTimeTasks
34{
35 // Forward declaration of User's custom-defined structure of global data.
36 struct GlobalData;
37
38 class RTTaskImplementation;
39 class RTTaskManagerImplementation;
40
45
47 static constexpr int32_t RTTaskManagerCountMaximum = 8;
49 static constexpr int32_t RTTaskCountMaximum = 64;
51 static constexpr char RTTaskManagerExecutableName[] = "rttaskmanager";
53
56
61 enum class RTTaskState : int32_t
62 {
63 Dead = 0,
64 Disabled = 1,
65 Waiting = 2,
66 Running = 3,
67 };
68
73 enum class RTTaskManagerState : int32_t
74 {
75 Dead = 0,
76 Running = 1,
77 Stopped = 2,
78 };
79
84 enum class PlatformType : int32_t
85 {
86 Native = 0,
87 INtime = 1,
88 Linux = 2,
89 Windows = 3,
90 };
91
99 enum class TaskPriority : int32_t
100 {
101 NonRealTime = 0,
102 Lowest,
103 Low,
104 MediumLow,
105 Medium,
106 MediumHigh,
107 High,
108 Highest
109 };
110
112
115
116 // Function pointer type for real-time task functions.
117 using TaskFunction = int32_t(*)(GlobalData*, char*, const uint32_t);
118
124 {
126 static constexpr int32_t DirectoryLengthMaximum = 256;
127
129 static constexpr int32_t NameLengthMaximum = 64;
130
132 static constexpr const char* const LibraryNameDefault = "RTTaskFunctions";
133
136
138 static constexpr int32_t RepeatForever = -1;
139
141 static constexpr int32_t RepeatNone = 0;
142
144 static constexpr int32_t PeriodDefault = 1;
145
147 static constexpr int32_t PhaseDefault = 0;
148
150 static constexpr bool EnableTimingDefault = false;
151
154
156 char LibraryName[NameLengthMaximum] = "RTTaskFunctions";
157
160
163
166
169
172
177
181
182 // Default constructor.
183 RTTaskCreationParameters() = default;
184
192 RTTaskCreationParameters(const char* const argFunctionName, const char* const argLibraryName = nullptr, const char* const argLibraryDirectory = nullptr)
198 {
199 if (argFunctionName == nullptr)
200 {
201 throw std::invalid_argument("Task function name must not be null.");
202 }
203 std::snprintf(FunctionName, NameLengthMaximum, "%s", argFunctionName);
204
205 if (argLibraryName != nullptr)
206 {
207 std::snprintf(LibraryName, NameLengthMaximum, "%s", argLibraryName);
208 }
209 else
210 {
211 std::snprintf(LibraryName, NameLengthMaximum, "%s", LibraryNameDefault);
212 }
213
214 if (argLibraryDirectory != nullptr)
215 {
216 std::snprintf(LibraryDirectory, DirectoryLengthMaximum, "%s", argLibraryDirectory);
217 }
218 else
219 {
221 }
222 }
223 };
224
232
237 {
240
243
246
248 uint64_t ExecutionTimeMin = std::numeric_limits<uint64_t>::max();
249
252
255
258
261
264
266 RTTaskStatus() = default;
267
269 static constexpr int64_t InvalidExecutionCount = -1;
270
272 static constexpr uint64_t InvalidExecutionTime = 0;
273
274 static constexpr uint64_t ErrorMessageSizeMaximum = 512;
275 char ErrorMessage[ErrorMessageSizeMaximum] = {};
276 };
277
282 {
285
288
290 int64_t CycleCount;
291
293 uint64_t CycleTimeMax;
294
296 uint64_t CycleTimeMin;
297
300
303
305 uint64_t StartTimeDeltaLast = 0;
306
308 uint64_t StartTimeDeltaMax = 0;
309
312 };
313
318 {
320 static constexpr int32_t DirectoryLengthMaximum = 256;
321
323 static constexpr int32_t NameLengthMaximum = 64;
324
327
330
333
335 int32_t CpuCore = -1;
336
339
341 bool NoRmp = false;
342 };
343
355
356 typedef int32_t (*GlobalMemberOffsetGetter)(const char* const name);
357 typedef int32_t (*GlobalNamesGetter)(const char* names[], int32_t capacity);
358 typedef int32_t (*GlobalMemberTypeGetter)(const char* const name);
359
360 inline constexpr int32_t GlobalMaxSize = 2048;
361
362#if !defined(RSI_INTERNAL)
370 class RSI_API RTTask : public virtual RapidCodeObject
371 {
372 public:
377
383 virtual void Stop() = 0;
384
392 virtual void TimingReset() = 0;
394
399
404 virtual RTTaskStatus StatusGet() = 0;
405
416 virtual int64_t ExecutionCountAbsoluteWait(int64_t count = ExecutionCountDefault, int32_t timeoutMs = ExecutionCountWaitTimeoutMillisecondsDefault) = 0;
417
428 virtual int64_t ExecutionCountRelativeWait(int64_t count = ExecutionCountDefault, int32_t timeoutMs = ExecutionCountWaitTimeoutMillisecondsDefault) = 0;
430
435
440 virtual int32_t IdGet() = 0;
441
446 virtual RTTaskInfo InfoGet() = 0;
448
453
455 static constexpr int64_t ExecutionCountWaitFailure = -1;
457 static constexpr int64_t ExecutionCountDefault = 1;
459 static constexpr int32_t ExecutionCountWaitTimeoutMillisecondsDefault = 250;
461
462 virtual ~RTTask() = default;
463 protected:
464 RTTask() = default;
465 }; // end class RTTask
466
473 class RSI_API RTTaskManager : public virtual RapidCodeObject
474 {
475 public:
480
486 static RapidVector<RTTaskManager*> Discover();
487
494 static RTTaskManager* Get(const int32_t managerId);
495
504
509
517 virtual RapidVector<const char*> GlobalNamesGet(const char* const libraryName = nullptr, const char* const libraryDirectory = nullptr) = 0;
518
524
531 virtual RSI::RapidCode::FirmwareValue GlobalValueGet(const char* const name, const char* const libraryName = nullptr, const char* const libraryDirectory = nullptr) = 0;
532
540 virtual void GlobalValueSet(const RSI::RapidCode::FirmwareValue& value, const char* const name, const char* const libraryName = nullptr, const char* const libraryDirectory = nullptr) = 0;
541
548 virtual RSI::RapidCode::RSIDataType GlobalTypeGet(const char* const name, const char* const libraryName = nullptr, const char* const libraryDirectory = nullptr) = 0;
549
551
556
563 virtual RTTask* TaskSubmit(const RTTaskCreationParameters& parameters) = 0;
564
571 virtual RTTask* TaskSubmit(RTTaskCreationParameters&& parameters) = 0;
572
581 virtual RTTask* TaskSubmit(const char* const functionName, const char* const libraryName = RTTaskCreationParameters::LibraryNameDefault, const char* const libraryDirectory = nullptr) = 0;
582
588 virtual void Shutdown() = 0;
590
591
596
601 virtual RapidVector<RTTask*> TasksGet() = 0;
602
608
610
615
621
626 virtual int32_t IdGet() = 0;
628
629 virtual ~RTTaskManager() = default;
630 protected:
631 RTTaskManager() = default;
632 }; // end class RTTaskManager
633
634 template <int32_t Capacity>
635 class GlobalMetadataMap {
636 public:
638 struct Metadata
639 {
641 const char* key;
642
644 int32_t offset;
645
647 int32_t size;
648
649 // const std::type_info* type;
651 };
652
653 constexpr GlobalMetadataMap() : data(), tail(0) {}
654
655 constexpr GlobalMetadataMap(std::initializer_list<Metadata> initData)
656 {
657 for (const auto& item : initData)
658 {
659 data[tail++] = item;
660 }
661 }
662
663 constexpr int32_t Size() const { return tail; }
664
665 constexpr Metadata operator[](int32_t index) const { return data[index]; }
666
667 constexpr Metadata operator[](const char* key) const
668 {
669 for (int32_t index = 0; index < tail; ++index)
670 {
671 auto& metadata = data[index];
672 if (std::strcmp(metadata.key, key)==0)
673 {
674 return metadata;
675 }
676 }
677 constexpr char errorMessageFormat[] = "Key '%s' not found in GlobalMetadata.";
678 constexpr int32_t bufferSize = 256;
679 char buffer[bufferSize] = {0};
680 std::snprintf(buffer, bufferSize, errorMessageFormat, key);
681 throw std::out_of_range(buffer);
682 }
683
684 private:
685 Metadata data[Capacity]{};
686 int32_t tail = 0;
687 };
688
689#if !defined(SWIG)
690 // Primary template for parsing the type of a global variable.
691 template<typename Type, typename = void>
692 struct RSIDataTypeGet { static constexpr RSI::RapidCode::RSIDataType type = RSIDataType::RSIDataTypeINVALID; };
693 template<typename Type>
694 struct RSIDataTypeGet<Type, typename std::enable_if<std::is_integral<Type>::value && std::is_signed<Type>::value , void>::type>
696 template<typename Type>
697 struct RSIDataTypeGet<Type, typename std::enable_if<std::is_integral<Type>::value && std::is_unsigned<Type>::value , void>::type>
699 template<typename Type>
700 struct RSIDataTypeGet<Type, typename std::enable_if<std::is_floating_point<Type>::value, void>::type>
702 template<>
703 struct RSIDataTypeGet<int16_t> { static constexpr RSI::RapidCode::RSIDataType type = RSIDataType::RSIDataTypeINT16; };
704 template<>
705 struct RSIDataTypeGet<uint16_t> { static constexpr RSI::RapidCode::RSIDataType type = RSIDataType::RSIDataTypeUINT16; };
706 template<>
707 struct RSIDataTypeGet<int32_t> { static constexpr RSI::RapidCode::RSIDataType type = RSIDataType::RSIDataTypeINT32; };
708 template<>
709 struct RSIDataTypeGet<uint32_t> { static constexpr RSI::RapidCode::RSIDataType type = RSIDataType::RSIDataTypeUINT32; };
710 template<>
711 struct RSIDataTypeGet<float> { static constexpr RSI::RapidCode::RSIDataType type = RSIDataType::RSIDataTypeFLOAT; };
712#endif // !defined(SWIG)
713
714#endif // !defined(RSI_INTERNAL)
715
716
718} // end namespace RealTimeTasks
719} // end namespace RapidCode
720} // end namespace RSI
721
722#endif // !defined(RTTASK_H)
The RapidCode base class. All non-error objects are derived from this class.
Definition rsi.h:184
RTTaskStatus StatusGet()=0
Get the current status of the task.
void Stop()=0
Stop the task from executing.
void TimingReset()=0
Reset the timing statistics for the task.
int32_t IdGet()=0
Get the ID of the task.
RTTaskInfo InfoGet()=0
Get information about the task.
int64_t ExecutionCountAbsoluteWait(int64_t count=ExecutionCountDefault, int32_t timeoutMs=ExecutionCountWaitTimeoutMillisecondsDefault)=0
Wait for the task to reach a specific execution count.
int64_t ExecutionCountRelativeWait(int64_t count=ExecutionCountDefault, int32_t timeoutMs=ExecutionCountWaitTimeoutMillisecondsDefault)=0
Wait for the task to execute a specific number of times relative to current count.
Interface for controlling and monitoring a single real-time task. See RTTaskManager::TaskSubmit and R...
Definition rttask.h:371
RTTaskManagerInfo InfoGet()=0
Get information about the manager.
RSI::RapidCode::FirmwareValue GlobalValueGet(const char *const name, const char *const libraryName=nullptr, const char *const libraryDirectory=nullptr)=0
Read a GlobalTag by its name.
RapidVector< RTTask * > TasksGet()=0
Get all tasks managed by this RTTaskManager.
RTTask * TaskSubmit(const RTTaskCreationParameters &parameters)=0
Submit a new task to the manager using creation parameters.
RSI::RapidCode::FirmwareValue GlobalValueGet(int32_t offset)=0
Read a GlobalTag by its offset. (internal use)
RTTask * TaskSubmit(const char *const functionName, const char *const libraryName=RTTaskCreationParameters::LibraryNameDefault, const char *const libraryDirectory=nullptr)=0
Submit a new task to the manager using function and library names.
void GlobalValueSet(const RSI::RapidCode::FirmwareValue &value, const char *const name, const char *const libraryName=nullptr, const char *const libraryDirectory=nullptr)=0
Set the value of a GlobalTag variable.
RTTaskManagerStatus StatusGet()=0
Get the current status of the manager.
int32_t IdGet()=0
Get the ID of the manager.
static RapidVector< RTTaskManager * > Discover()
Discover all active RTTaskManager instances.
RTTask * TaskSubmit(RTTaskCreationParameters &&parameters)=0
Submit a new task to the manager using move semantics.
RSI::RapidCode::RSIDataType GlobalTypeGet(const char *const name, const char *const libraryName=nullptr, const char *const libraryDirectory=nullptr)=0
Get the type of a GlobalTag variable.
static RTTaskManager * Get(const int32_t managerId)
Get an existing RTTaskManager by ID.
void Shutdown()=0
Shutdown the RTTaskManager firmware.
RapidVector< const char * > GlobalNamesGet(const char *const libraryName=nullptr, const char *const libraryDirectory=nullptr)=0
Get names of all global variables.
static RTTaskManager * Create(const RTTaskManagerCreationParameters &parameters)
Create a new RTTaskManager instance.
Interface for managing real-time tasks firmware. See Real-Time Tasks for more information.
Definition rttask.h:474
TaskPriority
Enum representing the priority levels for a real-time task.
Definition rttask.h:100
@ MediumLow
A medium-low real-time priority level.
@ Low
A low real-time priority level.
@ Highest
The highest real-time priority level for an RTTask. Is below the priority of the main thread of the R...
@ High
A high real-time priority level.
@ Medium
A medium real-time priority level. This is the default priority for real-time tasks.
@ MediumHigh
A medium-high real-time priority level.
@ Lowest
The lowest real-time priority level for an RTTask. Is above standard thread priorities.
@ NonRealTime
A task without any real-time priority, given the operating system's default.
RTTaskManagerState
Enum representing the possible states of an RTTaskManager.
Definition rttask.h:74
@ Stopped
Manager firmware is initialized but not currently running.
RTTaskState
Enum representing the possible states of a real-time task.
Definition rttask.h:62
@ 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.
Definition rttask.h:85
@ Native
Native platform (where the library is running, Windows or Linux).
@ Windows
Standard Windows (useful for debugging tasks before running on INtime).
RSIDataType
Data types for User Limits and other triggers.
Definition rsienums.h:657
@ RSIDataTypeUINT32
uint32 (unsigned 32-bit integer)
@ RSIDataTypeDOUBLE
double (64-bit floating point)
@ RSIDataTypeINT64
int64 (signed 64-bit integer)
@ RSIDataTypeINT16
signed 16-bit integer
@ RSIDataTypeUINT16
unsigned 16-bit integer
@ RSIDataTypeINT32
int32 (signed 32-bit integer)
@ RSIDataTypeUINT64
uint64 (unsigned 64-bit integer)
@ RSIDataTypeFLOAT
float (32-bit floating point, rarely used)
int32_t offset
Offset of the global variable within the GlobalData structure.
Definition rttask.h:644
const char * key
Name of the global variable.
Definition rttask.h:641
int32_t size
Size of the global variable in bytes.
Definition rttask.h:647
RTTaskCreationParameters(const char *const argFunctionName, const char *const argLibraryName=nullptr, const char *const argLibraryDirectory=nullptr)
Constructor with function name and library details.
Definition rttask.h:192
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
char FunctionName[NameLengthMaximum]
Name of the task function to execute.
Definition rttask.h:153
char LibraryName[NameLengthMaximum]
Name of the library containing the task function.
Definition rttask.h:156
char UserLabel[NameLengthMaximum]
User-defined label for the task.
Definition rttask.h:162
int32_t Repeats
Number of times the task should execute (RepeatForever for infinite, 0 for none (one-shot)).
Definition rttask.h:168
TaskPriority Priority
Priority of the task (coming soon).
Definition rttask.h:165
static constexpr int32_t RepeatNone
Special value to indicate the task should not repeat.
Definition rttask.h:141
static constexpr int32_t PeriodDefault
Default execution period in RMP sample periods.
Definition rttask.h:144
static constexpr int32_t DirectoryLengthMaximum
Maximum length of the library directory path.
Definition rttask.h:126
char LibraryDirectory[DirectoryLengthMaximum]
Path to the directory containing the library with the task function.
Definition rttask.h:159
int32_t Period
Execution period of the task in RMP sample periods.
Definition rttask.h:171
static constexpr int32_t PhaseDefault
Default phase offset for task execution.
Definition rttask.h:147
int32_t Phase
Phase offset for task execution. For example, if you have 4 tasks with a period of 4,...
Definition rttask.h:176
static constexpr bool EnableTimingDefault
Default setting for timing measurements.
Definition rttask.h:150
static constexpr int32_t NameLengthMaximum
Maximum length of name fields (library, function, user label).
Definition rttask.h:129
static constexpr TaskPriority PriorityDefault
Default priority for real-time tasks.
Definition rttask.h:135
static constexpr const char *const LibraryNameDefault
Default library name for the task function.
Definition rttask.h:132
bool EnableTiming
Whether to enable timing measurements for the task. Keep in mind, enabling timing does add a small am...
Definition rttask.h:180
RTTaskInfo provides information about a real-time task, including its creation parameters....
Definition rttask.h:228
RTTaskCreationParameters CreationParameters
Creation parameters used to create the task.
Definition rttask.h:230
RTTaskManagerCreationParameters specifies all the information required to create and configure an RTT...
Definition rttask.h:318
bool NoRmp
Disable the initialization of the RMP and RapidCode objects on task manager startup and their use in ...
Definition rttask.h:341
char UserLabel[NameLengthMaximum]
User-defined label for the manager.
Definition rttask.h:338
int32_t CpuCore
[Linux] CPU core to which the manager should be pinned (-1 for no pinning).
Definition rttask.h:335
static constexpr int32_t DirectoryLengthMaximum
Maximum length of the directory path.
Definition rttask.h:320
char NodeName[NameLengthMaximum]
[INtime] Name of the node on which the manager will run.
Definition rttask.h:332
char RTTaskDirectory[DirectoryLengthMaximum]
Path to the directory containing the real-time task libraries.
Definition rttask.h:326
static constexpr int32_t NameLengthMaximum
Maximum length of name fields (node name, user label).
Definition rttask.h:323
Information about RTTaskManager firmware, including its creation parameters and ID....
Definition rttask.h:348
RTTaskManagerCreationParameters CreationParameters
Creation parameters used to create the manager.
Definition rttask.h:350
RTTaskManagerStatus provides status information for RTTaskManager firmware, including its current sta...
Definition rttask.h:282
uint64_t CycleTimeMax
Maximum execution time of a cycle in nanoseconds.
Definition rttask.h:293
uint64_t TaskSubmissionCount
Number of tasks submitted to the manager.
Definition rttask.h:287
RTTaskManagerState State
Current state of the manager.
Definition rttask.h:284
double StartTimeDeltaMean
Mean difference between the current and previous start of the main task manager loop execution in nan...
Definition rttask.h:311
uint64_t CycleTimeLast
Execution time of the last cycle in nanoseconds.
Definition rttask.h:302
uint64_t StartTimeDeltaLast
Last difference between the current and previous start of the main task manager loop execution in nan...
Definition rttask.h:305
double CycleTimeMean
Mean execution time of cycles in nanoseconds.
Definition rttask.h:299
uint64_t CycleTimeMin
Minimum execution time of a cycle in nanoseconds.
Definition rttask.h:296
int64_t CycleCount
Number of cycles executed by the manager.
Definition rttask.h:290
uint64_t StartTimeDeltaMax
Maximum difference between the current and previous start of the main task manager loop execution in ...
Definition rttask.h:308
RTTaskStatus provides status information for a real-time task, including its current state,...
Definition rttask.h:237
double StartTimeDeltaMean
Mean difference between the current and previous start of the task execution in nanoseconds.
Definition rttask.h:263
RTTaskState State
Current state of the task.
Definition rttask.h:239
uint64_t StartTimeDeltaLast
Last difference between the current and previous start of the task execution in nanoseconds.
Definition rttask.h:257
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
uint64_t ExecutionTimeMin
Minimum execution time of the task in nanoseconds.
Definition rttask.h:248
uint64_t ExecutionTimeMax
Maximum execution time of the task in nanoseconds.
Definition rttask.h:245
int64_t ExecutionCount
Number of times the task has executed.
Definition rttask.h:242
uint64_t StartTimeDeltaMax
Maximum difference between the current and previous start of the task execution in nanoseconds.
Definition rttask.h:260
double ExecutionTimeMean
Mean execution time of the task in nanoseconds.
Definition rttask.h:251
uint64_t ExecutionTimeLast
Last execution time of the task in nanoseconds.
Definition rttask.h:254
RTTaskStatus()=default
Default constructor.
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