Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ AlignConsecutiveBitFields: Consecutive
AlignConsecutiveMacros: Consecutive
AlignEscapedNewlines: Left
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: WithoutElse
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma
Expand Down
79 changes: 47 additions & 32 deletions src/RTOScppBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@
#include <freertos/message_buffer.h>
#include <freertos/stream_buffer.h>

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) {
Expand All @@ -45,62 +44,78 @@ class DataBuffer {
bool isEmpty() { return xStreamBufferIsEmpty(_handle); }
bool isFull() { return xStreamBufferIsFull(_handle); }
uint32_t availableSpaces() { return xStreamBufferSpacesAvailable(_handle); }
};

template <uint32_t LENGTH>
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 <uint32_t BUFFER_SIZE>
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 =
xStreamBufferGenericCreateStatic(buffer_size + 1, trigger_bytes, pdFALSE, buffer, &_tcb);
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 <uint32_t LENGTH>
class MessageBuffer : public DataBuffer {
template <uint32_t BUFFER_SIZE>
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
95 changes: 72 additions & 23 deletions src/RTOScppLock.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,62 @@
#define RTOS_CPP_LOCK_H

#include <Arduino.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>

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);
Expand All @@ -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
69 changes: 43 additions & 26 deletions src/RTOScppQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,48 @@
#include <Arduino.h>
#include <freertos/queue.h>

// QueueBase forward declaration
template <typename T>
class QueueBase;

// operator==<T> forward declaration
template <typename T>
bool operator==(const QueueSetMemberHandle_t& queue_set_member, const QueueBase<T>& queue);
// Forward declaration of QueueSet
class QueueSet;

template <typename T>
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<T>& 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 <typename T>
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; }
Expand Down Expand Up @@ -79,17 +90,20 @@ class QueueBase {
};

template <typename T>
bool operator==(const QueueSetMemberHandle_t& queue_set_member, const QueueBase<T>& queue) {
return queue_set_member == queue._handle;
}
class QueueDynamic : public QueueBase<T> {
public:
QueueDynamic(uint32_t length)
: QueueBase<T>(xQueueCreate(length, sizeof(T))) {}
};

template <typename T, uint32_t LENGTH>
class Queue : public QueueBase<T> {
class QueueStatic : public QueueBase<T> {
public:
Queue()
QueueStatic()
: QueueBase<T>(xQueueCreateStatic(LENGTH, sizeof(T), _storage, &this->_tcb)) {}

private:
StaticQueue_t _tcb;
uint8_t _storage[LENGTH * sizeof(T)];
};

Expand All @@ -103,6 +117,9 @@ class QueueExternalStorage : public QueueBase<T> {
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
Loading