From 3f04d6dd46c9c1267718699d6b6a78aae7b36e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 30 May 2024 12:58:03 +0100 Subject: [PATCH] Furi: wrap message queue in container, prepare it for epoll. Accessor: disable expansion service on start. (#3672) * Furi: wrap message queue in container, prepare it for epoll. Accessor: disable expansion service on start. * Furi: one allocation, smaller message queue struct, type compatibility with FreeRTOS. --- applications/debug/accessor/accessor_app.cpp | 4 +++ applications/debug/accessor/accessor_app.h | 2 ++ applications/system/snake_game/snake_game.c | 10 +++--- furi/core/message_queue.c | 35 ++++++++++++++------ furi/core/message_queue.h | 2 +- 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/applications/debug/accessor/accessor_app.cpp b/applications/debug/accessor/accessor_app.cpp index 2e40b3c35d..8d43acc13b 100644 --- a/applications/debug/accessor/accessor_app.cpp +++ b/applications/debug/accessor/accessor_app.cpp @@ -34,12 +34,16 @@ void AccessorApp::run(void) { AccessorApp::AccessorApp() : text_store{0} { notification = static_cast(furi_record_open(RECORD_NOTIFICATION)); + expansion = static_cast(furi_record_open(RECORD_EXPANSION)); onewire_host = onewire_host_alloc(&gpio_ibutton); + expansion_disable(expansion); furi_hal_power_enable_otg(); } AccessorApp::~AccessorApp() { furi_hal_power_disable_otg(); + expansion_enable(expansion); + furi_record_close(RECORD_EXPANSION); furi_record_close(RECORD_NOTIFICATION); onewire_host_free(onewire_host); } diff --git a/applications/debug/accessor/accessor_app.h b/applications/debug/accessor/accessor_app.h index bfd5c06e15..890552f5f7 100644 --- a/applications/debug/accessor/accessor_app.h +++ b/applications/debug/accessor/accessor_app.h @@ -6,6 +6,7 @@ #include "helpers/wiegand.h" #include #include +#include class AccessorApp { public: @@ -51,4 +52,5 @@ private: OneWireHost* onewire_host; NotificationApp* notification; + Expansion* expansion; }; diff --git a/applications/system/snake_game/snake_game.c b/applications/system/snake_game/snake_game.c index bd7f1ce164..a7765f9452 100644 --- a/applications/system/snake_game/snake_game.c +++ b/applications/system/snake_game/snake_game.c @@ -136,15 +136,17 @@ static void snake_game_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(snake_state->mutex); } -static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void snake_game_input_callback(InputEvent* input_event, void* context) { + furi_assert(context); + FuriMessageQueue* event_queue = context; SnakeEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void snake_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void snake_game_update_timer_callback(void* context) { + furi_assert(context); + FuriMessageQueue* event_queue = context; SnakeEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/furi/core/message_queue.c b/furi/core/message_queue.c index 6e8ab18698..6a4e8c324b 100644 --- a/furi/core/message_queue.c +++ b/furi/core/message_queue.c @@ -5,13 +5,30 @@ #include #include +struct FuriMessageQueue { + // !!! Semi-Opaque type inheritance, Very Fragile, DO NOT MOVE !!! + StaticQueue_t container; + + // !!! Data buffer, must be last in the structure, DO NOT MOVE !!! + uint8_t buffer[]; +}; + FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) { furi_check((furi_kernel_is_irq_or_masked() == 0U) && (msg_count > 0U) && (msg_size > 0U)); - QueueHandle_t handle = xQueueCreate(msg_count, msg_size); - furi_check(handle); + FuriMessageQueue* instance = malloc(sizeof(FuriMessageQueue) + msg_count * msg_size); - return ((FuriMessageQueue*)handle); + // 3 things happens here: + // - create queue + // - check results + // - ensure that queue container is first in the FuriMessageQueue structure + // + // As a bonus it guarantees that FuriMessageQueue* can be casted into StaticQueue_t* or QueueHandle_t. + furi_check( + xQueueCreateStatic(msg_count, msg_size, instance->buffer, &instance->container) == + (void*)instance); + + return instance; } void furi_message_queue_free(FuriMessageQueue* instance) { @@ -19,6 +36,7 @@ void furi_message_queue_free(FuriMessageQueue* instance) { furi_check(instance); vQueueDelete((QueueHandle_t)instance); + free(instance); } FuriStatus @@ -102,11 +120,10 @@ FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uin uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) { furi_check(instance); - StaticQueue_t* mq = (StaticQueue_t*)instance; uint32_t capacity; /* capacity = pxQueue->uxLength */ - capacity = mq->uxDummy4[1]; + capacity = instance->container.uxDummy4[1]; /* Return maximum number of messages */ return (capacity); @@ -115,11 +132,10 @@ uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) { uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance) { furi_check(instance); - StaticQueue_t* mq = (StaticQueue_t*)instance; uint32_t size; /* size = pxQueue->uxItemSize */ - size = mq->uxDummy4[2]; + size = instance->container.uxDummy4[2]; /* Return maximum message size */ return (size); @@ -144,7 +160,6 @@ uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { furi_check(instance); - StaticQueue_t* mq = (StaticQueue_t*)instance; uint32_t space; uint32_t isrm; @@ -152,11 +167,11 @@ uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { isrm = taskENTER_CRITICAL_FROM_ISR(); /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ - space = mq->uxDummy4[1] - mq->uxDummy4[0]; + space = instance->container.uxDummy4[1] - instance->container.uxDummy4[0]; taskEXIT_CRITICAL_FROM_ISR(isrm); } else { - space = (uint32_t)uxQueueSpacesAvailable((QueueHandle_t)mq); + space = (uint32_t)uxQueueSpacesAvailable((QueueHandle_t)instance); } /* Return number of available slots */ diff --git a/furi/core/message_queue.h b/furi/core/message_queue.h index 8d7f389e12..a055a05f12 100644 --- a/furi/core/message_queue.h +++ b/furi/core/message_queue.h @@ -10,7 +10,7 @@ extern "C" { #endif -typedef void FuriMessageQueue; +typedef struct FuriMessageQueue FuriMessageQueue; /** Allocate furi message queue *