RTOS Wrapper
API reference
Loading...
Searching...
No Matches
RtosMutex.h
Go to the documentation of this file.
1
29#pragma once
30
31#include "OsAbstraction.h"
32#include "OsUtility.h"
33
34#include <atomic>
35#include <cstdint>
36
37/* ═══════════════════════════════════════════════════════════════════════════
38 * RtosTime — high-resolution timing utilities
39 * ═══════════════════════════════════════════════════════════════════════════ */
40
41class RtosTime {
42public:
47 static uint64_t GetCurrentTimeUs() noexcept {
48#if (defined(HF_RTOS_NONE) || defined(HF_MCU_FAMILY_NONE)) && defined(HF_RTOS_NONE_EXTERNAL_CLOCK)
49 return hf_os_none_clock_us();
50#elif defined(HF_RTOS_NONE) || defined(HF_MCU_FAMILY_NONE)
51 return 0;
52#else
53 const uint32_t ticks = static_cast<uint32_t>(os_time_get());
54 return static_cast<uint64_t>(os_convert_delay_ticks_to_msec(ticks)) * 1000ULL;
55#endif
56 }
57
63 static uint32_t MsToTicks(uint32_t ms) noexcept {
64 if (ms == 0) {
65 return 0;
66 }
67 const uint32_t ticks = os_convert_msec_to_delay_ticks(ms);
68 return (ticks > 0) ? ticks : 1;
69 }
70};
71
72/* ═══════════════════════════════════════════════════════════════════════════
73 * RtosMutex — recursive mutex built on OsAbstraction
74 * ═══════════════════════════════════════════════════════════════════════════ */
75
76class RtosMutex {
77public:
78 RtosMutex() noexcept;
79
80 ~RtosMutex() noexcept;
81
82 RtosMutex(const RtosMutex&) = delete;
83 RtosMutex& operator=(const RtosMutex&) = delete;
84
85 RtosMutex(RtosMutex&& other) noexcept;
86
87 RtosMutex& operator=(RtosMutex&& other) noexcept;
88
93 bool lock() noexcept;
94
99 bool try_lock() noexcept;
100
106 bool try_lock_for(uint32_t timeout_ms) noexcept;
107
111 void unlock() noexcept;
112
117 OS_Mutex native_handle() const noexcept {
118 return handle_;
119 }
120
121 // ── Convenience FreeRTOS-style API ──────────────────────────────────────
122
128 bool Take(uint32_t timeout_ms = 0) noexcept {
129 if (timeout_ms > 0) {
130 return try_lock_for(timeout_ms);
131 }
132 return lock();
133 }
134
138 void Give() noexcept {
139 unlock();
140 }
141
142 // ── Shared lock methods (delegated to regular mutex for simplicity) ─────
143
144 bool lock_shared() noexcept { return lock(); }
145 bool try_lock_shared() noexcept { return try_lock(); }
146 bool try_lock_shared_for(uint32_t timeout_ms) noexcept { return try_lock_for(timeout_ms); }
147 void unlock_shared() noexcept { unlock(); }
148
149private:
151};
152
153/* ═══════════════════════════════════════════════════════════════════════════
154 * RtosSharedMutex — reader-writer mutex
155 *
156 * Provides shared (read) and exclusive (write) locking semantics.
157 * Uses two underlying OS mutexes for writer exclusion and reader counting.
158 * ═══════════════════════════════════════════════════════════════════════════ */
159
161public:
162 RtosSharedMutex() noexcept;
163
164 ~RtosSharedMutex() noexcept;
165
168
169 RtosSharedMutex(RtosSharedMutex&& other) noexcept;
170
171 RtosSharedMutex& operator=(RtosSharedMutex&& other) noexcept;
172
173 bool lock() noexcept;
174
175 bool try_lock() noexcept;
176
177 bool try_lock_for(uint32_t timeout_ms) noexcept;
178
179 void unlock() noexcept;
180
181 bool lock_shared() noexcept;
182
183 bool try_lock_shared() noexcept;
184
185 bool try_lock_shared_for(uint32_t timeout_ms) noexcept;
186
187 void unlock_shared() noexcept;
188
189private:
192 std::atomic<int> readers_;
193 std::atomic<bool> writer_active_;
194};
195
196/* ═══════════════════════════════════════════════════════════════════════════
197 * RtosUniqueLock — RAII exclusive lock (similar to std::unique_lock)
198 * ═══════════════════════════════════════════════════════════════════════════ */
199
200template <typename MutexT>
202public:
208 explicit RtosUniqueLock(MutexT& mutex, uint32_t timeout_ms = 0) noexcept
209 : mutex_(&mutex), locked_(false) {
210 if (timeout_ms > 0) {
211 locked_ = mutex_->try_lock_for(timeout_ms);
212 } else {
213 locked_ = mutex_->lock();
214 }
215 }
216
217 ~RtosUniqueLock() noexcept {
218 if (locked_ && mutex_) {
219 mutex_->unlock();
220 }
221 }
222
225
226 RtosUniqueLock(RtosUniqueLock&& other) noexcept : mutex_(other.mutex_), locked_(other.locked_) {
227 other.mutex_ = nullptr;
228 other.locked_ = false;
229 }
230
232 if (this != &other) {
233 if (locked_ && mutex_) {
234 mutex_->unlock();
235 }
236 mutex_ = other.mutex_;
237 locked_ = other.locked_;
238 other.mutex_ = nullptr;
239 other.locked_ = false;
240 }
241 return *this;
242 }
243
245 [[nodiscard]] bool IsLocked() const noexcept {
246 return locked_;
247 }
248
250 void Unlock() noexcept {
251 if (locked_ && mutex_) {
252 mutex_->unlock();
253 locked_ = false;
254 }
255 }
256
257private:
258 MutexT* mutex_;
260};
261
262/* ═══════════════════════════════════════════════════════════════════════════
263 * RtosSharedLock — RAII shared (reader) lock
264 * ═══════════════════════════════════════════════════════════════════════════ */
265
266template <typename SharedMutexT>
268public:
269 explicit RtosSharedLock(SharedMutexT& mutex, uint32_t timeout_ms = 0) noexcept
270 : mutex_(&mutex), locked_(false) {
271 if (timeout_ms > 0) {
272 locked_ = mutex_->try_lock_shared_for(timeout_ms);
273 } else {
274 locked_ = mutex_->lock_shared();
275 }
276 }
277
278 ~RtosSharedLock() noexcept {
279 if (locked_ && mutex_) {
280 mutex_->unlock_shared();
281 }
282 }
283
286
287 RtosSharedLock(RtosSharedLock&& other) noexcept : mutex_(other.mutex_), locked_(other.locked_) {
288 other.mutex_ = nullptr;
289 other.locked_ = false;
290 }
291
293 if (this != &other) {
294 if (locked_ && mutex_) {
295 mutex_->unlock_shared();
296 }
297 mutex_ = other.mutex_;
298 locked_ = other.locked_;
299 other.mutex_ = nullptr;
300 other.locked_ = false;
301 }
302 return *this;
303 }
304
305 [[nodiscard]] bool IsLocked() const noexcept {
306 return locked_;
307 }
308
309 void Unlock() noexcept {
310 if (locked_ && mutex_) {
311 mutex_->unlock_shared();
312 locked_ = false;
313 }
314 }
315
316private:
317 SharedMutexT* mutex_;
319};
320
321/* ═══════════════════════════════════════════════════════════════════════════
322 * Convenience Type Aliases
323 * ═══════════════════════════════════════════════════════════════════════════ */
324
326template <typename MutexT>
328
Generic RTOS abstraction — public header.
C-facing helper functions for delays, cycle counters, and creation of RTOS handles (queues,...
constexpr uint32_t os_convert_msec_to_delay_ticks(uint32_t milliseconds)
Converts milliseconds to delay ticks, rounding down but never to zero.
Definition OsUtility.h:74
constexpr uint32_t os_convert_delay_ticks_to_msec(uint32_t delayTicks)
Converts delay ticks to milliseconds.
Definition OsUtility.h:85
Definition RtosMutex.h:76
bool try_lock() noexcept
Try to lock the mutex without blocking.
Definition RtosMutex.cpp:49
bool Take(uint32_t timeout_ms=0) noexcept
Take (lock) the mutex with optional timeout.
Definition RtosMutex.h:128
void unlock_shared() noexcept
Definition RtosMutex.h:147
RtosMutex(const RtosMutex &)=delete
OS_Mutex handle_
Definition RtosMutex.h:150
RtosMutex() noexcept
Definition RtosMutex.cpp:14
bool lock_shared() noexcept
Definition RtosMutex.h:144
bool try_lock_for(uint32_t timeout_ms) noexcept
Try to lock the mutex with a timeout.
Definition RtosMutex.cpp:53
RtosMutex & operator=(const RtosMutex &)=delete
bool try_lock_shared_for(uint32_t timeout_ms) noexcept
Definition RtosMutex.h:146
~RtosMutex() noexcept
Definition RtosMutex.cpp:19
OS_Mutex native_handle() const noexcept
Get the native RTOS handle (platform-specific).
Definition RtosMutex.h:117
bool try_lock_shared() noexcept
Definition RtosMutex.h:145
void unlock() noexcept
Unlock the mutex.
Definition RtosMutex.cpp:58
bool lock() noexcept
Lock the mutex, blocking indefinitely.
Definition RtosMutex.cpp:45
void Give() noexcept
Give (unlock) the mutex.
Definition RtosMutex.h:138
Definition RtosMutex.h:267
RtosSharedLock & operator=(const RtosSharedLock &)=delete
void Unlock() noexcept
Definition RtosMutex.h:309
RtosSharedLock & operator=(RtosSharedLock &&other) noexcept
Definition RtosMutex.h:292
bool locked_
Definition RtosMutex.h:318
bool IsLocked() const noexcept
Definition RtosMutex.h:305
~RtosSharedLock() noexcept
Definition RtosMutex.h:278
RtosSharedLock(const RtosSharedLock &)=delete
RtosSharedLock(SharedMutexT &mutex, uint32_t timeout_ms=0) noexcept
Definition RtosMutex.h:269
RtosSharedLock(RtosSharedLock &&other) noexcept
Definition RtosMutex.h:287
SharedMutexT * mutex_
Definition RtosMutex.h:317
Definition RtosMutex.h:160
OS_Mutex writer_mutex_
Definition RtosMutex.h:190
bool lock() noexcept
Definition RtosMutex.cpp:108
bool try_lock_for(uint32_t timeout_ms) noexcept
Definition RtosMutex.cpp:132
bool lock_shared() noexcept
Definition RtosMutex.cpp:156
OS_Mutex reader_mutex_
Definition RtosMutex.h:191
bool try_lock() noexcept
Definition RtosMutex.cpp:119
RtosSharedMutex() noexcept
Definition RtosMutex.cpp:64
~RtosSharedMutex() noexcept
Definition RtosMutex.cpp:70
bool try_lock_shared_for(uint32_t timeout_ms) noexcept
Definition RtosMutex.cpp:184
void unlock() noexcept
Definition RtosMutex.cpp:151
void unlock_shared() noexcept
Definition RtosMutex.cpp:210
bool try_lock_shared() noexcept
Definition RtosMutex.cpp:171
std::atomic< int > readers_
Definition RtosMutex.h:192
std::atomic< bool > writer_active_
Definition RtosMutex.h:193
RtosSharedMutex & operator=(const RtosSharedMutex &)=delete
RtosSharedMutex(const RtosSharedMutex &)=delete
Definition RtosMutex.h:41
static uint64_t GetCurrentTimeUs() noexcept
Get current time in microseconds.
Definition RtosMutex.h:47
static uint32_t MsToTicks(uint32_t ms) noexcept
Convert milliseconds to RTOS ticks.
Definition RtosMutex.h:63
Definition RtosMutex.h:201
~RtosUniqueLock() noexcept
Definition RtosMutex.h:217
bool IsLocked() const noexcept
Check if the mutex was successfully locked.
Definition RtosMutex.h:245
RtosUniqueLock(MutexT &mutex, uint32_t timeout_ms=0) noexcept
Construct and lock the mutex.
Definition RtosMutex.h:208
RtosUniqueLock(RtosUniqueLock &&other) noexcept
Definition RtosMutex.h:226
bool locked_
Definition RtosMutex.h:259
void Unlock() noexcept
Manually unlock before destruction.
Definition RtosMutex.h:250
RtosUniqueLock & operator=(const RtosUniqueLock &)=delete
MutexT * mutex_
Definition RtosMutex.h:258
RtosUniqueLock & operator=(RtosUniqueLock &&other) noexcept
Definition RtosMutex.h:231
RtosUniqueLock(const RtosUniqueLock &)=delete
static OS_Ulong os_time_get(void)
Definition os_cmsis.h:59
osMutexId_t OS_Mutex
Definition os_cmsis.h:28