Files
Leo-ElixirLights/components/freeRtosApi/include/Mutex.hpp
T

88 lines
2.2 KiB
C++

/**
* @file mutex.hpp
* @author Gustice
* @brief Mutex Wrapper
*
* @copyright Copyright (c) 2024
*/
#pragma once
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
namespace fos {
/**
* @brief Mutex
* @details FreeRTOS implementation uses already priority inheritance
* and are recursively callable
*/
class Mutex {
private:
QueueHandle_t _handle;
public:
/// @brief Tick type (redefinition for convenience)
using Tick = TickType_t;
/// @brief Definition for endless waittime
static constexpr Tick MaxDelay = portMAX_DELAY;
/// @brief Constructor
Mutex() {
_handle = xSemaphoreCreateMutex();
assert(_handle != 0 && "Semaphore create must finish successfully");
}
~Mutex() {
vSemaphoreDelete(_handle);
};
/// @brief Relase mutex
void release() {
auto ret = xSemaphoreGive(_handle);
assert(ret == pdPASS && "Underlying semaphore queue must be initialized correcty");
}
/// @brief Take mutex
/// @param timeout Timeout to wait for signal (default = wait forever)
/// @return true if successfully claimed (not timeout)
bool claim(Tick timeout = MaxDelay) {
auto ret = xSemaphoreTake(_handle, timeout);
return ret == pdPASS;
}
};
/**
* @brief Mutex Guard. Self releasing mutex for atomic operation
*/
class MutexGuard {
private:
Mutex &_mutex;
bool _claimed;
public:
/// @brief Constructor
/// @param mtx Mutex to claim
/// @param timeout Timeout to wait for signal (default = wait forever)
MutexGuard(Mutex &mtx, Mutex::Tick timeout = Mutex::MaxDelay) : _mutex(mtx) {
_claimed = _mutex.claim(timeout);
};
~MutexGuard() {
if (!_claimed) {
return;
}
_mutex.release();
}
/// @brief Check if mutex was claimed successfully
/// @return true if claimed
bool isActive() {
return _claimed;
}
};
} // namespace fos