diff --git a/.vscode/example/tasks.json b/.vscode/example/tasks.json index 1d2b55a2c..9861afa1e 100644 --- a/.vscode/example/tasks.json +++ b/.vscode/example/tasks.json @@ -28,29 +28,17 @@ "command": "./fbt -c" }, { - "label": "[Release] Flash (ST-Link)", + "label": "[Release] Flash (SWD)", "group": "build", "type": "shell", "command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash" }, { - "label": "[Debug] Flash (ST-Link)", + "label": "[Debug] Flash (SWD)", "group": "build", "type": "shell", "command": "./fbt FORCE=1 flash" }, - { - "label": "[Release] Flash (blackmagic)", - "group": "build", - "type": "shell", - "command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_blackmagic" - }, - { - "label": "[Debug] Flash (blackmagic)", - "group": "build", - "type": "shell", - "command": "./fbt FORCE=1 flash_blackmagic" - }, { "label": "[Release] Flash (JLink)", "group": "build", diff --git a/SConstruct b/SConstruct index 0b3d4ac1a..8d389b70b 100644 --- a/SConstruct +++ b/SConstruct @@ -185,27 +185,15 @@ copro_dist = distenv.CoproBuilder( distenv.AlwaysBuild(copro_dist) distenv.Alias("copro_dist", copro_dist) -firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env) + +firmware_flash = distenv.AddFwFlashTarget(firmware_env) distenv.Alias("flash", firmware_flash) +# To be implemented in fwflash.py firmware_jflash = distenv.AddJFlashTarget(firmware_env) distenv.Alias("jflash", firmware_jflash) -firmware_bm_flash = distenv.PhonyTarget( - "flash_blackmagic", - "$GDB $GDBOPTS $SOURCES $GDBFLASH", - source=firmware_env["FW_ELF"], - GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}", - GDBREMOTE="${BLACKMAGIC_ADDR}", - GDBFLASH=[ - "-ex", - "load", - "-ex", - "quit", - ], -) - -gdb_backtrace_all_threads = distenv.PhonyTarget( +distenv.PhonyTarget( "gdb_trace_all", "$GDB $GDBOPTS $SOURCES $GDBFLASH", source=firmware_env["FW_ELF"], diff --git a/applications/debug/accessor/helpers/wiegand.cpp b/applications/debug/accessor/helpers/wiegand.cpp index 5cb3a85f5..10b284eaa 100644 --- a/applications/debug/accessor/helpers/wiegand.cpp +++ b/applications/debug/accessor/helpers/wiegand.cpp @@ -174,7 +174,7 @@ bool WIEGAND::DoWiegandConversion() { return false; } - // TODO: Handle validation failure case! + // TODO FL-3490: Handle validation failure case! } else if(4 == _bitCount) { // 4-bit Wiegand codes have no data integrity check so we just // read the LOW nibble. diff --git a/applications/debug/subghz_test/views/subghz_test_packet.c b/applications/debug/subghz_test/views/subghz_test_packet.c index bab83ab5b..1f3458296 100644 --- a/applications/debug/subghz_test/views/subghz_test_packet.c +++ b/applications/debug/subghz_test/views/subghz_test_packet.c @@ -56,7 +56,6 @@ static void subghz_test_packet_rx_callback(bool level, uint32_t duration, void* subghz_decoder_princeton_for_testing_parse(instance->decoder, level, duration); } -//todo static void subghz_test_packet_rx_pt_callback(SubGhzDecoderPrinceton* parser, void* context) { UNUSED(parser); furi_assert(context); diff --git a/applications/debug/unit_tests/furi/furi_memmgr_test.c b/applications/debug/unit_tests/furi/furi_memmgr_test.c index f7bc234a0..05d967a99 100644 --- a/applications/debug/unit_tests/furi/furi_memmgr_test.c +++ b/applications/debug/unit_tests/furi/furi_memmgr_test.c @@ -26,7 +26,7 @@ void test_furi_memmgr() { mu_assert_int_eq(66, ((uint8_t*)ptr)[i]); } - // TODO: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized + // TODO FL-3492: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized free(ptr); // allocate and zero-initialize array (calloc) diff --git a/applications/debug/unit_tests/furi/furi_string_test.c b/applications/debug/unit_tests/furi/furi_string_test.c index 3ea95b92b..6cbcc0dcc 100644 --- a/applications/debug/unit_tests/furi/furi_string_test.c +++ b/applications/debug/unit_tests/furi/furi_string_test.c @@ -69,7 +69,7 @@ MU_TEST(mu_test_furi_string_mem) { mu_check(string != NULL); mu_check(!furi_string_empty(string)); - // TODO: how to test furi_string_reserve? + // TODO FL-3493: how to test furi_string_reserve? // test furi_string_reset furi_string_reset(string); diff --git a/applications/debug/unit_tests/lfrfid/bit_lib_test.c b/applications/debug/unit_tests/lfrfid/bit_lib_test.c index 726615703..dcb69de7f 100644 --- a/applications/debug/unit_tests/lfrfid/bit_lib_test.c +++ b/applications/debug/unit_tests/lfrfid/bit_lib_test.c @@ -311,7 +311,7 @@ MU_TEST(test_bit_lib_test_parity) { } MU_TEST(test_bit_lib_remove_bit_every_nth) { - // TODO: more tests + // TODO FL-3494: more tests uint8_t data_i[1] = {0b00001111}; uint8_t data_o[1] = {0b00011111}; size_t length; diff --git a/applications/debug/unit_tests/test_index.c b/applications/debug/unit_tests/test_index.c index f7a53d7c8..edaf950c5 100644 --- a/applications/debug/unit_tests/test_index.c +++ b/applications/debug/unit_tests/test_index.c @@ -90,7 +90,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) { Loader* loader = furi_record_open(RECORD_LOADER); NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - // TODO: lock device while test running + // TODO FL-3491: lock device while test running if(loader_is_locked(loader)) { printf("RPC: stop all applications to run tests\r\n"); notification_message(notification, &sequence_blink_magenta_100); diff --git a/applications/main/gpio/scenes/gpio_scene_usb_uart.c b/applications/main/gpio/scenes/gpio_scene_usb_uart.c index aa41aaf98..52b2142dc 100644 --- a/applications/main/gpio/scenes/gpio_scene_usb_uart.c +++ b/applications/main/gpio/scenes/gpio_scene_usb_uart.c @@ -19,7 +19,7 @@ void gpio_scene_usb_uart_on_enter(void* context) { uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUart); if(prev_state == 0) { scene_usb_uart = malloc(sizeof(SceneUsbUartBridge)); - scene_usb_uart->cfg.vcp_ch = 0; // TODO: settings load + scene_usb_uart->cfg.vcp_ch = 0; // TODO FL-3495: settings load scene_usb_uart->cfg.uart_ch = 0; scene_usb_uart->cfg.flow_pins = 0; scene_usb_uart->cfg.baudrate_mode = 0; diff --git a/applications/main/infrared/infrared_cli.c b/applications/main/infrared/infrared_cli.c index 3fa99cb02..54b5cabab 100644 --- a/applications/main/infrared/infrared_cli.c +++ b/applications/main/infrared/infrared_cli.c @@ -85,7 +85,7 @@ static void infrared_cli_print_usage(void) { printf("\tir decode []\r\n"); printf("\tir universal \r\n"); printf("\tir universal list \r\n"); - // TODO: Do not hardcode universal remote names + // TODO FL-3496: Do not hardcode universal remote names printf("\tAvailable universal remotes: tv audio ac projector\r\n"); } @@ -211,7 +211,7 @@ static bool infrared_cli_decode_raw_signal( size_t i; for(i = 0; i < raw_signal->timings_size; ++i) { - // TODO: Any infrared_check_decoder_ready() magic? + // TODO FL-3523: Any infrared_check_decoder_ready() magic? const InfraredMessage* message = infrared_decode(decoder, level, raw_signal->timings[i]); if(message) { diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index c08eb00aa..5c36a781a 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -336,7 +336,6 @@ static void subghz_txrx_tx_stop(SubGhzTxRx* instance) { } subghz_txrx_idle(instance); subghz_txrx_speaker_off(instance); - //Todo: Show message } FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) { diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index 0a9d12909..a83e17da6 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -30,7 +30,7 @@ bool subghz_txrx_gen_data_protocol( subghz_receiver_search_decoder_base_by_name(instance->receiver, protocol_name); if(instance->decoder_result == NULL) { - //TODO: Error + //TODO FL-3502: Error // furi_string_set(error_str, "Protocol not\nfound!"); // scene_manager_next_scene(scene_manager, SubGhzSceneShowErrorSub); FURI_LOG_E(TAG, "Protocol not found!"); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index fc1c1a8e9..d77d93b90 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -25,7 +25,7 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { if(subghz_txrx_load_decoder_by_name_protocol( subghz->txrx, subghz_history_get_protocol_name(subghz->history, subghz->idx_menu_chosen))) { - //todo we are trying to deserialize without checking for errors, since it is assumed that we just received this signal + // we are trying to deserialize without checking for errors, since it is assumed that we just received this chignal subghz_protocol_decoder_base_deserialize( subghz_txrx_get_decoder(subghz->txrx), subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen)); diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 0dbeaa10d..5cb33fd2b 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -142,7 +142,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx); if(!strcmp(furi_string_get_cstr(temp_str), "CUSTOM")) { - //Todo add Custom_preset_module + //TODO FL-3551: add Custom_preset_module //delete preset if it already exists subghz_setting_delete_custom_preset(setting, furi_string_get_cstr(temp_str)); //load custom preset from file diff --git a/applications/services/applications.h b/applications/services/applications.h index 426d6d2d2..7dbb7063f 100644 --- a/applications/services/applications.h +++ b/applications/services/applications.h @@ -51,6 +51,12 @@ extern const size_t FLIPPER_ON_SYSTEM_START_COUNT; extern const FlipperInternalApplication FLIPPER_SYSTEM_APPS[]; extern const size_t FLIPPER_SYSTEM_APPS_COUNT; +/* Debug apps + * Can only be spawned by loader by name + */ +extern const FlipperInternalApplication FLIPPER_DEBUG_APPS[]; +extern const size_t FLIPPER_DEBUG_APPS_COUNT; + extern const FlipperInternalApplication FLIPPER_ARCHIVE; /* Settings list diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index f4837bfb0..043ed58fd 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -101,7 +101,7 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) { char buffer[20]; snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->time_minute); - // ToDo: never do that, may cause visual glitches + // TODO FL-3515: never do that, may cause visual glitches view_port_set_width( desktop->clock_viewport, canvas_string_width(canvas, buffer) - 1 + (desktop->time_minute % 10 == 1)); @@ -126,7 +126,7 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { return true; case DesktopGlobalAfterAppFinished: animation_manager_load_and_continue_animation(desktop->animation_manager); - // TODO: Implement a message mechanism for loading settings and (optionally) + // TODO FL-3497: Implement a message mechanism for loading settings and (optionally) // locking and unlocking DESKTOP_SETTINGS_LOAD(&desktop->settings); @@ -382,12 +382,7 @@ Desktop* desktop_alloc() { } gui_add_view_port(desktop->gui, desktop->stealth_mode_icon_viewport, GuiLayerStatusBarLeft); - // Special case: autostart application is already running desktop->loader = furi_record_open(RECORD_LOADER); - if(loader_is_locked(desktop->loader) && - animation_manager_is_animation_loaded(desktop->animation_manager)) { - animation_manager_unload_and_stall_animation(desktop->animation_manager); - } desktop->notification = furi_record_open(RECORD_NOTIFICATION); desktop->app_start_stop_subscription = furi_pubsub_subscribe( @@ -478,6 +473,12 @@ int32_t desktop_srv(void* p) { scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault); } + // Special case: autostart application is already running + if(loader_is_locked(desktop->loader) && + animation_manager_is_animation_loaded(desktop->animation_manager)) { + animation_manager_unload_and_stall_animation(desktop->animation_manager); + } + view_dispatcher_run(desktop->view_dispatcher); furi_crash("That was unexpected"); diff --git a/applications/services/gui/modules/button_panel.c b/applications/services/gui/modules/button_panel.c index 6276c6a82..7421650f3 100644 --- a/applications/services/gui/modules/button_panel.c +++ b/applications/services/gui/modules/button_panel.c @@ -114,7 +114,6 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re ButtonArray_t* array = ButtonMatrix_get(model->button_matrix, i); ButtonArray_init(*array); ButtonArray_reserve(*array, reserve_x); - // TODO: do we need to clear allocated memory of ptr-s to ButtonItem ?? } LabelList_init(model->labels); }, diff --git a/applications/services/gui/view_dispatcher.c b/applications/services/gui/view_dispatcher.c index 920b3c139..83f0edbea 100644 --- a/applications/services/gui/view_dispatcher.c +++ b/applications/services/gui/view_dispatcher.c @@ -272,7 +272,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e } else if(view_dispatcher->navigation_event_callback) { // Dispatch navigation event if(!view_dispatcher->navigation_event_callback(view_dispatcher->event_context)) { - // TODO: should we allow view_dispatcher to stop without navigation_event_callback? + // TODO FL-3514: should we allow view_dispatcher to stop without navigation_event_callback? view_dispatcher_stop(view_dispatcher); return; } diff --git a/applications/services/gui/view_port.c b/applications/services/gui/view_port.c index 8c2ff6fe0..57c0fddb4 100644 --- a/applications/services/gui/view_port.c +++ b/applications/services/gui/view_port.c @@ -7,7 +7,7 @@ #include "gui.h" #include "gui_i.h" -// TODO add mutex to view_port ops +// TODO FL-3498: add mutex to view_port ops _Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count"); _Static_assert( diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index c484e850b..7af1f0c8a 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -1,4 +1,5 @@ #include "loader.h" +#include "core/core_defines.h" #include "loader_i.h" #include #include @@ -61,7 +62,7 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const dialog_message_free(message); furi_record_close(RECORD_DIALOGS); } else if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) { - // TODO: we have many places where we can emit a double start, ex: desktop, menu + // TODO FL-3522: we have many places where we can emit a double start, ex: desktop, menu // so i prefer to not show LoaderStatusErrorAppStarted error message for now DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogMessage* message = dialog_message_alloc(); @@ -186,18 +187,24 @@ static FlipperInternalApplication const* loader_find_application_by_name_in_list } static const FlipperInternalApplication* loader_find_application_by_name(const char* name) { - const FlipperInternalApplication* application = NULL; - application = loader_find_application_by_name_in_list(name, FLIPPER_APPS, FLIPPER_APPS_COUNT); - if(!application) { - application = loader_find_application_by_name_in_list( - name, FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT); - } - if(!application) { - application = loader_find_application_by_name_in_list( - name, FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_APPS_COUNT); + const struct { + const FlipperInternalApplication* list; + const uint32_t count; + } lists[] = { + {FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT}, + {FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_APPS_COUNT}, + {FLIPPER_DEBUG_APPS, FLIPPER_DEBUG_APPS_COUNT}, + }; + + for(size_t i = 0; i < COUNT_OF(lists); i++) { + const FlipperInternalApplication* application = + loader_find_application_by_name_in_list(name, lists[i].list, lists[i].count); + if(application) { + return application; + } } - return application; + return NULL; } static void loader_start_app_thread(Loader* loader, FlipperInternalApplicationFlag flags) { @@ -253,9 +260,7 @@ static void loader_log_status_error( furi_string_vprintf(error_message, format, args); FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(error_message)); } else { - FuriString* tmp = furi_string_alloc(); - FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(tmp)); - furi_string_free(tmp); + FURI_LOG_E(TAG, "Status [%d]", status); } } @@ -527,7 +532,9 @@ int32_t loader_srv(void* p) { FLIPPER_ON_SYSTEM_START[i](); } - if(FLIPPER_AUTORUN_APP_NAME && strlen(FLIPPER_AUTORUN_APP_NAME)) { + if((furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) && FLIPPER_AUTORUN_APP_NAME && + strlen(FLIPPER_AUTORUN_APP_NAME)) { + FURI_LOG_I(TAG, "Starting autorun app: %s", FLIPPER_AUTORUN_APP_NAME); loader_do_start_by_name(loader, FLIPPER_AUTORUN_APP_NAME, NULL, NULL); } diff --git a/applications/services/loader/loader_cli.c b/applications/services/loader/loader_cli.c index cbec4adca..489a576e5 100644 --- a/applications/services/loader/loader_cli.c +++ b/applications/services/loader/loader_cli.c @@ -28,7 +28,7 @@ static void loader_cli_info(Loader* loader) { if(!loader_is_locked(loader)) { printf("No application is running\r\n"); } else { - // TODO: print application name ??? + // TODO FL-3513: print application name ??? printf("Application is running\r\n"); } } diff --git a/applications/services/rpc/rpc_gui.c b/applications/services/rpc/rpc_gui.c index 9ba20a832..9eff4bca6 100644 --- a/applications/services/rpc/rpc_gui.c +++ b/applications/services/rpc/rpc_gui.c @@ -279,7 +279,7 @@ static void rpc_system_gui_start_virtual_display_process(const PB_Main* request, return; } - // TODO: consider refactoring + // TODO FL-3511: consider refactoring // Using display framebuffer size as an XBM buffer size is like comparing apples and oranges // Glad they both are 1024 for now size_t buffer_size = canvas_get_buffer_size(rpc_gui->gui->canvas); diff --git a/applications/services/storage/storage_processing.c b/applications/services/storage/storage_processing.c index e6b426961..70cb7b92f 100644 --- a/applications/services/storage/storage_processing.c +++ b/applications/services/storage/storage_processing.c @@ -399,7 +399,7 @@ static FS_Error storage_process_common_fs_info( } /****************** Raw SD API ******************/ -// TODO think about implementing a custom storage API to split that kind of api linkage +// TODO FL-3521: think about implementing a custom storage API to split that kind of api linkage #include "storages/storage_ext.h" static FS_Error storage_process_sd_format(Storage* app) { diff --git a/applications/services/storage/storages/storage_ext.c b/applications/services/storage/storages/storage_ext.c index 15a355dc2..35b3ee253 100644 --- a/applications/services/storage/storages/storage_ext.c +++ b/applications/services/storage/storages/storage_ext.c @@ -100,7 +100,7 @@ FS_Error sd_unmount_card(StorageData* storage) { storage->status = StorageStatusNotReady; error = FR_DISK_ERR; - // TODO do i need to close the files? + // TODO FL-3522: do i need to close the files? f_mount(0, sd_data->path, 0); return storage_ext_parse_error(error); diff --git a/applications/system/updater/scenes/updater_scene_main.c b/applications/system/updater/scenes/updater_scene_main.c index 2ef0732ca..9fd68161f 100644 --- a/applications/system/updater/scenes/updater_scene_main.c +++ b/applications/system/updater/scenes/updater_scene_main.c @@ -80,7 +80,7 @@ bool updater_scene_main_on_event(void* context, SceneManagerEvent event) { break; case UpdaterCustomEventSdUnmounted: - // TODO: error out, stop worker (it's probably dead actually) + // TODO FL-3499: error out, stop worker (it's probably dead actually) break; default: break; diff --git a/documentation/fbt.md b/documentation/fbt.md index af588382b..02de2949f 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -66,7 +66,7 @@ To use language servers other than the default VS Code C/C++ language server, us - `fap_dist` - build external plugins & publish to the `dist` folder. - `updater_package`, `updater_minpackage` - build a self-update package. The minimal version only includes the firmware's DFU file; the full version also includes a radio stack & resources for the SD card. - `copro_dist` - bundle Core2 FUS+stack binaries for qFlipper. -- `flash` - flash the attached device with OpenOCD over ST-Link. +- `flash` - flash the attached device over SWD interface with supported probes. Probe is detected automatically; you can override it with `SWD_TRANSPORT=...` variable. If multiple probes are attached, you can specify the serial number of the probe to use with `SWD_TRANSPORT_SERIAL=...`. - `flash_usb`, `flash_usb_full` - build, upload and install the update package to the device over USB. See details on `updater_package` and `updater_minpackage`. - `debug` - build and flash firmware, then attach with gdb with firmware's .elf loaded. - `debug_other`, `debug_other_blackmagic` - attach GDB without loading any `.elf`. It will allow you to manually add external `.elf` files with `add-symbol-file` in GDB. @@ -75,7 +75,7 @@ To use language servers other than the default VS Code C/C++ language server, us - `blackmagic` - debug firmware with Blackmagic probe (WiFi dev board). - `openocd` - just start OpenOCD. - `get_blackmagic` - output the blackmagic address in the GDB remote format. Useful for IDE integration. -- `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `OPENOCD_ADAPTER_SERIAL=...`. +- `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `SWD_TRANSPORT_SERIAL=...`. - `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs. - `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests. - `firmware_pvs` - generate a PVS Studio report for the firmware. Requires PVS Studio to be available on your system's `PATH`. @@ -88,9 +88,8 @@ To use language servers other than the default VS Code C/C++ language server, us - `fap_snake_game`, etc. - build single app as `.fap` by its application ID. - Check out [`--extra-ext-apps`](#command-line-parameters) for force adding extra apps to external build. - `fap_snake_game_list`, etc - generate source + assembler listing for app's `.fap`. -- `flash`, `firmware_flash` - flash the current version to the attached device with OpenOCD over ST-Link. +- `flash`, `firmware_flash` - flash the current version to the attached device over SWD. - `jflash` - flash the current version to the attached device with JFlash using a J-Link probe. The JFlash executable must be on your `$PATH`. -- `flash_blackmagic` - flash the current version to the attached device with a Blackmagic probe. - `firmware_all`, `updater_all` - build a basic set of binaries. - `firmware_list`, `updater_list` - generate source + assembler listing. - `firmware_cdb`, `updater_cdb` - generate a `compilation_database.json` file for external tools and IDEs. It can be created without actually building the firmware. diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 792e44e59..9b99c9d5b 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1037,18 +1037,18 @@ Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer Function,+,furi_hal_crypto_ctr,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t" +Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t +Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*" +Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*" +Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t +Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*" Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_gcm,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool" Function,+,furi_hal_crypto_gcm_decrypt_and_verify,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*" Function,+,furi_hal_crypto_gcm_encrypt_and_tag,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*" Function,-,furi_hal_crypto_init,void, Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*" -Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*" -Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*" -Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t Function,+,furi_hal_crypto_unload_key,_Bool, -Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*" -Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_is_gdb_session_active,_Bool, diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 32c9b619c..f28f98b09 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -225,7 +225,7 @@ void furi_hal_resources_init() { } int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) { - // TODO: describe second ROW + // TODO FL-3500: describe second ROW if(gpio == &gpio_ext_pa7) return 2; else if(gpio == &gpio_ext_pa6) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 8dd7017af..124799971 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1134,18 +1134,18 @@ Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer Function,+,furi_hal_crypto_ctr,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t" +Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t +Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*" +Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*" +Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t +Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*" Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_gcm,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool" Function,+,furi_hal_crypto_gcm_decrypt_and_verify,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*" Function,+,furi_hal_crypto_gcm_encrypt_and_tag,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*" Function,-,furi_hal_crypto_init,void, Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*" -Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*" -Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*" -Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t Function,+,furi_hal_crypto_unload_key,_Bool, -Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*" -Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_is_gdb_session_active,_Bool, diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 1cb5501d9..746df71c7 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -222,7 +222,7 @@ bool ble_glue_wait_for_c2_start(int32_t timeout) { bool started = false; do { - // TODO: use mutex? + // TODO FL-3505: use mutex? started = ble_glue->status == BleGlueStatusC2Started; if(!started) { timeout--; diff --git a/firmware/targets/f7/fatfs/sd_spi_io.c b/firmware/targets/f7/fatfs/sd_spi_io.c index e8e542b32..d420524df 100644 --- a/firmware/targets/f7/fatfs/sd_spi_io.c +++ b/firmware/targets/f7/fatfs/sd_spi_io.c @@ -283,7 +283,7 @@ static SdSpiCmdAnswer cmd_answer.r1 = sd_spi_wait_for_data_and_read(); break; case SdSpiCmdAnswerTypeR1B: - // TODO: can be wrong, at least for SD_CMD12_STOP_TRANSMISSION you need to purge one byte before reading R1 + // TODO FL-3507: can be wrong, at least for SD_CMD12_STOP_TRANSMISSION you need to purge one byte before reading R1 cmd_answer.r1 = sd_spi_wait_for_data_and_read(); // In general this shenenigans seems suspicious, please double check SD specs if you are using SdSpiCmdAnswerTypeR1B @@ -322,7 +322,7 @@ static SdSpiDataResponce sd_spi_get_data_response(uint32_t timeout_ms) { switch(responce & 0x1F) { case SdSpiDataResponceOK: - // TODO: check timings + // TODO FL-3508: check timings sd_spi_deselect_card(); sd_spi_select_card(); @@ -684,7 +684,7 @@ static SdSpiStatus sd_spi_cmd_write_blocks( } // Send dummy byte for NWR timing : one byte between CMD_WRITE and TOKEN - // TODO: check bytes count + // TODO FL-3509: check bytes count sd_spi_write_byte(SD_DUMMY_BYTE); sd_spi_write_byte(SD_DUMMY_BYTE); diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.h b/firmware/targets/f7/furi_hal/furi_hal_nfc.h index c87f04a9a..f4051926a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.h +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.h @@ -402,7 +402,6 @@ void furi_hal_nfc_ll_txrx_on(); void furi_hal_nfc_ll_txrx_off(); -// TODO rework all pollers with furi_hal_nfc_ll_txrx_bits FuriHalNfcReturn furi_hal_nfc_ll_txrx( uint8_t* txBuf, uint16_t txBufLen, diff --git a/firmware/targets/f7/src/update.c b/firmware/targets/f7/src/update.c index c6235a150..520305410 100644 --- a/firmware/targets/f7/src/update.c +++ b/firmware/targets/f7/src/update.c @@ -38,7 +38,7 @@ static bool flipper_update_mount_sd() { } static bool flipper_update_init() { - // TODO: Configure missing peripherals properly + // TODO FL-3504: Configure missing peripherals properly furi_hal_bus_enable(FuriHalBusHSEM); furi_hal_bus_enable(FuriHalBusIPCC); furi_hal_bus_enable(FuriHalBusRNG); diff --git a/lib/SConscript b/lib/SConscript index ab78c6ea4..907a5a41d 100644 --- a/lib/SConscript +++ b/lib/SConscript @@ -23,7 +23,7 @@ env.Append( env.Append( CPPPATH=[ "#/", - "#/lib", # TODO: remove! + "#/lib", # TODO FL-3553: remove! "#/lib/mlib", # Ugly hack Dir("../assets/compiled"), diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index 92dbfcd6a..4a9feed9b 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -69,7 +69,7 @@ static bool bq27220_parameter_check( uint8_t checksum = bq27220_get_checksum(buffer, size + 2); buffer[0] = checksum; - buffer[1] = 4 + size; // TODO: why 4? + buffer[1] = 4 + size; // TODO FL-3519: why 4? if(!furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT)) { FURI_LOG_I(TAG, "CRC write failed"); diff --git a/lib/flipper_application/application_manifest.h b/lib/flipper_application/application_manifest.h index 25e4f8d0a..d09ec9004 100644 --- a/lib/flipper_application/application_manifest.h +++ b/lib/flipper_application/application_manifest.h @@ -16,7 +16,7 @@ extern "C" { #define FAP_MANIFEST_SUPPORTED_VERSION 1 #define FAP_MANIFEST_MAX_APP_NAME_LENGTH 32 -#define FAP_MANIFEST_MAX_ICON_SIZE 32 // TODO: reduce size? +#define FAP_MANIFEST_MAX_ICON_SIZE 32 // TODO FL-3524: reduce size? #pragma pack(push, 1) diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index 539a48c85..bea7c1231 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -1,3 +1,4 @@ +#include "storage/storage.h" #include #include "elf_file.h" #include "elf_file_i.h" @@ -57,6 +58,13 @@ static void address_cache_put(AddressCache_t cache, int symEntry, Elf32_Addr sym /********************************************** ELF ***********************************************/ /**************************************************************************************************/ +static void elf_file_maybe_release_fd(ELFFile* elf) { + if(elf->fd) { + storage_file_free(elf->fd); + elf->fd = NULL; + } +} + static ELFSection* elf_file_get_section(ELFFile* elf, const char* name) { return ELFSectionDict_get(elf->sections, name); } @@ -507,7 +515,7 @@ static SectionType elf_preload_section( #endif // ignore .ARM and .rel.ARM sections - // TODO: how to do it not by name? + // TODO FL-3525: how to do it not by name? // .ARM: type 0x70000001, flags SHF_ALLOC | SHF_LINK_ORDER // .rel.ARM: type 0x9, flags SHT_REL if(str_prefix(name, ".ARM.") || str_prefix(name, ".rel.ARM.") || @@ -764,7 +772,7 @@ void elf_file_free(ELFFile* elf) { free(elf->debug_link_info.debug_link); } - storage_file_free(elf->fd); + elf_file_maybe_release_fd(elf); free(elf); } @@ -792,7 +800,7 @@ bool elf_file_load_section_table(ELFFile* elf) { FuriString* name = furi_string_alloc(); FURI_LOG_D(TAG, "Scan ELF indexs..."); - // TODO: why we start from 1? + // TODO FL-3526: why we start from 1? for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) { Elf32_Shdr section_header; @@ -828,7 +836,7 @@ ElfProcessSectionResult elf_process_section( Elf32_Shdr section_header; // find section - // TODO: why we start from 1? + // TODO FL-3526: why we start from 1? for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) { furi_string_reset(section_name); if(!elf_read_section(elf, section_idx, §ion_header, section_name)) { @@ -855,6 +863,7 @@ ElfProcessSectionResult elf_process_section( } ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { + furi_check(elf->fd != NULL); ELFFileLoadStatus status = ELFFileLoadStatusSuccess; ELFSectionDict_it_t it; @@ -895,6 +904,7 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { FURI_LOG_I(TAG, "Total size of loaded sections: %zu", total_size); } + elf_file_maybe_release_fd(elf); return status; } diff --git a/lib/ibutton/ibutton_worker_modes.c b/lib/ibutton/ibutton_worker_modes.c index 1b8e0a3b8..83e207de9 100644 --- a/lib/ibutton/ibutton_worker_modes.c +++ b/lib/ibutton/ibutton_worker_modes.c @@ -127,7 +127,7 @@ void ibutton_worker_mode_write_blank_tick(iButtonWorker* worker) { furi_assert(worker->key); const bool success = ibutton_protocols_write_blank(worker->protocols, worker->key); - // TODO: pass a proper result to the callback + // TODO FL-3527: pass a proper result to the callback const iButtonWorkerWriteResult result = success ? iButtonWorkerWriteOK : iButtonWorkerWriteNoDetect; if(worker->write_cb != NULL) { @@ -139,7 +139,7 @@ void ibutton_worker_mode_write_copy_tick(iButtonWorker* worker) { furi_assert(worker->key); const bool success = ibutton_protocols_write_copy(worker->protocols, worker->key); - // TODO: pass a proper result to the callback + // TODO FL-3527: pass a proper result to the callback const iButtonWorkerWriteResult result = success ? iButtonWorkerWriteOK : iButtonWorkerWriteNoDetect; if(worker->write_cb != NULL) { diff --git a/lib/ibutton/protocols/blanks/rw1990.c b/lib/ibutton/protocols/blanks/rw1990.c index d3350fcf0..f86e43d99 100644 --- a/lib/ibutton/protocols/blanks/rw1990.c +++ b/lib/ibutton/protocols/blanks/rw1990.c @@ -62,7 +62,7 @@ bool rw1990_write_v1(OneWireHost* host, const uint8_t* data, size_t data_size) { onewire_host_write_bit(host, true); furi_delay_us(10000); - // TODO: Better error handling + // TODO FL-3528: Better error handling return rw1990_read_and_compare(host, data, data_size); } @@ -90,6 +90,6 @@ bool rw1990_write_v2(OneWireHost* host, const uint8_t* data, size_t data_size) { onewire_host_write_bit(host, false); furi_delay_us(10000); - // TODO: Better error handling + // TODO Fl-3528: Better error handling return rw1990_read_and_compare(host, data, data_size); } diff --git a/lib/ibutton/protocols/blanks/tm2004.c b/lib/ibutton/protocols/blanks/tm2004.c index ef6f0619e..b020a218d 100644 --- a/lib/ibutton/protocols/blanks/tm2004.c +++ b/lib/ibutton/protocols/blanks/tm2004.c @@ -21,7 +21,7 @@ bool tm2004_write(OneWireHost* host, const uint8_t* data, size_t data_size) { onewire_host_write(host, data[i]); answer = onewire_host_read(host); - // TODO: check answer CRC + // TODO FL-3529: check answer CRC // pulse indicating that data is correct furi_delay_us(600); @@ -37,6 +37,6 @@ bool tm2004_write(OneWireHost* host, const uint8_t* data, size_t data_size) { } } - // TODO: Better error handling + // TODO FL-3529: Better error handling return i == data_size; } diff --git a/lib/ibutton/protocols/dallas/dallas_common.c b/lib/ibutton/protocols/dallas/dallas_common.c index ebf57e555..6e99a3be2 100644 --- a/lib/ibutton/protocols/dallas/dallas_common.c +++ b/lib/ibutton/protocols/dallas/dallas_common.c @@ -149,7 +149,7 @@ bool dallas_common_emulate_search_rom(OneWireSlave* bus, const DallasCommonRomDa if(!onewire_slave_send_bit(bus, !bit)) return false; onewire_slave_receive_bit(bus); - // TODO: check for errors and return if any + // TODO FL-3530: check for errors and return if any } } diff --git a/lib/ibutton/protocols/dallas/protocol_ds1971.c b/lib/ibutton/protocols/dallas/protocol_ds1971.c index a806acb22..b65e64584 100644 --- a/lib/ibutton/protocols/dallas/protocol_ds1971.c +++ b/lib/ibutton/protocols/dallas/protocol_ds1971.c @@ -53,7 +53,7 @@ const iButtonProtocolDallasBase ibutton_protocol_ds1971 = { .name = DS1971_FAMILY_NAME, .read = dallas_ds1971_read, - .write_blank = NULL, // TODO: Implement writing to blank + .write_blank = NULL, // TODO FL-3531: Implement writing to blank .write_copy = dallas_ds1971_write_copy, .emulate = dallas_ds1971_emulate, .save = dallas_ds1971_save, diff --git a/lib/ibutton/protocols/dallas/protocol_ds1992.c b/lib/ibutton/protocols/dallas/protocol_ds1992.c index 0b4d4b34f..7440882ea 100644 --- a/lib/ibutton/protocols/dallas/protocol_ds1992.c +++ b/lib/ibutton/protocols/dallas/protocol_ds1992.c @@ -73,7 +73,7 @@ bool dallas_ds1992_read(OneWireHost* host, iButtonProtocolData* protocol_data) { bool dallas_ds1992_write_blank(OneWireHost* host, iButtonProtocolData* protocol_data) { DS1992ProtocolData* data = protocol_data; - // TODO: Make this work, currently broken + // TODO FL-3532: Make this work, currently broken return tm2004_write(host, (uint8_t*)data, sizeof(DallasCommonRomData) + DS1992_SRAM_DATA_SIZE); } diff --git a/lib/ibutton/protocols/dallas/protocol_ds1996.c b/lib/ibutton/protocols/dallas/protocol_ds1996.c index 5358b63e2..5970a67bb 100644 --- a/lib/ibutton/protocols/dallas/protocol_ds1996.c +++ b/lib/ibutton/protocols/dallas/protocol_ds1996.c @@ -159,7 +159,7 @@ static bool dallas_ds1996_command_callback(uint8_t command, void* context) { case DALLAS_COMMON_CMD_MATCH_ROM: case DALLAS_COMMON_CMD_OVERDRIVE_MATCH_ROM: - /* TODO: Match ROM command support */ + /* TODO FL-3533: Match ROM command support */ default: return false; } diff --git a/lib/lfrfid/lfrfid_dict_file.c b/lib/lfrfid/lfrfid_dict_file.c index 7ae84f8b6..18bf505f0 100644 --- a/lib/lfrfid/lfrfid_dict_file.c +++ b/lib/lfrfid/lfrfid_dict_file.c @@ -17,13 +17,13 @@ bool lfrfid_dict_file_save(ProtocolDict* dict, ProtocolId protocol, const char* if(!flipper_format_file_open_always(file, filename)) break; if(!flipper_format_write_header_cstr(file, LFRFID_DICT_FILETYPE, 1)) break; - // TODO: write comment about protocol types into file + // TODO FL-3517: write comment about protocol types into file if(!flipper_format_write_string_cstr( file, "Key type", protocol_dict_get_name(dict, protocol))) break; - // TODO: write comment about protocol sizes into file + // TODO FL-3517: write comment about protocol sizes into file protocol_dict_get_data(dict, protocol, data, data_size); diff --git a/lib/lfrfid/lfrfid_worker.h b/lib/lfrfid/lfrfid_worker.h index def9f89a4..22135097e 100644 --- a/lib/lfrfid/lfrfid_worker.h +++ b/lib/lfrfid/lfrfid_worker.h @@ -26,8 +26,8 @@ typedef enum { } LFRFIDWorkerReadType; typedef enum { - LFRFIDWorkerReadSenseStart, // TODO: not implemented - LFRFIDWorkerReadSenseEnd, // TODO: not implemented + LFRFIDWorkerReadSenseStart, // TODO FL-3516: not implemented + LFRFIDWorkerReadSenseEnd, // TODO FL-3516: not implemented LFRFIDWorkerReadSenseCardStart, LFRFIDWorkerReadSenseCardEnd, LFRFIDWorkerReadStartASK, diff --git a/lib/lfrfid/protocols/protocol_hid_ex_generic.c b/lib/lfrfid/protocols/protocol_hid_ex_generic.c index 240128cbe..35500ab59 100644 --- a/lib/lfrfid/protocols/protocol_hid_ex_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_ex_generic.c @@ -193,7 +193,7 @@ bool protocol_hid_ex_generic_write_data(ProtocolHIDEx* protocol, void* data) { }; void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, FuriString* result) { - // TODO: parser and render functions + // TODO FL-3518: parser and render functions UNUSED(protocol); furi_string_printf(result, "Generic HID Extended\r\nData: Unknown"); }; diff --git a/lib/lfrfid/tools/bit_lib.c b/lib/lfrfid/tools/bit_lib.c index 54decb3e8..e0d0ff402 100644 --- a/lib/lfrfid/tools/bit_lib.c +++ b/lib/lfrfid/tools/bit_lib.c @@ -38,7 +38,7 @@ uint8_t bit_lib_get_bits(const uint8_t* data, size_t position, uint8_t length) { if(shift == 0) { return data[position / 8] >> (8 - length); } else { - // TODO fix read out of bounds + // TODO FL-3534: fix read out of bounds uint8_t value = (data[position / 8] << (shift)); value |= data[position / 8 + 1] >> (8 - shift); value = value >> (8 - length); diff --git a/lib/littlefs b/lib/littlefs index 40dba4a55..611c9b20d 160000 --- a/lib/littlefs +++ b/lib/littlefs @@ -1 +1 @@ -Subproject commit 40dba4a556e0d81dfbe64301a6aa4e18ceca896c +Subproject commit 611c9b20db2b99faee261daa7cc9bbe175d3eaca diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index 017b06cae..281463281 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -29,7 +29,7 @@ ReturnCode nfcv_inventory(uint8_t* uid) { ReturnCode ret = ERR_NONE; for(int tries = 0; tries < NFCV_COMMAND_RETRIES; tries++) { - /* TODO: needs proper abstraction via fury_hal(_ll)_* */ + /* TODO: needs proper abstraction via furi_hal(_ll)_* */ ret = rfalNfcvPollerInventory(RFAL_NFCV_NUM_SLOTS_1, 0, NULL, &res, &received); if(ret == ERR_NONE) { @@ -89,7 +89,7 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { FURI_LOG_D(TAG, "Read SYSTEM INFORMATION..."); for(int tries = 0; tries < NFCV_COMMAND_RETRIES; tries++) { - /* TODO: needs proper abstraction via fury_hal(_ll)_* */ + /* TODO: needs proper abstraction via furi_hal(_ll)_* */ ret = rfalNfcvPollerGetSystemInformation( RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, rxBuf, sizeof(rxBuf), &received); diff --git a/lib/print/wrappers.c b/lib/print/wrappers.c index 5cfe10600..b248aeb3d 100644 --- a/lib/print/wrappers.c +++ b/lib/print/wrappers.c @@ -59,7 +59,6 @@ int __wrap_fflush(FILE* stream) { __attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e) { UNUSED(file); UNUSED(line); - // TODO: message file and line number furi_crash(e); } @@ -68,6 +67,5 @@ __attribute__((__noreturn__)) void UNUSED(file); UNUSED(line); UNUSED(func); - // TODO: message file and line number furi_crash(e); } \ No newline at end of file diff --git a/lib/subghz/devices/registry.c b/lib/subghz/devices/registry.c index c0d5bb292..779ba81d7 100644 --- a/lib/subghz/devices/registry.c +++ b/lib/subghz/devices/registry.c @@ -22,7 +22,7 @@ void subghz_device_registry_init(void) { SUBGHZ_RADIO_DEVICE_PLUGIN_API_VERSION, firmware_api_interface); - //ToDo: fix path to plugins + //TODO FL-3556: fix path to plugins if(plugin_manager_load_all(subghz_device->manager, "/any/apps_data/subghz/plugins") != //if(plugin_manager_load_all(subghz_device->manager, APP_DATA_PATH("plugins")) != PluginManagerErrorNone) { diff --git a/lib/subghz/protocols/bin_raw.c b/lib/subghz/protocols/bin_raw.c index 003cc5edd..9e68141b6 100644 --- a/lib/subghz/protocols/bin_raw.c +++ b/lib/subghz/protocols/bin_raw.c @@ -744,7 +744,7 @@ static bool bin_raw_debug("\r\n\r\n"); #endif - //todo can be optimized + //TODO FL-3557: can be optimized BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT]; memcpy( markup_temp, @@ -770,7 +770,7 @@ static bool } } } - //todo can be optimized + //TODO FL-3557: can be optimized if(bin_raw_type == BinRAWTypeGap) { if(data_temp != 0) { //there are sequences with the same number of bits diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index d945d19a1..ae3fef9b5 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -265,7 +265,7 @@ SubGhzProtocolStatus furi_assert(context); UNUSED(context); UNUSED(flipper_format); - //ToDo stub, for backwards compatibility + // stub, for backwards compatibility return SubGhzProtocolStatusOk; } @@ -273,7 +273,6 @@ void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) { furi_assert(context); //SubGhzProtocolDecoderRAW* instance = context; UNUSED(context); - //ToDo no use furi_string_cat_printf(output, "RAW Data"); } diff --git a/lib/subghz/subghz_setting.c b/lib/subghz/subghz_setting.c index da4b8f728..0277e4aed 100644 --- a/lib/subghz/subghz_setting.c +++ b/lib/subghz/subghz_setting.c @@ -255,7 +255,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { } while(flipper_format_read_uint32( fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { - //Todo: add a frequency support check depending on the selected radio device + //Todo FL-3535: add a frequency support check depending on the selected radio device if(furi_hal_subghz_is_frequency_valid(temp_data32)) { FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); FrequencyList_push_back(instance->frequencies, temp_data32); diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index 4eca17419..369f5206c 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -165,7 +165,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); } else { - //todo checking that he managed to write all the data to the TX buffer + //TODO FL-3554: checking that it managed to write all the data to the TX buffer furi_stream_buffer_receive( instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); subghz_tx_rx_worker_tx(instance, data, size_tx); @@ -178,7 +178,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { furi_stream_buffer_bytes_available(instance->stream_rx) == 0) { callback_rx = true; } - //todo checking that he managed to write all the data to the RX buffer + //TODO FL-3554: checking that it managed to write all the data to the RX buffer furi_stream_buffer_send( instance->stream_rx, &data, @@ -189,7 +189,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { callback_rx = false; } } else { - //todo RX buffer overflow + //TODO FL-3555: RX buffer overflow } } } diff --git a/lib/toolbox/crc32_calc.c b/lib/toolbox/crc32_calc.c index c8ae3524a..c0cd169b1 100644 --- a/lib/toolbox/crc32_calc.c +++ b/lib/toolbox/crc32_calc.c @@ -4,7 +4,7 @@ #define CRC_DATA_BUFFER_MAX_LEN 512 uint32_t crc32_calc_buffer(uint32_t crc, const void* buffer, size_t size) { - // TODO: consider removing dependency on LFS + // TODO FL-3547: consider removing dependency on LFS return ~lfs_crc(~crc, buffer, size); } diff --git a/lib/toolbox/stream/file_stream.c b/lib/toolbox/stream/file_stream.c index 064912168..095dce472 100644 --- a/lib/toolbox/stream/file_stream.c +++ b/lib/toolbox/stream/file_stream.c @@ -134,7 +134,7 @@ static size_t file_stream_size(FileStream* stream) { } static size_t file_stream_write(FileStream* stream, const uint8_t* data, size_t size) { - // TODO cache + // TODO FL-3545: cache size_t need_to_write = size; while(need_to_write > 0) { uint16_t was_written = @@ -148,7 +148,7 @@ static size_t file_stream_write(FileStream* stream, const uint8_t* data, size_t } static size_t file_stream_read(FileStream* stream, uint8_t* data, size_t size) { - // TODO cache + // TODO FL-3545: cache size_t need_to_read = size; while(need_to_read > 0) { uint16_t was_read = @@ -172,7 +172,7 @@ static bool file_stream_delete_and_insert( // open scratchpad Stream* scratch_stream = file_stream_alloc(_stream->storage); - // TODO: we need something like "storage_open_tmpfile and storage_close_tmpfile" + // TODO FL-3546: we need something like "storage_open_tmpfile and storage_close_tmpfile" FuriString* scratch_name; FuriString* tmp_name; tmp_name = furi_string_alloc(); diff --git a/lib/toolbox/stream/string_stream.c b/lib/toolbox/stream/string_stream.c index 075f0b26f..f8a360c03 100644 --- a/lib/toolbox/stream/string_stream.c +++ b/lib/toolbox/stream/string_stream.c @@ -106,7 +106,7 @@ static size_t string_stream_size(StringStream* stream) { } static size_t string_stream_write(StringStream* stream, const char* data, size_t size) { - // TODO: can be optimized for edge cases + // TODO FL-3544: can be optimized for edge cases size_t i; for(i = 0; i < size; i++) { string_stream_write_char(stream, data[i]); diff --git a/lib/update_util/dfu_file.c b/lib/update_util/dfu_file.c index 62b139e86..eef9f0645 100644 --- a/lib/update_util/dfu_file.c +++ b/lib/update_util/dfu_file.c @@ -55,7 +55,7 @@ uint8_t dfu_file_validate_headers(File* dfuf, const DfuValidationParams* referen if((dfu_suffix.bLength != sizeof(DfuSuffix)) || (dfu_suffix.bcdDFU != DFU_SUFFIX_VERSION)) { return 0; } - /* TODO: check DfuSignature?.. */ + /* TODO FL-3561: check DfuSignature?.. */ if((dfu_suffix.idVendor != reference_params->vendor) || (dfu_suffix.idProduct != reference_params->product) || @@ -137,7 +137,7 @@ bool dfu_file_process_targets(const DfuUpdateTask* task, File* dfuf, const uint8 return UpdateBlockResult_Failed; } - /* TODO: look into TargetPrefix and validate/filter?.. */ + /* TODO FL-3562: look into TargetPrefix and validate/filter?.. */ for(uint32_t i_element = 0; i_element < target_prefix.dwNbElements; ++i_element) { bytes_read = storage_file_read(dfuf, &image_element, sizeof(ImageElementHeader)); if(bytes_read != sizeof(ImageElementHeader)) { diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index 795fdd5eb..47b2cc0b9 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -54,7 +54,7 @@ static bool FuriString* filetype; - // TODO: compare filetype? + // TODO FL-3543: compare filetype? filetype = furi_string_alloc(); update_manifest->valid = flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) && diff --git a/scripts/fbt/appmanifest.py b/scripts/fbt/appmanifest.py index a677d8413..b8b8a8d68 100644 --- a/scripts/fbt/appmanifest.py +++ b/scripts/fbt/appmanifest.py @@ -2,9 +2,15 @@ import os import re from dataclasses import dataclass, field from enum import Enum -from fbt.util import resolve_real_dir_node from typing import Callable, ClassVar, List, Optional, Tuple, Union +try: + from fbt.util import resolve_real_dir_node +except ImportError: + # When running outside of SCons, we don't have access to SCons.Node + def resolve_real_dir_node(node): + return node + class FlipperManifestException(Exception): pass diff --git a/scripts/fbt/sdk/cache.py b/scripts/fbt/sdk/cache.py index b6f6edbe5..074cac6b9 100644 --- a/scripts/fbt/sdk/cache.py +++ b/scripts/fbt/sdk/cache.py @@ -237,6 +237,7 @@ class SdkCache: removed_entries = known_set - new_set if removed_entries: print(f"Removed: {removed_entries}") + self.loaded_dirty_version = True known_set -= removed_entries # If any of removed entries was a part of active API, that's a major bump if update_version and any( diff --git a/scripts/fbt_tools/compilation_db.py b/scripts/fbt_tools/compilation_db.py index 17ff6aaa3..1f829ddb4 100644 --- a/scripts/fbt_tools/compilation_db.py +++ b/scripts/fbt_tools/compilation_db.py @@ -38,7 +38,7 @@ from SCons.Tool.cxx import CXXSuffixes from SCons.Tool.cc import CSuffixes from SCons.Tool.asm import ASSuffixes, ASPPSuffixes -# TODO: Is there a better way to do this than this global? Right now this exists so that the +# TODO FL-3542: Is there a better way to do this than this global? Right now this exists so that the # emitter we add can record all of the things it emits, so that the scanner for the top level # compilation database can access the complete list, and also so that the writer has easy # access to write all of the files. But it seems clunky. How can the emitter and the scanner @@ -91,7 +91,7 @@ def make_emit_compilation_DB_entry(comstr): __COMPILATIONDB_ENV=env, ) - # TODO: Technically, these next two lines should not be required: it should be fine to + # TODO FL-3541: Technically, these next two lines should not be required: it should be fine to # cache the entries. However, they don't seem to update properly. Since they are quick # to re-generate disable caching and sidestep this problem. env.AlwaysBuild(entry) diff --git a/scripts/fbt_tools/fbt_debugopts.py b/scripts/fbt_tools/fbt_debugopts.py index d46ecd8f3..392465a51 100644 --- a/scripts/fbt_tools/fbt_debugopts.py +++ b/scripts/fbt_tools/fbt_debugopts.py @@ -21,7 +21,7 @@ def generate(env, **kw): FBT_DEBUG_DIR="${FBT_SCRIPT_DIR}/debug", ) - if (adapter_serial := env.subst("$OPENOCD_ADAPTER_SERIAL")) != "auto": + if (adapter_serial := env.subst("$SWD_TRANSPORT_SERIAL")) != "auto": env.Append( OPENOCD_OPTS=[ "-c", diff --git a/scripts/fbt_tools/fbt_dist.py b/scripts/fbt_tools/fbt_dist.py index 105f501aa..3645008c5 100644 --- a/scripts/fbt_tools/fbt_dist.py +++ b/scripts/fbt_tools/fbt_dist.py @@ -52,22 +52,16 @@ def AddFwProject(env, base_env, fw_type, fw_env_key): return project_env -def AddOpenOCDFlashTarget(env, targetenv, **kw): - openocd_target = env.OpenOCDFlash( - "#build/oocd-${BUILD_CFG}-flash.flag", - targetenv["FW_BIN"], - OPENOCD_COMMAND=[ - "-c", - "program ${SOURCE.posix} reset exit ${BASE_ADDRESS}", - ], - BUILD_CFG=targetenv.subst("$FIRMWARE_BUILD_CFG"), - BASE_ADDRESS=targetenv.subst("$IMAGE_BASE_ADDRESS"), +def AddFwFlashTarget(env, targetenv, **kw): + fwflash_target = env.FwFlash( + "#build/flash.flag", + targetenv["FW_ELF"], **kw, ) - env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_flash"), openocd_target) + env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_flash"), fwflash_target) if env["FORCE"]: - env.AlwaysBuild(openocd_target) - return openocd_target + env.AlwaysBuild(fwflash_target) + return fwflash_target def AddJFlashTarget(env, targetenv, **kw): @@ -115,7 +109,7 @@ def generate(env): env.SetDefault(COPROCOMSTR="\tCOPRO\t${TARGET}") env.AddMethod(AddFwProject) env.AddMethod(DistCommand) - env.AddMethod(AddOpenOCDFlashTarget) + env.AddMethod(AddFwFlashTarget) env.AddMethod(GetProjectDirName) env.AddMethod(AddJFlashTarget) env.AddMethod(AddUsbFlashTarget) @@ -125,30 +119,53 @@ def generate(env): SELFUPDATE_SCRIPT="${FBT_SCRIPT_DIR}/selfupdate.py", DIST_SCRIPT="${FBT_SCRIPT_DIR}/sconsdist.py", COPRO_ASSETS_SCRIPT="${FBT_SCRIPT_DIR}/assets.py", + FW_FLASH_SCRIPT="${FBT_SCRIPT_DIR}/fwflash.py", ) env.Append( BUILDERS={ + "FwFlash": Builder( + action=[ + [ + "${PYTHON3}", + "${FW_FLASH_SCRIPT}", + "-d" if env["VERBOSE"] else "", + "--interface=${SWD_TRANSPORT}", + "--serial=${SWD_TRANSPORT_SERIAL}", + "${SOURCE}", + ], + Touch("${TARGET}"), + ] + ), "UsbInstall": Builder( action=[ - Action( - '${PYTHON3} "${SELFUPDATE_SCRIPT}" -p ${FLIP_PORT} ${UPDATE_BUNDLE_DIR}/update.fuf' - ), + [ + "${PYTHON3}", + "${SELFUPDATE_SCRIPT}", + "-p", + "${FLIP_PORT}", + "${UPDATE_BUNDLE_DIR}/update.fuf", + ], Touch("${TARGET}"), ] ), "CoproBuilder": Builder( action=Action( [ - '${PYTHON3} "${COPRO_ASSETS_SCRIPT}" ' - "copro ${COPRO_CUBE_DIR} " - "${TARGET} ${COPRO_MCU_FAMILY} " - "--cube_ver=${COPRO_CUBE_VERSION} " - "--stack_type=${COPRO_STACK_TYPE} " - '--stack_file="${COPRO_STACK_BIN}" ' - "--stack_addr=${COPRO_STACK_ADDR} ", + [ + "${PYTHON3}", + "${COPRO_ASSETS_SCRIPT}", + "copro", + "${COPRO_CUBE_DIR}", + "${TARGET}", + "${COPRO_MCU_FAMILY}", + "--cube_ver=${COPRO_CUBE_VERSION}", + "--stack_type=${COPRO_STACK_TYPE}", + "--stack_file=${COPRO_STACK_BIN}", + "--stack_addr=${COPRO_STACK_ADDR}", + ] ], - "$COPROCOMSTR", + "${COPROCOMSTR}", ) ), } diff --git a/scripts/fbt_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py index 642c1c989..6059628f0 100644 --- a/scripts/fbt_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -53,6 +53,11 @@ class AppBuilder: FAP_SRC_DIR=self.app._appdir, FAP_WORK_DIR=self.app_work_dir, ) + self.app_env.Append( + CPPDEFINES=[ + ("FAP_VERSION", f'"{".".join(map(str, self.app.fap_version))}"') + ], + ) self.app_env.VariantDir(self.app_work_dir, self.app._appdir, duplicate=False) def _build_external_files(self): diff --git a/scripts/fbt_tools/fbt_help.py b/scripts/fbt_tools/fbt_help.py index e9364a42b..701435639 100644 --- a/scripts/fbt_tools/fbt_help.py +++ b/scripts/fbt_tools/fbt_help.py @@ -16,8 +16,8 @@ Firmware & apps: Flashing & debugging: - flash, flash_blackmagic, jflash: - Flash firmware to target using debug probe + flash, jflash: + Flash firmware to target using SWD probe. See also SWD_TRANSPORT, SWD_TRANSPORT_SERIAL flash_usb, flash_usb_full: Install firmware using self-update package debug, debug_other, blackmagic: diff --git a/scripts/flipper/storage.py b/scripts/flipper/storage.py index 2c9c043d5..40af5cebc 100644 --- a/scripts/flipper/storage.py +++ b/scripts/flipper/storage.py @@ -150,7 +150,7 @@ class FlipperStorage: for line in lines: try: - # TODO: better decoding, considering non-ascii characters + # TODO FL-3539: better decoding, considering non-ascii characters line = line.decode("ascii") except Exception: continue @@ -193,7 +193,7 @@ class FlipperStorage: for line in lines: try: - # TODO: better decoding, considering non-ascii characters + # TODO FL-3539: better decoding, considering non-ascii characters line = line.decode("ascii") except Exception: continue diff --git a/scripts/flipper/utils/openocd.py b/scripts/flipper/utils/openocd.py index 1309055b8..a43568090 100644 --- a/scripts/flipper/utils/openocd.py +++ b/scripts/flipper/utils/openocd.py @@ -78,7 +78,7 @@ class OpenOCD: def _wait_for_openocd_tcl(self): """Wait for OpenOCD to start""" - # TODO: timeout + # TODO Fl-3538: timeout while True: stderr = self.process.stderr if not stderr: @@ -128,7 +128,7 @@ class OpenOCD: def _recv(self): """Read from the stream until the token (\x1a) was received.""" - # TODO: timeout + # TODO FL-3538: timeout data = bytes() while True: chunk = self.socket.recv(4096) diff --git a/scripts/flipper/utils/stm32wb55.py b/scripts/flipper/utils/stm32wb55.py index 4a47b8bea..9ea803220 100644 --- a/scripts/flipper/utils/stm32wb55.py +++ b/scripts/flipper/utils/stm32wb55.py @@ -247,7 +247,7 @@ class STM32WB55: def flash_wait_for_operation(self): # Wait for flash operation to complete - # TODO: timeout + # TODO FL-3537: timeout while True: self.FLASH_SR.load() if self.FLASH_SR.BSY == 0: diff --git a/scripts/program.py b/scripts/fwflash.py similarity index 71% rename from scripts/program.py rename to scripts/fwflash.py index f3e7e3e2d..2b1ad543b 100755 --- a/scripts/program.py +++ b/scripts/fwflash.py @@ -6,14 +6,17 @@ import subprocess import time import typing from abc import ABC, abstractmethod -from dataclasses import dataclass +from dataclasses import dataclass, field from flipper.app import App +# When adding an interface, also add it to SWD_TRANSPORT in fbt options + + class Programmer(ABC): @abstractmethod - def flash(self, bin: str) -> bool: + def flash(self, file_path: str, do_verify: bool) -> bool: pass @abstractmethod @@ -32,9 +35,9 @@ class Programmer(ABC): @dataclass class OpenOCDInterface: name: str - file: str + config_file: str serial_cmd: str - additional_args: typing.Optional[list[str]] = None + additional_args: typing.Optional[list[str]] = field(default_factory=list) class OpenOCDProgrammer(Programmer): @@ -44,12 +47,10 @@ class OpenOCDProgrammer(Programmer): self.serial: typing.Optional[str] = None def _add_file(self, params: list[str], file: str): - params.append("-f") - params.append(file) + params += ["-f", file] def _add_command(self, params: list[str], command: str): - params.append("-c") - params.append(command) + params += ["-c", command] def _add_serial(self, params: list[str], serial: str): self._add_command(params, f"{self.interface.serial_cmd} {serial}") @@ -57,22 +58,27 @@ class OpenOCDProgrammer(Programmer): def set_serial(self, serial: str): self.serial = serial - def flash(self, bin: str) -> bool: - i = self.interface - + def flash(self, file_path: str, do_verify: bool) -> bool: if os.altsep: - bin = bin.replace(os.sep, os.altsep) + file_path = file_path.replace(os.sep, os.altsep) openocd_launch_params = ["openocd"] - self._add_file(openocd_launch_params, i.file) + self._add_file(openocd_launch_params, self.interface.config_file) if self.serial: self._add_serial(openocd_launch_params, self.serial) - if i.additional_args: - for a in i.additional_args: - self._add_command(openocd_launch_params, a) + for additional_arg in self.interface.additional_args: + self._add_command(openocd_launch_params, additional_arg) self._add_file(openocd_launch_params, "target/stm32wbx.cfg") self._add_command(openocd_launch_params, "init") - self._add_command(openocd_launch_params, f"program {bin} reset exit 0x8000000") + program_params = [ + "program", + f'"{file_path}"', + "verify" if do_verify else "", + "reset", + "exit", + "0x8000000" if file_path.endswith(".bin") else "", + ] + self._add_command(openocd_launch_params, " ".join(program_params)) # join the list of parameters into a string, but add quote if there are spaces openocd_launch_params_string = " ".join( @@ -105,7 +111,7 @@ class OpenOCDProgrammer(Programmer): i = self.interface openocd_launch_params = ["openocd"] - self._add_file(openocd_launch_params, i.file) + self._add_file(openocd_launch_params, i.config_file) if self.serial: self._add_serial(openocd_launch_params, self.serial) if i.additional_args: @@ -187,7 +193,7 @@ def _resolve_hostname(hostname): def blackmagic_find_networked(serial: str): - if not serial: + if not serial or serial == "auto": serial = "blackmagic.local" # remove the tcp: prefix if it's there @@ -234,7 +240,7 @@ class BlackmagicProgrammer(Programmer): else: self.port = serial - def flash(self, bin: str) -> bool: + def flash(self, file_path: str, do_verify: bool) -> bool: if not self.port: if not self.probe(): return False @@ -242,12 +248,14 @@ class BlackmagicProgrammer(Programmer): # We can convert .bin to .elf with objcopy: # arm-none-eabi-objcopy -I binary -O elf32-littlearm --change-section-address=.data=0x8000000 -B arm -S app.bin app.elf # But I choose to use the .elf file directly because we are flashing our own firmware and it always has an elf predecessor. - elf = bin.replace(".bin", ".elf") - if not os.path.exists(elf): - self.logger.error( - f"Sorry, but Blackmagic can't flash .bin file, and {elf} doesn't exist" - ) - return False + + if file_path.endswith(".bin"): + file_path = file_path[:-4] + ".elf" + if not os.path.exists(file_path): + self.logger.error( + f"Sorry, but Blackmagic can't flash .bin file, and {file_path} doesn't exist" + ) + return False # arm-none-eabi-gdb build/f7-firmware-D/firmware.bin # -ex 'set pagination off' @@ -260,7 +268,7 @@ class BlackmagicProgrammer(Programmer): # -ex 'compare-sections' # -ex 'quit' - gdb_launch_params = ["arm-none-eabi-gdb", elf] + gdb_launch_params = ["arm-none-eabi-gdb", file_path] self._add_command(gdb_launch_params, f"target extended-remote {self.port}") self._add_command(gdb_launch_params, "set pagination off") self._add_command(gdb_launch_params, "set confirm off") @@ -268,7 +276,8 @@ class BlackmagicProgrammer(Programmer): self._add_command(gdb_launch_params, "attach 1") self._add_command(gdb_launch_params, "set mem inaccessible-by-default off") self._add_command(gdb_launch_params, "load") - self._add_command(gdb_launch_params, "compare-sections") + if do_verify: + self._add_command(gdb_launch_params, "compare-sections") self._add_command(gdb_launch_params, "quit") self.logger.debug(f"Launching: {' '.join(gdb_launch_params)}") @@ -314,7 +323,9 @@ class BlackmagicProgrammer(Programmer): return self.name -programmers: list[Programmer] = [ +#################### + +local_flash_interfaces: list[Programmer] = [ OpenOCDProgrammer( OpenOCDInterface( "cmsis-dap", @@ -325,47 +336,64 @@ programmers: list[Programmer] = [ ), OpenOCDProgrammer( OpenOCDInterface( - "stlink", "interface/stlink.cfg", "hla_serial", ["transport select hla_swd"] + "stlink", + "interface/stlink.cfg", + "hla_serial", + ["transport select hla_swd"], ), ), BlackmagicProgrammer(blackmagic_find_serial, "blackmagic_usb"), ] -network_programmers = [ +network_flash_interfaces: list[Programmer] = [ BlackmagicProgrammer(blackmagic_find_networked, "blackmagic_wifi") ] +all_flash_interfaces = [*local_flash_interfaces, *network_flash_interfaces] + +#################### + class Main(App): + AUTO_INTERFACE = "auto" + def init(self): - self.subparsers = self.parser.add_subparsers(help="sub-command help") - self.parser_flash = self.subparsers.add_parser("flash", help="Flash a binary") - self.parser_flash.add_argument( - "bin", + self.parser.add_argument( + "filename", type=str, - help="Binary to flash", + help="File to flash", ) - interfaces = [i.get_name() for i in programmers] - interfaces.extend([i.get_name() for i in network_programmers]) - self.parser_flash.add_argument( + self.parser.add_argument( + "--verify", + "-v", + action="store_true", + help="Verify flash after programming", + default=False, + ) + self.parser.add_argument( "--interface", - choices=interfaces, + choices=( + self.AUTO_INTERFACE, + *[i.get_name() for i in all_flash_interfaces], + ), type=str, + default=self.AUTO_INTERFACE, help="Interface to use", ) - self.parser_flash.add_argument( + self.parser.add_argument( "--serial", type=str, + default=self.AUTO_INTERFACE, help="Serial number or port of the programmer", ) - self.parser_flash.set_defaults(func=self.flash) + self.parser.set_defaults(func=self.flash) - def _search_interface(self, serial: typing.Optional[str]) -> list[Programmer]: + def _search_interface(self, interface_list: list[Programmer]) -> list[Programmer]: found_programmers = [] - for p in programmers: + for p in interface_list: name = p.get_name() - if serial: + if (serial := self.args.serial) != self.AUTO_INTERFACE: p.set_serial(serial) self.logger.debug(f"Trying {name} with {serial}") else: @@ -373,29 +401,7 @@ class Main(App): if p.probe(): self.logger.debug(f"Found {name}") - found_programmers += [p] - else: - self.logger.debug(f"Failed to probe {name}") - - return found_programmers - - def _search_network_interface( - self, serial: typing.Optional[str] - ) -> list[Programmer]: - found_programmers = [] - - for p in network_programmers: - name = p.get_name() - - if serial: - p.set_serial(serial) - self.logger.debug(f"Trying {name} with {serial}") - else: - self.logger.debug(f"Trying {name}") - - if p.probe(): - self.logger.debug(f"Found {name}") - found_programmers += [p] + found_programmers.append(p) else: self.logger.debug(f"Failed to probe {name}") @@ -403,55 +409,60 @@ class Main(App): def flash(self): start_time = time.time() - bin_path = os.path.abspath(self.args.bin) + file_path = os.path.abspath(self.args.filename) - if not os.path.exists(bin_path): - self.logger.error(f"Binary file not found: {bin_path}") + if not os.path.exists(file_path): + self.logger.error(f"Binary file not found: {file_path}") return 1 - if self.args.interface: - i_name = self.args.interface - interfaces = [p for p in programmers if p.get_name() == i_name] - if len(interfaces) == 0: - interfaces = [p for p in network_programmers if p.get_name() == i_name] - else: - self.logger.info("Probing for interfaces...") - interfaces = self._search_interface(self.args.serial) + if self.args.interface != self.AUTO_INTERFACE: + available_interfaces = list( + filter( + lambda p: p.get_name() == self.args.interface, + all_flash_interfaces, + ) + ) - if len(interfaces) == 0: + else: + self.logger.info("Probing for local interfaces...") + available_interfaces = self._search_interface(local_flash_interfaces) + + if not available_interfaces: # Probe network blackmagic self.logger.info("Probing for network interfaces...") - interfaces = self._search_network_interface(self.args.serial) + available_interfaces = self._search_interface(network_flash_interfaces) - if len(interfaces) == 0: + if not available_interfaces: self.logger.error("No interface found") return 1 - - if len(interfaces) > 1: + elif len(available_interfaces) > 1: self.logger.error("Multiple interfaces found: ") self.logger.error( - f"Please specify '--interface={[i.get_name() for i in interfaces]}'" + f"Please specify '--interface={[i.get_name() for i in available_interfaces]}'" ) return 1 - interface = interfaces[0] + interface = available_interfaces.pop(0) - if self.args.serial: + if self.args.serial != self.AUTO_INTERFACE: interface.set_serial(self.args.serial) self.logger.info( - f"Flashing {bin_path} via {interface.get_name()} with {self.args.serial}" + f"Flashing {file_path} via {interface.get_name()} with {self.args.serial}" ) else: - self.logger.info(f"Flashing {bin_path} via {interface.get_name()}") + self.logger.info(f"Flashing {file_path} via {interface.get_name()}") - if not interface.flash(bin_path): + if not interface.flash(file_path, self.args.verify): self.logger.error(f"Failed to flash via {interface.get_name()}") return 1 flash_time = time.time() - start_time - bin_size = os.path.getsize(bin_path) self.logger.info(f"Flashed successfully in {flash_time:.2f}s") - self.logger.info(f"Effective speed: {bin_size / flash_time / 1024:.2f} KiB/s") + if file_path.endswith(".bin"): + bin_size = os.path.getsize(file_path) + self.logger.info( + f"Effective speed: {bin_size / flash_time / 1024:.2f} KiB/s" + ) return 0 diff --git a/scripts/toolchain/windows-toolchain-download.ps1 b/scripts/toolchain/windows-toolchain-download.ps1 index 05ea4be2c..f30b157da 100644 --- a/scripts/toolchain/windows-toolchain-download.ps1 +++ b/scripts/toolchain/windows-toolchain-download.ps1 @@ -1,7 +1,7 @@ Set-StrictMode -Version 2.0 $ErrorActionPreference = "Stop" [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" -# TODO: fix +# TODO FL-3536: fix path to download_dir $download_dir = (Get-Item "$PSScriptRoot\..\..").FullName $toolchain_version = $args[0] $toolchain_target_path = $args[1] diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index 1c2f2bdf5..1630135c2 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -144,24 +144,20 @@ dist_env = env.Clone( ], ) -openocd_target = dist_env.OpenOCDFlash( +flash_target = dist_env.FwFlash( dist_env["UFBT_STATE_DIR"].File("flash"), - dist_env["FW_BIN"], - OPENOCD_COMMAND=[ - "-c", - "program ${SOURCE.posix} reset exit 0x08000000", - ], + dist_env["FW_ELF"], ) -dist_env.Alias("firmware_flash", openocd_target) -dist_env.Alias("flash", openocd_target) +dist_env.Alias("firmware_flash", flash_target) +dist_env.Alias("flash", flash_target) if env["FORCE"]: - env.AlwaysBuild(openocd_target) + env.AlwaysBuild(flash_target) firmware_jflash = dist_env.JFlash( dist_env["UFBT_STATE_DIR"].File("jflash"), dist_env["FW_BIN"], - JFLASHADDR="0x20000000", + JFLASHADDR="0x08000000", ) dist_env.Alias("firmware_jflash", firmware_jflash) dist_env.Alias("jflash", firmware_jflash) @@ -213,21 +209,6 @@ dist_env.PhonyTarget( GDBPYOPTS=debug_other_opts, ) - -dist_env.PhonyTarget( - "flash_blackmagic", - "$GDB $GDBOPTS $SOURCES $GDBFLASH", - source=dist_env["FW_ELF"], - GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}", - GDBREMOTE="${BLACKMAGIC_ADDR}", - GDBFLASH=[ - "-ex", - "load", - "-ex", - "quit", - ], -) - flash_usb_full = dist_env.UsbInstall( dist_env["UFBT_STATE_DIR"].File("usbinstall"), [], diff --git a/scripts/ufbt/commandline.scons b/scripts/ufbt/commandline.scons index 349b4ef25..99c34c35d 100644 --- a/scripts/ufbt/commandline.scons +++ b/scripts/ufbt/commandline.scons @@ -55,9 +55,21 @@ vars.AddVariables( "Blackmagic probe location", "auto", ), + EnumVariable( + "SWD_TRANSPORT", + help="SWD interface adapter type", + default="auto", + allowed_values=[ + "auto", + "cmsis-dap", + "stlink", + "blackmagic_usb", + "blackmagic_wifi", + ], + ), ( - "OPENOCD_ADAPTER_SERIAL", - "OpenOCD adapter serial number", + "SWD_TRANSPORT_SERIAL", + "SWD interface adapter serial number", "auto", ), ( diff --git a/scripts/ufbt/site_tools/ufbt_help.py b/scripts/ufbt/site_tools/ufbt_help.py index 3d7f6f002..1df6a0591 100644 --- a/scripts/ufbt/site_tools/ufbt_help.py +++ b/scripts/ufbt/site_tools/ufbt_help.py @@ -20,8 +20,8 @@ Building: Build FAP app with appid={APPID}; upload & start it over USB Flashing & debugging: - flash, flash_blackmagic, *jflash: - Flash firmware to target using debug probe + flash, *jflash: + Flash firmware to target using SWD probe. See also SWD_TRANSPORT, SWD_TRANSPORT_SERIAL flash_usb, flash_usb_full: Install firmware using self-update package debug, debug_other, blackmagic: diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index bc0e65093..b8965afe1 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -180,9 +180,21 @@ vars.AddVariables( "Blackmagic probe location", "auto", ), + EnumVariable( + "SWD_TRANSPORT", + help="SWD interface adapter type", + default="auto", + allowed_values=[ + "auto", + "cmsis-dap", + "stlink", + "blackmagic_usb", + "blackmagic_wifi", + ], + ), ( - "OPENOCD_ADAPTER_SERIAL", - "OpenOCD adapter serial number", + "SWD_TRANSPORT_SERIAL", + "SWD interface adapter serial number", "auto", ), ( diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 5c6f18d68..97b7ac095 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -23,18 +23,14 @@ appenv.Replace( appenv.AppendUnique( CCFLAGS=[ - "-ggdb3", "-mword-relocations", "-mlong-calls", "-fno-common", "-nostdlib", - "-fvisibility=hidden", ], LINKFLAGS=[ "-Ur", "-Wl,-Ur", - # "-Wl,--orphan-handling=error", - "-Bsymbolic", "-nostartfiles", "-mlong-calls", "-fno-common",