Merge branch 'ofw-dev' into dev

This commit is contained in:
MX 2023-08-22 21:53:50 +03:00
commit 20593d56c0
No known key found for this signature in database
GPG key ID: 7CCC66B7DBDD1C83
78 changed files with 336 additions and 303 deletions

View file

@ -28,29 +28,17 @@
"command": "./fbt -c" "command": "./fbt -c"
}, },
{ {
"label": "[Release] Flash (ST-Link)", "label": "[Release] Flash (SWD)",
"group": "build", "group": "build",
"type": "shell", "type": "shell",
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash" "command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash"
}, },
{ {
"label": "[Debug] Flash (ST-Link)", "label": "[Debug] Flash (SWD)",
"group": "build", "group": "build",
"type": "shell", "type": "shell",
"command": "./fbt FORCE=1 flash" "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)", "label": "[Release] Flash (JLink)",
"group": "build", "group": "build",

View file

@ -185,27 +185,15 @@ copro_dist = distenv.CoproBuilder(
distenv.AlwaysBuild(copro_dist) distenv.AlwaysBuild(copro_dist)
distenv.Alias("copro_dist", 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) distenv.Alias("flash", firmware_flash)
# To be implemented in fwflash.py
firmware_jflash = distenv.AddJFlashTarget(firmware_env) firmware_jflash = distenv.AddJFlashTarget(firmware_env)
distenv.Alias("jflash", firmware_jflash) distenv.Alias("jflash", firmware_jflash)
firmware_bm_flash = distenv.PhonyTarget( 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(
"gdb_trace_all", "gdb_trace_all",
"$GDB $GDBOPTS $SOURCES $GDBFLASH", "$GDB $GDBOPTS $SOURCES $GDBFLASH",
source=firmware_env["FW_ELF"], source=firmware_env["FW_ELF"],

View file

@ -174,7 +174,7 @@ bool WIEGAND::DoWiegandConversion() {
return false; return false;
} }
// TODO: Handle validation failure case! // TODO FL-3490: Handle validation failure case!
} else if(4 == _bitCount) { } else if(4 == _bitCount) {
// 4-bit Wiegand codes have no data integrity check so we just // 4-bit Wiegand codes have no data integrity check so we just
// read the LOW nibble. // read the LOW nibble.

View file

@ -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); subghz_decoder_princeton_for_testing_parse(instance->decoder, level, duration);
} }
//todo
static void subghz_test_packet_rx_pt_callback(SubGhzDecoderPrinceton* parser, void* context) { static void subghz_test_packet_rx_pt_callback(SubGhzDecoderPrinceton* parser, void* context) {
UNUSED(parser); UNUSED(parser);
furi_assert(context); furi_assert(context);

View file

@ -26,7 +26,7 @@ void test_furi_memmgr() {
mu_assert_int_eq(66, ((uint8_t*)ptr)[i]); 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); free(ptr);
// allocate and zero-initialize array (calloc) // allocate and zero-initialize array (calloc)

View file

@ -69,7 +69,7 @@ MU_TEST(mu_test_furi_string_mem) {
mu_check(string != NULL); mu_check(string != NULL);
mu_check(!furi_string_empty(string)); 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 // test furi_string_reset
furi_string_reset(string); furi_string_reset(string);

View file

@ -311,7 +311,7 @@ MU_TEST(test_bit_lib_test_parity) {
} }
MU_TEST(test_bit_lib_remove_bit_every_nth) { 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_i[1] = {0b00001111};
uint8_t data_o[1] = {0b00011111}; uint8_t data_o[1] = {0b00011111};
size_t length; size_t length;

View file

@ -90,7 +90,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
Loader* loader = furi_record_open(RECORD_LOADER); Loader* loader = furi_record_open(RECORD_LOADER);
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); 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)) { if(loader_is_locked(loader)) {
printf("RPC: stop all applications to run tests\r\n"); printf("RPC: stop all applications to run tests\r\n");
notification_message(notification, &sequence_blink_magenta_100); notification_message(notification, &sequence_blink_magenta_100);

View file

@ -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); uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUart);
if(prev_state == 0) { if(prev_state == 0) {
scene_usb_uart = malloc(sizeof(SceneUsbUartBridge)); 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.uart_ch = 0;
scene_usb_uart->cfg.flow_pins = 0; scene_usb_uart->cfg.flow_pins = 0;
scene_usb_uart->cfg.baudrate_mode = 0; scene_usb_uart->cfg.baudrate_mode = 0;

View file

@ -85,7 +85,7 @@ static void infrared_cli_print_usage(void) {
printf("\tir decode <input_file> [<output_file>]\r\n"); printf("\tir decode <input_file> [<output_file>]\r\n");
printf("\tir universal <remote_name> <signal_name>\r\n"); printf("\tir universal <remote_name> <signal_name>\r\n");
printf("\tir universal list <remote_name>\r\n"); printf("\tir universal list <remote_name>\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"); printf("\tAvailable universal remotes: tv audio ac projector\r\n");
} }
@ -211,7 +211,7 @@ static bool infrared_cli_decode_raw_signal(
size_t i; size_t i;
for(i = 0; i < raw_signal->timings_size; ++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]); const InfraredMessage* message = infrared_decode(decoder, level, raw_signal->timings[i]);
if(message) { if(message) {

View file

@ -336,7 +336,6 @@ static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
} }
subghz_txrx_idle(instance); subghz_txrx_idle(instance);
subghz_txrx_speaker_off(instance); subghz_txrx_speaker_off(instance);
//Todo: Show message
} }
FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) { FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) {

View file

@ -30,7 +30,7 @@ bool subghz_txrx_gen_data_protocol(
subghz_receiver_search_decoder_base_by_name(instance->receiver, protocol_name); subghz_receiver_search_decoder_base_by_name(instance->receiver, protocol_name);
if(instance->decoder_result == NULL) { if(instance->decoder_result == NULL) {
//TODO: Error //TODO FL-3502: Error
// furi_string_set(error_str, "Protocol not\nfound!"); // furi_string_set(error_str, "Protocol not\nfound!");
// scene_manager_next_scene(scene_manager, SubGhzSceneShowErrorSub); // scene_manager_next_scene(scene_manager, SubGhzSceneShowErrorSub);
FURI_LOG_E(TAG, "Protocol not found!"); FURI_LOG_E(TAG, "Protocol not found!");

View file

@ -25,7 +25,7 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
if(subghz_txrx_load_decoder_by_name_protocol( if(subghz_txrx_load_decoder_by_name_protocol(
subghz->txrx, subghz->txrx,
subghz_history_get_protocol_name(subghz->history, subghz->idx_menu_chosen))) { 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_protocol_decoder_base_deserialize(
subghz_txrx_get_decoder(subghz->txrx), subghz_txrx_get_decoder(subghz->txrx),
subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen)); subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen));

View file

@ -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); SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
if(!strcmp(furi_string_get_cstr(temp_str), "CUSTOM")) { 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 //delete preset if it already exists
subghz_setting_delete_custom_preset(setting, furi_string_get_cstr(temp_str)); subghz_setting_delete_custom_preset(setting, furi_string_get_cstr(temp_str));
//load custom preset from file //load custom preset from file

View file

@ -51,6 +51,12 @@ extern const size_t FLIPPER_ON_SYSTEM_START_COUNT;
extern const FlipperInternalApplication FLIPPER_SYSTEM_APPS[]; extern const FlipperInternalApplication FLIPPER_SYSTEM_APPS[];
extern const size_t FLIPPER_SYSTEM_APPS_COUNT; 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; extern const FlipperInternalApplication FLIPPER_ARCHIVE;
/* Settings list /* Settings list

View file

@ -101,7 +101,7 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) {
char buffer[20]; char buffer[20];
snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->time_minute); 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( view_port_set_width(
desktop->clock_viewport, desktop->clock_viewport,
canvas_string_width(canvas, buffer) - 1 + (desktop->time_minute % 10 == 1)); 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; return true;
case DesktopGlobalAfterAppFinished: case DesktopGlobalAfterAppFinished:
animation_manager_load_and_continue_animation(desktop->animation_manager); 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 // locking and unlocking
DESKTOP_SETTINGS_LOAD(&desktop->settings); DESKTOP_SETTINGS_LOAD(&desktop->settings);
@ -382,12 +382,7 @@ Desktop* desktop_alloc() {
} }
gui_add_view_port(desktop->gui, desktop->stealth_mode_icon_viewport, GuiLayerStatusBarLeft); 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); 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->notification = furi_record_open(RECORD_NOTIFICATION);
desktop->app_start_stop_subscription = furi_pubsub_subscribe( 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); 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); view_dispatcher_run(desktop->view_dispatcher);
furi_crash("That was unexpected"); furi_crash("That was unexpected");

View file

@ -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_t* array = ButtonMatrix_get(model->button_matrix, i);
ButtonArray_init(*array); ButtonArray_init(*array);
ButtonArray_reserve(*array, reserve_x); ButtonArray_reserve(*array, reserve_x);
// TODO: do we need to clear allocated memory of ptr-s to ButtonItem ??
} }
LabelList_init(model->labels); LabelList_init(model->labels);
}, },

View file

@ -272,7 +272,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e
} else if(view_dispatcher->navigation_event_callback) { } else if(view_dispatcher->navigation_event_callback) {
// Dispatch navigation event // Dispatch navigation event
if(!view_dispatcher->navigation_event_callback(view_dispatcher->event_context)) { 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); view_dispatcher_stop(view_dispatcher);
return; return;
} }

View file

@ -7,7 +7,7 @@
#include "gui.h" #include "gui.h"
#include "gui_i.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(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count");
_Static_assert( _Static_assert(

View file

@ -1,4 +1,5 @@
#include "loader.h" #include "loader.h"
#include "core/core_defines.h"
#include "loader_i.h" #include "loader_i.h"
#include <applications.h> #include <applications.h>
#include <storage/storage.h> #include <storage/storage.h>
@ -61,7 +62,7 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const
dialog_message_free(message); dialog_message_free(message);
furi_record_close(RECORD_DIALOGS); furi_record_close(RECORD_DIALOGS);
} else if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) { } 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 // so i prefer to not show LoaderStatusErrorAppStarted error message for now
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
DialogMessage* message = dialog_message_alloc(); 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) { static const FlipperInternalApplication* loader_find_application_by_name(const char* name) {
const FlipperInternalApplication* application = NULL; const struct {
application = loader_find_application_by_name_in_list(name, FLIPPER_APPS, FLIPPER_APPS_COUNT); const FlipperInternalApplication* list;
if(!application) { const uint32_t count;
application = loader_find_application_by_name_in_list( } lists[] = {
name, FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT); {FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT},
} {FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_APPS_COUNT},
if(!application) { {FLIPPER_DEBUG_APPS, FLIPPER_DEBUG_APPS_COUNT},
application = loader_find_application_by_name_in_list( };
name, FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_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) { 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_string_vprintf(error_message, format, args);
FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(error_message)); FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(error_message));
} else { } else {
FuriString* tmp = furi_string_alloc(); FURI_LOG_E(TAG, "Status [%d]", status);
FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(tmp));
furi_string_free(tmp);
} }
} }
@ -527,7 +532,9 @@ int32_t loader_srv(void* p) {
FLIPPER_ON_SYSTEM_START[i](); 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); loader_do_start_by_name(loader, FLIPPER_AUTORUN_APP_NAME, NULL, NULL);
} }

View file

@ -28,7 +28,7 @@ static void loader_cli_info(Loader* loader) {
if(!loader_is_locked(loader)) { if(!loader_is_locked(loader)) {
printf("No application is running\r\n"); printf("No application is running\r\n");
} else { } else {
// TODO: print application name ??? // TODO FL-3513: print application name ???
printf("Application is running\r\n"); printf("Application is running\r\n");
} }
} }

View file

@ -279,7 +279,7 @@ static void rpc_system_gui_start_virtual_display_process(const PB_Main* request,
return; return;
} }
// TODO: consider refactoring // TODO FL-3511: consider refactoring
// Using display framebuffer size as an XBM buffer size is like comparing apples and oranges // Using display framebuffer size as an XBM buffer size is like comparing apples and oranges
// Glad they both are 1024 for now // Glad they both are 1024 for now
size_t buffer_size = canvas_get_buffer_size(rpc_gui->gui->canvas); size_t buffer_size = canvas_get_buffer_size(rpc_gui->gui->canvas);

View file

@ -399,7 +399,7 @@ static FS_Error storage_process_common_fs_info(
} }
/****************** Raw SD API ******************/ /****************** 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" #include "storages/storage_ext.h"
static FS_Error storage_process_sd_format(Storage* app) { static FS_Error storage_process_sd_format(Storage* app) {

View file

@ -100,7 +100,7 @@ FS_Error sd_unmount_card(StorageData* storage) {
storage->status = StorageStatusNotReady; storage->status = StorageStatusNotReady;
error = FR_DISK_ERR; 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); f_mount(0, sd_data->path, 0);
return storage_ext_parse_error(error); return storage_ext_parse_error(error);

View file

@ -80,7 +80,7 @@ bool updater_scene_main_on_event(void* context, SceneManagerEvent event) {
break; break;
case UpdaterCustomEventSdUnmounted: 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; break;
default: default:
break; break;

View file

@ -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. - `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. - `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. - `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`. - `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` - 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. - `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). - `blackmagic` - debug firmware with Blackmagic probe (WiFi dev board).
- `openocd` - just start OpenOCD. - `openocd` - just start OpenOCD.
- `get_blackmagic` - output the blackmagic address in the GDB remote format. Useful for IDE integration. - `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`, `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. - `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`. - `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. - `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. - 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`. - `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`. - `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_all`, `updater_all` - build a basic set of binaries.
- `firmware_list`, `updater_list` - generate source + assembler listing. - `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. - `firmware_cdb`, `updater_cdb` - generate a `compilation_database.json` file for external tools and IDEs. It can be created without actually building the firmware.

View file

@ -1037,18 +1037,18 @@ Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer
Function,+,furi_hal_cortex_timer_wait,void,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_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_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_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,_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_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_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_init,void,
Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*" 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_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_disable,void,
Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_enable,void,
Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,+,furi_hal_debug_is_gdb_session_active,_Bool,

1 entry status name type params
1037 Function + furi_hal_cortex_timer_wait void FuriHalCortexTimer
1038 Function + furi_hal_crypto_ctr _Bool const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t
1039 Function + furi_hal_crypto_decrypt _Bool const uint8_t*, uint8_t*, size_t
1040 Function + furi_hal_crypto_enclave_ensure_key _Bool uint8_t
1041 Function + furi_hal_crypto_enclave_load_key _Bool uint8_t, const uint8_t*
1042 Function + furi_hal_crypto_enclave_store_key _Bool FuriHalCryptoKey*, uint8_t*
1043 Function + furi_hal_crypto_enclave_unload_key _Bool uint8_t
1044 Function + furi_hal_crypto_enclave_verify _Bool uint8_t*, uint8_t*
1045 Function + furi_hal_crypto_encrypt _Bool const uint8_t*, uint8_t*, size_t
1046 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
1047 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*
1048 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*
1049 Function - furi_hal_crypto_init void
1050 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
1051 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
1052 Function + furi_hal_debug_disable void
1053 Function + furi_hal_debug_enable void
1054 Function + furi_hal_debug_is_gdb_session_active _Bool

View file

@ -225,7 +225,7 @@ void furi_hal_resources_init() {
} }
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) { 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) if(gpio == &gpio_ext_pa7)
return 2; return 2;
else if(gpio == &gpio_ext_pa6) else if(gpio == &gpio_ext_pa6)

View file

@ -1134,18 +1134,18 @@ Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer
Function,+,furi_hal_cortex_timer_wait,void,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_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_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_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,_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_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_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_init,void,
Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*" 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_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_disable,void,
Function,+,furi_hal_debug_enable,void, Function,+,furi_hal_debug_enable,void,
Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,+,furi_hal_debug_is_gdb_session_active,_Bool,

1 entry status name type params
1134 Function + furi_hal_cortex_timer_wait void FuriHalCortexTimer
1135 Function + furi_hal_crypto_ctr _Bool const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t
1136 Function + furi_hal_crypto_decrypt _Bool const uint8_t*, uint8_t*, size_t
1137 Function + furi_hal_crypto_enclave_ensure_key _Bool uint8_t
1138 Function + furi_hal_crypto_enclave_load_key _Bool uint8_t, const uint8_t*
1139 Function + furi_hal_crypto_enclave_store_key _Bool FuriHalCryptoKey*, uint8_t*
1140 Function + furi_hal_crypto_enclave_unload_key _Bool uint8_t
1141 Function + furi_hal_crypto_enclave_verify _Bool uint8_t*, uint8_t*
1142 Function + furi_hal_crypto_encrypt _Bool const uint8_t*, uint8_t*, size_t
1143 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
1144 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*
1145 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*
1146 Function - furi_hal_crypto_init void
1147 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
1148 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
1149 Function + furi_hal_debug_disable void
1150 Function + furi_hal_debug_enable void
1151 Function + furi_hal_debug_is_gdb_session_active _Bool

View file

@ -222,7 +222,7 @@ bool ble_glue_wait_for_c2_start(int32_t timeout) {
bool started = false; bool started = false;
do { do {
// TODO: use mutex? // TODO FL-3505: use mutex?
started = ble_glue->status == BleGlueStatusC2Started; started = ble_glue->status == BleGlueStatusC2Started;
if(!started) { if(!started) {
timeout--; timeout--;

View file

@ -283,7 +283,7 @@ static SdSpiCmdAnswer
cmd_answer.r1 = sd_spi_wait_for_data_and_read(); cmd_answer.r1 = sd_spi_wait_for_data_and_read();
break; break;
case SdSpiCmdAnswerTypeR1B: 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(); 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 // 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) { switch(responce & 0x1F) {
case SdSpiDataResponceOK: case SdSpiDataResponceOK:
// TODO: check timings // TODO FL-3508: check timings
sd_spi_deselect_card(); sd_spi_deselect_card();
sd_spi_select_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 // 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);
sd_spi_write_byte(SD_DUMMY_BYTE); sd_spi_write_byte(SD_DUMMY_BYTE);

View file

@ -402,7 +402,6 @@ void furi_hal_nfc_ll_txrx_on();
void furi_hal_nfc_ll_txrx_off(); void furi_hal_nfc_ll_txrx_off();
// TODO rework all pollers with furi_hal_nfc_ll_txrx_bits
FuriHalNfcReturn furi_hal_nfc_ll_txrx( FuriHalNfcReturn furi_hal_nfc_ll_txrx(
uint8_t* txBuf, uint8_t* txBuf,
uint16_t txBufLen, uint16_t txBufLen,

View file

@ -38,7 +38,7 @@ static bool flipper_update_mount_sd() {
} }
static bool flipper_update_init() { 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(FuriHalBusHSEM);
furi_hal_bus_enable(FuriHalBusIPCC); furi_hal_bus_enable(FuriHalBusIPCC);
furi_hal_bus_enable(FuriHalBusRNG); furi_hal_bus_enable(FuriHalBusRNG);

View file

@ -23,7 +23,7 @@ env.Append(
env.Append( env.Append(
CPPPATH=[ CPPPATH=[
"#/", "#/",
"#/lib", # TODO: remove! "#/lib", # TODO FL-3553: remove!
"#/lib/mlib", "#/lib/mlib",
# Ugly hack # Ugly hack
Dir("../assets/compiled"), Dir("../assets/compiled"),

View file

@ -69,7 +69,7 @@ static bool bq27220_parameter_check(
uint8_t checksum = bq27220_get_checksum(buffer, size + 2); uint8_t checksum = bq27220_get_checksum(buffer, size + 2);
buffer[0] = checksum; 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( if(!furi_hal_i2c_write_mem(
handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT)) { handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT)) {
FURI_LOG_I(TAG, "CRC write failed"); FURI_LOG_I(TAG, "CRC write failed");

View file

@ -16,7 +16,7 @@ extern "C" {
#define FAP_MANIFEST_SUPPORTED_VERSION 1 #define FAP_MANIFEST_SUPPORTED_VERSION 1
#define FAP_MANIFEST_MAX_APP_NAME_LENGTH 32 #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) #pragma pack(push, 1)

View file

@ -1,3 +1,4 @@
#include "storage/storage.h"
#include <elf.h> #include <elf.h>
#include "elf_file.h" #include "elf_file.h"
#include "elf_file_i.h" #include "elf_file_i.h"
@ -57,6 +58,13 @@ static void address_cache_put(AddressCache_t cache, int symEntry, Elf32_Addr sym
/********************************************** ELF ***********************************************/ /********************************************** 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) { static ELFSection* elf_file_get_section(ELFFile* elf, const char* name) {
return ELFSectionDict_get(elf->sections, name); return ELFSectionDict_get(elf->sections, name);
} }
@ -507,7 +515,7 @@ static SectionType elf_preload_section(
#endif #endif
// ignore .ARM and .rel.ARM sections // 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 // .ARM: type 0x70000001, flags SHF_ALLOC | SHF_LINK_ORDER
// .rel.ARM: type 0x9, flags SHT_REL // .rel.ARM: type 0x9, flags SHT_REL
if(str_prefix(name, ".ARM.") || str_prefix(name, ".rel.ARM.") || 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); free(elf->debug_link_info.debug_link);
} }
storage_file_free(elf->fd); elf_file_maybe_release_fd(elf);
free(elf); free(elf);
} }
@ -792,7 +800,7 @@ bool elf_file_load_section_table(ELFFile* elf) {
FuriString* name = furi_string_alloc(); FuriString* name = furi_string_alloc();
FURI_LOG_D(TAG, "Scan ELF indexs..."); 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++) { for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
Elf32_Shdr section_header; Elf32_Shdr section_header;
@ -828,7 +836,7 @@ ElfProcessSectionResult elf_process_section(
Elf32_Shdr section_header; Elf32_Shdr section_header;
// find section // 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++) { for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
furi_string_reset(section_name); furi_string_reset(section_name);
if(!elf_read_section(elf, section_idx, &section_header, section_name)) { if(!elf_read_section(elf, section_idx, &section_header, section_name)) {
@ -855,6 +863,7 @@ ElfProcessSectionResult elf_process_section(
} }
ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) {
furi_check(elf->fd != NULL);
ELFFileLoadStatus status = ELFFileLoadStatusSuccess; ELFFileLoadStatus status = ELFFileLoadStatusSuccess;
ELFSectionDict_it_t it; 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); FURI_LOG_I(TAG, "Total size of loaded sections: %zu", total_size);
} }
elf_file_maybe_release_fd(elf);
return status; return status;
} }

View file

@ -127,7 +127,7 @@ void ibutton_worker_mode_write_blank_tick(iButtonWorker* worker) {
furi_assert(worker->key); furi_assert(worker->key);
const bool success = ibutton_protocols_write_blank(worker->protocols, 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 : const iButtonWorkerWriteResult result = success ? iButtonWorkerWriteOK :
iButtonWorkerWriteNoDetect; iButtonWorkerWriteNoDetect;
if(worker->write_cb != NULL) { if(worker->write_cb != NULL) {
@ -139,7 +139,7 @@ void ibutton_worker_mode_write_copy_tick(iButtonWorker* worker) {
furi_assert(worker->key); furi_assert(worker->key);
const bool success = ibutton_protocols_write_copy(worker->protocols, 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 : const iButtonWorkerWriteResult result = success ? iButtonWorkerWriteOK :
iButtonWorkerWriteNoDetect; iButtonWorkerWriteNoDetect;
if(worker->write_cb != NULL) { if(worker->write_cb != NULL) {

View file

@ -62,7 +62,7 @@ bool rw1990_write_v1(OneWireHost* host, const uint8_t* data, size_t data_size) {
onewire_host_write_bit(host, true); onewire_host_write_bit(host, true);
furi_delay_us(10000); furi_delay_us(10000);
// TODO: Better error handling // TODO FL-3528: Better error handling
return rw1990_read_and_compare(host, data, data_size); 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); onewire_host_write_bit(host, false);
furi_delay_us(10000); furi_delay_us(10000);
// TODO: Better error handling // TODO Fl-3528: Better error handling
return rw1990_read_and_compare(host, data, data_size); return rw1990_read_and_compare(host, data, data_size);
} }

View file

@ -21,7 +21,7 @@ bool tm2004_write(OneWireHost* host, const uint8_t* data, size_t data_size) {
onewire_host_write(host, data[i]); onewire_host_write(host, data[i]);
answer = onewire_host_read(host); answer = onewire_host_read(host);
// TODO: check answer CRC // TODO FL-3529: check answer CRC
// pulse indicating that data is correct // pulse indicating that data is correct
furi_delay_us(600); 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; return i == data_size;
} }

View file

@ -149,7 +149,7 @@ bool dallas_common_emulate_search_rom(OneWireSlave* bus, const DallasCommonRomDa
if(!onewire_slave_send_bit(bus, !bit)) return false; if(!onewire_slave_send_bit(bus, !bit)) return false;
onewire_slave_receive_bit(bus); onewire_slave_receive_bit(bus);
// TODO: check for errors and return if any // TODO FL-3530: check for errors and return if any
} }
} }

View file

@ -53,7 +53,7 @@ const iButtonProtocolDallasBase ibutton_protocol_ds1971 = {
.name = DS1971_FAMILY_NAME, .name = DS1971_FAMILY_NAME,
.read = dallas_ds1971_read, .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, .write_copy = dallas_ds1971_write_copy,
.emulate = dallas_ds1971_emulate, .emulate = dallas_ds1971_emulate,
.save = dallas_ds1971_save, .save = dallas_ds1971_save,

View file

@ -73,7 +73,7 @@ bool dallas_ds1992_read(OneWireHost* host, iButtonProtocolData* protocol_data) {
bool dallas_ds1992_write_blank(OneWireHost* host, iButtonProtocolData* protocol_data) { bool dallas_ds1992_write_blank(OneWireHost* host, iButtonProtocolData* protocol_data) {
DS1992ProtocolData* data = 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); return tm2004_write(host, (uint8_t*)data, sizeof(DallasCommonRomData) + DS1992_SRAM_DATA_SIZE);
} }

View file

@ -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_MATCH_ROM:
case DALLAS_COMMON_CMD_OVERDRIVE_MATCH_ROM: case DALLAS_COMMON_CMD_OVERDRIVE_MATCH_ROM:
/* TODO: Match ROM command support */ /* TODO FL-3533: Match ROM command support */
default: default:
return false; return false;
} }

View file

@ -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_file_open_always(file, filename)) break;
if(!flipper_format_write_header_cstr(file, LFRFID_DICT_FILETYPE, 1)) 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( if(!flipper_format_write_string_cstr(
file, "Key type", protocol_dict_get_name(dict, protocol))) file, "Key type", protocol_dict_get_name(dict, protocol)))
break; 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); protocol_dict_get_data(dict, protocol, data, data_size);

