Implement LVGL with SDL for simulator (#16)

* Implemented LVGL with SDL for simulator

* cleanup

* added SDL to build

* build fix

* mutex fixes

* sim app cleanup and improvements

* docs updated

* fix for sdl?

* fix for SDL cmake setup
This commit is contained in:
Ken Van Hoeylandt
2024-01-21 22:27:00 +01:00
committed by GitHub
parent 18a5c5aa45
commit d6baf40d0b
118 changed files with 15327 additions and 1181 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <tactility_core_config.h>
#include "tactility_core_config.h"
#ifdef __cplusplus
extern "C" {
+90 -85
View File
@@ -12,122 +12,127 @@
#include "semphr.h"
#endif
typedef struct {
SemaphoreHandle_t handle;
MutexType type;
} MutexData;
Mutex* tt_mutex_alloc(MutexType type) {
tt_assert(!TT_IS_IRQ_MODE());
#define MUTEX_DEBUGGING false
SemaphoreHandle_t hMutex = NULL;
if (type == MutexTypeNormal) {
hMutex = xSemaphoreCreateMutex();
} else if (type == MutexTypeRecursive) {
hMutex = xSemaphoreCreateRecursiveMutex();
#if MUTEX_DEBUGGING
#define TAG "mutex"
void tt_mutex_info(Mutex mutex, const char* label) {
MutexData* data = (MutexData*)mutex;
if (data == NULL) {
TT_LOG_I(TAG, "mutex %s: is NULL", label);
} else {
tt_crash("Programming error");
TT_LOG_I(TAG, "mutex %s: handle=%0X type=%d owner=%0x", label, data->handle, data->type, tt_mutex_get_owner(mutex));
}
}
#else
#define tt_mutex_info(mutex, text)
#endif
Mutex tt_mutex_alloc(MutexType type) {
tt_assert(!TT_IS_IRQ_MODE());
MutexData* data = malloc(sizeof(MutexData));
data->type = type;
switch (type) {
case MutexTypeNormal:
data->handle = xSemaphoreCreateMutex();
break;
case MutexTypeRecursive:
data->handle = xSemaphoreCreateRecursiveMutex();
break;
default:
tt_crash("mutex type unknown/corrupted");
}
tt_check(hMutex != NULL);
if (type == MutexTypeRecursive) {
/* Set LSB as 'recursive mutex flag' */
hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U);
}
/* Return mutex ID */
return ((Mutex*)hMutex);
tt_check(data->handle != NULL);
tt_mutex_info(data, "alloc ");
return (Mutex)data;
}
void tt_mutex_free(Mutex* instance) {
void tt_mutex_free(Mutex mutex) {
tt_assert(!TT_IS_IRQ_MODE());
tt_assert(instance);
tt_assert(mutex);
vSemaphoreDelete((SemaphoreHandle_t)((uint32_t)instance & ~1U));
MutexData* data = (MutexData*)mutex;
vSemaphoreDelete(data->handle);
data->handle = NULL; // If the mutex is used after release, this might help debugging
data->type = 0xBAADF00D; // Set to an invalid value
free(data);
}
TtStatus tt_mutex_acquire(Mutex* instance, uint32_t timeout) {
SemaphoreHandle_t hMutex;
TtStatus stat;
uint32_t rmtx;
TtStatus tt_mutex_acquire(Mutex mutex, uint32_t timeout) {
tt_assert(mutex);
tt_assert(!TT_IS_IRQ_MODE());
MutexData* data = (MutexData*)mutex;
tt_assert(data->handle);
TtStatus status = TtStatusOk;
hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U);
tt_mutex_info(mutex, "acquire");
/* Extract recursive mutex flag */
rmtx = (uint32_t)instance & 1U;
stat = TtStatusOk;
if (TT_IS_IRQ_MODE()) {
stat = TtStatusErrorISR;
} else if (hMutex == NULL) {
stat = TtStatusErrorParameter;
} else {
if (rmtx != 0U) {
if (xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) {
switch (data->type) {
case MutexTypeNormal:
if (xSemaphoreTake(data->handle, timeout) != pdPASS) {
if (timeout != 0U) {
stat = TtStatusErrorTimeout;
status = TtStatusErrorTimeout;
} else {
stat = TtStatusErrorResource;
status = TtStatusErrorResource;
}
}
} else {
if (xSemaphoreTake(hMutex, timeout) != pdPASS) {
break;
case MutexTypeRecursive:
if (xSemaphoreTakeRecursive(data->handle, timeout) != pdPASS) {
if (timeout != 0U) {
stat = TtStatusErrorTimeout;
status = TtStatusErrorTimeout;
} else {
stat = TtStatusErrorResource;
status = TtStatusErrorResource;
}
}
}
break;
default:
tt_crash("mutex type unknown/corrupted");
}
/* Return execution status */
return (stat);
return status;
}
TtStatus tt_mutex_release(Mutex* instance) {
SemaphoreHandle_t hMutex;
TtStatus stat;
uint32_t rmtx;
TtStatus tt_mutex_release(Mutex mutex) {
tt_assert(mutex);
assert(!TT_IS_IRQ_MODE());
MutexData* data = (MutexData*)mutex;
tt_assert(data->handle);
TtStatus status = TtStatusOk;
hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U);
tt_mutex_info(mutex, "release");
/* Extract recursive mutex flag */
rmtx = (uint32_t)instance & 1U;
stat = TtStatusOk;
if (TT_IS_IRQ_MODE()) {
stat = TtStatusErrorISR;
} else if (hMutex == NULL) {
stat = TtStatusErrorParameter;
} else {
if (rmtx != 0U) {
if (xSemaphoreGiveRecursive(hMutex) != pdPASS) {
stat = TtStatusErrorResource;
}
} else {
if (xSemaphoreGive(hMutex) != pdPASS) {
stat = TtStatusErrorResource;
switch (data->type) {
case MutexTypeNormal: {
if (xSemaphoreGive(data->handle) != pdPASS) {
status = TtStatusErrorResource;
}
break;
}
case MutexTypeRecursive:
if (xSemaphoreGiveRecursive(data->handle) != pdPASS) {
status = TtStatusErrorResource;
}
break;
default:
tt_crash("mutex type unknown/corrupted %d");
}
/* Return execution status */
return (stat);
return status;
}
ThreadId tt_mutex_get_owner(Mutex* instance) {
SemaphoreHandle_t hMutex;
ThreadId owner;
hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U);
if ((TT_IS_IRQ_MODE()) || (hMutex == NULL)) {
owner = 0;
} else {
owner = (ThreadId)xSemaphoreGetMutexHolder(hMutex);
}
/* Return owner thread ID */
return (owner);
ThreadId tt_mutex_get_owner(Mutex mutex) {
tt_assert(mutex != NULL);
tt_assert(!TT_IS_IRQ_MODE());
MutexData* data = (MutexData*)mutex;
tt_assert(data->handle);
return (ThreadId)xSemaphoreGetMutexHolder(data->handle);
}
+10 -10
View File
@@ -16,7 +16,7 @@ typedef enum {
MutexTypeRecursive,
} MutexType;
typedef void Mutex;
typedef void* Mutex;
/** Allocate Mutex
*
@@ -24,38 +24,38 @@ typedef void Mutex;
*
* @return pointer to Mutex instance
*/
Mutex* tt_mutex_alloc(MutexType type);
Mutex tt_mutex_alloc(MutexType type);
/** Free Mutex
*
* @param instance The pointer to Mutex instance
* @param mutex The Mutex instance
*/
void tt_mutex_free(Mutex* instance);
void tt_mutex_free(Mutex mutex);
/** Acquire mutex
*
* @param instance The pointer to Mutex instance
* @param mutex The Mutex instance
* @param[in] timeout The timeout
*
* @return The status.
*/
TtStatus tt_mutex_acquire(Mutex* instance, uint32_t timeout);
TtStatus tt_mutex_acquire(Mutex mutex, uint32_t timeout);
/** Release mutex
*
* @param instance The pointer to Mutex instance
* @param mutex The Mutex instance
*
* @return The status.
*/
TtStatus tt_mutex_release(Mutex* instance);
TtStatus tt_mutex_release(Mutex mutex);
/** Get mutex owner thread id
*
* @param instance The pointer to Mutex instance
* @param mutex The Mutex instance
*
* @return The thread identifier.
*/
ThreadId tt_mutex_get_owner(Mutex* instance);
ThreadId tt_mutex_get_owner(Mutex mutex);
#ifdef __cplusplus
}
+1 -1
View File
@@ -19,7 +19,7 @@ struct PubSub {
PubSub* tt_pubsub_alloc() {
PubSub* pubsub = malloc(sizeof(PubSub));
pubsub->mutex = tt_mutex_alloc(MutexTypeRecursive);
pubsub->mutex = tt_mutex_alloc(MutexTypeNormal);
tt_assert(pubsub->mutex);
PubSubSubscriptionList_init(pubsub->items);
+1
View File
@@ -9,4 +9,5 @@
#include "core_types.h"
#include "critical.h"
#include "event_flag.h"
#include "kernel.h"
#include "log.h"
+1 -1
View File
@@ -1,3 +1,3 @@
#pragma once
#define TT_CONFIG_THREAD_MAX_PRIORITIES (32)
#define TT_CONFIG_THREAD_MAX_PRIORITIES 10
+5 -5
View File
@@ -21,11 +21,11 @@ typedef enum {
typedef enum {
ThreadPriorityNone = 0, /**< Uninitialized, choose system default */
ThreadPriorityIdle = 1, /**< Idle priority */
ThreadPriorityLowest = 14, /**< Lowest */
ThreadPriorityLow = 15, /**< Low */
ThreadPriorityNormal = 16, /**< Normal */
ThreadPriorityHigh = 17, /**< High */
ThreadPriorityHighest = 18, /**< Highest */
ThreadPriorityLowest = 2, /**< Lowest */
ThreadPriorityLow = 3, /**< Low */
ThreadPriorityNormal = 4, /**< Normal */
ThreadPriorityHigh = 5, /**< High */
ThreadPriorityHighest = 6, /**< Highest */
ThreadPriorityIsr =
(TT_CONFIG_THREAD_MAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */
} ThreadPriority;