diff --git a/applications/debug/accessor/accessor_app.cpp b/applications/debug/accessor/accessor_app.cpp index 2e40b3c35..8d43acc13 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 bfd5c06e1..890552f5f 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 185f75578..d59eaf26f 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 6e8ab1869..6a4e8c324 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 8d7f389e1..a055a05f1 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 * diff --git a/targets/f7/src/update.c b/targets/f7/src/update.c index e6cb4aabe..261adb5ca 100644 --- a/targets/f7/src/update.c +++ b/targets/f7/src/update.c @@ -78,21 +78,21 @@ static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest furi_string_free(loader_img_path); void* img = malloc(stat.fsize); - uint32_t bytes_read = 0; + uint32_t read_total = 0; + uint16_t read_current = 0; const uint16_t MAX_READ = 0xFFFF; uint32_t crc = 0; do { - uint16_t size_read = 0; - if(f_read(&file, img + bytes_read, MAX_READ, &size_read) != FR_OK) { //-V769 + if(f_read(&file, img + read_total, MAX_READ, &read_current) != FR_OK) { //-V769 break; } - crc = crc32_calc_buffer(crc, img + bytes_read, size_read); - bytes_read += size_read; - } while(bytes_read == MAX_READ); + crc = crc32_calc_buffer(crc, img + read_total, read_current); + read_total += read_current; + } while(read_current == MAX_READ); do { - if((bytes_read != stat.fsize) || (crc != manifest->staged_loader_crc)) { + if((read_total != stat.fsize) || (crc != manifest->staged_loader_crc)) { break; }