فهرست منبع

Cli: fix memleak, add more commands. (#244)

* Cli: add statndard applications, fix memory leak, add reset and reset to dfu.

* Lib: pass proper data pointer to osMessageQueueGet

* App-loader: optional cli

* Format sources
あく 5 سال پیش
والد
کامیت
d57b7fd448

+ 27 - 13
applications/app-loader/app-loader.c

@@ -1,4 +1,5 @@
 #include "flipper_v2.h"
+#include <cli/cli.h>
 #include <gui/gui.h>
 #include "menu/menu.h"
 #include "menu/menu_item.h"
@@ -52,6 +53,21 @@ static void handle_menu(void* _ctx) {
     ctx->state->handler = furiac_start(ctx->app->app, ctx->app->name, NULL);
 }
 
+static void handle_cli(string_t args, void* _ctx) {
+    AppLoaderContext* ctx = (AppLoaderContext*)_ctx;
+
+    cli_print("Starting furi application\r\n");
+
+    ctx->state->current_app = ctx->app;
+    ctx->state->handler = furiac_start(ctx->app->app, ctx->app->name, NULL);
+
+    cli_print("Press any key to kill application");
+
+    char c;
+    cli_read(&c, 1);
+    furiac_kill(ctx->state->handler);
+}
+
 void app_loader(void* p) {
     osThreadId_t self_id = osThreadGetId();
     furi_check(self_id);
@@ -72,6 +88,8 @@ void app_loader(void* p) {
         furiac_exit(NULL);
     }
 
+    Cli* cli = furi_open("cli");
+
     // Open GUI and register widget
     GuiApi* gui = furi_open("gui");
     if(gui == NULL) {
@@ -93,20 +111,16 @@ void app_loader(void* p) {
                 state.menu_plugins,
                 menu_item_alloc_function(
                     FLIPPER_APPS[i].name, assets_icons_get(A_Infrared_14), handle_menu, ctx));
-        }
 
-        /*
-        menu_item_add(menu, menu_item_alloc_function("Sub 1 gHz", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("125 kHz RFID", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("Infrared", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("I-Button", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("USB", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("Bluetooth", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("GPIO / HW", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("U2F", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("Tamagotchi", NULL, NULL, NULL));
-        menu_item_add(menu, menu_item_alloc_function("Plugins", NULL, NULL, NULL));
-        */
+            // Add cli command
+            if(cli) {
+                string_t cli_name;
+                string_init_set_str(cli_name, "app_");
+                string_cat_str(cli_name, FLIPPER_APPS[i].name);
+                cli_add_command(cli, string_get_cstr(cli_name), handle_cli, ctx);
+                string_clear(cli_name);
+            }
+        }
     }
 
     with_value_mutex(

+ 1 - 1
applications/applications.h

@@ -67,7 +67,7 @@ const FlipperStartupApp FLIPPER_STARTUP[] = {
 
 #ifdef APP_MENU
     {.app = menu_task, .name = "menu_task", .libs = {1, FURI_LIB{"gui_task"}}},
-    {.app = app_loader, .name = "app_loader", .libs = {1, FURI_LIB{"menu_task"}}},
+    {.app = app_loader, .name = "app_loader", .libs = {2, FURI_LIB{"menu_task", "cli_task"}}},
 #endif
 
 #ifdef APP_IRUKAGOTCHI

+ 15 - 0
applications/cli/cli.c

@@ -20,6 +20,7 @@ void cli_free(Cli* cli) {
 }
 
 void cli_reset_state(Cli* cli) {
+    // Release allocated buffer, reset state
     string_clear(cli->line);
     string_init(cli->line);
 }
@@ -28,6 +29,10 @@ void cli_putc(char c) {
     api_hal_vcp_tx((uint8_t*)&c, 1);
 }
 
+void cli_read(char* buffer, size_t size) {
+    api_hal_vcp_rx((uint8_t*)buffer, size);
+}
+
 void cli_print(const char* str) {
     api_hal_vcp_tx((uint8_t*)str, strlen(str));
 }
@@ -103,6 +108,7 @@ void cli_enter(Cli* cli) {
         cli_putc(CliSymbolAsciiBell);
     }
 
+    string_clear(command);
     // Always finish with clean state
     cli_reset_state(cli);
 }
@@ -145,6 +151,13 @@ void cli_process_input(Cli* cli) {
 void cli_add_command(Cli* cli, const char* name, CliCallback callback, void* context) {
     string_t name_str;
     string_init_set_str(name_str, name);
+    string_strim(name_str);
+
+    size_t name_replace;
+    do {
+        name_replace = string_replace_str(name_str, " ", "_");
+    } while(name_replace != STRING_FAILURE);
+
     CliCommand c;
     c.callback = callback;
     c.context = context;
@@ -152,6 +165,8 @@ void cli_add_command(Cli* cli, const char* name, CliCallback callback, void* con
     furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK);
     CliCommandDict_set_at(cli->commands, name_str, c);
     furi_check(osMutexRelease(cli->mutex) == osOK);
+
+    string_clear(name_str);
 }
 
 void cli_task(void* p) {

+ 17 - 2
applications/power/power.c

@@ -87,17 +87,32 @@ void power_free(Power* power) {
 }
 
 void power_cli_poweroff(string_t args, void* context) {
-    cli_print("Poweroff in 5 seconds");
-    osDelay(5000);
+    cli_print("Poweroff in 3 seconds");
+    osDelay(3000);
     api_hal_power_off();
 }
 
+void power_cli_reset(string_t args, void* context) {
+    cli_print("NVIC System Reset in 3 seconds");
+    osDelay(3000);
+    NVIC_SystemReset();
+}
+
+void power_cli_dfu(string_t args, void* context) {
+    cli_print("NVIC System Reset to DFU mode in 3 seconds");
+    api_hal_boot_set_mode(ApiHalBootModeDFU);
+    osDelay(3000);
+    NVIC_SystemReset();
+}
+
 void power_task(void* p) {
     (void)p;
     Power* power = power_alloc();
 
     if(power->cli) {
         cli_add_command(power->cli, "poweroff", power_cli_poweroff, power);
+        cli_add_command(power->cli, "reset", power_cli_reset, power);
+        cli_add_command(power->cli, "dfu", power_cli_dfu, power);
     }
 
     FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL);

+ 0 - 15
core/boot.h

@@ -1,15 +0,0 @@
-/*
-Flipper devices inc.
-
-Bootloader API, must be implemented by target
-*/
-
-#ifndef __BOOT_H
-#define __BOOT_H
-
-/*
- * @brief Request DFU and reboot
-*/
-void boot_restart_in_dfu();
-
-#endif

+ 8 - 0
firmware/targets/Inc/api-hal-boot.h

@@ -0,0 +1,8 @@
+#pragma once
+
+typedef enum {
+    ApiHalBootModeNormal,
+    ApiHalBootModeDFU
+} ApiHalBootMode;
+
+void api_hal_boot_set_mode(ApiHalBootMode mode);

+ 1 - 0
firmware/targets/Inc/api-hal.h

@@ -1,5 +1,6 @@
 #pragma once
 
+#include "api-hal-boot.h"
 #include "api-hal-gpio.h"
 #include "api-hal-delay.h"
 #include "api-hal-pwm.h"

+ 13 - 0
firmware/targets/f2/api-hal/api-hal-boot.c

@@ -0,0 +1,13 @@
+#include <api-hal-boot.h>
+#include <stm32l4xx_ll_rtc.h>
+
+#define BOOT_REQUEST_NONE 0x00000000
+#define BOOT_REQUEST_DFU 0xDF00B000
+
+void api_hal_boot_set_mode(ApiHalBootMode mode) {
+    if (mode == ApiHalBootModeNormal) {
+        LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_NONE);
+    } else if (mode == ApiHalBootModeDFU) {
+        LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU);
+    }
+}

+ 13 - 0
firmware/targets/f3/api-hal/api-hal-boot.c

@@ -0,0 +1,13 @@
+#include <api-hal-boot.h>
+#include <stm32wbxx_ll_rtc.h>
+
+#define BOOT_REQUEST_NONE 0x00000000
+#define BOOT_REQUEST_DFU 0xDF00B000
+
+void api_hal_boot_set_mode(ApiHalBootMode mode) {
+    if (mode == ApiHalBootModeNormal) {
+        LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_NONE);
+    } else if (mode == ApiHalBootModeDFU) {
+        LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU);
+    }
+}

+ 1 - 1
lib/app-template/app-template.h

@@ -91,7 +91,7 @@ template <class TState, class TEvent> void AppTemplate<TState, TEvent>::release_
 
 template <class TState, class TEvent>
 bool AppTemplate<TState, TEvent>::get_event(TEvent* event, uint32_t timeout) {
-    osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, timeout);
+    osStatus_t event_status = osMessageQueueGet(event_queue, event, NULL, timeout);
 
     return (event_status == osOK);
 }