mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 19:03:16 +00:00
Added Dispatcher and fix sim (#54)
- Add dispatcher mechanism (a queue for function calls) and tests - Added tests for MessageQueue - Fix FreeRTOS config for simulator - Explicit dependencies for touch-related libs, because minor version changes caused broken builds on CI.
This commit is contained in:
parent
69a0c01686
commit
b659d5b940
@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
espressif/esp_lcd_ili9341: "^2.0.0"
|
||||
espressif/esp_lcd_touch_cst816s: "^1.0.3"
|
||||
espressif/esp_lcd_touch_gt911: "^1.0.0"
|
||||
espressif/esp_lcd_touch: "1.1.1"
|
||||
espressif/esp_lcd_ili9341: "2.0.0"
|
||||
espressif/esp_lcd_touch_cst816s: "1.0.3"
|
||||
espressif/esp_lcd_touch_gt911: "1.1.1"
|
||||
espressif/esp_lcd_touch: "1.1.2"
|
||||
idf: '~5.2'
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
extern void vAssertCalled(unsigned long line, const char* const file);
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
@ -8,7 +10,6 @@
|
||||
#define configMINIMAL_STACK_SIZE 128
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_16_BITS
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 2 // Must be the same as ESP32!
|
||||
@ -27,16 +28,13 @@
|
||||
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
#define configHEAP_CLEAR_MEMORY_ON_FREE 1
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#define configSTATS_BUFFER_MAX_LENGTH 0xFFFF
|
||||
|
||||
/* Memory allocation related definitions. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configKERNEL_PROVIDED_STATIC_MEMORY 1
|
||||
#define configTOTAL_HEAP_SIZE (1024 * 1024)
|
||||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 // TODO: Compare with ESP defaults
|
||||
#define configENABLE_HEAP_PROTECTOR 1
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
@ -61,29 +59,11 @@
|
||||
#define configTIMER_QUEUE_LENGTH 10
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
/* Interrupt nesting behaviour configuration. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 1
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
|
||||
#define configMAX_API_CALL_INTERRUPT_PRIORITY 10
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
#define configASSERT(x) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
|
||||
#define configASSERT(x) if( ( x ) == 0 ) vAssertCalled(__LINE__, __FILE__)
|
||||
|
||||
/* FreeRTOS MPU specific definitions. */
|
||||
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
|
||||
#define configTOTAL_MPU_REGIONS 8 /* Default value. */
|
||||
#define configTEX_S_C_B_FLASH 0x07UL /* Default value. */
|
||||
#define configTEX_S_C_B_SRAM 0x07UL /* Default value. */
|
||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1
|
||||
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1
|
||||
#define configENABLE_ERRATA_837070_WORKAROUND 1
|
||||
#define configUSE_MPU_WRAPPERS_V1 0
|
||||
#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 10
|
||||
#define configSYSTEM_CALL_STACK_SIZE 128
|
||||
#define configENABLE_ACCESS_CONTROL_LIST 1
|
||||
|
||||
/* ARMv8-M secure side port related definitions. */
|
||||
#define secureconfigMAX_SECURE_CONTEXTS 5
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
/* Ensure these are closely match ESP32: you can activate more features, but not less. */
|
||||
@ -91,7 +71,6 @@
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_xResumeFromISR 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
@ -100,7 +79,6 @@
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark2 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
|
||||
48
tactility-core/src/dispatcher.c
Normal file
48
tactility-core/src/dispatcher.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "dispatcher.h"
|
||||
|
||||
#include "tactility_core.h"
|
||||
|
||||
Dispatcher* tt_dispatcher_alloc(uint32_t message_count) {
|
||||
Dispatcher* dispatcher = malloc(sizeof(Dispatcher));
|
||||
*dispatcher = (Dispatcher) {
|
||||
.queue = tt_message_queue_alloc(message_count, sizeof(DispatcherMessage)),
|
||||
.mutex = tt_mutex_alloc(MutexTypeNormal),
|
||||
.buffer = {
|
||||
.callback = NULL,
|
||||
.context = NULL
|
||||
}
|
||||
};
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
void tt_dispatcher_free(Dispatcher* dispatcher) {
|
||||
tt_mutex_acquire(dispatcher->mutex, TtWaitForever);
|
||||
tt_message_queue_reset(dispatcher->queue);
|
||||
tt_message_queue_free(dispatcher->queue);
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
tt_mutex_free(dispatcher->mutex);
|
||||
free(dispatcher);
|
||||
}
|
||||
|
||||
void tt_dispatcher_dispatch(Dispatcher* dispatcher, Callback callback, void* context) {
|
||||
DispatcherMessage message = {
|
||||
.callback = callback,
|
||||
.context = context
|
||||
};
|
||||
tt_mutex_acquire(dispatcher->mutex, TtWaitForever);
|
||||
tt_message_queue_put(dispatcher->queue, &message, TtWaitForever);
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
}
|
||||
|
||||
bool tt_dispatcher_consume(Dispatcher* dispatcher, uint32_t timeout_ticks) {
|
||||
tt_mutex_acquire(dispatcher->mutex, TtWaitForever);
|
||||
if (tt_message_queue_get(dispatcher->queue, &(dispatcher->buffer), timeout_ticks) == TtStatusOk) {
|
||||
DispatcherMessage* message = &(dispatcher->buffer);
|
||||
message->callback(message->context);
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
return true;
|
||||
} else {
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
36
tactility-core/src/dispatcher.h
Normal file
36
tactility-core/src/dispatcher.h
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file message_queue.h
|
||||
*
|
||||
* Dispatcher is a thread-safe message queue implementation for callbacks.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "message_queue.h"
|
||||
#include "mutex.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*Callback)(void* data);
|
||||
|
||||
typedef struct {
|
||||
Callback callback;
|
||||
void* context;
|
||||
} DispatcherMessage;
|
||||
|
||||
typedef struct {
|
||||
MessageQueue* queue;
|
||||
Mutex* mutex;
|
||||
DispatcherMessage buffer; // Buffer for consuming a message
|
||||
} Dispatcher;
|
||||
|
||||
Dispatcher* tt_dispatcher_alloc(uint32_t message_count);
|
||||
void tt_dispatcher_free(Dispatcher* dispatcher);
|
||||
void tt_dispatcher_dispatch(Dispatcher* dispatcher, Callback callback, void* context);
|
||||
bool tt_dispatcher_consume(Dispatcher* dispatcher, uint32_t timeout_ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -1,6 +1,9 @@
|
||||
/**
|
||||
* @file message_queue.h
|
||||
* MessageQueue
|
||||
*
|
||||
* MessageQueue is a wrapper for FreeRTOS xQueue functionality.
|
||||
* There is no additional thread-safety on top of the xQueue functionality,
|
||||
* so make sure you create a lock if needed.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ static void register_user_apps(const AppManifest* const apps[TT_CONFIG_APPS_LIMI
|
||||
|
||||
static void register_and_start_system_services() {
|
||||
TT_LOG_I(TAG, "Registering and starting system services");
|
||||
int app_count = sizeof(system_services) / sizeof(ServiceManifest *);
|
||||
int app_count = sizeof(system_services) / sizeof(ServiceManifest*);
|
||||
for (int i = 0; i < app_count; ++i) {
|
||||
tt_service_registry_add(system_services[i]);
|
||||
tt_check(tt_service_registry_start(system_services[i]->id));
|
||||
|
||||
38
tests/tactility-core/dispatcher_test.cpp
Normal file
38
tests/tactility-core/dispatcher_test.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "doctest.h"
|
||||
#include "tactility_core.h"
|
||||
#include "dispatcher.h"
|
||||
|
||||
void increment_callback(void* context) {
|
||||
auto* counter = (uint32_t*)context;
|
||||
(*counter)++;
|
||||
}
|
||||
|
||||
TEST_CASE("dispatcher should not call callback if consume isn't called") {
|
||||
Dispatcher* dispatcher = tt_dispatcher_alloc(10);
|
||||
|
||||
uint32_t counter = 0;
|
||||
tt_dispatcher_dispatch(dispatcher, &increment_callback, &counter);
|
||||
tt_delay_tick(10);
|
||||
CHECK_EQ(counter, 0);
|
||||
|
||||
tt_dispatcher_free(dispatcher);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("dispatcher should be able to dealloc when message is not consumed") {
|
||||
Dispatcher* dispatcher = tt_dispatcher_alloc(10);
|
||||
uint32_t counter = 0;
|
||||
tt_dispatcher_dispatch(dispatcher, increment_callback, &counter);
|
||||
tt_dispatcher_free(dispatcher);
|
||||
}
|
||||
|
||||
TEST_CASE("dispatcher should call callback when consume is called") {
|
||||
Dispatcher* dispatcher = tt_dispatcher_alloc(10);
|
||||
|
||||
uint32_t counter = 0;
|
||||
tt_dispatcher_dispatch(dispatcher, increment_callback, &counter);
|
||||
tt_dispatcher_consume(dispatcher, 100);
|
||||
CHECK_EQ(counter, 1);
|
||||
|
||||
tt_dispatcher_free(dispatcher);
|
||||
}
|
||||
81
tests/tactility-core/message_queue_test.cpp
Normal file
81
tests/tactility-core/message_queue_test.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "doctest.h"
|
||||
#include "message_queue.h"
|
||||
|
||||
TEST_CASE("message queue capacity should be correct") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(10, 1);
|
||||
|
||||
uint32_t capacity = tt_message_queue_get_capacity(queue);
|
||||
CHECK_EQ(capacity, 10);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue initial count should be 0") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(10, 1);
|
||||
|
||||
uint32_t count = tt_message_queue_get_count(queue);
|
||||
CHECK_EQ(count, 0);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue size should be correct") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(1, 123);
|
||||
|
||||
uint32_t size = tt_message_queue_get_message_size(queue);
|
||||
CHECK_EQ(size, 123);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue count should increase when message is added") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(10, sizeof(uint32_t));
|
||||
|
||||
uint32_t message = 123;
|
||||
|
||||
tt_message_queue_put(queue, &message, 100);
|
||||
uint32_t count = tt_message_queue_get_count(queue);
|
||||
CHECK_EQ(count, 1);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue count should be 0 when message is added and queue is reset") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(10, sizeof(uint32_t));
|
||||
|
||||
uint32_t message = 123;
|
||||
|
||||
tt_message_queue_put(queue, &message, 100);
|
||||
tt_message_queue_reset(queue);
|
||||
uint32_t count = tt_message_queue_get_count(queue);
|
||||
CHECK_EQ(count, 0);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue consumption should work") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(10, sizeof(uint32_t));
|
||||
|
||||
uint32_t out_message = 123;
|
||||
tt_message_queue_put(queue, &out_message, 100);
|
||||
|
||||
uint32_t in_message = 0;
|
||||
tt_message_queue_get(queue, &in_message, 100);
|
||||
CHECK_EQ(in_message, 123);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
|
||||
TEST_CASE("message queue count should decrease when message is consumed") {
|
||||
MessageQueue* queue = tt_message_queue_alloc(10, sizeof(uint32_t));
|
||||
|
||||
uint32_t out_message = 123;
|
||||
tt_message_queue_put(queue, &out_message, 100);
|
||||
|
||||
uint32_t in_message = 0;
|
||||
tt_message_queue_get(queue, &in_message, 100);
|
||||
uint32_t count = tt_message_queue_get_count(queue);
|
||||
CHECK_EQ(count, 0);
|
||||
|
||||
tt_message_queue_free(queue);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user