View file

@ -26,8 +26,8 @@ typedef enum {
} LFRFIDWorkerReadType; } LFRFIDWorkerReadType;
typedef enum { typedef enum {
LFRFIDWorkerReadSenseStart, // TODO: not implemented LFRFIDWorkerReadSenseStart, // TODO FL-3516: not implemented
LFRFIDWorkerReadSenseEnd, // TODO: not implemented LFRFIDWorkerReadSenseEnd, // TODO FL-3516: not implemented
LFRFIDWorkerReadSenseCardStart, LFRFIDWorkerReadSenseCardStart,
LFRFIDWorkerReadSenseCardEnd, LFRFIDWorkerReadSenseCardEnd,
LFRFIDWorkerReadStartASK, LFRFIDWorkerReadStartASK,

View file

@ -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) { 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); UNUSED(protocol);
furi_string_printf(result, "Generic HID Extended\r\nData: Unknown"); furi_string_printf(result, "Generic HID Extended\r\nData: Unknown");
}; };

View file

@ -38,7 +38,7 @@ uint8_t bit_lib_get_bits(const uint8_t* data, size_t position, uint8_t length) {
if(shift == 0) { if(shift == 0) {
return data[position / 8] >> (8 - length); return data[position / 8] >> (8 - length);
} else { } else {
// TODO fix read out of bounds // TODO FL-3534: fix read out of bounds
uint8_t value = (data[position / 8] << (shift)); uint8_t value = (data[position / 8] << (shift));
value |= data[position / 8 + 1] >> (8 - shift); value |= data[position / 8 + 1] >> (8 - shift);
value = value >> (8 - length); value = value >> (8 - length);

@ -1 +1 @@
Subproject commit 40dba4a556e0d81dfbe64301a6aa4e18ceca896c Subproject commit 611c9b20db2b99faee261daa7cc9bbe175d3eaca

View file

@ -29,7 +29,7 @@ ReturnCode nfcv_inventory(uint8_t* uid) {
ReturnCode ret = ERR_NONE; ReturnCode ret = ERR_NONE;
for(int tries = 0; tries < NFCV_COMMAND_RETRIES; tries++) { 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); ret = rfalNfcvPollerInventory(RFAL_NFCV_NUM_SLOTS_1, 0, NULL, &res, &received);
if(ret == ERR_NONE) { 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..."); FURI_LOG_D(TAG, "Read SYSTEM INFORMATION...");
for(int tries = 0; tries < NFCV_COMMAND_RETRIES; tries++) { 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( ret = rfalNfcvPollerGetSystemInformation(
RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, rxBuf, sizeof(rxBuf), &received); RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, rxBuf, sizeof(rxBuf), &received);

View file

@ -59,7 +59,6 @@ int __wrap_fflush(FILE* stream) {
__attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e) { __attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e) {
UNUSED(file); UNUSED(file);
UNUSED(line); UNUSED(line);
// TODO: message file and line number
furi_crash(e); furi_crash(e);
} }
@ -68,6 +67,5 @@ __attribute__((__noreturn__)) void
UNUSED(file); UNUSED(file);
UNUSED(line); UNUSED(line);
UNUSED(func); UNUSED(func);
// TODO: message file and line number
furi_crash(e); furi_crash(e);
} }

View file

@ -22,7 +22,7 @@ void subghz_device_registry_init(void) {
SUBGHZ_RADIO_DEVICE_PLUGIN_API_VERSION, SUBGHZ_RADIO_DEVICE_PLUGIN_API_VERSION,
firmware_api_interface); 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, "/any/apps_data/subghz/plugins") !=
//if(plugin_manager_load_all(subghz_device->manager, APP_DATA_PATH("plugins")) != //if(plugin_manager_load_all(subghz_device->manager, APP_DATA_PATH("plugins")) !=
PluginManagerErrorNone) { PluginManagerErrorNone) {

View file

@ -744,7 +744,7 @@ static bool
bin_raw_debug("\r\n\r\n"); bin_raw_debug("\r\n\r\n");
#endif #endif
//todo can be optimized //TODO FL-3557: can be optimized
BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT]; BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
memcpy( memcpy(
markup_temp, markup_temp,
@ -770,7 +770,7 @@ static bool
} }
} }
} }
//todo can be optimized //TODO FL-3557: can be optimized
if(bin_raw_type == BinRAWTypeGap) { if(bin_raw_type == BinRAWTypeGap) {
if(data_temp != 0) { //there are sequences with the same number of bits if(data_temp != 0) { //there are sequences with the same number of bits

View file

@ -265,7 +265,7 @@ SubGhzProtocolStatus
furi_assert(context); furi_assert(context);
UNUSED(context); UNUSED(context);
UNUSED(flipper_format); UNUSED(flipper_format);
//ToDo stub, for backwards compatibility // stub, for backwards compatibility
return SubGhzProtocolStatusOk; return SubGhzProtocolStatusOk;
} }
@ -273,7 +273,6 @@ void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) {
furi_assert(context); furi_assert(context);
//SubGhzProtocolDecoderRAW* instance = context; //SubGhzProtocolDecoderRAW* instance = context;
UNUSED(context); UNUSED(context);
//ToDo no use
furi_string_cat_printf(output, "RAW Data"); furi_string_cat_printf(output, "RAW Data");
} }

