20#include "esp_heap_caps.h"
21#include "freertos/FreeRTOS.h"
22#include "freertos/semphr.h"
37 if (p) heap_caps_free(p);
53 auto* raw =
static_cast<T*
>(
54 heap_caps_malloc(count *
sizeof(T), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
74 if (fp) std::fclose(fp);
79using FilePtr = std::unique_ptr<std::FILE, FileCloseDeleter>;
89 return FilePtr{std::fopen(path, mode)};
112 NvsScope(const
char* ns, nvs_open_mode_t mode) noexcept
114 status_ = nvs_open(ns, mode, &handle_);
115 if (status_ != ESP_OK) handle_ = 0;
120 if (handle_) nvs_close(handle_);
129 other.status_ = ESP_FAIL;
133 if (
this != &other) {
134 if (handle_) nvs_close(handle_);
135 handle_ = other.handle_;
136 status_ = other.status_;
138 other.status_ = ESP_FAIL;
144 explicit operator bool() const noexcept {
return status_ == ESP_OK; }
147 operator nvs_handle_t() const noexcept {
return handle_; }
150 esp_err_t
status() const noexcept {
return status_; }
155 return handle_ ? nvs_commit(handle_) : ESP_FAIL;
169 nvs_handle_t handle_ = 0;
170 esp_err_t status_ = ESP_FAIL;
184 explicit MutexGuard(SemaphoreHandle_t sem) noexcept : sem_(sem)
186 if (sem_) xSemaphoreTake(sem_, portMAX_DELAY);
191 if (sem_ && locked_) xSemaphoreGive(sem_);
198 : sem_(other.sem_), locked_(other.locked_)
200 other.sem_ =
nullptr;
201 other.locked_ =
false;
205 bool locked() const noexcept {
return locked_; }
210 if (sem_ && locked_) {
211 xSemaphoreGive(sem_);
222 if (sem && xSemaphoreTake(sem, ticks) == pdTRUE) {
229 MutexGuard() noexcept : sem_(
nullptr), locked_(false) {}
231 SemaphoreHandle_t sem_ =
nullptr;
250 if (sem_) xSemaphoreTakeRecursive(sem_, portMAX_DELAY);
255 if (sem_) xSemaphoreGiveRecursive(sem_);
262 SemaphoreHandle_t sem_ =
nullptr;
bool locked() const noexcept
True if the semaphore is currently held.
MutexGuard(MutexGuard &&other) noexcept
MutexGuard(const MutexGuard &)=delete
void release() noexcept
Release the semaphore before destruction. Idempotent.
MutexGuard(SemaphoreHandle_t sem) noexcept
Take sem blocking until acquired.
static MutexGuard tryLock(SemaphoreHandle_t sem, TickType_t ticks) noexcept
MutexGuard & operator=(const MutexGuard &)=delete
void close() noexcept
Manually close before destruction. Idempotent.
NvsScope() noexcept=default
Construct an empty, closed scope. Status reports ESP_FAIL until opened.
NvsScope & operator=(NvsScope &&other) noexcept
NvsScope(const NvsScope &)=delete
esp_err_t commit() noexcept
Commit pending writes. Caller checks the return value if needed.
esp_err_t status() const noexcept
esp_err_t result of the original nvs_open call.
NvsScope(NvsScope &&other) noexcept
NvsScope & operator=(const NvsScope &)=delete
RecursiveMutexGuard(const RecursiveMutexGuard &)=delete
~RecursiveMutexGuard() noexcept
RecursiveMutexGuard(SemaphoreHandle_t sem) noexcept
Take sem blocking until acquired; no-op when sem is nullptr.
RecursiveMutexGuard & operator=(const RecursiveMutexGuard &)=delete
std::unique_ptr< T, CStdFreeDeleter > CStdUniquePtr
unique_ptr for buffers allocated via realloc/malloc (e.g. esp_http_client body chunks).
std::unique_ptr< T[], CapsFreeDeleter > PsramUniquePtr
FilePtr openFile(const char *path, const char *mode) noexcept
Open a FILE* and wrap it in a FilePtr.
std::unique_ptr< std::FILE, FileCloseDeleter > FilePtr
unique_ptr for FILE* handles. Destructor calls std::fclose.
PsramUniquePtr< T > psramAlloc(std::size_t count) noexcept
Allocate count elements of T in PSRAM (8-bit capable region).
Deleter for buffers allocated via malloc/realloc.
void operator()(void *p) const noexcept
Deleter for buffers allocated via heap_caps_malloc.
void operator()(void *p) const noexcept
Deleter for FILE* opened with std::fopen.
void operator()(std::FILE *fp) const noexcept