mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 19:03:16 +00:00
129 lines
3.2 KiB
C++
129 lines
3.2 KiB
C++
#include "Semaphore.h"
|
|
#include "Check.h"
|
|
#include "CoreDefines.h"
|
|
|
|
#ifdef ESP_PLATFORM
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/semphr.h"
|
|
#else
|
|
#include "FreeRTOS.h"
|
|
#include "semphr.h"
|
|
#endif
|
|
|
|
namespace tt {
|
|
|
|
Semaphore* tt_semaphore_alloc(uint32_t max_count, uint32_t initial_count) {
|
|
tt_assert(!TT_IS_IRQ_MODE());
|
|
tt_assert((max_count > 0U) && (initial_count <= max_count));
|
|
|
|
SemaphoreHandle_t hSemaphore = nullptr;
|
|
if (max_count == 1U) {
|
|
hSemaphore = xSemaphoreCreateBinary();
|
|
if ((hSemaphore != nullptr) && (initial_count != 0U)) {
|
|
if (xSemaphoreGive(hSemaphore) != pdPASS) {
|
|
vSemaphoreDelete(hSemaphore);
|
|
hSemaphore = nullptr;
|
|
}
|
|
}
|
|
} else {
|
|
hSemaphore = xSemaphoreCreateCounting(max_count, initial_count);
|
|
}
|
|
|
|
tt_check(hSemaphore);
|
|
|
|
return (Semaphore*)hSemaphore;
|
|
}
|
|
|
|
void tt_semaphore_free(Semaphore* instance) {
|
|
tt_assert(instance);
|
|
tt_assert(!TT_IS_IRQ_MODE());
|
|
|
|
SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
|
|
|
|
vSemaphoreDelete(hSemaphore);
|
|
}
|
|
|
|
TtStatus tt_semaphore_acquire(Semaphore* instance, uint32_t timeout) {
|
|
tt_assert(instance);
|
|
|
|
SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
|
|
TtStatus status;
|
|
BaseType_t yield;
|
|
|
|
status = TtStatusOk;
|
|
|
|
if (TT_IS_IRQ_MODE()) {
|
|
if (timeout != 0U) {
|
|
status = TtStatusErrorParameter;
|
|
} else {
|
|
yield = pdFALSE;
|
|
|
|
if (xSemaphoreTakeFromISR(hSemaphore, &yield) != pdPASS) {
|
|
status = TtStatusErrorResource;
|
|
} else {
|
|
portYIELD_FROM_ISR(yield);
|
|
}
|
|
}
|
|
} else {
|
|
if (xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) {
|
|
if (timeout != 0U) {
|
|
status = TtStatusErrorTimeout;
|
|
} else {
|
|
status = TtStatusErrorResource;
|
|
}
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
TtStatus tt_semaphore_release(Semaphore* instance) {
|
|
tt_assert(instance);
|
|
|
|
SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
|
|
TtStatus stat;
|
|
BaseType_t yield;
|
|
|
|
stat = TtStatusOk;
|
|
|
|
if (TT_IS_IRQ_MODE()) {
|
|
yield = pdFALSE;
|
|
|
|
if (xSemaphoreGiveFromISR(hSemaphore, &yield) != pdTRUE) {
|
|
stat = TtStatusErrorResource;
|
|
} else {
|
|
portYIELD_FROM_ISR(yield);
|
|
}
|
|
} else {
|
|
if (xSemaphoreGive(hSemaphore) != pdPASS) {
|
|
stat = TtStatusErrorResource;
|
|
}
|
|
}
|
|
|
|
/* Return execution status */
|
|
return (stat);
|
|
}
|
|
|
|
uint32_t tt_semaphore_get_count(Semaphore* instance) {
|
|
tt_assert(instance);
|
|
|
|
SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance;
|
|
uint32_t count;
|
|
|
|
if (TT_IS_IRQ_MODE()) {
|
|
// TODO: uxSemaphoreGetCountFromISR is not supported on esp-idf 5.1.2 - perhaps later on?
|
|
#ifdef uxSemaphoreGetCountFromISR
|
|
count = (uint32_t)uxSemaphoreGetCountFromISR(hSemaphore);
|
|
#else
|
|
count = (uint32_t)uxQueueMessagesWaitingFromISR((QueueHandle_t)hSemaphore);
|
|
#endif
|
|
} else {
|
|
count = (uint32_t)uxSemaphoreGetCount(hSemaphore);
|
|
}
|
|
|
|
/* Return number of tokens */
|
|
return (count);
|
|
}
|
|
|
|
} // namespace
|