diff --git a/.clang-format b/.clang-format index 9bed2bc..38e8a64 100644 --- a/.clang-format +++ b/.clang-format @@ -7,6 +7,7 @@ AlignConsecutiveBitFields: Consecutive AlignConsecutiveMacros: Consecutive AlignEscapedNewlines: Left AllowShortCaseLabelsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: WithoutElse AlwaysBreakTemplateDeclarations: Yes BreakBeforeBraces: Custom BreakConstructorInitializers: BeforeComma diff --git a/src/RTOScppBuffer.h b/src/RTOScppBuffer.h index bfbc948..ffbf2b5 100644 --- a/src/RTOScppBuffer.h +++ b/src/RTOScppBuffer.h @@ -11,18 +11,17 @@ #include #include -class DataBuffer { +class DataBufferBase { private: - DataBuffer(const DataBuffer&) = delete; - void operator=(const DataBuffer&) = delete; + DataBufferBase(const DataBufferBase&) = delete; // Delete copy constructor + void operator=(const DataBufferBase&) = delete; // Delete copy assignment operator protected: - DataBuffer(StreamBufferHandle_t handle) + DataBufferBase(StreamBufferHandle_t handle) : _handle(handle) {} - ~DataBuffer() { vStreamBufferDelete(_handle); } + virtual ~DataBufferBase() { vStreamBufferDelete(_handle); } StreamBufferHandle_t _handle; - StaticStreamBuffer_t _tcb; public: uint32_t send(const void* tx_buffer, uint32_t bytes, TickType_t ticks_to_wait = portMAX_DELAY) { @@ -45,29 +44,37 @@ class DataBuffer { bool isEmpty() { return xStreamBufferIsEmpty(_handle); } bool isFull() { return xStreamBufferIsFull(_handle); } uint32_t availableSpaces() { return xStreamBufferSpacesAvailable(_handle); } -}; - -template -class StreamBuffer : public DataBuffer { - public: - StreamBuffer(uint32_t trigger_bytes) - : DataBuffer( - xStreamBufferGenericCreateStatic(LENGTH + 1, trigger_bytes, pdFALSE, _storage, &_tcb)) {} - uint32_t availableBytes() { return xStreamBufferBytesAvailable(_handle); } bool setTriggerLevel(uint32_t trigger_bytes) { return xStreamBufferSetTriggerLevel(_handle, trigger_bytes); } + explicit operator bool() const { return _handle != nullptr; } +}; + +class StreamBufferDynamic : public DataBufferBase { + public: + StreamBufferDynamic(uint32_t buffer_size, uint32_t trigger_bytes) + : DataBufferBase(xStreamBufferGenericCreate(buffer_size + 1, trigger_bytes, false)) {} +}; + +template +class StreamBufferStatic : public DataBufferBase { + public: + StreamBufferStatic(uint32_t trigger_bytes) + : DataBufferBase(xStreamBufferGenericCreateStatic(BUFFER_SIZE + 1, trigger_bytes, false, + _storage, &_tcb)) {} + private: - uint8_t _storage[LENGTH + 1]; + StaticStreamBuffer_t _tcb; + uint8_t _storage[BUFFER_SIZE + 1]; }; -class StreamBufferExternalStorage : public DataBuffer { +class StreamBufferExternalStorage : public DataBufferBase { public: - StreamBufferExternalStorage() - : DataBuffer(nullptr) {} + StreamBufferExternalStorage(uint32_t trigger_bytes) + : DataBufferBase(nullptr) {} bool init(uint32_t trigger_bytes, uint8_t* buffer, uint32_t buffer_size) { _handle = @@ -75,32 +82,40 @@ class StreamBufferExternalStorage : public DataBuffer { return _handle != nullptr ? true : false; } - uint32_t availableBytes() { return xStreamBufferBytesAvailable(_handle); } + private: + StaticStreamBuffer_t _tcb; +}; - bool setTriggerLevel(uint32_t trigger_bytes) { - return xStreamBufferSetTriggerLevel(_handle, trigger_bytes); - } +class MessageBufferDynamic : public DataBufferBase { + public: + MessageBufferDynamic(uint32_t buffer_size) + : DataBufferBase(xStreamBufferGenericCreate(buffer_size + 1, 0, false)) {} }; -template -class MessageBuffer : public DataBuffer { +template +class MessageBufferStatic : public DataBufferBase { public: - MessageBuffer() - : DataBuffer(xStreamBufferGenericCreateStatic(LENGTH + 1, 0, pdTRUE, _storage, &_tcb)) {} + MessageBufferStatic() + : DataBufferBase( + xStreamBufferGenericCreateStatic(BUFFER_SIZE + 1, 0, false, _storage, &_tcb)) {} private: - uint8_t _storage[LENGTH + 1]; + StaticStreamBuffer_t _tcb; + uint8_t _storage[BUFFER_SIZE + 1]; }; -class MessageBufferExternalStorage : public DataBuffer { +class MessageBufferExternalStorage : public DataBufferBase { public: MessageBufferExternalStorage() - : DataBuffer(nullptr) {} + : DataBufferBase(nullptr) {} - bool init(uint8_t* buffer, uint32_t buffer_size) { - _handle = xStreamBufferGenericCreateStatic(buffer_size + 1, 0, pdTRUE, buffer, &_tcb); + bool init(uint32_t trigger_bytes, uint8_t* buffer, uint32_t buffer_size) { + _handle = xStreamBufferGenericCreateStatic(buffer_size + 1, 0, true, buffer, &_tcb); return _handle != nullptr ? true : false; } + + private: + StaticStreamBuffer_t _tcb; }; #endif // RTOS_CPP_BUFFER_H diff --git a/src/RTOScppLock.h b/src/RTOScppLock.h index 083dfe4..9487683 100644 --- a/src/RTOScppLock.h +++ b/src/RTOScppLock.h @@ -8,47 +8,62 @@ #define RTOS_CPP_LOCK_H #include +#include #include -class Lock { +// Forward declaration of QueueSet +class QueueSet; + +class LockBase { private: - Lock(Lock const&) = delete; - void operator=(Lock const&) = delete; + LockBase(LockBase const&) = delete; // Delete copy constructor + void operator=(LockBase const&) = delete; // Delete copy assignment operator - friend bool operator==(const QueueSetMemberHandle_t& queue_set_member, const Lock& semaphore); + friend class QueueSet; + friend bool operator==(const QueueSetMemberHandle_t& queue_set_member, const LockBase& lock); protected: - Lock(SemaphoreHandle_t handle) + LockBase(SemaphoreHandle_t handle) : _handle(handle) {} - ~Lock() { vSemaphoreDelete(_handle); } + virtual ~LockBase() { + if (_handle) vSemaphoreDelete(_handle); + } SemaphoreHandle_t _handle; - StaticSemaphore_t _tcb; public: - SemaphoreHandle_t getHandle() { return _handle; } - virtual bool take(const TickType_t ticks_to_wait = portMAX_DELAY) { return xSemaphoreTake(_handle, ticks_to_wait); } virtual bool give() { return xSemaphoreGive(_handle); } + + explicit operator bool() const { return _handle != nullptr; } }; -inline bool operator==(const QueueSetMemberHandle_t& queue_set_member, const Lock& semaphore) { - return queue_set_member == semaphore._handle; +inline bool operator==(const QueueSetMemberHandle_t& queue_set_member, const LockBase& lock) { + return queue_set_member == lock._handle; } -class Mutex : public Lock { +class MutexDynamic : public LockBase { public: - Mutex() - : Lock(xSemaphoreCreateMutexStatic(&_tcb)) {} + MutexDynamic() + : LockBase(xSemaphoreCreateMutex()) {} +}; + +class MutexStatic : public LockBase { + public: + MutexStatic() + : LockBase(xSemaphoreCreateMutexStatic(&_tcb)) {} + + private: + StaticSemaphore_t _tcb; }; -class MutexRecursive : public Lock { +class MutexRecursiveDynamic : public LockBase { public: - MutexRecursive() - : Lock(xSemaphoreCreateRecursiveMutexStatic(&_tcb)) {} + MutexRecursiveDynamic() + : LockBase(xSemaphoreCreateRecursiveMutex()) {} bool take(const TickType_t ticks_to_wait = portMAX_DELAY) override { return xSemaphoreTakeRecursive(_handle, ticks_to_wait); @@ -57,26 +72,60 @@ class MutexRecursive : public Lock { bool give() override { return xSemaphoreGiveRecursive(_handle); } }; -class Semaphore : public Lock { +class MutexRecursiveStatic : public LockBase { + public: + MutexRecursiveStatic() + : LockBase(xSemaphoreCreateRecursiveMutexStatic(&_tcb)) {} + + bool take(const TickType_t ticks_to_wait = portMAX_DELAY) override { + return xSemaphoreTakeRecursive(_handle, ticks_to_wait); + } + + bool give() override { return xSemaphoreGiveRecursive(_handle); } + + private: + StaticSemaphore_t _tcb; +}; + +class Semaphore : public LockBase { protected: Semaphore(SemaphoreHandle_t handle) - : Lock(handle) {} + : LockBase(handle) {} public: bool takeFromISR(BaseType_t& task_woken) { return xSemaphoreTakeFromISR(_handle, &task_woken); } bool giveFromISR(BaseType_t& task_woken) { return xSemaphoreGiveFromISR(_handle, &task_woken); } + uint8_t getCount() { return uxSemaphoreGetCount(_handle); } }; -class SemaphoreBinary : public Semaphore { +class SemaphoreBinaryDynamic : public Semaphore { public: - SemaphoreBinary() + SemaphoreBinaryDynamic() + : Semaphore(xSemaphoreCreateBinary()) {} +}; + +class SemaphoreBinaryStatic : public Semaphore { + public: + SemaphoreBinaryStatic() : Semaphore(xSemaphoreCreateBinaryStatic(&_tcb)) {} + + private: + StaticSemaphore_t _tcb; +}; + +class SemaphoreCountingDynamic : public Semaphore { + public: + SemaphoreCountingDynamic(const uint8_t max_count, const uint8_t initial_count = 0) + : Semaphore(xSemaphoreCreateCounting(max_count, initial_count)) {} }; -class SemaphoreCounting : public Semaphore { +class SemaphoreCountingStatic : public Semaphore { public: - SemaphoreCounting(const uint8_t max_count, const uint8_t initial_count = 0) + SemaphoreCountingStatic(const uint8_t max_count, const uint8_t initial_count = 0) : Semaphore(xSemaphoreCreateCountingStatic(max_count, initial_count, &_tcb)) {} + + private: + StaticSemaphore_t _tcb; }; #endif // RTOS_CPP_LOCK_H \ No newline at end of file diff --git a/src/RTOScppQueue.h b/src/RTOScppQueue.h index 045f5a1..054051f 100644 --- a/src/RTOScppQueue.h +++ b/src/RTOScppQueue.h @@ -10,37 +10,48 @@ #include #include -// QueueBase forward declaration -template -class QueueBase; - -// operator== forward declaration -template -bool operator==(const QueueSetMemberHandle_t& queue_set_member, const QueueBase& queue); +// Forward declaration of QueueSet +class QueueSet; -template -class QueueBase { +class QueueInterface { private: - QueueBase(QueueBase const&) = delete; - void operator=(QueueBase const&) = delete; - - friend bool operator== - <>(const QueueSetMemberHandle_t& queue_set_member, const QueueBase& queue); + friend class QueueSet; + friend bool operator==(const QueueSetMemberHandle_t& queue_set_member, + const QueueInterface& queue); protected: - QueueBase(QueueHandle_t handle) + QueueInterface(QueueHandle_t handle) : _handle(handle) {} - ~QueueBase() { vQueueDelete(_handle); } + virtual ~QueueInterface() { + if (_handle) vQueueDelete(_handle); + } - StaticQueue_t _tcb; QueueHandle_t _handle; public: - QueueHandle_t getHandle() { return _handle; } + explicit operator bool() const { return _handle != nullptr; } +}; - uint32_t availableMessages() { return uxQueueMessagesWaiting(_handle); } - uint32_t availableMessagesFromISR() { return uxQueueMessagesWaitingFromISR(_handle); } - uint32_t availableSpaces() { return uxQueueSpacesAvailable(_handle); } +inline bool operator==(const QueueSetMemberHandle_t& queue_set_member, + const QueueInterface& queue) { + return queue_set_member == queue._handle; +} + +template +class QueueBase : public QueueInterface { + private: + QueueBase(QueueBase const&) = delete; // Delete copy constructor + void operator=(QueueBase const&) = delete; // Delete copy assignment operator + + protected: + QueueBase(QueueHandle_t handle) + : QueueInterface(handle) {} + virtual ~QueueBase() {} + + public: + uint32_t getAvailableMessages() { return uxQueueMessagesWaiting(_handle); } + uint32_t getAvailableMessagesFromISR() { return uxQueueMessagesWaitingFromISR(_handle); } + uint32_t getAvailableSpaces() { return uxQueueSpacesAvailable(_handle); } void reset() { xQueueReset(_handle); } bool isFull() { return uxQueueSpacesAvailable(_handle) == 0; } bool isEmpty() { return uxQueueMessagesWaiting(_handle) == 0; } @@ -79,17 +90,20 @@ class QueueBase { }; template -bool operator==(const QueueSetMemberHandle_t& queue_set_member, const QueueBase& queue) { - return queue_set_member == queue._handle; -} +class QueueDynamic : public QueueBase { + public: + QueueDynamic(uint32_t length) + : QueueBase(xQueueCreate(length, sizeof(T))) {} +}; template -class Queue : public QueueBase { +class QueueStatic : public QueueBase { public: - Queue() + QueueStatic() : QueueBase(xQueueCreateStatic(LENGTH, sizeof(T), _storage, &this->_tcb)) {} private: + StaticQueue_t _tcb; uint8_t _storage[LENGTH * sizeof(T)]; }; @@ -103,6 +117,9 @@ class QueueExternalStorage : public QueueBase { this->_handle = xQueueCreateStatic(buffer_size, sizeof(T), buffer, &this->_tcb); return this->_handle != nullptr ? true : false; } + + private: + StaticQueue_t _tcb; }; #endif // RTOS_CPP_QUEUE_H \ No newline at end of file diff --git a/src/RTOScppQueueSet.h b/src/RTOScppQueueSet.h index 9b83f2e..e0e2b5c 100644 --- a/src/RTOScppQueueSet.h +++ b/src/RTOScppQueueSet.h @@ -16,25 +16,34 @@ class QueueSet { public: QueueSet(const uint8_t queue_length) : _handle(xQueueCreateSet(queue_length)) {} - ~QueueSet() { vQueueDelete(_handle); } + ~QueueSet() { + if (_handle) vQueueDelete(_handle); + } - bool add(QueueSetMemberHandle_t queue_or_semaphore) { - return xQueueAddToSet(queue_or_semaphore, _handle); + bool add(LockBase& lock) { return xQueueAddToSet(lock._handle, _handle); } + bool add(QueueInterface& queue) { return xQueueAddToSet(queue._handle, _handle); } + bool add(RingBufferInterface& ring_buffer) { + return xRingbufferAddToQueueSetRead(ring_buffer._handle, _handle); } - bool add(RingbufHandle_t ring_buffer) { - return xRingbufferAddToQueueSetRead(ring_buffer, _handle); + bool remove(LockBase& lock) { return xQueueRemoveFromSet(lock._handle, _handle); } + bool remove(QueueInterface& queue) { return xQueueRemoveFromSet(queue._handle, _handle); } + bool remove(RingBufferInterface& ring_buffer) { + return xRingbufferRemoveFromQueueSetRead(ring_buffer._handle, _handle); } QueueSetMemberHandle_t select(TickType_t ticks_to_wait = portMAX_DELAY) { return xQueueSelectFromSet(_handle, ticks_to_wait); } + QueueSetMemberHandle_t selectFromISR() { return xQueueSelectFromSetFromISR(_handle); } + + explicit operator bool() const { return _handle != nullptr; } private: QueueSetHandle_t _handle; - QueueSet(const QueueSet&) = delete; - QueueSet& operator=(const QueueSet&) = delete; + QueueSet(const QueueSet&) = delete; // Delete copy constructor + void operator=(const QueueSet&) = delete; // Delete copy assignment operator }; #endif // RTOS_CPP_QUEUE_SET_H \ No newline at end of file diff --git a/src/RTOScppRingBuffer.h b/src/RTOScppRingBuffer.h index bbd90b8..973fd1d 100644 --- a/src/RTOScppRingBuffer.h +++ b/src/RTOScppRingBuffer.h @@ -10,53 +10,87 @@ #include #include -class RingBufBase { +// Forward declaration of QueueSet +class QueueSet; + +class RingBufferInterface { private: - RingBufBase(const RingBufBase&) = delete; - RingBufBase& operator=(const RingBufBase&) = delete; + RingBufferInterface(const RingBufferInterface&) = delete; // Delete copy constructor + RingBufferInterface& operator=(const RingBufferInterface&) = delete; // Delete copy assignment op. + friend class QueueSet; friend bool operator==(const QueueSetMemberHandle_t& queue_set_member, - const RingBufBase& ring_buffer); + const RingBufferInterface& ring_buffer); protected: - RingBufBase(RingbufHandle_t handle) + RingBufferInterface(RingbufHandle_t handle) : _handle(handle) {} - ~RingBufBase() { vRingbufferDelete(_handle); } + virtual ~RingBufferInterface() { + if (_handle) vRingbufferDelete(_handle); + } RingbufHandle_t _handle; public: - RingbufHandle_t getHandle() { return _handle; } + explicit operator bool() const { return _handle != nullptr; } }; inline bool operator==(const QueueSetMemberHandle_t& queue_set_member, - const RingBufBase& ring_buffer) { + const RingBufferInterface& ring_buffer) { return xRingbufferCanRead(ring_buffer._handle, queue_set_member); } template -class RingBufNoSplitBase : public RingBufBase { +class RingBufferBase : public RingBufferInterface { protected: - RingBufNoSplitBase(RingbufHandle_t handle) - : RingBufBase(handle) {} + RingBufferBase(RingbufHandle_t handle) + : RingBufferInterface(handle) {} + virtual ~RingBufferBase() {} public: bool send(const T* item, uint32_t item_size, TickType_t ticks_to_wait = portMAX_DELAY) { return xRingbufferSend(_handle, (void*)item, item_size, ticks_to_wait); } - T* receive(uint32_t& item_size, TickType_t ticks_to_wait = portMAX_DELAY) { - return (T*)xRingbufferReceive(_handle, &item_size, ticks_to_wait); + bool sendFromISR(const T* item, uint32_t item_size, BaseType_t& higher_priority_task_woken) { + return xRingbufferSendFromISR(_handle, (void*)item, item_size, &higher_priority_task_woken); } void returnItem(T* item) { vRingbufferReturnItem(_handle, (void*)item); } + void returnItemFromISR(T* item, BaseType_t& higher_priority_task_woken) { + vRingbufferReturnItemFromISR(_handle, (void*)item, &higher_priority_task_woken); + } +}; + +template +class RingBufferNoSplitBase : public RingBufferBase { + protected: + RingBufferNoSplitBase(RingbufHandle_t handle) + : RingBufferBase(handle) {} + virtual ~RingBufferNoSplitBase() {} + + public: + T* receive(uint32_t& item_size, TickType_t ticks_to_wait = portMAX_DELAY) { + return (T*)xRingbufferReceive(this->_handle, &item_size, ticks_to_wait); + } + + T* receiveFromISR(uint32_t& item_size) { + return (T*)xRingbufferReceiveFromISR(this->_handle, &item_size); + } +}; + +template +class RingBufferNoSplitDynamic : public RingBufferNoSplitBase { + public: + RingBufferNoSplitDynamic(uint32_t buffer_size) + : RingBufferNoSplitBase(xRingbufferCreate(buffer_size, RINGBUF_TYPE_NOSPLIT)) {} }; template -class RingBufNoSplit : public RingBufNoSplitBase { +class RingBufferNoSplitStatic : public RingBufferNoSplitBase { public: - RingBufNoSplit() - : RingBufNoSplitBase( + RingBufferNoSplitStatic() + : RingBufferNoSplitBase( xRingbufferCreateStatic(BUFFER_SIZE, RINGBUF_TYPE_NOSPLIT, _storage, &_tcb)) {} private: @@ -65,14 +99,114 @@ class RingBufNoSplit : public RingBufNoSplitBase { }; template -class RingBufNoSplitExtStorage : public RingBufNoSplitBase { +class RingBufferNoSplitExternalStorage : public RingBufferNoSplitBase { public: - RingBufNoSplitExtStorage() - : RingBufNoSplitBase(nullptr) {} + RingBufferNoSplitExternalStorage() + : RingBufferNoSplitBase(nullptr) {} bool create(StaticRingbuffer_t* tcb, uint8_t* buffer_storage, uint32_t buffer_size) { this->_handle = xRingbufferCreateStatic(buffer_size, RINGBUF_TYPE_NOSPLIT, buffer_storage, tcb); + return this->_handle != nullptr ? true : false; + } +}; + +template +class RingBufferSplitBase : public RingBufferBase { + protected: + RingBufferSplitBase(RingbufHandle_t handle) + : RingBufferBase(handle) {} + virtual ~RingBufferSplitBase() {} + public: + bool receive(T** head, T** tail, uint32_t& head_item_size, uint32_t& tail_item_size, + TickType_t ticks_to_wait = portMAX_DELAY) { + return xRingbufferReceiveSplit( + this->_handle, head, tail, &head_item_size, &tail_item_size, ticks_to_wait); + } + + bool receiveFromISR(T** head, T** tail, uint32_t& head_item_size, uint32_t& tail_item_size) { + return xRingbufferReceiveSplitFromISR( + this->_handle, head, tail, &head_item_size, &tail_item_size); + } +}; + +template +class RingBufferSplitDynamic : public RingBufferSplitBase { + public: + RingBufferSplitDynamic(uint32_t buffer_size) + : RingBufferSplitBase(xRingbufferCreate(buffer_size, RINGBUF_TYPE_ALLOWSPLIT)) {} +}; + +template +class RingBufferSplitStatic : public RingBufferSplitBase { + public: + RingBufferSplitStatic() + : RingBufferSplitBase( + xRingbufferCreateStatic(BUFFER_SIZE, RINGBUF_TYPE_ALLOWSPLIT, _storage, &_tcb)) {} + + private: + StaticRingbuffer_t _tcb; + uint8_t _storage[BUFFER_SIZE]; +}; + +template +class RingBufferSplitExternalStorage : public RingBufferSplitBase { + public: + RingBufferSplitExternalStorage() + : RingBufferSplitBase(nullptr) {} + + bool create(StaticRingbuffer_t* tcb, uint8_t* buffer_storage, uint32_t buffer_size) { + this->_handle = + xRingbufferCreateStatic(buffer_size, RINGBUF_TYPE_ALLOWSPLIT, buffer_storage, tcb); + return this->_handle != nullptr ? true : false; + } +}; + +template +class RingBufferByteBase : public RingBufferBase { + protected: + RingBufferByteBase(RingbufHandle_t handle) + : RingBufferBase(handle) {} + virtual ~RingBufferByteBase() {} + + public: + T* receiveUpTo(uint32_t max_item_size, uint32_t& item_size, + TickType_t ticks_to_wait = portMAX_DELAY) { + return (T*)xRingbufferReceiveUpTo(this->_handle, &item_size, ticks_to_wait, max_item_size); + } + + T* receiveUpToFromISR(uint32_t max_item_size, uint32_t& item_size) { + return (T*)xRingbufferReceiveUpToFromISR(this->_handle, &item_size, max_item_size); + } +}; + +template +class RingBufferByteDynamic : public RingBufferByteBase { + public: + RingBufferByteDynamic(uint32_t buffer_size) + : RingBufferByteBase(xRingbufferCreate(buffer_size, RINGBUF_TYPE_BYTEBUF)) {} +}; + +template +class RingBufferByteStatic : public RingBufferByteBase { + public: + RingBufferByteStatic() + : RingBufferByteBase( + xRingbufferCreateStatic(BUFFER_SIZE, RINGBUF_TYPE_BYTEBUF, _storage, &_tcb)) {} + + private: + StaticRingbuffer_t _tcb; + uint8_t _storage[BUFFER_SIZE]; +}; + +template +class RingBufferByteExternalStorage : public RingBufferByteBase { + public: + RingBufferByteExternalStorage() + : RingBufferByteBase(nullptr) {} + + bool create(StaticRingbuffer_t* tcb, uint8_t* buffer_storage, uint32_t buffer_size) { + this->_handle = xRingbufferCreateStatic(buffer_size, RINGBUF_TYPE_BYTEBUF, buffer_storage, tcb); return this->_handle != nullptr ? true : false; } }; diff --git a/src/RTOScppTask.h b/src/RTOScppTask.h index 910d444..7565c2a 100644 --- a/src/RTOScppTask.h +++ b/src/RTOScppTask.h @@ -12,8 +12,8 @@ class TaskBase { private: - TaskBase(const TaskBase&) = delete; - void operator=(const TaskBase&) = delete; + TaskBase(const TaskBase&) = delete; // Delete copy constructor + void operator=(const TaskBase&) = delete; // Delete copy assignment operator protected: TaskBase(const char* name, TaskFunction_t function, uint8_t priority) @@ -21,7 +21,10 @@ class TaskBase { , _function(function) , _priority(priority) , _handle(nullptr) {} - ~TaskBase() { vTaskDelete(_handle); } + + virtual ~TaskBase() { + if (_handle) vTaskDelete(_handle); + } const char* _name; TaskFunction_t _function; @@ -31,6 +34,20 @@ class TaskBase { public: virtual bool init() = 0; + void suspend() { vTaskSuspend(_handle); } + void resume() { vTaskResume(_handle); } + bool abortDelay() { return xTaskAbortDelay(_handle); } + + void setPriority(uint8_t priority) { + _priority = priority; + vTaskPrioritySet(_handle, _priority); + } + + uint8_t getPriority() { return uxTaskPriorityGet(_handle); } + uint8_t getPriorityFromISR() { return uxTaskPriorityGetFromISR(_handle); } + const char* getName() { return _name; } + TaskHandle_t getHandle() { return _handle; } + bool notify(uint32_t value, eNotifyAction action) { return xTaskNotify(_handle, value, action); } bool notifyFromISR(uint32_t value, eNotifyAction action, BaseType_t& task_woken) { @@ -57,6 +74,54 @@ class TaskBase { uint32_t notifyTake(bool clear, TickType_t ticks_to_wait = portMAX_DELAY) { return ulTaskNotifyTake(clear, ticks_to_wait); } + + explicit operator bool() const { return _handle != nullptr; } +}; + +class TaskDynamic : public TaskBase { + public: + TaskDynamic(const char* name, TaskFunction_t function, uint8_t priority, uint32_t stack_size) + : TaskBase(name, function, priority) + , _stack_size(stack_size) {} + + bool init() { return xTaskCreate(_function, _name, _stack_size, nullptr, _priority, &_handle); } + + private: + uint32_t _stack_size; +}; + +class TaskDynamicPinnedToCore : public TaskBase { + public: + TaskDynamicPinnedToCore(const char* name, TaskFunction_t function, uint8_t priority, + uint32_t stack_size, BaseType_t running_core) + : TaskBase(name, function, priority) + , _stack_size(stack_size) + , _running_core(running_core) {} + + bool init() { + return xTaskCreatePinnedToCore( + _function, _name, _stack_size, nullptr, _priority, &_handle, _running_core); + } + + private: + uint32_t _stack_size; + BaseType_t _running_core; +}; + +template +class TaskStatic : public TaskBase { + public: + TaskStatic(const char* name, TaskFunction_t function, uint8_t priority) + : TaskBase(name, function, priority) {} + + bool init() { + _handle = xTaskCreateStatic(_function, _name, STACK_SIZE, nullptr, _priority, _stack, &_tcb); + return _handle != nullptr ? true : false; + } + + private: + StaticTask_t _tcb; + StackType_t _stack[STACK_SIZE]; }; template @@ -68,14 +133,8 @@ class TaskStaticPinnedToCore : public TaskBase { , _running_core(running_core) {} bool init() { - _handle = xTaskCreateStaticPinnedToCore(_function, // Función - _name, // Nombre - STACK_SIZE, // Tamaño stack - NULL, // Parámetros - _priority, // Prioridad - _stack, // Buffer stack - &_tcb, // Buffer tarea - _running_core); // Core + _handle = xTaskCreateStaticPinnedToCore( + _function, _name, STACK_SIZE, nullptr, _priority, _stack, &_tcb, _running_core); return _handle != nullptr ? true : false; } diff --git a/src/RTOScppTimer.h b/src/RTOScppTimer.h index d98e46c..b4599b4 100644 --- a/src/RTOScppTimer.h +++ b/src/RTOScppTimer.h @@ -12,13 +12,15 @@ class TimerBase { private: - TimerBase(const TimerBase&) = delete; - void operator=(const TimerBase&) = delete; + TimerBase(const TimerBase&) = delete; // Delete copy constructor + void operator=(const TimerBase&) = delete; // Delete copy assignment operator protected: TimerBase(TimerHandle_t handle) : _handle(handle) {} - ~TimerBase() { xTimerDelete(_handle, portMAX_DELAY); } + virtual ~TimerBase() { + if (_handle) xTimerDelete(_handle, portMAX_DELAY); + } TimerHandle_t _handle; @@ -31,16 +33,15 @@ class TimerBase { bool stop(TickType_t ticks_to_wait = portMAX_DELAY) { return xTimerStop(_handle, ticks_to_wait); } bool stopFromISR(BaseType_t& task_woken) { return xTimerStopFromISR(_handle, &task_woken); } + bool isActive() { return xTimerIsTimerActive(_handle); } bool reset(TickType_t ticks_to_wait = portMAX_DELAY) { return xTimerReset(_handle, ticks_to_wait); } bool resetFromISR(BaseType_t& task_woken) { return xTimerResetFromISR(_handle, &task_woken); } - bool isActive() { return xTimerIsTimerActive(_handle); } const char* getName() { return pcTimerGetName(_handle); } TickType_t getExpiryTime() { return xTimerGetExpiryTime(_handle); } - TickType_t getPeriod() { return xTimerGetPeriod(_handle); } bool setPeriod(TickType_t period, TickType_t ticks_to_wait = portMAX_DELAY) { return xTimerChangePeriod(_handle, period, ticks_to_wait); @@ -49,15 +50,30 @@ class TimerBase { bool setPeriodFromISR(TickType_t period, BaseType_t& task_woken) { return xTimerChangePeriodFromISR(_handle, period, &task_woken); } + + TickType_t getPeriod() { return xTimerGetPeriod(_handle); } + + void setReloadMode(bool auto_reload) { vTimerSetReloadMode(_handle, auto_reload); } + bool getReloadMode() { return uxTimerGetReloadMode(_handle); } + + explicit operator bool() const { return _handle != nullptr; } +}; + +class TimerDynamic : public TimerBase { + public: + TimerDynamic(const char* name, TimerCallbackFunction_t callback, TickType_t period, + bool auto_reload, bool start) + : TimerBase(xTimerCreate(name, period, auto_reload, 0, callback)) { + if (start) this->start(); + } }; -class Timer : public TimerBase { +class TimerStatic : public TimerBase { public: - Timer(const char* name, TimerCallbackFunction_t callback, TickType_t period, bool auto_reload, - bool start) - : TimerBase(xTimerCreateStatic(name, period, auto_reload, this, callback, &_tcb)) { - if (start) - this->start(); + TimerStatic(const char* name, TimerCallbackFunction_t callback, TickType_t period, + bool auto_reload, bool start) + : TimerBase(xTimerCreateStatic(name, period, auto_reload, 0, callback, &_tcb)) { + if (start) this->start(); } private: