Ken Van Hoeylandt 96eccbdc8d
Add tests and update licenses (#458)
Replace LGPL from past commit with Apache License 2.0 for the newly created projects:
- in Platforms/*
- TactilityKernel

Add license headers to source code in:
- in Platforms/*
- TactilityKernel
- TactilityFreeRtos

Updated LICENSE.md
2026-01-24 21:33:44 +01:00

167 lines
5.1 KiB
C++

// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "freertoscompat/EventGroups.h"
#include "freertoscompat/PortCompat.h"
#include "kernel/Kernel.h"
#include <cassert>
#include <memory>
namespace tt {
/** Wrapper for FreeRTOS xEventGroup and related code */
class EventGroup final {
struct EventGroupHandleDeleter {
static void operator()(EventGroupHandle_t handleToDelete) {
vEventGroupDelete(handleToDelete);
}
};
std::unique_ptr<std::remove_pointer_t<EventGroupHandle_t>, EventGroupHandleDeleter> handle = std::unique_ptr<std::remove_pointer_t<EventGroupHandle_t>, EventGroupHandleDeleter>(xEventGroupCreate());
public:
EventGroup() {
assert(xPortInIsrContext() == pdFALSE);
assert(handle != nullptr);
}
~EventGroup() {
assert(xPortInIsrContext() == pdFALSE);
}
enum class Error {
Unknown,
Timeout,
Resource,
Parameter,
IsrStatus
};
/**
* Set the flags.
* @param[in] flags the flags to set
* @param[out] outFlags optional resulting flags: this is set when the return value is true
* @param[out] outError optional error output: this is set when the return value is false
* @return true on success
*/
bool set(uint32_t flags, uint32_t* outFlags = nullptr, Error* outError = nullptr) const {
assert(handle);
if (xPortInIsrContext() == pdTRUE) {
uint32_t result;
BaseType_t yield = pdFALSE;
if (xEventGroupSetBitsFromISR(handle.get(), flags, &yield) == pdFAIL) {
if (outError != nullptr) {
*outError = Error::Resource;
}
return false;
} else {
if (outFlags != nullptr) {
*outFlags = flags;
}
portYIELD_FROM_ISR(yield);
return true;
}
} else {
auto result = xEventGroupSetBits(handle.get(), flags);
if (outFlags != nullptr) {
*outFlags = result;
}
return true;
}
}
/**
* Clear flags
* @param[in] flags the flags to clear
* @param[out] outFlags optional resulting flags: this is set when the return value is true
* @param[out] outError optional error output: this is set when the return value is false
* @return true on success
*/
bool clear(uint32_t flags, uint32_t* outFlags = nullptr, Error* outError = nullptr) const {
if (xPortInIsrContext() == pdTRUE) {
uint32_t result = xEventGroupGetBitsFromISR(handle.get());
if (xEventGroupClearBitsFromISR(handle.get(), flags) == pdFAIL) {
if (outError != nullptr) {
*outError = Error::Resource;
}
return false;
}
if (outFlags != nullptr) {
*outFlags = result;
}
portYIELD_FROM_ISR(pdTRUE);
return true;
} else {
auto result = xEventGroupClearBits(handle.get(), flags);
if (outFlags != nullptr) {
*outFlags = result;
}
return true;
}
}
/**
* @return the current flags
*/
uint32_t get() const {
if (xPortInIsrContext() == pdTRUE) {
return xEventGroupGetBitsFromISR(handle.get());
} else {
return xEventGroupGetBits(handle.get());
}
}
/**
* Wait for flags to be set
* @param[in] flags the flags to await
* @param[in] awaitAll If true, await for all bits to be set. Otherwise, await for any.
* @param[in] clearOnExit If true, clears all the bits on exit, otherwise don't clear.
* @param[in] timeout the maximum amount of ticks to wait for flags to be set
* @param[out] outFlags optional resulting flags: this is set when the return value is true
* @param[out] outError optional error output: this is set when the return value is false
*/
bool wait(
uint32_t flags,
bool awaitAll = false,
bool clearOnExit = true,
TickType_t timeout = kernel::MAX_TICKS,
uint32_t* outFlags = nullptr,
Error* outError = nullptr
) const {
assert(xPortInIsrContext() == pdFALSE);
uint32_t result_flags = xEventGroupWaitBits(
handle.get(),
flags,
clearOnExit ? pdTRUE : pdFALSE,
awaitAll ? pdTRUE : pdFALSE,
timeout
);
auto invalid_flags = awaitAll
? ((flags & result_flags) != flags) // await all
: ((flags & result_flags) == 0U); // await any
if (invalid_flags) {
if (outError != nullptr) {
if (timeout > 0U) { // assume time-out
*outError = Error::Timeout;
} else {
*outError = Error::Resource;
}
}
return false;
}
if (outFlags != nullptr) {
*outFlags = result_flags;
}
return true;
}
};
} // namespace