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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ lib_deps =

; Release vx.y.z (using an exact version is recommended)
lib_deps =
https://github.com/alkonosst/RTOScppESP32.git#v1.0.0
https://github.com/alkonosst/RTOScppESP32.git#v1.1.0
```

## Using the library
Expand Down Expand Up @@ -166,6 +166,9 @@ microcontroller with limited resources.
For now, only the constructors are explained here. You can check the methods using the code
completion feature of your IDE or checking the source code of each object type.

All objects have a name parameter that is used for debugging purposes (**with a default name if you
don't provide one**). It is a good practice to give a meaningful name to each object to make it easier to identify them in the debugging process.

### Using tasks

```cpp
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "RTOScppESP32",
"version": "1.0.2",
"version": "1.1.0",
"authors": {
"name": "Maximiliano Ramirez",
"email": "maximiliano.ramirezbravo@gmail.com"
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=RTOScppESP32
version=1.0.2
version=1.1.0
author=Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
maintainer=Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
sentence=FreeRTOS abstraction layer for ESP32 with C++ interface.
Expand Down
20 changes: 11 additions & 9 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html

[platformio]
lib_dir = .
; lib_dir = .
; src_dir = examples/Task
; src_dir = examples/Timer
; src_dir = examples/Mutex
Expand All @@ -25,22 +25,19 @@ lib_dir = .
; src_dir = examples/QueueSet

[env:esp32-s3]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13+github/platform-espressif32.zip
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip
board = esp32-s3-devkitc-1
framework = arduino

; Tests
; Ignore Unity library to avoid conflicts with source code due to lib_dir = .
lib_ignore = Unity

; test_ignore =
; test_tasks
; test_timers
; test_buffers
; test_locks
; test_queues
; test_buffers
; test_ringbuffers
; test_queuesets
; test_ringbuffers
; test_tasks
; test_timers

; Config ESP32
board_build.f_flash = 80000000L
Expand All @@ -59,6 +56,11 @@ monitor_filters =

; Flags
build_flags =
; Enable all warnings and treat them as errors
-Wall
-Wextra
-Werror

; Enable debug (ESP-IDF logs)
; -DUSE_ESP_IDF_LOG
; -DCORE_DEBUG_LEVEL=5
Expand Down
39 changes: 33 additions & 6 deletions src/RTOScppBuffer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2025 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
* SPDX-FileCopyrightText: 2026 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
Expand Down Expand Up @@ -32,6 +32,12 @@ class IBuffer {
*/
virtual StreamBufferHandle_t getHandle() const = 0;

/**
* @brief Get the name of the buffer. Useful for debugging and logging purposes.
* @return const char* Name of the buffer. Default is "RtosBuffer" if no name is provided.
*/
virtual const char* getName() const = 0;

/**
* @brief Check if the buffer is created.
* @return true Buffer is created.
Expand Down Expand Up @@ -128,12 +134,15 @@ class Policy {
StreamBufferHandle_t getHandle() const { return _handle; }

bool isCreated() const { return _handle != nullptr; }
const char* getName() const { return _name; }

protected:
Policy()
: _handle(nullptr) {}
: _handle(nullptr)
, _name("RtosBuffer") {}

StreamBufferHandle_t _handle;
const char* _name;
};

// CRTP stream buffer base policy class
Expand All @@ -157,8 +166,9 @@ template <uint32_t BufferSize, uint32_t TriggerBytes>
class StreamBufferDynamicPolicy
: public StreamBufferPolicy<StreamBufferDynamicPolicy<BufferSize, TriggerBytes>> {
public:
StreamBufferDynamicPolicy() {
StreamBufferDynamicPolicy(const char* name = nullptr) {
this->_handle = xStreamBufferGenericCreate(BufferSize, TriggerBytes, false, nullptr, nullptr);
if (name) this->_name = name;
}
};

Expand All @@ -167,14 +177,15 @@ template <uint32_t BufferSize, uint32_t TriggerBytes>
class StreamBufferStaticPolicy
: public StreamBufferPolicy<StreamBufferStaticPolicy<BufferSize, TriggerBytes>> {
public:
StreamBufferStaticPolicy() {
StreamBufferStaticPolicy(const char* name = nullptr) {
this->_handle = xStreamBufferGenericCreateStatic(BufferSize + 1,
TriggerBytes,
false,
_storage,
&_buf_buffer,
nullptr,
nullptr);
if (name) this->_name = name;
}

private:
Expand All @@ -189,6 +200,10 @@ class StreamBufferExternalStoragePolicy
public:
static constexpr uint32_t REQUIRED_SIZE = BufferSize + 2;

StreamBufferExternalStoragePolicy(const char* name = nullptr) {
if (name) this->_name = name;
}

/**
* @brief Create the stream buffer with an external memory allocation.
* @param buffer External memory buffer.
Expand Down Expand Up @@ -216,23 +231,25 @@ class StreamBufferExternalStoragePolicy
template <uint32_t BufferSize>
class MessageBufferDynamicPolicy : public Policy<MessageBufferDynamicPolicy<BufferSize>> {
public:
MessageBufferDynamicPolicy() {
MessageBufferDynamicPolicy(const char* name = nullptr) {
this->_handle = xStreamBufferGenericCreate(BufferSize, 0, true, nullptr, nullptr);
if (name) this->_name = name;
}
};

// Policy for message buffer with static memory allocation
template <uint32_t BufferSize>
class MessageBufferStaticPolicy : public Policy<MessageBufferStaticPolicy<BufferSize>> {
public:
MessageBufferStaticPolicy() {
MessageBufferStaticPolicy(const char* name = nullptr) {
this->_handle = xStreamBufferGenericCreateStatic(BufferSize + 1,
0,
true,
_storage,
&_buf_buffer,
nullptr,
nullptr);
if (name) this->_name = name;
}

private:
Expand All @@ -247,6 +264,10 @@ class MessageBufferExternalStoragePolicy
public:
static constexpr uint32_t REQUIRED_SIZE = BufferSize + 2;

MessageBufferExternalStoragePolicy(const char* name = nullptr) {
if (name) this->_name = name;
}

/**
* @brief Create the message buffer with an external memory allocation.
* @param buffer External memory buffer.
Expand Down Expand Up @@ -287,6 +308,12 @@ class DataBuffer : public IBuffer, public Policy {
*/
StreamBufferHandle_t getHandle() const override { return Policy::getHandle(); }

/**
* @brief Get the name of the buffer. Useful for debugging and logging purposes.
* @return const char* Name of the buffer. Default is "RtosBuffer" if no name is provided.
*/
virtual const char* getName() const override { return Policy::getName(); }

/**
* @brief Check if the buffer is created.
* @return true Buffer is created.
Expand Down
64 changes: 49 additions & 15 deletions src/RTOScppLock.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2025 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
* SPDX-FileCopyrightText: 2026 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
Expand Down Expand Up @@ -32,6 +32,12 @@ class ILock {
*/
virtual SemaphoreHandle_t getHandle() const = 0;

/**
* @brief Get the name of the lock. Useful for debugging and logging purposes.
* @return const char* Name of the lock. Default is "RtosLock" if no name is provided.
*/
virtual const char* getName() const = 0;

/**
* @brief Check if the lock is created.
* @return true Lock is created.
Expand Down Expand Up @@ -72,11 +78,14 @@ template <typename Derived>
class Policy {
protected:
Policy()
: _handle(nullptr) {}
: _handle(nullptr)
, _name("RtosLock") {}

public:
SemaphoreHandle_t getHandle() const { return _handle; }

const char* getName() const { return _name; }

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

bool take(const TickType_t ticks_to_wait = portMAX_DELAY) {
Expand All @@ -91,6 +100,7 @@ class Policy {

protected:
SemaphoreHandle_t _handle;
const char* _name;
};

// CRTP mutex base policy class
Expand All @@ -110,14 +120,20 @@ class MutexPolicy : public Policy<MutexPolicy<Derived>> {
template <uint8_t Dummy = 0>
class MutexDynamicPolicy : public MutexPolicy<MutexDynamicPolicy<>> {
public:
MutexDynamicPolicy() { this->_handle = xSemaphoreCreateMutex(); }
MutexDynamicPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateMutex();
if (name) this->_name = name;
}
};

// Policy for mutex with static memory allocation
template <uint8_t Dummy = 0>
class MutexStaticPolicy : public MutexPolicy<MutexStaticPolicy<>> {
public:
MutexStaticPolicy() { this->_handle = xSemaphoreCreateMutexStatic(&_mutex_buffer); }
MutexStaticPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateMutexStatic(&_mutex_buffer);
if (name) this->_name = name;
}

private:
StaticSemaphore_t _mutex_buffer;
Expand All @@ -140,15 +156,19 @@ class MutexRecursivePolicy : public Policy<MutexRecursivePolicy<Derived>> {
template <uint8_t Dummy = 0>
class MutexRecursiveDynamicPolicy : public MutexRecursivePolicy<MutexRecursiveDynamicPolicy<>> {
public:
MutexRecursiveDynamicPolicy() { this->_handle = xSemaphoreCreateRecursiveMutex(); }
MutexRecursiveDynamicPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateRecursiveMutex();
if (name) this->_name = name;
}
};

// Policy for recursive mutex with static memory allocation
template <uint8_t Dummy = 0>
class MutexRecursiveStaticPolicy : public MutexRecursivePolicy<MutexRecursiveStaticPolicy<>> {
public:
MutexRecursiveStaticPolicy() {
MutexRecursiveStaticPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateRecursiveMutexStatic(&_mutex_recursive_buffer);
if (name) this->_name = name;
}

private:
Expand All @@ -172,15 +192,19 @@ class SemaphoreBinaryPolicy : public Policy<SemaphoreBinaryPolicy<Derived>> {
template <uint8_t Dummy = 0>
class SemaphoreBinaryDynamicPolicy : public SemaphoreBinaryPolicy<SemaphoreBinaryDynamicPolicy<>> {
public:
SemaphoreBinaryDynamicPolicy() { this->_handle = xSemaphoreCreateBinary(); }
SemaphoreBinaryDynamicPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateBinary();
if (name) this->_name = name;
}
};

// Policy for binary semaphore with static memory allocation
template <uint8_t Dummy = 0>
class SemaphoreBinaryStaticPolicy : public SemaphoreBinaryPolicy<SemaphoreBinaryStaticPolicy<>> {
public:
SemaphoreBinaryStaticPolicy() {
SemaphoreBinaryStaticPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateBinaryStatic(&_sem_binary_buffer);
if (name) this->_name = name;
}

private:
Expand Down Expand Up @@ -216,8 +240,9 @@ class SemaphoreCountingDynamicPolicy
: public SemaphoreCountingPolicy<SemaphoreCountingDynamicPolicy<MaxCount, InitialCount>> {

public:
SemaphoreCountingDynamicPolicy() {
SemaphoreCountingDynamicPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateCounting(MaxCount, InitialCount);
if (name) this->_name = name;
}
};

Expand All @@ -227,8 +252,9 @@ class SemaphoreCountingStaticPolicy
: public SemaphoreCountingPolicy<SemaphoreCountingStaticPolicy<MaxCount, InitialCount>> {

public:
SemaphoreCountingStaticPolicy() {
SemaphoreCountingStaticPolicy(const char* name = nullptr) {
this->_handle = xSemaphoreCreateCountingStatic(MaxCount, InitialCount, &_sem_counting_buffer);
if (name) this->_name = name;
}

private:
Expand All @@ -250,32 +276,40 @@ class Lock : public ILock, public Policy {
* caution.
* @return SemaphoreHandle_t Lock handle, nullptr if the lock is not created.
*/
SemaphoreHandle_t getHandle() const { return Policy::getHandle(); }
SemaphoreHandle_t getHandle() const override { return Policy::getHandle(); }

/**
* @brief Get the name of the lock. Useful for debugging and logging purposes.
* @return const char* Name of the lock. Default is "RtosLock" if no name is provided.
*/
const char* getName() const override { return Policy::getName(); }

/**
* @brief Check if the lock is created.
* @return true Lock is created.
*/
bool isCreated() const { return Policy::isCreated(); }
bool isCreated() const override { return Policy::isCreated(); }

/**
* @brief Take the lock.
* @param ticks_to_wait Maximum time to wait for the operation to complete.
* @return true Lock taken successfully, false if the lock is not created or failed to take.
*/
bool take(const TickType_t ticks_to_wait = portMAX_DELAY) { return Policy::take(ticks_to_wait); }
bool take(const TickType_t ticks_to_wait = portMAX_DELAY) override {
return Policy::take(ticks_to_wait);
}

/**
* @brief Give the lock.
* @return true Lock given successfully, false if the lock is not created or failed to give.
*/
bool give() { return Policy::give(); }
bool give() override { return Policy::give(); }

/**
* @brief Check if the lock is taken.
* @return true Lock is taken.
*/
explicit operator bool() const { return isCreated(); }
explicit operator bool() const override { return isCreated(); }
};

} // namespace Internal
Expand Down
Loading