View file

@ -255,7 +255,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
} }
while(flipper_format_read_uint32( while(flipper_format_read_uint32(
fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { 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)) { if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
FrequencyList_push_back(instance->frequencies, temp_data32); FrequencyList_push_back(instance->frequencies, temp_data32);

View file

@ -165,7 +165,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) {
SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE);
} else { } 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( furi_stream_buffer_receive(
instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF);
subghz_tx_rx_worker_tx(instance, data, size_tx); 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) { furi_stream_buffer_bytes_available(instance->stream_rx) == 0) {
callback_rx = true; 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( furi_stream_buffer_send(
instance->stream_rx, instance->stream_rx,
&data, &data,
@ -189,7 +189,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) {
callback_rx = false; callback_rx = false;
} }
} else { } else {
//todo RX buffer overflow //TODO FL-3555: RX buffer overflow
} }
} }
} }

View file

@ -4,7 +4,7 @@
#define CRC_DATA_BUFFER_MAX_LEN 512 #define CRC_DATA_BUFFER_MAX_LEN 512
uint32_t crc32_calc_buffer(uint32_t crc, const void* buffer, size_t size) { 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); return ~lfs_crc(~crc, buffer, size);
} }

View file

@ -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) { 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; size_t need_to_write = size;
while(need_to_write > 0) { while(need_to_write > 0) {
uint16_t was_written = 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) { 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; size_t need_to_read = size;
while(need_to_read > 0) { while(need_to_read > 0) {
uint16_t was_read = uint16_t was_read =
@ -172,7 +172,7 @@ static bool file_stream_delete_and_insert(
// open scratchpad // open scratchpad
Stream* scratch_stream = file_stream_alloc(_stream->storage); 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* scratch_name;
FuriString* tmp_name; FuriString* tmp_name;
tmp_name = furi_string_alloc(); tmp_name = furi_string_alloc();

View file

@ -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) { 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; size_t i;
for(i = 0; i < size; i++) { for(i = 0; i < size; i++) {
string_stream_write_char(stream, data[i]); string_stream_write_char(stream, data[i]);

View file

@ -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)) { if((dfu_suffix.bLength != sizeof(DfuSuffix)) || (dfu_suffix.bcdDFU != DFU_SUFFIX_VERSION)) {
return 0; return 0;
} }
/* TODO: check DfuSignature?.. */ /* TODO FL-3561: check DfuSignature?.. */
if((dfu_suffix.idVendor != reference_params->vendor) || if((dfu_suffix.idVendor != reference_params->vendor) ||
(dfu_suffix.idProduct != reference_params->product) || (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; 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) { for(uint32_t i_element = 0; i_element < target_prefix.dwNbElements; ++i_element) {
bytes_read = storage_file_read(dfuf, &image_element, sizeof(ImageElementHeader)); bytes_read = storage_file_read(dfuf, &image_element, sizeof(ImageElementHeader));
if(bytes_read != sizeof(ImageElementHeader)) { if(bytes_read != sizeof(ImageElementHeader)) {

View file

@ -54,7 +54,7 @@ static bool
FuriString* filetype; FuriString* filetype;
// TODO: compare filetype? // TODO FL-3543: compare filetype?
filetype = furi_string_alloc(); filetype = furi_string_alloc();
update_manifest->valid = update_manifest->valid =
flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) && flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) &&

View file

@ -2,9 +2,15 @@ import os
import re import re
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from fbt.util import resolve_real_dir_node
from typing import Callable, ClassVar, List, Optional, Tuple, Union 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): class FlipperManifestException(Exception):
pass pass

View file

@ -237,6 +237,7 @@ class SdkCache:
removed_entries = known_set - new_set removed_entries = known_set - new_set
if removed_entries: if removed_entries:
print(f"Removed: {removed_entries}") print(f"Removed: {removed_entries}")
self.loaded_dirty_version = True
known_set -= removed_entries known_set -= removed_entries
# If any of removed entries was a part of active API, that's a major bump # If any of removed entries was a part of active API, that's a major bump
if update_version and any( if update_version and any(

View file

@ -38,7 +38,7 @@ from SCons.Tool.cxx import CXXSuffixes
from SCons.Tool.cc import CSuffixes from SCons.Tool.cc import CSuffixes
from SCons.Tool.asm import ASSuffixes, ASPPSuffixes 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 # 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 # 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 # 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, __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 # cache the entries. However, they don't seem to update properly. Since they are quick
# to re-generate disable caching and sidestep this problem. # to re-generate disable caching and sidestep this problem.
env.AlwaysBuild(entry) env.AlwaysBuild(entry)

View file

@ -21,7 +21,7 @@ def generate(env, **kw):
FBT_DEBUG_DIR="${FBT_SCRIPT_DIR}/debug", 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( env.Append(
OPENOCD_OPTS=[ OPENOCD_OPTS=[
"-c", "-c",

View file

@ -52,22 +52,16 @@ def AddFwProject(env, base_env, fw_type, fw_env_key):
return project_env return project_env
def AddOpenOCDFlashTarget(env, targetenv, **kw): def AddFwFlashTarget(env, targetenv, **kw):
openocd_target = env.OpenOCDFlash( fwflash_target = env.FwFlash(
"#build/oocd-${BUILD_CFG}-flash.flag", "#build/flash.flag",
targetenv["FW_BIN"], targetenv["FW_ELF"],
OPENOCD_COMMAND=[
"-c",
"program ${SOURCE.posix} reset exit ${BASE_ADDRESS}",
],
BUILD_CFG=targetenv.subst("$FIRMWARE_BUILD_CFG"),
BASE_ADDRESS=targetenv.subst("$IMAGE_BASE_ADDRESS"),
**kw, **kw,
) )
env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_flash"), openocd_target) env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_flash"), fwflash_target)
if env["FORCE"]: if env["FORCE"]:
env.AlwaysBuild(openocd_target) env.AlwaysBuild(fwflash_target)
return openocd_target return fwflash_target
def AddJFlashTarget(env, targetenv, **kw): def AddJFlashTarget(env, targetenv, **kw):
@ -115,7 +109,7 @@ def generate(env):
env.SetDefault(COPROCOMSTR="\tCOPRO\t${TARGET}") env.SetDefault(COPROCOMSTR="\tCOPRO\t${TARGET}")
env.AddMethod(AddFwProject) env.AddMethod(AddFwProject)
env.AddMethod(DistCommand) env.AddMethod(DistCommand)
env.AddMethod(AddOpenOCDFlashTarget) env.AddMethod(AddFwFlashTarget)
env.AddMethod(GetProjectDirName) env.AddMethod(GetProjectDirName)
env.AddMethod(AddJFlashTarget) env.AddMethod(AddJFlashTarget)
env.AddMethod(AddUsbFlashTarget) env.AddMethod(AddUsbFlashTarget)
@ -125,30 +119,53 @@ def generate(env):
SELFUPDATE_SCRIPT="${FBT_SCRIPT_DIR}/selfupdate.py", SELFUPDATE_SCRIPT="${FBT_SCRIPT_DIR}/selfupdate.py",
DIST_SCRIPT="${FBT_SCRIPT_DIR}/sconsdist.py", DIST_SCRIPT="${FBT_SCRIPT_DIR}/sconsdist.py",
COPRO_ASSETS_SCRIPT="${FBT_SCRIPT_DIR}/assets.py", COPRO_ASSETS_SCRIPT="${FBT_SCRIPT_DIR}/assets.py",
FW_FLASH_SCRIPT="${FBT_SCRIPT_DIR}/fwflash.py",
) )
env.Append( env.Append(
BUILDERS={ 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( "UsbInstall": Builder(
action=[ 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}"), Touch("${TARGET}"),
] ]
), ),
"CoproBuilder": Builder( "CoproBuilder": Builder(
action=Action( action=Action(
[ [
'${PYTHON3} "${COPRO_ASSETS_SCRIPT}" ' [
"copro ${COPRO_CUBE_DIR} " "${PYTHON3}",
"${TARGET} ${COPRO_MCU_FAMILY} " "${COPRO_ASSETS_SCRIPT}",
"--cube_ver=${COPRO_CUBE_VERSION} " "copro",
"--stack_type=${COPRO_STACK_TYPE} " "${COPRO_CUBE_DIR}",
'--stack_file="${COPRO_STACK_BIN}" ' "${TARGET}",
"--stack_addr=${COPRO_STACK_ADDR} ", "${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}",
) )
), ),
} }

View file

@ -53,6 +53,11 @@ class AppBuilder:
FAP_SRC_DIR=self.app._appdir, FAP_SRC_DIR=self.app._appdir,
FAP_WORK_DIR=self.app_work_dir, 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) self.app_env.VariantDir(self.app_work_dir, self.app._appdir, duplicate=False)
def _build_external_files(self): def _build_external_files(self):

View file

@ -16,8 +16,8 @@ Firmware & apps:
Flashing & debugging: Flashing & debugging:
flash, flash_blackmagic, jflash: flash, jflash:
Flash firmware to target using debug probe Flash firmware to target using SWD probe. See also SWD_TRANSPORT, SWD_TRANSPORT_SERIAL
flash_usb, flash_usb_full: flash_usb, flash_usb_full:
Install firmware using self-update package Install firmware using self-update package
debug, debug_other, blackmagic: debug, debug_other, blackmagic:

View file

@ -150,7 +150,7 @@ class FlipperStorage:
for line in lines: for line in lines:
try: try:
# TODO: better decoding, considering non-ascii characters # TODO FL-3539: better decoding, considering non-ascii characters
line = line.decode("ascii") line = line.decode("ascii")
except Exception: except Exception:
continue continue
@ -193,7 +193,7 @@ class FlipperStorage:
for line in lines: for line in lines:
try: try:
# TODO: better decoding, considering non-ascii characters # TODO FL-3539: better decoding, considering non-ascii characters
line = line.decode("ascii") line = line.decode("ascii")
except Exception: except Exception:
continue continue

View file

@ -78,7 +78,7 @@ class OpenOCD:
def _wait_for_openocd_tcl(self): def _wait_for_openocd_tcl(self):
"""Wait for OpenOCD to start""" """Wait for OpenOCD to start"""
# TODO: timeout # TODO Fl-3538: timeout
while True: while True:
stderr = self.process.stderr stderr = self.process.stderr
if not stderr: if not stderr:
@ -128,7 +128,7 @@ class OpenOCD:
def _recv(self): def _recv(self):
"""Read from the stream until the token (\x1a) was received.""" """Read from the stream until the token (\x1a) was received."""
# TODO: timeout # TODO FL-3538: timeout
data = bytes() data = bytes()
while True: while True:
chunk = self.socket.recv(4096) chunk = self.socket.recv(4096)

View file

@ -247,7 +247,7 @@ class STM32WB55:
def flash_wait_for_operation(self): def flash_wait_for_operation(self):
# Wait for flash operation to complete # Wait for flash operation to complete
# TODO: timeout # TODO FL-3537: timeout
while True: while True:
self.FLASH_SR.load() self.FLASH_SR.load()
if self.FLASH_SR.BSY == 0: if self.FLASH_SR.BSY == 0:

View file

@ -6,14 +6,17 @@ import subprocess
import time import time
import typing import typing
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from dataclasses import dataclass from dataclasses import dataclass, field
from flipper.app import App from flipper.app import App
# When adding an interface, also add it to SWD_TRANSPORT in fbt options
class Programmer(ABC): class Programmer(ABC):
@abstractmethod @abstractmethod
def flash(self, bin: str) -> bool: def flash(self, file_path: str, do_verify: bool) -> bool:
pass pass
@abstractmethod @abstractmethod
@ -32,9 +35,9 @@ class Programmer(ABC):
@dataclass @dataclass
class OpenOCDInterface: class OpenOCDInterface:
name: str name: str
file: str config_file: str
serial_cmd: str serial_cmd: str
additional_args: typing.Optional[list[str]] = None additional_args: typing.Optional[list[str]] = field(default_factory=list)
class OpenOCDProgrammer(Programmer): class OpenOCDProgrammer(Programmer):
@ -44,12 +47,10 @@ class OpenOCDProgrammer(Programmer):
self.serial: typing.Optional[str] = None self.serial: typing.Optional[str] = None
def _add_file(self, params: list[str], file: str): def _add_file(self, params: list[str], file: str):
params.append("-f") params += ["-f", file]
params.append(file)
def _add_command(self, params: list[str], command: str): def _add_command(self, params: list[str], command: str):
params.append("-c") params += ["-c", command]
params.append(command)
def _add_serial(self, params: list[str], serial: str): def _add_serial(self, params: list[str], serial: str):
self._add_command(params, f"{self.interface.serial_cmd} {serial}") self._add_command(params, f"{self.interface.serial_cmd} {serial}")
@ -57,22 +58,27 @@ class OpenOCDProgrammer(Programmer):
def set_serial(self, serial: str): def set_serial(self, serial: str):
self.serial = serial self.serial = serial
def flash(self, bin: str) -> bool: def flash(self, file_path: str, do_verify: bool) -> bool:
i = self.interface
if os.altsep: if os.altsep:
bin = bin.replace(os.sep, os.altsep) file_path = file_path.replace(os.sep, os.altsep)
openocd_launch_params = ["openocd"] 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: if self.serial:
self._add_serial(openocd_launch_params, self.serial) self._add_serial(openocd_launch_params, self.serial)
if i.additional_args: for additional_arg in self.interface.additional_args:
for a in i.additional_args: self._add_command(openocd_launch_params, additional_arg)
self._add_command(openocd_launch_params, a)
self._add_file(openocd_launch_params, "target/stm32wbx.cfg") self._add_file(openocd_launch_params, "target/stm32wbx.cfg")
self._add_command(openocd_launch_params, "init") 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 # join the list of parameters into a string, but add quote if there are spaces
openocd_launch_params_string = " ".join( openocd_launch_params_string = " ".join(
@ -105,7 +111,7 @@ class OpenOCDProgrammer(Programmer):
i = self.interface i = self.interface
openocd_launch_params = ["openocd"] openocd_launch_params = ["openocd"]
self._add_file(openocd_launch_params, i.file) self._add_file(openocd_launch_params, i.config_file)
if self.serial: if self.serial:
self._add_serial(openocd_launch_params, self.serial) self._add_serial(openocd_launch_params, self.serial)
if i.additional_args: if i.additional_args:
@ -187,7 +193,7 @@ def _resolve_hostname(hostname):
def blackmagic_find_networked(serial: str): def blackmagic_find_networked(serial: str):
if not serial: if not serial or serial == "auto":
serial = "blackmagic.local" serial = "blackmagic.local"
# remove the tcp: prefix if it's there # remove the tcp: prefix if it's there
@ -234,7 +240,7 @@ class BlackmagicProgrammer(Programmer):
else: else:
self.port = serial 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.port:
if not self.probe(): if not self.probe():
return False return False
@ -242,12 +248,14 @@ class BlackmagicProgrammer(Programmer):
# We can convert .bin to .elf with objcopy: # 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 # 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. # 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): if file_path.endswith(".bin"):
self.logger.error( file_path = file_path[:-4] + ".elf"
f"Sorry, but Blackmagic can't flash .bin file, and {elf} doesn't exist" if not os.path.exists(file_path):
) self.logger.error(
return False 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 # arm-none-eabi-gdb build/f7-firmware-D/firmware.bin
# -ex 'set pagination off' # -ex 'set pagination off'
@ -260,7 +268,7 @@ class BlackmagicProgrammer(Programmer):
# -ex 'compare-sections' # -ex 'compare-sections'
# -ex 'quit' # -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, f"target extended-remote {self.port}")
self._add_command(gdb_launch_params, "set pagination off") self._add_command(gdb_launch_params, "set pagination off")
self._add_command(gdb_launch_params, "set confirm 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, "attach 1")
self._add_command(gdb_launch_params, "set mem inaccessible-by-default off") 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, "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._add_command(gdb_launch_params, "quit")
self.logger.debug(f"Launching: {' '.join(gdb_launch_params)}") self.logger.debug(f"Launching: {' '.join(gdb_launch_params)}")
@ -314,7 +323,9 @@ class BlackmagicProgrammer(Programmer):
return self.name return self.name
programmers: list[Programmer] = [ ####################
local_flash_interfaces: list[Programmer] = [
OpenOCDProgrammer( OpenOCDProgrammer(
OpenOCDInterface( OpenOCDInterface(
"cmsis-dap", "cmsis-dap",
@ -325,47 +336,64 @@ programmers: list[Programmer] = [
), ),
OpenOCDProgrammer( OpenOCDProgrammer(
OpenOCDInterface( 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"), BlackmagicProgrammer(blackmagic_find_serial, "blackmagic_usb"),
] ]
network_programmers = [ network_flash_interfaces: list[Programmer] = [
BlackmagicProgrammer(blackmagic_find_networked, "blackmagic_wifi") BlackmagicProgrammer(blackmagic_find_networked, "blackmagic_wifi")
] ]
all_flash_interfaces = [*local_flash_interfaces, *network_flash_interfaces]
####################
class Main(App): class Main(App):
AUTO_INTERFACE = "auto"
def init(self): def init(self):
self.subparsers = self.parser.add_subparsers(help="sub-command help") self.parser.add_argument(
self.parser_flash = self.subparsers.add_parser("flash", help="Flash a binary") "filename",
self.parser_flash.add_argument(
"bin",
type=str, type=str,
help="Binary to flash", help="File to flash",
) )
interfaces = [i.get_name() for i in programmers] self.parser.add_argument(
interfaces.extend([i.get_name() for i in network_programmers]) "--verify",
self.parser_flash.add_argument( "-v",
action="store_true",
help="Verify flash after programming",
default=False,
)
self.parser.add_argument(
"--interface", "--interface",
choices=interfaces, choices=(
self.AUTO_INTERFACE,
*[i.get_name() for i in all_flash_interfaces],
),
type=str, type=str,
default=self.AUTO_INTERFACE,
help="Interface to use", help="Interface to use",
) )
self.parser_flash.add_argument( self.parser.add_argument(
"--serial", "--serial",
type=str, type=str,
default=self.AUTO_INTERFACE,
help="Serial number or port of the programmer", 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 = [] found_programmers = []
for p in programmers: for p in interface_list:
name = p.get_name() name = p.get_name()
if serial: if (serial := self.args.serial) != self.AUTO_INTERFACE:
p.set_serial(serial) p.set_serial(serial)
self.logger.debug(f"Trying {name} with {serial}") self.logger.debug(f"Trying {name} with {serial}")
else: else:
@ -373,29 +401,7 @@ class Main(App):
if p.probe(): if p.probe():
self.logger.debug(f"Found {name}") self.logger.debug(f"Found {name}")
found_programmers += [p] found_programmers.append(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]
else: else:
self.logger.debug(f"Failed to probe {name}") self.logger.debug(f"Failed to probe {name}")
@ -403,55 +409,60 @@ class Main(App):
def flash(self): def flash(self):
start_time = time.time() 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): if not os.path.exists(file_path):
self.logger.error(f"Binary file not found: {bin_path}") self.logger.error(f"Binary file not found: {file_path}")
return 1 return 1
if self.args.interface: if self.args.interface != self.AUTO_INTERFACE:
i_name = self.args.interface available_interfaces = list(
interfaces = [p for p in programmers if p.get_name() == i_name] filter(
if len(interfaces) == 0: lambda p: p.get_name() == self.args.interface,
interfaces = [p for p in network_programmers if p.get_name() == i_name] all_flash_interfaces,
else: )
self.logger.info("Probing for interfaces...") )
interfaces = self._search_interface(self.args.serial)
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 # Probe network blackmagic
self.logger.info("Probing for network interfaces...") 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") self.logger.error("No interface found")
return 1 return 1
elif len(available_interfaces) > 1:
if len(interfaces) > 1:
self.logger.error("Multiple interfaces found: ") self.logger.error("Multiple interfaces found: ")
self.logger.error( 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 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) interface.set_serial(self.args.serial)
self.logger.info( 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: 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()}") self.logger.error(f"Failed to flash via {interface.get_name()}")
return 1 return 1
flash_time = time.time() - start_time 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"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 return 0

View file

@ -1,7 +1,7 @@
Set-StrictMode -Version 2.0 Set-StrictMode -Version 2.0
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
# TODO: fix # TODO FL-3536: fix path to download_dir
$download_dir = (Get-Item "$PSScriptRoot\..\..").FullName $download_dir = (Get-Item "$PSScriptRoot\..\..").FullName
$toolchain_version = $args[0] $toolchain_version = $args[0]
$toolchain_target_path = $args[1] $toolchain_target_path = $args[1]

View file

@ -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["UFBT_STATE_DIR"].File("flash"),
dist_env["FW_BIN"], dist_env["FW_ELF"],
OPENOCD_COMMAND=[
"-c",
"program ${SOURCE.posix} reset exit 0x08000000",
],
) )
dist_env.Alias("firmware_flash", openocd_target) dist_env.Alias("firmware_flash", flash_target)
dist_env.Alias("flash", openocd_target) dist_env.Alias("flash", flash_target)
if env["FORCE"]: if env["FORCE"]:
env.AlwaysBuild(openocd_target) env.AlwaysBuild(flash_target)
firmware_jflash = dist_env.JFlash( firmware_jflash = dist_env.JFlash(
dist_env["UFBT_STATE_DIR"].File("jflash"), dist_env["UFBT_STATE_DIR"].File("jflash"),
dist_env["FW_BIN"], dist_env["FW_BIN"],
JFLASHADDR="0x20000000", JFLASHADDR="0x08000000",
) )
dist_env.Alias("firmware_jflash", firmware_jflash) dist_env.Alias("firmware_jflash", firmware_jflash)
dist_env.Alias("jflash", firmware_jflash) dist_env.Alias("jflash", firmware_jflash)
@ -213,21 +209,6 @@ dist_env.PhonyTarget(
GDBPYOPTS=debug_other_opts, 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( flash_usb_full = dist_env.UsbInstall(
dist_env["UFBT_STATE_DIR"].File("usbinstall"), dist_env["UFBT_STATE_DIR"].File("usbinstall"),
[], [],

View file

@ -55,9 +55,21 @@ vars.AddVariables(
"Blackmagic probe location", "Blackmagic probe location",
"auto", "auto",
), ),
EnumVariable(
"SWD_TRANSPORT",
help="SWD interface adapter type",
default="auto",
allowed_values=[
"auto",
"cmsis-dap",
"stlink",
"blackmagic_usb",
"blackmagic_wifi",
],
),
( (
"OPENOCD_ADAPTER_SERIAL", "SWD_TRANSPORT_SERIAL",
"OpenOCD adapter serial number", "SWD interface adapter serial number",
"auto", "auto",
), ),
( (

View file

@ -20,8 +20,8 @@ Building:
Build FAP app with appid={APPID}; upload & start it over USB Build FAP app with appid={APPID}; upload & start it over USB
Flashing & debugging: Flashing & debugging:
flash, flash_blackmagic, *jflash: flash, *jflash:
Flash firmware to target using debug probe Flash firmware to target using SWD probe. See also SWD_TRANSPORT, SWD_TRANSPORT_SERIAL
flash_usb, flash_usb_full: flash_usb, flash_usb_full:
Install firmware using self-update package Install firmware using self-update package
debug, debug_other, blackmagic: debug, debug_other, blackmagic:

View file

@ -180,9 +180,21 @@ vars.AddVariables(
"Blackmagic probe location", "Blackmagic probe location",
"auto", "auto",
), ),
EnumVariable(
"SWD_TRANSPORT",
help="SWD interface adapter type",
default="auto",
allowed_values=[
"auto",
"cmsis-dap",
"stlink",
"blackmagic_usb",
"blackmagic_wifi",
],
),
( (
"OPENOCD_ADAPTER_SERIAL", "SWD_TRANSPORT_SERIAL",
"OpenOCD adapter serial number", "SWD interface adapter serial number",
"auto", "auto",
), ),
( (

View file

@ -23,18 +23,14 @@ appenv.Replace(
appenv.AppendUnique( appenv.AppendUnique(
CCFLAGS=[ CCFLAGS=[
"-ggdb3",
"-mword-relocations", "-mword-relocations",
"-mlong-calls", "-mlong-calls",
"-fno-common", "-fno-common",
"-nostdlib", "-nostdlib",
"-fvisibility=hidden",
], ],
LINKFLAGS=[ LINKFLAGS=[
"-Ur", "-Ur",
"-Wl,-Ur", "-Wl,-Ur",
# "-Wl,--orphan-handling=error",
"-Bsymbolic",
"-nostartfiles", "-nostartfiles",
"-mlong-calls", "-mlong-calls",
"-fno-common", "-fno-common",