From ec5e5da1389b017a3e0d3c6821b118def0a84f71 Mon Sep 17 00:00:00 2001 From: DrZlo13 Date: Mon, 5 Oct 2020 20:17:34 +1000 Subject: [PATCH] Applications dependency, initial realization (#159) --- applications/display-u8g2/display-u8g2.c | 3 ++ applications/examples/input_dump.c | 3 -- applications/examples/u8g2_example.c | 3 -- applications/input/input.c | 2 + applications/startup.h | 21 ++++---- core/app.cpp | 13 +++-- core/furi.h | 12 +++++ core/furi_ac.c | 66 ++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 20 deletions(-) diff --git a/applications/display-u8g2/display-u8g2.c b/applications/display-u8g2/display-u8g2.c index b8293b8f..8fc3b668 100644 --- a/applications/display-u8g2/display-u8g2.c +++ b/applications/display-u8g2/display-u8g2.c @@ -171,6 +171,9 @@ void display_u8g2(void* p) { u8g2_SendBuffer(u8g2); furi_give(fb_record); + // we ready to work + furiac_ready(); + while(1) { // wait for event if(xSemaphoreTake(update, 10000) == pdTRUE) { diff --git a/applications/examples/input_dump.c b/applications/examples/input_dump.c index c8f0bed9..2aa50cdf 100644 --- a/applications/examples/input_dump.c +++ b/applications/examples/input_dump.c @@ -14,9 +14,6 @@ static void event_cb(const void* value, size_t size, void* ctx) { } void application_input_dump(void* p) { - // TODO try open record and retry on timeout (needs FURI behaviour change) - delay(1000); - // open record FuriRecordSubscriber* state_record = furi_open("input_state", false, false, state_cb, NULL, NULL); diff --git a/applications/examples/u8g2_example.c b/applications/examples/u8g2_example.c index 92b43447..6c0aaf85 100644 --- a/applications/examples/u8g2_example.c +++ b/applications/examples/u8g2_example.c @@ -4,9 +4,6 @@ void u8g2_example(void* p) { FuriRecordSubscriber* log = get_default_log(); - // TODO try open record and retry on timeout (needs FURI behaviour change) - delay(1000); - // open record FuriRecordSubscriber* fb_record = furi_open("u8g2_fb", false, false, NULL, NULL, NULL); diff --git a/applications/input/input.c b/applications/input/input.c index 8d0b1b46..7858fd63 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -40,6 +40,8 @@ void input_task(void* p) { furiac_exit(NULL); } + // we ready to work + furiac_ready(); initialized = true; // Force state update diff --git a/applications/startup.h b/applications/startup.h index 9ff0be7e..132873c9 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -5,6 +5,7 @@ typedef struct { FlipperApplication app; const char* name; + const char* libs; } FlipperStartupApp; #ifdef TEST @@ -27,31 +28,31 @@ void coreglitch_demo_0(void* p); const FlipperStartupApp FLIPPER_STARTUP[] = { #ifndef TEST - {.app = display_u8g2, .name = "display_u8g2"}, - {.app = u8g2_example, .name = "u8g2_example"}, + {.app = display_u8g2, .name = "display_u8g2", .libs = ""}, + {.app = u8g2_example, .name = "u8g2_example", .libs = "display_u8g2"}, #endif #ifdef USE_INPUT - {.app = input_task, .name = "input_task"}, + {.app = input_task, .name = "input_task", .libs = ""}, #endif -// {.app = coreglitch_demo_0, .name = "coreglitch_demo_0"}, +// {.app = coreglitch_demo_0, .name = "coreglitch_demo_0", .libs = ""}, #ifdef TEST - {.app = flipper_test_app, .name = "test app"}, + {.app = flipper_test_app, .name = "test app", .libs = ""}, #endif #ifdef EXAMPLE_BLINK - {.app = application_blink, .name = "blink"}, + {.app = application_blink, .name = "blink", .libs = ""}, #endif #ifdef EXAMPLE_UART_WRITE - {.app = application_uart_write, .name = "uart write"}, + {.app = application_uart_write, .name = "uart write", .libs = ""}, #endif #ifdef EXAMPLE_IPC - {.app = application_ipc_display, .name = "ipc display"}, - {.app = application_ipc_widget, .name = "ipc widget"}, + {.app = application_ipc_display, .name = "ipc display", .libs = ""}, + {.app = application_ipc_widget, .name = "ipc widget", .libs = ""}, #endif #ifdef EXAMPLE_INPUT_DUMP - {.app = application_input_dump, .name = "input dump"}, + {.app = application_input_dump, .name = "input dump", .libs = "input_task"}, #endif }; diff --git a/core/app.cpp b/core/app.cpp index 36b9de52..6f1de5dd 100644 --- a/core/app.cpp +++ b/core/app.cpp @@ -2,9 +2,9 @@ #include extern "C" { -#include "startup.h" #include "furi.h" #include "log.h" +#include "startup.h" #include "tty_uart.h" } @@ -15,16 +15,19 @@ extern "C" void app() { fuprintf(log, "\n=== Welcome to Flipper Zero! ===\n\n"); // FURI startup - FuriApp* handlers[sizeof(FLIPPER_STARTUP) / sizeof(FLIPPER_STARTUP[0])]; + const size_t flipper_app_count = sizeof(FLIPPER_STARTUP) / sizeof(FLIPPER_STARTUP[0]); + FuriApp* handlers[flipper_app_count]; - for(size_t i = 0; i < sizeof(FLIPPER_STARTUP) / sizeof(FLIPPER_STARTUP[0]); i++) { + for(size_t i = 0; i < flipper_app_count; i++) { + // TODO create a dependency tree and run tasks in the desired order + furiac_wait_libs(FLIPPER_STARTUP[i].libs); handlers[i] = furiac_start(FLIPPER_STARTUP[i].app, FLIPPER_STARTUP[i].name, NULL); } bool is_alive = false; do { is_alive = false; - for(size_t i = 0; i < sizeof(FLIPPER_STARTUP) / sizeof(FLIPPER_STARTUP[0]); i++) { + for(size_t i = 0; i < flipper_app_count; i++) { if(handlers[i]->handler != NULL) { is_alive = true; } @@ -32,4 +35,6 @@ extern "C" void app() { delay(500); // TODO add deferred event queue here } while(is_alive); + + fuprintf(log, "\n=== Bye from Flipper Zero! ===\n\n"); } \ No newline at end of file diff --git a/core/furi.h b/core/furi.h index dca99be0..f6a9585a 100644 --- a/core/furi.h +++ b/core/furi.h @@ -56,6 +56,8 @@ typedef struct { TaskHandle_t handler; uint8_t records_count; ///< count of records which task open FuriRecord* records[MAX_TASK_RECORDS]; ///< list of records which task open + + bool ready; } FuriApp; /*! @@ -82,6 +84,16 @@ application registry. */ void furiac_exit(void* param); +/*! +Mark application as prepared and ready to perform actions +*/ +void furiac_ready(); + +/* +Wait for the libraries we depend on +*/ +void furiac_wait_libs(const char* libs); + /*! Stop specified app without returning to prev application. */ diff --git a/core/furi_ac.c b/core/furi_ac.c index 3c940ebf..f8e09ae5 100644 --- a/core/furi_ac.c +++ b/core/furi_ac.c @@ -7,8 +7,11 @@ #include #endif +#include + #define DEFAULT_STACK_SIZE 1024 // Stack size in bytes #define MAX_TASK_COUNT 8 +#define INVALID_TASK_ID UINT16_MAX static StaticTask_t task_info_buffer[MAX_TASK_COUNT]; static StackType_t stack_buffer[MAX_TASK_COUNT][DEFAULT_STACK_SIZE / 4]; @@ -16,6 +19,45 @@ static FuriApp task_buffer[MAX_TASK_COUNT]; static size_t current_buffer_idx = 0; +uint16_t furiac_get_task_id_by_name(const char* app_name) { + for(size_t i = 0; i < MAX_TASK_RECORDS; i++) { + if(strcmp(task_buffer[i].name, app_name) == 0) return i; + } + + return INVALID_TASK_ID; +} + +void furiac_wait_libs(const char* libs) { + char* lib_rest = NULL; + char* lib_name = strtok_r((char*)libs, " ", &lib_rest); + + while(lib_name != NULL) { + // trim library name + for(uint16_t i = 0; i < strlen(lib_name); i++) { + if(lib_name[i] == ' ') { + lib_name[i] = 0; + } + } + + uint16_t app_id = furiac_get_task_id_by_name(lib_name); + + if(app_id == INVALID_TASK_ID) { +#ifdef FURI_DEBUG + printf("[FURIAC] Invalid library name %s\n", lib_name); +#endif + } else { + while(!task_buffer[app_id].ready) { +#ifdef FURI_DEBUG + printf("[FURIAC] waiting for library \"%s\"\n", lib_name); +#endif + osDelay(50); + } + } + + lib_name = strtok_r(NULL, " ", &lib_rest); + } +} + // find task pointer by handle FuriApp* find_task(TaskHandle_t handler) { FuriApp* res = NULL; @@ -43,6 +85,9 @@ FuriApp* furiac_start(FlipperApplication app, const char* name, void* param) { return NULL; } + // application ready + task_buffer[current_buffer_idx].ready = false; + // create task on static stack memory task_buffer[current_buffer_idx].handler = xTaskCreateStatic( (TaskFunction_t)app, @@ -135,4 +180,25 @@ void furiac_switch(FlipperApplication app, char* name, void* param) { // kill itself vTaskDelete(NULL); } +} + +// set task to ready state +void furiac_ready() { + /* + TODO: + Currently i think that better way is to use application name + and restrict applications to "one task per application" + */ + FuriApp* app = find_task(xTaskGetCurrentTaskHandle()); + + if(app == NULL) { +#ifdef FURI_DEBUG + printf("[FURIAC] cannot find task to set ready state\n"); +#endif + } else { +#ifdef FURI_DEBUG + printf("[FURIAC] task is ready\n"); +#endif + app->ready = true; + } } \ No newline at end of file