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
85 changes: 44 additions & 41 deletions src/RTOScppBuffer.h
Original file line number Diff line number Diff line change
@@ -1,82 +1,87 @@
/**
* SPDX-FileCopyrightText: 2023 Maximiliano Ramirez
* SPDX-FileCopyrightText: 2024 Maximiliano Ramirez
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#ifndef RTOS_CPP_BUFFER_H
#define RTOS_CPP_BUFFER_H
#pragma once

#include <Arduino.h>
#include <freertos/message_buffer.h>
#include <freertos/stream_buffer.h>

class DataBufferBase {
private:
DataBufferBase(const DataBufferBase&) = delete; // Delete copy constructor
void operator=(const DataBufferBase&) = delete; // Delete copy assignment operator

class DataBufferInterface {
protected:
DataBufferBase(StreamBufferHandle_t handle)
DataBufferInterface(const StreamBufferHandle_t handle)
: _handle(handle) {}
virtual ~DataBufferBase() { vStreamBufferDelete(_handle); }

StreamBufferHandle_t _handle;

public:
uint32_t send(const void* tx_buffer, uint32_t bytes, TickType_t ticks_to_wait = portMAX_DELAY) {
virtual ~DataBufferInterface() {
if (_handle) vStreamBufferDelete(_handle);
}

DataBufferInterface(const DataBufferInterface&) = delete;
DataBufferInterface& operator=(const DataBufferInterface&) = delete;
DataBufferInterface(DataBufferInterface&&) noexcept = delete;
DataBufferInterface& operator=(DataBufferInterface&&) noexcept = delete;

uint32_t send(const void* tx_buffer, const uint32_t bytes,
const TickType_t ticks_to_wait = portMAX_DELAY) const {
return xStreamBufferSend(_handle, tx_buffer, bytes, ticks_to_wait);
}

uint32_t sendFromISR(const void* tx_buffer, uint32_t bytes, BaseType_t& task_woken) {
uint32_t sendFromISR(const void* tx_buffer, const uint32_t bytes, BaseType_t& task_woken) const {
return xStreamBufferSendFromISR(_handle, tx_buffer, bytes, &task_woken);
}

uint32_t receive(void* rx_buffer, uint32_t bytes, TickType_t ticks_to_wait = portMAX_DELAY) {
uint32_t receive(void* rx_buffer, const uint32_t bytes,
const TickType_t ticks_to_wait = portMAX_DELAY) const {
return xStreamBufferReceive(_handle, rx_buffer, bytes, ticks_to_wait);
}

uint32_t receiveFromISR(void* rx_buffer, uint32_t bytes, BaseType_t& task_woken) {
uint32_t receiveFromISR(void* rx_buffer, const uint32_t bytes, BaseType_t& task_woken) const {
return xStreamBufferReceiveFromISR(_handle, rx_buffer, bytes, &task_woken);
}

bool reset() { return xStreamBufferReset(_handle); }
bool isEmpty() { return xStreamBufferIsEmpty(_handle); }
bool isFull() { return xStreamBufferIsFull(_handle); }
uint32_t availableSpaces() { return xStreamBufferSpacesAvailable(_handle); }
uint32_t availableBytes() { return xStreamBufferBytesAvailable(_handle); }
bool reset() const { return xStreamBufferReset(_handle); }
bool isEmpty() const { return xStreamBufferIsEmpty(_handle); }
bool isFull() const { return xStreamBufferIsFull(_handle); }
uint32_t availableSpaces() const { return xStreamBufferSpacesAvailable(_handle); }
uint32_t availableBytes() const { return xStreamBufferBytesAvailable(_handle); }

bool setTriggerLevel(uint32_t trigger_bytes) {
bool setTriggerLevel(const uint32_t trigger_bytes) {
return xStreamBufferSetTriggerLevel(_handle, trigger_bytes);
}

explicit operator bool() const { return _handle != nullptr; }
};

class StreamBufferDynamic : public DataBufferBase {
class StreamBufferDynamic : public DataBufferInterface {
public:
StreamBufferDynamic(uint32_t buffer_size, uint32_t trigger_bytes)
: DataBufferBase(xStreamBufferGenericCreate(buffer_size + 1, trigger_bytes, false)) {}
StreamBufferDynamic(const uint32_t buffer_size, const uint32_t trigger_bytes)
: DataBufferInterface(xStreamBufferGenericCreate(buffer_size + 1, trigger_bytes, false)) {}
};

template <uint32_t BUFFER_SIZE>
class StreamBufferStatic : public DataBufferBase {
class StreamBufferStatic : public DataBufferInterface {
public:
StreamBufferStatic(uint32_t trigger_bytes)
: DataBufferBase(xStreamBufferGenericCreateStatic(BUFFER_SIZE + 1, trigger_bytes, false,
_storage, &_tcb)) {}
StreamBufferStatic(const uint32_t trigger_bytes)
: DataBufferInterface(xStreamBufferGenericCreateStatic(BUFFER_SIZE + 1, trigger_bytes, false,
_storage, &_tcb)) {}

private:
StaticStreamBuffer_t _tcb;
uint8_t _storage[BUFFER_SIZE + 1];
};

class StreamBufferExternalStorage : public DataBufferBase {
class StreamBufferExternalStorage : public DataBufferInterface {
public:
StreamBufferExternalStorage(uint32_t trigger_bytes)
: DataBufferBase(nullptr) {}
StreamBufferExternalStorage(const uint32_t trigger_bytes)
: DataBufferInterface(nullptr) {}

bool init(uint32_t trigger_bytes, uint8_t* buffer, uint32_t buffer_size) {
bool init(const uint32_t trigger_bytes, uint8_t* const buffer, const uint32_t buffer_size) {
_handle =
xStreamBufferGenericCreateStatic(buffer_size + 1, trigger_bytes, pdFALSE, buffer, &_tcb);
return _handle != nullptr ? true : false;
Expand All @@ -86,36 +91,34 @@ class StreamBufferExternalStorage : public DataBufferBase {
StaticStreamBuffer_t _tcb;
};

class MessageBufferDynamic : public DataBufferBase {
class MessageBufferDynamic : public DataBufferInterface {
public:
MessageBufferDynamic(uint32_t buffer_size)
: DataBufferBase(xStreamBufferGenericCreate(buffer_size + 1, 0, false)) {}
MessageBufferDynamic(const uint32_t buffer_size)
: DataBufferInterface(xStreamBufferGenericCreate(buffer_size + 1, 0, false)) {}
};

template <uint32_t BUFFER_SIZE>
class MessageBufferStatic : public DataBufferBase {
class MessageBufferStatic : public DataBufferInterface {
public:
MessageBufferStatic()
: DataBufferBase(
: DataBufferInterface(
xStreamBufferGenericCreateStatic(BUFFER_SIZE + 1, 0, false, _storage, &_tcb)) {}

private:
StaticStreamBuffer_t _tcb;
uint8_t _storage[BUFFER_SIZE + 1];
};

class MessageBufferExternalStorage : public DataBufferBase {
class MessageBufferExternalStorage : public DataBufferInterface {
public:
MessageBufferExternalStorage()
: DataBufferBase(nullptr) {}
: DataBufferInterface(nullptr) {}

bool init(uint32_t trigger_bytes, uint8_t* buffer, uint32_t buffer_size) {
bool init(const uint32_t trigger_bytes, uint8_t* const buffer, const 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
76 changes: 40 additions & 36 deletions src/RTOScppLock.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/**
* SPDX-FileCopyrightText: 2023 Maximiliano Ramirez
* SPDX-FileCopyrightText: 2024 Maximiliano Ramirez
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#ifndef RTOS_CPP_LOCK_H
#define RTOS_CPP_LOCK_H
#pragma once

#include <Arduino.h>
#include <freertos/queue.h>
Expand All @@ -14,88 +13,95 @@
// Forward declaration of QueueSet
class QueueSet;

class LockBase {
class LockInterface {
private:
LockBase(LockBase const&) = delete; // Delete copy constructor
void operator=(LockBase const&) = delete; // Delete copy assignment operator

friend class QueueSet;
friend bool operator==(const QueueSetMemberHandle_t& queue_set_member, const LockBase& lock);
friend bool operator==(const QueueSetMemberHandle_t& queue_set_member, const LockInterface& lock);

protected:
LockBase(SemaphoreHandle_t handle)
LockInterface(SemaphoreHandle_t handle)
: _handle(handle) {}
virtual ~LockBase() {
if (_handle) vSemaphoreDelete(_handle);
}

SemaphoreHandle_t _handle;

public:
virtual bool take(const TickType_t ticks_to_wait = portMAX_DELAY) {
virtual ~LockInterface() {
if (_handle) vSemaphoreDelete(_handle);
}

LockInterface(const LockInterface&) = delete;
LockInterface& operator=(const LockInterface&) = delete;
LockInterface(LockInterface&&) noexcept = delete;
LockInterface& operator=(LockInterface&&) noexcept = delete;

virtual bool take(const TickType_t ticks_to_wait = portMAX_DELAY) const {
return xSemaphoreTake(_handle, ticks_to_wait);
}

virtual bool give() { return xSemaphoreGive(_handle); }
virtual bool give() const { return xSemaphoreGive(_handle); }

explicit operator bool() const { return _handle != nullptr; }
};

inline bool operator==(const QueueSetMemberHandle_t& queue_set_member, const LockBase& lock) {
inline bool operator==(const QueueSetMemberHandle_t& queue_set_member, const LockInterface& lock) {
return queue_set_member == lock._handle;
}

class MutexDynamic : public LockBase {
class MutexDynamic : public LockInterface {
public:
MutexDynamic()
: LockBase(xSemaphoreCreateMutex()) {}
: LockInterface(xSemaphoreCreateMutex()) {}
};

class MutexStatic : public LockBase {
class MutexStatic : public LockInterface {
public:
MutexStatic()
: LockBase(xSemaphoreCreateMutexStatic(&_tcb)) {}
: LockInterface(xSemaphoreCreateMutexStatic(&_tcb)) {}

private:
StaticSemaphore_t _tcb;
};

class MutexRecursiveDynamic : public LockBase {
class MutexRecursiveDynamic : public LockInterface {
public:
MutexRecursiveDynamic()
: LockBase(xSemaphoreCreateRecursiveMutex()) {}
: LockInterface(xSemaphoreCreateRecursiveMutex()) {}

bool take(const TickType_t ticks_to_wait = portMAX_DELAY) override {
bool take(const TickType_t ticks_to_wait = portMAX_DELAY) const override {
return xSemaphoreTakeRecursive(_handle, ticks_to_wait);
}

bool give() override { return xSemaphoreGiveRecursive(_handle); }
bool give() const override { return xSemaphoreGiveRecursive(_handle); }
};

class MutexRecursiveStatic : public LockBase {
class MutexRecursiveStatic : public LockInterface {
public:
MutexRecursiveStatic()
: LockBase(xSemaphoreCreateRecursiveMutexStatic(&_tcb)) {}
: LockInterface(xSemaphoreCreateRecursiveMutexStatic(&_tcb)) {}

bool take(const TickType_t ticks_to_wait = portMAX_DELAY) override {
bool take(const TickType_t ticks_to_wait = portMAX_DELAY) const override {
return xSemaphoreTakeRecursive(_handle, ticks_to_wait);
}

bool give() override { return xSemaphoreGiveRecursive(_handle); }
bool give() const override { return xSemaphoreGiveRecursive(_handle); }

private:
StaticSemaphore_t _tcb;
};

class Semaphore : public LockBase {
class Semaphore : public LockInterface {
protected:
Semaphore(SemaphoreHandle_t handle)
: LockBase(handle) {}
Semaphore(const SemaphoreHandle_t handle)
: LockInterface(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); }
bool takeFromISR(BaseType_t& task_woken) const {
return xSemaphoreTakeFromISR(_handle, &task_woken);
}
bool giveFromISR(BaseType_t& task_woken) const {
return xSemaphoreGiveFromISR(_handle, &task_woken);
}
uint8_t getCount() const { return uxSemaphoreGetCount(_handle); }
};

class SemaphoreBinaryDynamic : public Semaphore {
Expand Down Expand Up @@ -126,6 +132,4 @@ class SemaphoreCountingStatic : public Semaphore {

private:
StaticSemaphore_t _tcb;
};

#endif // RTOS_CPP_LOCK_H
};
Loading