CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
Raii.h
Go to the documentation of this file.
1
17
18#pragma once
19
20#include "esp_heap_caps.h"
21#include "freertos/FreeRTOS.h"
22#include "freertos/semphr.h"
23#include "nvs.h"
24
25#include <cstddef>
26#include <cstdint>
27#include <cstdio>
28#include <cstdlib>
29#include <memory>
30
31namespace cdc::core {
32
35 void operator()(void* p) const noexcept
36 {
37 if (p) heap_caps_free(p);
38 }
39};
40
43template <typename T>
44using PsramUniquePtr = std::unique_ptr<T[], CapsFreeDeleter>;
45
50template <typename T>
51PsramUniquePtr<T> psramAlloc(std::size_t count) noexcept
52{
53 auto* raw = static_cast<T*>(
54 heap_caps_malloc(count * sizeof(T), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
55 return PsramUniquePtr<T>{raw};
56}
57
60 void operator()(void* p) const noexcept
61 {
62 if (p) std::free(p);
63 }
64};
65
67template <typename T>
68using CStdUniquePtr = std::unique_ptr<T, CStdFreeDeleter>;
69
72 void operator()(std::FILE* fp) const noexcept
73 {
74 if (fp) std::fclose(fp);
75 }
76};
77
79using FilePtr = std::unique_ptr<std::FILE, FileCloseDeleter>;
80
87inline FilePtr openFile(const char* path, const char* mode) noexcept
88{
89 return FilePtr{std::fopen(path, mode)};
90}
91
106class NvsScope {
107public:
109 NvsScope() noexcept = default;
110
112 NvsScope(const char* ns, nvs_open_mode_t mode) noexcept
113 {
114 status_ = nvs_open(ns, mode, &handle_);
115 if (status_ != ESP_OK) handle_ = 0;
116 }
117
118 ~NvsScope() noexcept
119 {
120 if (handle_) nvs_close(handle_);
121 }
122
123 NvsScope(const NvsScope&) = delete;
124 NvsScope& operator=(const NvsScope&) = delete;
125
126 NvsScope(NvsScope&& other) noexcept : handle_(other.handle_), status_(other.status_)
127 {
128 other.handle_ = 0;
129 other.status_ = ESP_FAIL;
130 }
131 NvsScope& operator=(NvsScope&& other) noexcept
132 {
133 if (this != &other) {
134 if (handle_) nvs_close(handle_);
135 handle_ = other.handle_;
136 status_ = other.status_;
137 other.handle_ = 0;
138 other.status_ = ESP_FAIL;
139 }
140 return *this;
141 }
142
144 explicit operator bool() const noexcept { return status_ == ESP_OK; }
145
147 operator nvs_handle_t() const noexcept { return handle_; }
148
150 esp_err_t status() const noexcept { return status_; }
151
153 esp_err_t commit() noexcept
154 {
155 return handle_ ? nvs_commit(handle_) : ESP_FAIL;
156 }
157
159 void close() noexcept
160 {
161 if (handle_) {
162 nvs_close(handle_);
163 handle_ = 0;
164 }
165 status_ = ESP_FAIL;
166 }
167
168private:
169 nvs_handle_t handle_ = 0;
170 esp_err_t status_ = ESP_FAIL;
171};
172
182public:
184 explicit MutexGuard(SemaphoreHandle_t sem) noexcept : sem_(sem)
185 {
186 if (sem_) xSemaphoreTake(sem_, portMAX_DELAY);
187 }
188
189 ~MutexGuard() noexcept
190 {
191 if (sem_ && locked_) xSemaphoreGive(sem_);
192 }
193
194 MutexGuard(const MutexGuard&) = delete;
195 MutexGuard& operator=(const MutexGuard&) = delete;
196
197 MutexGuard(MutexGuard&& other) noexcept
198 : sem_(other.sem_), locked_(other.locked_)
199 {
200 other.sem_ = nullptr;
201 other.locked_ = false;
202 }
203
205 bool locked() const noexcept { return locked_; }
206
208 void release() noexcept
209 {
210 if (sem_ && locked_) {
211 xSemaphoreGive(sem_);
212 locked_ = false;
213 }
214 }
215
218 static MutexGuard tryLock(SemaphoreHandle_t sem, TickType_t ticks) noexcept
219 {
220 MutexGuard g{};
221 g.sem_ = sem;
222 if (sem && xSemaphoreTake(sem, ticks) == pdTRUE) {
223 g.locked_ = true;
224 }
225 return g;
226 }
227
228private:
229 MutexGuard() noexcept : sem_(nullptr), locked_(false) {}
230
231 SemaphoreHandle_t sem_ = nullptr;
232 bool locked_ = true;
233};
234
246public:
248 explicit RecursiveMutexGuard(SemaphoreHandle_t sem) noexcept : sem_(sem)
249 {
250 if (sem_) xSemaphoreTakeRecursive(sem_, portMAX_DELAY);
251 }
252
254 {
255 if (sem_) xSemaphoreGiveRecursive(sem_);
256 }
257
260
261private:
262 SemaphoreHandle_t sem_ = nullptr;
263};
264
265} // namespace cdc::core
bool locked() const noexcept
True if the semaphore is currently held.
Definition Raii.h:205
MutexGuard(MutexGuard &&other) noexcept
Definition Raii.h:197
MutexGuard(const MutexGuard &)=delete
void release() noexcept
Release the semaphore before destruction. Idempotent.
Definition Raii.h:208
~MutexGuard() noexcept
Definition Raii.h:189
MutexGuard(SemaphoreHandle_t sem) noexcept
Take sem blocking until acquired.
Definition Raii.h:184
static MutexGuard tryLock(SemaphoreHandle_t sem, TickType_t ticks) noexcept
Definition Raii.h:218
MutexGuard & operator=(const MutexGuard &)=delete
void close() noexcept
Manually close before destruction. Idempotent.
Definition Raii.h:159
NvsScope() noexcept=default
Construct an empty, closed scope. Status reports ESP_FAIL until opened.
NvsScope & operator=(NvsScope &&other) noexcept
Definition Raii.h:131
NvsScope(const NvsScope &)=delete
esp_err_t commit() noexcept
Commit pending writes. Caller checks the return value if needed.
Definition Raii.h:153
~NvsScope() noexcept
Definition Raii.h:118
esp_err_t status() const noexcept
esp_err_t result of the original nvs_open call.
Definition Raii.h:150
NvsScope(NvsScope &&other) noexcept
Definition Raii.h:126
NvsScope & operator=(const NvsScope &)=delete
RecursiveMutexGuard(const RecursiveMutexGuard &)=delete
~RecursiveMutexGuard() noexcept
Definition Raii.h:253
RecursiveMutexGuard(SemaphoreHandle_t sem) noexcept
Take sem blocking until acquired; no-op when sem is nullptr.
Definition Raii.h:248
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).
Definition Raii.h:68
std::unique_ptr< T[], CapsFreeDeleter > PsramUniquePtr
Definition Raii.h:44
FilePtr openFile(const char *path, const char *mode) noexcept
Open a FILE* and wrap it in a FilePtr.
Definition Raii.h:87
std::unique_ptr< std::FILE, FileCloseDeleter > FilePtr
unique_ptr for FILE* handles. Destructor calls std::fclose.
Definition Raii.h:79
PsramUniquePtr< T > psramAlloc(std::size_t count) noexcept
Allocate count elements of T in PSRAM (8-bit capable region).
Definition Raii.h:51
Deleter for buffers allocated via malloc/realloc.
Definition Raii.h:59
void operator()(void *p) const noexcept
Definition Raii.h:60
Deleter for buffers allocated via heap_caps_malloc.
Definition Raii.h:34
void operator()(void *p) const noexcept
Definition Raii.h:35
Deleter for FILE* opened with std::fopen.
Definition Raii.h:71
void operator()(std::FILE *fp) const noexcept
Definition Raii.h:72