From 03196fa11007c0f1e002cbb0b82102d8492456b5 Mon Sep 17 00:00:00 2001 From: hedger Date: Mon, 3 Jun 2024 17:43:23 +0400 Subject: [PATCH 1/2] cleanup of various warnings from clangd (#3682) * cleanup of various warnings from clangs * lfrfid_debug: cast fixes * subghz: binraw: round->roundf * furi: thread: updated internal stack size variable to size_t * github: fail faster on unsuccessful build * unit_tests: double trouble --- .clangd | 4 ++++ .github/workflows/unit_tests.yml | 2 +- .../accessor/scene/accessor_scene_start.cpp | 1 - .../battery_test_app/views/battery_info.c | 2 +- .../debug/display_test/display_test.c | 2 -- .../debug/display_test/display_test.h | 1 - .../views/lfrfid_debug_view_tune.c | 4 ++-- .../subghz_test/scenes/subghz_test_scene.c | 2 +- .../debug/subghz_test/subghz_test_app_i.c | 2 -- .../subghz_test/views/subghz_test_carrier.c | 3 +-- .../subghz_test/views/subghz_test_packet.c | 3 +-- .../subghz_test/views/subghz_test_static.c | 2 -- .../unit_tests/tests/bit_lib/bit_lib_test.c | 2 +- .../debug/unit_tests/tests/bt/bt_test.c | 2 +- .../unit_tests/tests/compress/compress_test.c | 2 +- .../tests/datetime/datetimelib_test.c | 2 +- .../dialogs_file_browser_options.c | 2 +- .../unit_tests/tests/dirwalk/dirwalk_test.c | 2 +- .../tests/expansion/expansion_test.c | 2 +- .../flipper_format/flipper_format_test.c | 2 +- .../flipper_format_string_test.c | 2 +- .../tests/float_tools/float_tools_test.c | 2 +- .../unit_tests/tests/furi/furi_memmgr_test.c | 2 +- .../unit_tests/tests/furi/furi_pubsub_test.c | 2 +- .../unit_tests/tests/furi/furi_record_test.c | 4 +--- .../debug/unit_tests/tests/furi/furi_test.c | 3 +-- .../tests/furi_hal/furi_hal_tests.c | 4 +--- .../furi_hal_crypto/furi_hal_crypto_tests.c | 3 +-- .../tests/furi_string/furi_string_test.c | 2 +- .../unit_tests/tests/infrared/infrared_test.c | 2 +- .../tests/lfrfid/lfrfid_protocols.c | 2 +- .../unit_tests/tests/manifest/manifest.c | 4 ++-- .../debug/unit_tests/tests/nfc/nfc_test.c | 2 +- .../debug/unit_tests/tests/power/power_test.c | 23 ++++++++++--------- .../tests/protocol_dict/protocol_dict_test.c | 2 +- .../debug/unit_tests/tests/rpc/rpc_test.c | 2 +- .../unit_tests/tests/storage/storage_test.c | 2 +- .../unit_tests/tests/stream/stream_test.c | 2 +- .../unit_tests/tests/subghz/subghz_test.c | 2 +- .../unit_tests/tests/varint/varint_test.c | 2 +- .../main/archive/helpers/archive_apps.c | 1 - .../main/archive/helpers/archive_browser.c | 1 - .../archive/scenes/archive_scene_browser.c | 1 - .../archive/scenes/archive_scene_delete.c | 1 - .../main/archive/views/archive_browser_view.c | 1 - .../bad_usb/scenes/bad_usb_scene_config.c | 1 - .../scenes/bad_usb_scene_config_layout.c | 1 - applications/main/gpio/views/gpio_usb_uart.c | 3 ++- .../scenes/infrared_scene_universal_ac.c | 2 +- .../mf_ultralight/mf_ultralight.c | 2 +- .../main/nfc/plugins/supported_cards/troika.c | 1 - .../subghz_frequency_analyzer_worker.c | 2 +- .../subghz/helpers/subghz_threshold_rssi.c | 2 +- .../main/subghz/helpers/subghz_txrx.c | 2 +- .../helpers/subghz_txrx_create_protocol_key.c | 2 +- .../scenes/subghz_scene_delete_success.c | 2 +- .../scenes/subghz_scene_frequency_analyzer.c | 2 +- .../scenes/subghz_scene_radio_setting.c | 2 +- .../subghz/scenes/subghz_scene_read_raw.c | 2 +- .../subghz/scenes/subghz_scene_region_info.c | 2 +- .../subghz/scenes/subghz_scene_saved_menu.c | 2 +- .../subghz/scenes/subghz_scene_show_error.c | 2 +- .../scenes/subghz_scene_show_error_sub.c | 2 +- applications/main/subghz/subghz_i.c | 2 -- applications/main/subghz/views/receiver.c | 3 +-- .../subghz/views/subghz_frequency_analyzer.c | 2 -- .../main/subghz/views/subghz_read_raw.c | 6 ++--- applications/main/subghz/views/transmitter.c | 2 +- applications/main/u2f/u2f.c | 1 - applications/services/cli/cli_vcp.c | 2 +- .../desktop/animations/animation_storage.c | 1 - .../animations/views/bubble_animation_view.c | 1 - applications/services/desktop/helpers/pin.c | 2 -- .../desktop/scenes/desktop_scene_lock_menu.c | 2 -- .../desktop/scenes/desktop_scene_locked.c | 1 - .../desktop/scenes/desktop_scene_main.c | 1 - .../desktop/scenes/desktop_scene_pin_input.c | 2 -- .../scenes/desktop_scene_pin_timeout.c | 1 - .../desktop/views/desktop_view_lock_menu.c | 4 ++-- .../desktop/views/desktop_view_main.c | 1 - .../desktop/views/desktop_view_slideshow.c | 2 -- .../desktop/views/desktop_view_slideshow.h | 1 + applications/services/dialogs/dialogs.c | 1 - applications/services/dialogs/dialogs_api.c | 1 - .../dialogs/dialogs_module_file_browser.c | 3 +-- .../services/dialogs/dialogs_module_message.c | 4 +++- applications/services/dolphin/dolphin.c | 5 ++-- .../services/dolphin/helpers/dolphin_state.c | 1 - applications/services/gui/elements.c | 1 - applications/services/gui/icon.c | 2 +- applications/services/gui/icon_animation.c | 2 +- .../services/gui/modules/button_panel.c | 2 +- applications/services/gui/modules/widget.c | 2 +- .../notification/notification_app_api.c | 1 - .../services/power/power_service/power.c | 2 +- applications/services/rpc/rpc.c | 1 - applications/services/rpc/rpc_desktop.c | 1 - .../services/storage/storage_external_api.c | 2 +- .../desktop_settings_scene_pin_disable.c | 1 - .../desktop_settings_scene_pin_setup_done.c | 1 - .../desktop_settings_scene_pin_setup_howto2.c | 1 - .../scenes/desktop_settings_scene_start.c | 1 - .../settings/dolphin_passport/passport.c | 13 +++++------ .../power_settings_app/views/battery_info.c | 2 +- .../system/js_app/modules/js_flipper.c | 2 +- .../js_app/plugin_api/app_api_table_i.h | 1 - furi/core/kernel.c | 2 -- furi/core/memmgr.c | 1 - furi/core/mutex.c | 2 +- furi/core/pubsub.c | 1 - furi/core/record.c | 1 - furi/core/thread.c | 9 +++++--- furi/core/timer.c | 1 - furi/furi.c | 1 - lib/ble_profile/extra_services/hid_service.c | 2 +- lib/drivers/lp5562.c | 2 -- lib/flipper_application/application_assets.c | 6 +---- lib/flipper_application/flipper_application.c | 11 +++++---- .../plugins/composite_resolver.c | 2 +- .../plugins/plugin_manager.c | 2 +- lib/lfrfid/protocols/protocol_pac_stanley.c | 2 +- .../iso14443_3a/iso14443_3a_poller_sync.c | 2 +- lib/nfc/protocols/iso14443_3b/iso14443_3b_i.c | 1 - lib/nfc/protocols/iso14443_4b/iso14443_4b.c | 2 +- lib/pulse_reader/pulse_reader.c | 1 - lib/signal_reader/signal_reader.c | 1 - lib/subghz/blocks/const.c | 1 - lib/subghz/protocols/bin_raw.c | 13 ++++++----- lib/subghz/protocols/intertechno_v3.c | 2 +- lib/subghz/protocols/princeton.c | 2 +- lib/subghz/protocols/protocol_items.c | 2 +- lib/subghz/protocols/raw.c | 3 --- lib/subghz/receiver.c | 1 - lib/subghz/subghz_setting.c | 3 +-- lib/subghz/transmitter.c | 1 - lib/toolbox/manchester_encoder.c | 1 - 136 files changed, 127 insertions(+), 196 deletions(-) delete mode 100644 applications/debug/display_test/display_test.h delete mode 100644 lib/nfc/protocols/iso14443_3b/iso14443_3b_i.c delete mode 100644 lib/subghz/blocks/const.c diff --git a/.clangd b/.clangd index 3e0024e8c..12e13751d 100644 --- a/.clangd +++ b/.clangd @@ -5,6 +5,10 @@ CompileFlags: Remove: - -mword-relocations +Diagnostics: + ClangTidy: + FastCheckFilter: None + --- If: diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 40f72bd0b..d35ca0c17 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -64,6 +64,6 @@ jobs: python3 scripts/testing/units.py ${{steps.device.outputs.flipper}} - name: 'Check GDB output' - if: failure() + if: failure() && steps.flashing.outcome == 'success' run: | ./fbt gdb_trace_all SWD_TRANSPORT_SERIAL=2A0906016415303030303032 LIB_DEBUG=1 FIRMWARE_APP_SET=unit_tests FORCE=1 diff --git a/applications/debug/accessor/scene/accessor_scene_start.cpp b/applications/debug/accessor/scene/accessor_scene_start.cpp index d31001d2d..79f51f061 100644 --- a/applications/debug/accessor/scene/accessor_scene_start.cpp +++ b/applications/debug/accessor/scene/accessor_scene_start.cpp @@ -1,7 +1,6 @@ #include "../accessor_app.h" #include "../accessor_view_manager.h" #include "../accessor_event.h" -#include "callback_connector.h" #include "accessor_scene_start.h" void AccessorSceneStart::on_enter(AccessorApp* app) { diff --git a/applications/debug/battery_test_app/views/battery_info.c b/applications/debug/battery_test_app/views/battery_info.c index 4b5dcd627..5c5a3bd45 100644 --- a/applications/debug/battery_test_app/views/battery_info.c +++ b/applications/debug/battery_test_app/views/battery_info.c @@ -68,7 +68,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); } else if(drain_current != 0) { snprintf(header, 20, "..."); - } else if(data->charging_voltage < 4.2) { + } else if(data->charging_voltage < 4.2f) { // Non-default battery charging limit, mention it snprintf(emote, sizeof(emote), "Charged!"); snprintf(header, sizeof(header), "Limited to"); diff --git a/applications/debug/display_test/display_test.c b/applications/debug/display_test/display_test.c index ac1b6c65d..3028a13b9 100644 --- a/applications/debug/display_test/display_test.c +++ b/applications/debug/display_test/display_test.c @@ -1,5 +1,3 @@ -#include "display_test.h" - #include #include diff --git a/applications/debug/display_test/display_test.h b/applications/debug/display_test/display_test.h deleted file mode 100644 index 6f70f09be..000000000 --- a/applications/debug/display_test/display_test.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c index 6b9501e5b..ddca372e3 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c @@ -34,8 +34,8 @@ static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) { canvas_set_color(canvas, ColorBlack); char buffer[TEMP_STR_LEN + 1]; - double freq = ((float)SystemCoreClock / ((float)model->ARR + 1)); - double duty = ((float)model->CCR + 1) / ((float)model->ARR + 1) * 100.0f; + double freq = ((double)SystemCoreClock / (model->ARR + 1)); + double duty = (double)((model->CCR + 1) * 100) / (model->ARR + 1); snprintf( buffer, TEMP_STR_LEN, diff --git a/applications/debug/subghz_test/scenes/subghz_test_scene.c b/applications/debug/subghz_test/scenes/subghz_test_scene.c index ff439ef0f..fad16ddb4 100644 --- a/applications/debug/subghz_test/scenes/subghz_test_scene.c +++ b/applications/debug/subghz_test/scenes/subghz_test_scene.c @@ -1,4 +1,4 @@ -#include "../subghz_test_app_i.h" +#include "../subghz_test_app_i.h" // IWYU pragma: keep // Generate scene on_enter handlers array #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, diff --git a/applications/debug/subghz_test/subghz_test_app_i.c b/applications/debug/subghz_test/subghz_test_app_i.c index 0ec6635a0..e0daee6a6 100644 --- a/applications/debug/subghz_test/subghz_test_app_i.c +++ b/applications/debug/subghz_test/subghz_test_app_i.c @@ -1,5 +1,3 @@ -#include "subghz_test_app_i.h" - #include #define TAG "SubGhzTest" diff --git a/applications/debug/subghz_test/views/subghz_test_carrier.c b/applications/debug/subghz_test/views/subghz_test_carrier.c index a941cd4bb..2c82380f7 100644 --- a/applications/debug/subghz_test/views/subghz_test_carrier.c +++ b/applications/debug/subghz_test/views/subghz_test_carrier.c @@ -1,5 +1,4 @@ #include "subghz_test_carrier.h" -#include "../subghz_test_app_i.h" #include "../helpers/subghz_test_frequency.h" #include @@ -74,7 +73,7 @@ void subghz_test_carrier_draw(Canvas* canvas, SubGhzTestCarrierModel* model) { sizeof(buffer), "RSSI: %ld.%ld dBm", (int32_t)(model->rssi), - (int32_t)fabs(model->rssi * 10) % 10); + (int32_t)fabsf(model->rssi * 10.f) % 10); canvas_draw_str(canvas, 0, 42, buffer); } else { canvas_draw_str(canvas, 0, 42, "TX"); diff --git a/applications/debug/subghz_test/views/subghz_test_packet.c b/applications/debug/subghz_test/views/subghz_test_packet.c index d50f10ad4..674e7c737 100644 --- a/applications/debug/subghz_test/views/subghz_test_packet.c +++ b/applications/debug/subghz_test/views/subghz_test_packet.c @@ -1,5 +1,4 @@ #include "subghz_test_packet.h" -#include "../subghz_test_app_i.h" #include "../helpers/subghz_test_frequency.h" #include @@ -123,7 +122,7 @@ static void subghz_test_packet_draw(Canvas* canvas, SubGhzTestPacketModel* model sizeof(buffer), "RSSI: %ld.%ld dBm", (int32_t)(model->rssi), - (int32_t)fabs(model->rssi * 10) % 10); + (int32_t)fabsf(model->rssi * 10.0f) % 10); canvas_draw_str(canvas, 0, 53, buffer); } else { canvas_draw_str(canvas, 0, 53, "TX"); diff --git a/applications/debug/subghz_test/views/subghz_test_static.c b/applications/debug/subghz_test/views/subghz_test_static.c index 22ad662c5..b7b514bd3 100644 --- a/applications/debug/subghz_test/views/subghz_test_static.c +++ b/applications/debug/subghz_test/views/subghz_test_static.c @@ -1,9 +1,7 @@ #include "subghz_test_static.h" -#include "../subghz_test_app_i.h" #include "../helpers/subghz_test_frequency.h" #include -#include #include #include #include diff --git a/applications/debug/unit_tests/tests/bit_lib/bit_lib_test.c b/applications/debug/unit_tests/tests/bit_lib/bit_lib_test.c index d12aeb2aa..1487cdb48 100644 --- a/applications/debug/unit_tests/tests/bit_lib/bit_lib_test.c +++ b/applications/debug/unit_tests/tests/bit_lib/bit_lib_test.c @@ -1,5 +1,5 @@ #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include MU_TEST(test_bit_lib_increment_index) { diff --git a/applications/debug/unit_tests/tests/bt/bt_test.c b/applications/debug/unit_tests/tests/bt/bt_test.c index e7704381d..b65a35bf5 100644 --- a/applications/debug/unit_tests/tests/bt/bt_test.c +++ b/applications/debug/unit_tests/tests/bt/bt_test.c @@ -1,6 +1,6 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include diff --git a/applications/debug/unit_tests/tests/compress/compress_test.c b/applications/debug/unit_tests/tests/compress/compress_test.c index 8f6153297..15984083d 100644 --- a/applications/debug/unit_tests/tests/compress/compress_test.c +++ b/applications/debug/unit_tests/tests/compress/compress_test.c @@ -1,4 +1,4 @@ -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include diff --git a/applications/debug/unit_tests/tests/datetime/datetimelib_test.c b/applications/debug/unit_tests/tests/datetime/datetimelib_test.c index 7d90f18de..9ba3e59d1 100644 --- a/applications/debug/unit_tests/tests/datetime/datetimelib_test.c +++ b/applications/debug/unit_tests/tests/datetime/datetimelib_test.c @@ -1,5 +1,5 @@ #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include diff --git a/applications/debug/unit_tests/tests/dialogs_file_browser_options/dialogs_file_browser_options.c b/applications/debug/unit_tests/tests/dialogs_file_browser_options/dialogs_file_browser_options.c index e42e00f9a..14cd078d5 100644 --- a/applications/debug/unit_tests/tests/dialogs_file_browser_options/dialogs_file_browser_options.c +++ b/applications/debug/unit_tests/tests/dialogs_file_browser_options/dialogs_file_browser_options.c @@ -1,6 +1,6 @@ #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep MU_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields) { mu_assert( diff --git a/applications/debug/unit_tests/tests/dirwalk/dirwalk_test.c b/applications/debug/unit_tests/tests/dirwalk/dirwalk_test.c index c2474e755..e0102a575 100644 --- a/applications/debug/unit_tests/tests/dirwalk/dirwalk_test.c +++ b/applications/debug/unit_tests/tests/dirwalk/dirwalk_test.c @@ -1,4 +1,4 @@ -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include #include diff --git a/applications/debug/unit_tests/tests/expansion/expansion_test.c b/applications/debug/unit_tests/tests/expansion/expansion_test.c index 79d9b0a57..ea4fea28c 100644 --- a/applications/debug/unit_tests/tests/expansion/expansion_test.c +++ b/applications/debug/unit_tests/tests/expansion/expansion_test.c @@ -1,4 +1,4 @@ -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include diff --git a/applications/debug/unit_tests/tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/tests/flipper_format/flipper_format_test.c index 1a2eaf222..03a9e5ab0 100644 --- a/applications/debug/unit_tests/tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/tests/flipper_format/flipper_format_test.c @@ -2,7 +2,7 @@ #include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #define TEST_DIR TEST_DIR_NAME "/" #define TEST_DIR_NAME EXT_PATH("unit_tests_tmp") diff --git a/applications/debug/unit_tests/tests/flipper_format_string/flipper_format_string_test.c b/applications/debug/unit_tests/tests/flipper_format_string/flipper_format_string_test.c index 821b1ba22..a6e1b7700 100644 --- a/applications/debug/unit_tests/tests/flipper_format_string/flipper_format_string_test.c +++ b/applications/debug/unit_tests/tests/flipper_format_string/flipper_format_string_test.c @@ -3,7 +3,7 @@ #include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep static const char* test_filetype = "Flipper Format test"; static const uint32_t test_version = 666; diff --git a/applications/debug/unit_tests/tests/float_tools/float_tools_test.c b/applications/debug/unit_tests/tests/float_tools/float_tools_test.c index d016ca4a2..41d78da05 100644 --- a/applications/debug/unit_tests/tests/float_tools/float_tools_test.c +++ b/applications/debug/unit_tests/tests/float_tools/float_tools_test.c @@ -1,7 +1,7 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep MU_TEST(float_tools_equal_test) { mu_check(float_is_equal(FLT_MAX, FLT_MAX)); diff --git a/applications/debug/unit_tests/tests/furi/furi_memmgr_test.c b/applications/debug/unit_tests/tests/furi/furi_memmgr_test.c index 837fd6085..43a1d20eb 100644 --- a/applications/debug/unit_tests/tests/furi/furi_memmgr_test.c +++ b/applications/debug/unit_tests/tests/furi/furi_memmgr_test.c @@ -1,4 +1,4 @@ -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include #include diff --git a/applications/debug/unit_tests/tests/furi/furi_pubsub_test.c b/applications/debug/unit_tests/tests/furi/furi_pubsub_test.c index fdf15e6f5..d9956b0ae 100644 --- a/applications/debug/unit_tests/tests/furi/furi_pubsub_test.c +++ b/applications/debug/unit_tests/tests/furi/furi_pubsub_test.c @@ -1,7 +1,7 @@ #include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep const uint32_t context_value = 0xdeadbeef; const uint32_t notify_value_0 = 0x12345678; diff --git a/applications/debug/unit_tests/tests/furi/furi_record_test.c b/applications/debug/unit_tests/tests/furi/furi_record_test.c index 6a2b5a3d2..b192f1527 100644 --- a/applications/debug/unit_tests/tests/furi/furi_record_test.c +++ b/applications/debug/unit_tests/tests/furi/furi_record_test.c @@ -1,7 +1,5 @@ -#include -#include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #define TEST_RECORD_NAME "test/holding" diff --git a/applications/debug/unit_tests/tests/furi/furi_test.c b/applications/debug/unit_tests/tests/furi/furi_test.c index eab9a917d..f08e4aa6b 100644 --- a/applications/debug/unit_tests/tests/furi/furi_test.c +++ b/applications/debug/unit_tests/tests/furi/furi_test.c @@ -1,7 +1,6 @@ -#include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep // v2 tests void test_furi_create_open(void); diff --git a/applications/debug/unit_tests/tests/furi_hal/furi_hal_tests.c b/applications/debug/unit_tests/tests/furi_hal/furi_hal_tests.c index 985daa03d..4b515206c 100644 --- a/applications/debug/unit_tests/tests/furi_hal/furi_hal_tests.c +++ b/applications/debug/unit_tests/tests/furi_hal/furi_hal_tests.c @@ -1,11 +1,9 @@ -#include "furi_hal_rtc.h" #include #include #include #include #include -#include "../test.h" -#include +#include "../test.h" // IWYU pragma: keep #define DATA_SIZE 4 #define EEPROM_ADDRESS 0b10101000 diff --git a/applications/debug/unit_tests/tests/furi_hal_crypto/furi_hal_crypto_tests.c b/applications/debug/unit_tests/tests/furi_hal_crypto/furi_hal_crypto_tests.c index 0a264a18a..26527c669 100644 --- a/applications/debug/unit_tests/tests/furi_hal_crypto/furi_hal_crypto_tests.c +++ b/applications/debug/unit_tests/tests/furi_hal_crypto/furi_hal_crypto_tests.c @@ -1,7 +1,6 @@ -#include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep static const uint8_t key_ctr_1[32] = { 0x77, 0x6B, 0xEF, 0xF2, 0x85, 0x1D, 0xB0, 0x6F, 0x4C, 0x8A, 0x05, 0x42, 0xC8, 0x69, 0x6F, 0x6C, diff --git a/applications/debug/unit_tests/tests/furi_string/furi_string_test.c b/applications/debug/unit_tests/tests/furi_string/furi_string_test.c index 949d8c048..df835006e 100644 --- a/applications/debug/unit_tests/tests/furi_string/furi_string_test.c +++ b/applications/debug/unit_tests/tests/furi_string/furi_string_test.c @@ -1,5 +1,5 @@ #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep static void test_setup(void) { } diff --git a/applications/debug/unit_tests/tests/infrared/infrared_test.c b/applications/debug/unit_tests/tests/infrared/infrared_test.c index 922577aa8..cf6a13220 100644 --- a/applications/debug/unit_tests/tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/tests/infrared/infrared_test.c @@ -2,7 +2,7 @@ #include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #define IR_TEST_FILES_DIR EXT_PATH("unit_tests/infrared/") #define IR_TEST_FILE_PREFIX "test_" diff --git a/applications/debug/unit_tests/tests/lfrfid/lfrfid_protocols.c b/applications/debug/unit_tests/tests/lfrfid/lfrfid_protocols.c index fc380ecc4..8bf7753c0 100644 --- a/applications/debug/unit_tests/tests/lfrfid/lfrfid_protocols.c +++ b/applications/debug/unit_tests/tests/lfrfid/lfrfid_protocols.c @@ -1,5 +1,5 @@ #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include #include diff --git a/applications/debug/unit_tests/tests/manifest/manifest.c b/applications/debug/unit_tests/tests/manifest/manifest.c index fcbab0ae8..b2c888f1a 100644 --- a/applications/debug/unit_tests/tests/manifest/manifest.c +++ b/applications/debug/unit_tests/tests/manifest/manifest.c @@ -1,5 +1,5 @@ -#include -#include "../test.h" +#include +#include "../test.h" // IWYU pragma: keep #include #define TAG "Manifest" diff --git a/applications/debug/unit_tests/tests/nfc/nfc_test.c b/applications/debug/unit_tests/tests/nfc/nfc_test.c index 4de364a09..94fe53632 100644 --- a/applications/debug/unit_tests/tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/tests/nfc/nfc_test.c @@ -24,7 +24,7 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #define TAG "NfcTest" diff --git a/applications/debug/unit_tests/tests/power/power_test.c b/applications/debug/unit_tests/tests/power/power_test.c index d121acba6..ae332c96d 100644 --- a/applications/debug/unit_tests/tests/power/power_test.c +++ b/applications/debug/unit_tests/tests/power/power_test.c @@ -1,6 +1,6 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep static void power_test_deinit(void) { // Try to reset to default charge voltage limit @@ -13,46 +13,47 @@ MU_TEST(test_power_charge_voltage_limit_exact) { // // This test may need adapted if other charge controllers are used in the future. for(uint16_t charge_mv = 3840; charge_mv <= 4208; charge_mv += 16) { - float charge_volt = (float)charge_mv / 1000.0f; + float charge_volt = (float)charge_mv / 1000; furi_hal_power_set_battery_charge_voltage_limit(charge_volt); - mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq( + (double)charge_volt, (double)furi_hal_power_get_battery_charge_voltage_limit()); } } MU_TEST(test_power_charge_voltage_limit_floating_imprecision) { // 4.016f should act as 4.016 V, even with floating point imprecision furi_hal_power_set_battery_charge_voltage_limit(4.016f); - mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(4.016, (double)furi_hal_power_get_battery_charge_voltage_limit()); } MU_TEST(test_power_charge_voltage_limit_inexact) { // Charge voltage limits that are not power of 16mV get truncated down furi_hal_power_set_battery_charge_voltage_limit(3.841f); - mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(3.840, (double)furi_hal_power_get_battery_charge_voltage_limit()); furi_hal_power_set_battery_charge_voltage_limit(3.900f); - mu_assert_double_eq(3.888, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(3.888, (double)furi_hal_power_get_battery_charge_voltage_limit()); furi_hal_power_set_battery_charge_voltage_limit(4.200f); - mu_assert_double_eq(4.192, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(4.192, (double)furi_hal_power_get_battery_charge_voltage_limit()); } MU_TEST(test_power_charge_voltage_limit_invalid_clamped) { // Out-of-range charge voltage limits get clamped to 3.840 V and 4.208 V furi_hal_power_set_battery_charge_voltage_limit(3.808f); - mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(3.840, (double)furi_hal_power_get_battery_charge_voltage_limit()); furi_hal_power_set_battery_charge_voltage_limit(1.0f); - mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(3.840, (double)furi_hal_power_get_battery_charge_voltage_limit()); // NOTE: Intentionally picking a small increment above 4.208 V to reduce the risk of an // unhappy battery if this fails. furi_hal_power_set_battery_charge_voltage_limit(4.240f); - mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(4.208, (double)furi_hal_power_get_battery_charge_voltage_limit()); // Likewise, picking a number that the uint8_t wraparound in the driver would result in a // VREG value under 23 if this test fails. // E.g. (uint8_t)((8105-3840)/16) -> 10 furi_hal_power_set_battery_charge_voltage_limit(8.105f); - mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit()); + mu_assert_double_eq(4.208, (double)furi_hal_power_get_battery_charge_voltage_limit()); } MU_TEST_SUITE(test_power_suite) { diff --git a/applications/debug/unit_tests/tests/protocol_dict/protocol_dict_test.c b/applications/debug/unit_tests/tests/protocol_dict/protocol_dict_test.c index 9ced106ab..4e2975218 100644 --- a/applications/debug/unit_tests/tests/protocol_dict/protocol_dict_test.c +++ b/applications/debug/unit_tests/tests/protocol_dict/protocol_dict_test.c @@ -1,5 +1,5 @@ #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include typedef enum { diff --git a/applications/debug/unit_tests/tests/rpc/rpc_test.c b/applications/debug/unit_tests/tests/rpc/rpc_test.c index be7b331f9..fdbfb6c7a 100644 --- a/applications/debug/unit_tests/tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/tests/rpc/rpc_test.c @@ -17,7 +17,7 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include diff --git a/applications/debug/unit_tests/tests/storage/storage_test.c b/applications/debug/unit_tests/tests/storage/storage_test.c index 1d887ced0..65a25cf49 100644 --- a/applications/debug/unit_tests/tests/storage/storage_test.c +++ b/applications/debug/unit_tests/tests/storage/storage_test.c @@ -1,4 +1,4 @@ -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include diff --git a/applications/debug/unit_tests/tests/stream/stream_test.c b/applications/debug/unit_tests/tests/stream/stream_test.c index a9c22c723..ad41c08ec 100644 --- a/applications/debug/unit_tests/tests/stream/stream_test.c +++ b/applications/debug/unit_tests/tests/stream/stream_test.c @@ -4,7 +4,7 @@ #include #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep static const char* stream_test_data = "I write differently from what I speak, " "I speak differently from what I think, " diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index 030a4223f..6a4129359 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -1,6 +1,6 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include #include diff --git a/applications/debug/unit_tests/tests/varint/varint_test.c b/applications/debug/unit_tests/tests/varint/varint_test.c index 3fdf5115a..6a9d94c16 100644 --- a/applications/debug/unit_tests/tests/varint/varint_test.c +++ b/applications/debug/unit_tests/tests/varint/varint_test.c @@ -1,7 +1,7 @@ #include #include -#include "../test.h" +#include "../test.h" // IWYU pragma: keep #include #include diff --git a/applications/main/archive/helpers/archive_apps.c b/applications/main/archive/helpers/archive_apps.c index c8ad67625..43befc055 100644 --- a/applications/main/archive/helpers/archive_apps.c +++ b/applications/main/archive/helpers/archive_apps.c @@ -1,4 +1,3 @@ -#include "archive_files.h" #include "archive_apps.h" #include "archive_browser.h" diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 51457fe81..ea9cdbdc3 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -7,7 +7,6 @@ #include #include #include -#include static void archive_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root) { diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index ba928c499..c08deb60a 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -1,6 +1,5 @@ #include "../archive_i.h" #include "../helpers/archive_files.h" -#include "../helpers/archive_apps.h" #include "../helpers/archive_favorites.h" #include "../helpers/archive_browser.h" #include "../views/archive_browser_view.h" diff --git a/applications/main/archive/scenes/archive_scene_delete.c b/applications/main/archive/scenes/archive_scene_delete.c index 45d5b47cc..cbeb4824d 100644 --- a/applications/main/archive/scenes/archive_scene_delete.c +++ b/applications/main/archive/scenes/archive_scene_delete.c @@ -1,5 +1,4 @@ #include "../archive_i.h" -#include "../helpers/archive_favorites.h" #include "../helpers/archive_files.h" #include "../helpers/archive_apps.h" #include "../helpers/archive_browser.h" diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 6cdf12c62..de06b9684 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -1,7 +1,6 @@ #include "assets_icons.h" #include "toolbox/path.h" #include -#include "../archive_i.h" #include "archive_browser_view.h" #include "../helpers/archive_browser.h" diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_config.c b/applications/main/bad_usb/scenes/bad_usb_scene_config.c index d5f6fce23..1acf3acb1 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_config.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_config.c @@ -1,5 +1,4 @@ #include "../bad_usb_app_i.h" -#include "furi_hal_power.h" enum SubmenuIndex { ConfigIndexKeyboardLayout, diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_config_layout.c b/applications/main/bad_usb/scenes/bad_usb_scene_config_layout.c index a5d0df94c..3f01d7090 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_config_layout.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_config_layout.c @@ -1,5 +1,4 @@ #include "../bad_usb_app_i.h" -#include "furi_hal_power.h" #include static bool bad_usb_layout_select(BadUsbApp* bad_usb) { diff --git a/applications/main/gpio/views/gpio_usb_uart.c b/applications/main/gpio/views/gpio_usb_uart.c index f3d047d67..5e714576d 100644 --- a/applications/main/gpio/views/gpio_usb_uart.c +++ b/applications/main/gpio/views/gpio_usb_uart.c @@ -1,7 +1,8 @@ +#include "gpio_usb_uart.h" #include "../usb_uart_bridge.h" -#include "../gpio_app_i.h" #include #include +#include struct GpioUsbUart { View* view; diff --git a/applications/main/infrared/scenes/infrared_scene_universal_ac.c b/applications/main/infrared/scenes/infrared_scene_universal_ac.c index b82bcc1f9..9288a4a4d 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_ac.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_ac.c @@ -1,4 +1,4 @@ -#include "../infrared_app_i.h" +#include "../infrared_app_i.h" // IWYU pragma: keep #include "common/infrared_scene_universal_common.h" diff --git a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c index cd16374bc..e7acf4863 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c +++ b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c @@ -167,7 +167,7 @@ bool nfc_scene_read_on_event_mf_ultralight(NfcApp* instance, SceneManagerEvent e if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventCardDetected) { nfc_unlock_helper_card_detected_handler(instance); - } else if((event.event == NfcCustomEventPollerIncomplete)) { + } else if(event.event == NfcCustomEventPollerIncomplete) { notification_message(instance->notifications, &sequence_semi_success); scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess); dolphin_deed(DolphinDeedNfcReadSuccess); diff --git a/applications/main/nfc/plugins/supported_cards/troika.c b/applications/main/nfc/plugins/supported_cards/troika.c index 64a9ac5dc..de9a47fac 100644 --- a/applications/main/nfc/plugins/supported_cards/troika.c +++ b/applications/main/nfc/plugins/supported_cards/troika.c @@ -7,7 +7,6 @@ #include #include #include "../../api/mosgortrans/mosgortrans_util.h" -#include "furi_hal_rtc.h" #define TAG "Troika" diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index 995434631..624caf30e 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -49,7 +49,7 @@ static uint32_t subghz_frequency_analyzer_worker_expRunningAverageAdaptive( float k; float newValFloat = newVal; // the sharpness of the filter depends on the absolute value of the difference - if(fabs(newValFloat - instance->filVal) > 500000) + if(fabsf(newValFloat - instance->filVal) > 500000.f) k = 0.9; else k = 0.03; diff --git a/applications/main/subghz/helpers/subghz_threshold_rssi.c b/applications/main/subghz/helpers/subghz_threshold_rssi.c index 07d7bccf9..f9906b513 100644 --- a/applications/main/subghz/helpers/subghz_threshold_rssi.c +++ b/applications/main/subghz/helpers/subghz_threshold_rssi.c @@ -1,6 +1,6 @@ #include "subghz_threshold_rssi.h" +#include "../views/subghz_read_raw.h" #include -#include "../subghz_i.h" #define TAG "SubGhzThresholdRssi" #define THRESHOLD_RSSI_LOW_COUNT 10 diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index bcc0cc433..d14be4768 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -1,4 +1,4 @@ -#include "subghz_txrx_i.h" +#include "subghz_txrx_i.h" // IWYU pragma: keep #include #include 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 bafaef5ee..3e0656550 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -1,4 +1,4 @@ -#include "subghz_txrx_i.h" +#include "subghz_txrx_i.h" // IWYU pragma: keep #include "subghz_txrx_create_protocol_key.h" #include #include diff --git a/applications/main/subghz/scenes/subghz_scene_delete_success.c b/applications/main/subghz/scenes/subghz_scene_delete_success.c index d5c2b391c..0150f2996 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_success.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_success.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep #include "../helpers/subghz_custom_event.h" void subghz_scene_delete_success_popup_callback(void* context) { diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index b48a821da..da861d718 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep #include "../views/subghz_frequency_analyzer.h" void subghz_scene_frequency_analyzer_callback(SubGhzCustomEvent event, void* context) { diff --git a/applications/main/subghz/scenes/subghz_scene_radio_setting.c b/applications/main/subghz/scenes/subghz_scene_radio_setting.c index 1f8e4d83d..c324d0d2e 100644 --- a/applications/main/subghz/scenes/subghz_scene_radio_setting.c +++ b/applications/main/subghz/scenes/subghz_scene_radio_setting.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep #include #include #include diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index f2ab65770..a0578ff95 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -2,7 +2,7 @@ #include "../views/subghz_read_raw.h" #include #include -#include +#include #define RAW_FILE_NAME "Raw_signal_" #define TAG "SubGhzSceneReadRaw" diff --git a/applications/main/subghz/scenes/subghz_scene_region_info.c b/applications/main/subghz/scenes/subghz_scene_region_info.c index 61bd1acc8..ce123dab3 100644 --- a/applications/main/subghz/scenes/subghz_scene_region_info.c +++ b/applications/main/subghz/scenes/subghz_scene_region_info.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep #include diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index a65830f4b..61e362d5b 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep enum SubmenuIndex { SubmenuIndexEmulate, diff --git a/applications/main/subghz/scenes/subghz_scene_show_error.c b/applications/main/subghz/scenes/subghz_scene_show_error.c index d52eca9b6..904663e0b 100644 --- a/applications/main/subghz/scenes/subghz_scene_show_error.c +++ b/applications/main/subghz/scenes/subghz_scene_show_error.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep #include "../helpers/subghz_custom_event.h" static const NotificationSequence subghs_sequence_sd_error = { diff --git a/applications/main/subghz/scenes/subghz_scene_show_error_sub.c b/applications/main/subghz/scenes/subghz_scene_show_error_sub.c index 0de48c442..e7eda9c71 100644 --- a/applications/main/subghz/scenes/subghz_scene_show_error_sub.c +++ b/applications/main/subghz/scenes/subghz_scene_show_error_sub.c @@ -1,4 +1,4 @@ -#include "../subghz_i.h" +#include "../subghz_i.h" // IWYU pragma: keep #include "../helpers/subghz_custom_event.h" void subghz_scene_show_error_sub_popup_callback(void* context) { diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index b553d00de..243ad101f 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -2,7 +2,6 @@ #include "assets_icons.h" #include "subghz/types.h" -#include #include #include #include @@ -10,7 +9,6 @@ #include #include #include -#include "views/receiver.h" #include #include diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index ea332f544..39b5c78b9 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -1,7 +1,6 @@ #include "receiver.h" -#include "../subghz_i.h" -#include +#include "types.h" #include #include #include diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 133868dde..b59426f02 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -1,7 +1,5 @@ #include "subghz_frequency_analyzer.h" -#include "../subghz_i.h" -#include #include #include #include diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index eff3eb1ab..322c0d499 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -1,7 +1,5 @@ #include "subghz_read_raw.h" -#include "../subghz_i.h" -#include #include #include #include @@ -72,7 +70,7 @@ void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi, bool tra if(rssi < SUBGHZ_RAW_THRESHOLD_MIN) { u_rssi = 0; } else { - u_rssi = (uint8_t)((rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7); + u_rssi = (uint8_t)((rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7f); } with_view_model( @@ -272,7 +270,7 @@ void subghz_read_raw_draw_threshold_rssi(Canvas* canvas, SubGhzReadRAWModel* mod if(model->raw_threshold_rssi > SUBGHZ_RAW_THRESHOLD_MIN) { uint8_t x = 118; - y -= (uint8_t)((model->raw_threshold_rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7); + y -= (uint8_t)((model->raw_threshold_rssi - SUBGHZ_RAW_THRESHOLD_MIN) / 2.7f); uint8_t width = 3; for(uint8_t i = 0; i < x; i += width * 2) { diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index f9b3f44ba..ab41ea956 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -1,6 +1,6 @@ #include "transmitter.h" -#include "../subghz_i.h" +#include #include #include diff --git a/applications/main/u2f/u2f.c b/applications/main/u2f/u2f.c index 2a2e91f21..b61cfa15d 100644 --- a/applications/main/u2f/u2f.c +++ b/applications/main/u2f/u2f.c @@ -1,5 +1,4 @@ #include "u2f.h" -#include "u2f_hid.h" #include "u2f_data.h" #include diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index 58c5c887f..cdabaaa05 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -1,7 +1,7 @@ +#include "cli_i.h" // IWYU pragma: keep #include #include #include -#include "cli_i.h" #define TAG "CliVcp" diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index c99cc7b5d..1db61f1ab 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -8,7 +8,6 @@ #include "animation_manager.h" #include "animation_storage.h" -#include "animation_storage_i.h" #include #include diff --git a/applications/services/desktop/animations/views/bubble_animation_view.c b/applications/services/desktop/animations/views/bubble_animation_view.c index 9585b2771..cea039671 100644 --- a/applications/services/desktop/animations/views/bubble_animation_view.c +++ b/applications/services/desktop/animations/views/bubble_animation_view.c @@ -1,6 +1,5 @@ #include "../animation_manager.h" -#include "../animation_storage.h" #include "bubble_animation_view.h" #include diff --git a/applications/services/desktop/helpers/pin.c b/applications/services/desktop/helpers/pin.c index 374b569f0..0b1149d6c 100644 --- a/applications/services/desktop/helpers/pin.c +++ b/applications/services/desktop/helpers/pin.c @@ -7,8 +7,6 @@ #include #include -#include "../desktop_i.h" - static const NotificationSequence sequence_pin_fail = { &message_display_backlight_on, diff --git a/applications/services/desktop/scenes/desktop_scene_lock_menu.c b/applications/services/desktop/scenes/desktop_scene_lock_menu.c index 105b2b37a..5951a8e4e 100644 --- a/applications/services/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/services/desktop/scenes/desktop_scene_lock_menu.c @@ -8,9 +8,7 @@ #include "../desktop_i.h" #include #include "../views/desktop_view_lock_menu.h" -#include "desktop_scene_i.h" #include "desktop_scene.h" -#include "../helpers/pin.h" #define TAG "DesktopSceneLock" diff --git a/applications/services/desktop/scenes/desktop_scene_locked.c b/applications/services/desktop/scenes/desktop_scene_locked.c index c4cd5748f..6d432858a 100644 --- a/applications/services/desktop/scenes/desktop_scene_locked.c +++ b/applications/services/desktop/scenes/desktop_scene_locked.c @@ -9,7 +9,6 @@ #include "../helpers/pin.h" #include "../animations/animation_manager.h" #include "../views/desktop_events.h" -#include "../views/desktop_view_pin_input.h" #include "../views/desktop_view_locked.h" #include "desktop_scene.h" #include "desktop_scene_i.h" diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index 41b1c3e75..5f3778d13 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -8,7 +8,6 @@ #include "../views/desktop_events.h" #include "../views/desktop_view_main.h" #include "desktop_scene.h" -#include "desktop_scene_i.h" #define TAG "DesktopSrv" diff --git a/applications/services/desktop/scenes/desktop_scene_pin_input.c b/applications/services/desktop/scenes/desktop_scene_pin_input.c index f6de987bf..b1c0d4c85 100644 --- a/applications/services/desktop/scenes/desktop_scene_pin_input.c +++ b/applications/services/desktop/scenes/desktop_scene_pin_input.c @@ -8,12 +8,10 @@ #include "../desktop.h" #include "../desktop_i.h" -#include "../animations/animation_manager.h" #include "../views/desktop_events.h" #include "../views/desktop_view_pin_input.h" #include "../helpers/pin.h" #include "desktop_scene.h" -#include "desktop_scene_i.h" #define WRONG_PIN_HEADER_TIMEOUT 3000 #define INPUT_PIN_VIEW_TIMEOUT 15000 diff --git a/applications/services/desktop/scenes/desktop_scene_pin_timeout.c b/applications/services/desktop/scenes/desktop_scene_pin_timeout.c index e3336ad76..82543a944 100644 --- a/applications/services/desktop/scenes/desktop_scene_pin_timeout.c +++ b/applications/services/desktop/scenes/desktop_scene_pin_timeout.c @@ -5,7 +5,6 @@ #include "../desktop_i.h" #include "../views/desktop_view_pin_timeout.h" #include "desktop_scene.h" -#include "desktop_scene_i.h" static void desktop_scene_pin_timeout_callback(void* context) { Desktop* desktop = (Desktop*)context; diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 9f8b5f51a..1b6bdab9c 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -126,8 +126,8 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { update); if(event->key == InputKeyOk) { - if((idx == DesktopLockMenuIndexLock)) { - if((event->type == InputTypeShort)) { + if(idx == DesktopLockMenuIndexLock) { + if(event->type == InputTypeShort) { lock_menu->callback(DesktopLockMenuEventLock, lock_menu->context); } } else if(idx == DesktopLockMenuIndexStealth) { diff --git a/applications/services/desktop/views/desktop_view_main.c b/applications/services/desktop/views/desktop_view_main.c index 0c1160d40..87f12d84a 100644 --- a/applications/services/desktop/views/desktop_view_main.c +++ b/applications/services/desktop/views/desktop_view_main.c @@ -6,7 +6,6 @@ #include #include -#include "../desktop_i.h" #include "desktop_view_main.h" struct DesktopMainView { diff --git a/applications/services/desktop/views/desktop_view_slideshow.c b/applications/services/desktop/views/desktop_view_slideshow.c index 84e4d5706..de8c1cb86 100644 --- a/applications/services/desktop/views/desktop_view_slideshow.c +++ b/applications/services/desktop/views/desktop_view_slideshow.c @@ -3,9 +3,7 @@ #include #include "desktop_view_slideshow.h" -#include "../desktop_i.h" #include "../helpers/slideshow.h" -#include "../helpers/slideshow_filename.h" #define DESKTOP_SLIDESHOW_POWEROFF_SHORT 5000 #define DESKTOP_SLIDESHOW_POWEROFF_LONG (60 * 60 * 1000) diff --git a/applications/services/desktop/views/desktop_view_slideshow.h b/applications/services/desktop/views/desktop_view_slideshow.h index b9e610c62..942a0d25a 100644 --- a/applications/services/desktop/views/desktop_view_slideshow.h +++ b/applications/services/desktop/views/desktop_view_slideshow.h @@ -4,6 +4,7 @@ #include "desktop_events.h" #include "../helpers/slideshow_filename.h" +#include #define SLIDESHOW_FS_PATH INT_PATH(SLIDESHOW_FILE_NAME) diff --git a/applications/services/dialogs/dialogs.c b/applications/services/dialogs/dialogs.c index ec1289d5b..31856aa29 100644 --- a/applications/services/dialogs/dialogs.c +++ b/applications/services/dialogs/dialogs.c @@ -1,5 +1,4 @@ #include "dialogs/dialogs_message.h" -#include "dialogs_i.h" #include #include "dialogs_module_file_browser.h" #include "dialogs_module_message.h" diff --git a/applications/services/dialogs/dialogs_api.c b/applications/services/dialogs/dialogs_api.c index 73d1d876a..9df3eedb9 100644 --- a/applications/services/dialogs/dialogs_api.c +++ b/applications/services/dialogs/dialogs_api.c @@ -1,5 +1,4 @@ #include "dialogs_message.h" -#include "dialogs_i.h" #include #include #include diff --git a/applications/services/dialogs/dialogs_module_file_browser.c b/applications/services/dialogs/dialogs_module_file_browser.c index 79d151c59..b1558f1e9 100644 --- a/applications/services/dialogs/dialogs_module_file_browser.c +++ b/applications/services/dialogs/dialogs_module_file_browser.c @@ -1,5 +1,4 @@ -#include "dialogs_i.h" - +#include "dialogs_message.h" #include #include diff --git a/applications/services/dialogs/dialogs_module_message.c b/applications/services/dialogs/dialogs_module_message.c index 69d28c405..a71f403c5 100644 --- a/applications/services/dialogs/dialogs_module_message.c +++ b/applications/services/dialogs/dialogs_module_message.c @@ -1,4 +1,6 @@ -#include "dialogs_i.h" +#include "dialogs.h" +#include "dialogs_message.h" +#include #include #include diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index 5f3d5cb28..a838edc60 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -1,7 +1,6 @@ -#include "dolphin/dolphin.h" -#include "dolphin/helpers/dolphin_state.h" +#include "dolphin.h" +#include "helpers/dolphin_state.h" #include "dolphin_i.h" -#include "projdefs.h" #include #include #include diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index 55c2286d9..724060e53 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #define TAG "DolphinState" diff --git a/applications/services/gui/elements.c b/applications/services/gui/elements.c index 06b63fd90..5b38c5c79 100644 --- a/applications/services/gui/elements.c +++ b/applications/services/gui/elements.c @@ -9,7 +9,6 @@ #include #include -#include "canvas_i.h" #include #include diff --git a/applications/services/gui/icon.c b/applications/services/gui/icon.c index 6e015ed75..85d640f30 100644 --- a/applications/services/gui/icon.c +++ b/applications/services/gui/icon.c @@ -1,5 +1,5 @@ #include "icon.h" -#include "icon_i.h" +#include "icon_i.h" // IWYU pragma: keep #include #include diff --git a/applications/services/gui/icon_animation.c b/applications/services/gui/icon_animation.c index f887b90ac..f456ba368 100644 --- a/applications/services/gui/icon_animation.c +++ b/applications/services/gui/icon_animation.c @@ -1,5 +1,5 @@ #include "icon_animation_i.h" -#include "icon_i.h" +#include "icon_i.h" // IWYU pragma: keep #include diff --git a/applications/services/gui/modules/button_panel.c b/applications/services/gui/modules/button_panel.c index d768b324a..0aa9dd005 100644 --- a/applications/services/gui/modules/button_panel.c +++ b/applications/services/gui/modules/button_panel.c @@ -39,7 +39,7 @@ typedef struct ButtonItem { void* callback_context; } ButtonItem; -ARRAY_DEF(ButtonArray, ButtonItem*, M_PTR_OPLIST); +ARRAY_DEF(ButtonArray, ButtonItem*, M_PTR_OPLIST); // NOLINT #define M_OPL_ButtonArray_t() ARRAY_OPLIST(ButtonArray, M_PTR_OPLIST) ARRAY_DEF(ButtonMatrix, ButtonArray_t); #define M_OPL_ButtonMatrix_t() ARRAY_OPLIST(ButtonMatrix, M_OPL_ButtonArray_t()) diff --git a/applications/services/gui/modules/widget.c b/applications/services/gui/modules/widget.c index 50171e0cc..ea3315d8d 100644 --- a/applications/services/gui/modules/widget.c +++ b/applications/services/gui/modules/widget.c @@ -3,7 +3,7 @@ #include #include -ARRAY_DEF(ElementArray, WidgetElement*, M_PTR_OPLIST); +ARRAY_DEF(ElementArray, WidgetElement*, M_PTR_OPLIST); // NOLINT struct Widget { View* view; diff --git a/applications/services/notification/notification_app_api.c b/applications/services/notification/notification_app_api.c index 9c9a2680e..90e3f236e 100644 --- a/applications/services/notification/notification_app_api.c +++ b/applications/services/notification/notification_app_api.c @@ -1,7 +1,6 @@ #include #include #include "notification.h" -#include "notification_messages.h" #include "notification_app.h" void notification_message(NotificationApp* app, const NotificationSequence* sequence) { diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index 2db9bb1c3..557beaf64 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -13,7 +13,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { if(power->info.gauge_is_ok) { canvas_draw_box(canvas, 2, 2, (power->info.charge + 4) / 5, 4); - if(power->info.voltage_battery_charge_limit < 4.2) { + if(power->info.voltage_battery_charge_limit < 4.2f) { // Battery charge voltage limit is modified, indicate with cross pattern canvas_invert_color(canvas); uint8_t battery_bar_width = (power->info.charge + 4) / 5; diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index 054a0286f..32371fa82 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -1,4 +1,3 @@ -#include "profiles/serial_profile.h" #include "rpc_i.h" #include diff --git a/applications/services/rpc/rpc_desktop.c b/applications/services/rpc/rpc_desktop.c index 0d72b43d5..a70e84363 100644 --- a/applications/services/rpc/rpc_desktop.c +++ b/applications/services/rpc/rpc_desktop.c @@ -1,7 +1,6 @@ #include "flipper.pb.h" #include "rpc_i.h" #include -#include "desktop.pb.h" #define TAG "RpcDesktop" diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index a377751ea..adc0e2465 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -1,7 +1,7 @@ #include #include #include "storage.h" -#include "storage_i.h" +#include "storage_i.h" // IWYU pragma: keep #include "storage_message.h" #include #include diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index 2f21fd999..f31a96894 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c index 4cef4ba98..170e6bca5 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c index 0ebf85c64..efa39f1f0 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_howto2.c @@ -1,6 +1,5 @@ #include #include -#include #include "desktop_settings_scene.h" #include "../desktop_settings_app.h" diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index 8dec26016..7b3e5b96b 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -3,7 +3,6 @@ #include "../desktop_settings_app.h" #include "desktop_settings_scene.h" -#include "desktop_settings_scene_i.h" typedef enum { DesktopSettingsPinSetup = 0, diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index d43f150c6..0f3008a36 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -1,12 +1,11 @@ -#include "assets_icons.h" -#include "dolphin/helpers/dolphin_state.h" -#include -#include #include -#include #include -#include "dolphin/dolphin.h" -#include "math.h" + +#include +#include +#include + +#include #define MOODS_TOTAL 3 #define BUTTHURT_MAX 3 diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index dd2ec2dbc..c626d1844 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -68,7 +68,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { ABS(current), current < HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); } else if(data->vbus_voltage > 0) { - if(data->charge_voltage_limit < 4.2) { + if(data->charge_voltage_limit < 4.2f) { // Non-default battery charging limit, mention it snprintf(emote, sizeof(emote), "Charged!"); snprintf(header, sizeof(header), "Limited to"); diff --git a/applications/system/js_app/modules/js_flipper.c b/applications/system/js_app/modules/js_flipper.c index 17c0ad36b..4619a1593 100644 --- a/applications/system/js_app/modules/js_flipper.c +++ b/applications/system/js_app/modules/js_flipper.c @@ -1,5 +1,5 @@ +#include "../js_modules.h" // IWYU pragma: keep #include -#include "../js_modules.h" #include #include diff --git a/applications/system/js_app/plugin_api/app_api_table_i.h b/applications/system/js_app/plugin_api/app_api_table_i.h index d84ae8110..b48221343 100644 --- a/applications/system/js_app/plugin_api/app_api_table_i.h +++ b/applications/system/js_app/plugin_api/app_api_table_i.h @@ -1,4 +1,3 @@ -#include #include "js_plugin_api.h" /* * A list of app's private functions and objects to expose for plugins. diff --git a/furi/core/kernel.c b/furi/core/kernel.c index db3d6a716..52c0e285e 100644 --- a/furi/core/kernel.c +++ b/furi/core/kernel.c @@ -8,8 +8,6 @@ #include #include -#include CMSIS_device_header - bool furi_kernel_is_irq_or_masked(void) { bool irq = false; BaseType_t state; diff --git a/furi/core/memmgr.c b/furi/core/memmgr.c index 768adc05d..ba9a7336a 100644 --- a/furi/core/memmgr.c +++ b/furi/core/memmgr.c @@ -1,5 +1,4 @@ #include "memmgr.h" -#include "common_defines.h" #include #include diff --git a/furi/core/mutex.c b/furi/core/mutex.c index e32be1a39..4fc3099fe 100644 --- a/furi/core/mutex.c +++ b/furi/core/mutex.c @@ -120,7 +120,7 @@ FuriThreadId furi_mutex_get_owner(FuriMutex* instance) { hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); - if((hMutex == NULL)) { + if(hMutex == NULL) { owner = 0; } else if(FURI_IS_IRQ_MODE()) { owner = (FuriThreadId)xSemaphoreGetMutexHolderFromISR(hMutex); diff --git a/furi/core/pubsub.c b/furi/core/pubsub.c index bcabc74a7..0fdd5d02d 100644 --- a/furi/core/pubsub.c +++ b/furi/core/pubsub.c @@ -1,5 +1,4 @@ #include "pubsub.h" -#include "memmgr.h" #include "check.h" #include "mutex.h" diff --git a/furi/core/record.c b/furi/core/record.c index e9bd8edcd..6c44df846 100644 --- a/furi/core/record.c +++ b/furi/core/record.c @@ -1,6 +1,5 @@ #include "record.h" #include "check.h" -#include "memmgr.h" #include "mutex.h" #include "event_flag.h" diff --git a/furi/core/thread.c b/furi/core/thread.c index f9f73b4f7..3ae0b8c25 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -15,7 +15,9 @@ #define TAG "FuriThread" -#define THREAD_NOTIFY_INDEX 1 // Index 0 is used for stream buffers +#define THREAD_NOTIFY_INDEX (1) // Index 0 is used for stream buffers + +#define THREAD_MAX_STACK_SIZE (UINT16_MAX * sizeof(StackType_t)) typedef struct FuriThreadStdout FuriThreadStdout; @@ -49,7 +51,7 @@ struct FuriThread { bool is_service; bool heap_trace_enabled; - configSTACK_DEPTH_TYPE stack_size; + size_t stack_size; }; static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size); @@ -203,6 +205,7 @@ void furi_thread_set_stack_size(FuriThread* thread, size_t stack_size) { furi_check(thread); furi_check(thread->state == FuriThreadStateStopped); furi_check(stack_size % 4 == 0); + furi_check(stack_size <= THREAD_MAX_STACK_SIZE); thread->stack_size = stack_size; } @@ -263,7 +266,7 @@ void furi_thread_start(FuriThread* thread) { furi_check(thread); furi_check(thread->callback); furi_check(thread->state == FuriThreadStateStopped); - furi_check(thread->stack_size > 0 && thread->stack_size < (UINT16_MAX * sizeof(StackType_t))); + furi_check(thread->stack_size > 0); furi_thread_set_state(thread, FuriThreadStateStarting); diff --git a/furi/core/timer.c b/furi/core/timer.c index 2e688dcc3..671761fca 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -1,6 +1,5 @@ #include "timer.h" #include "check.h" -#include "memmgr.h" #include "kernel.h" #include diff --git a/furi/furi.c b/furi/furi.c index 628c47ea2..dca674da5 100644 --- a/furi/furi.c +++ b/furi/furi.c @@ -1,5 +1,4 @@ #include "furi.h" -#include #include #include diff --git a/lib/ble_profile/extra_services/hid_service.c b/lib/ble_profile/extra_services/hid_service.c index 92422d5d5..e46d2010c 100644 --- a/lib/ble_profile/extra_services/hid_service.c +++ b/lib/ble_profile/extra_services/hid_service.c @@ -1,5 +1,5 @@ #include "hid_service.h" -#include "app_common.h" +#include "app_common.h" // IWYU pragma: keep #include #include #include diff --git a/lib/drivers/lp5562.c b/lib/drivers/lp5562.c index e755d2d60..30a5b559a 100644 --- a/lib/drivers/lp5562.c +++ b/lib/drivers/lp5562.c @@ -3,8 +3,6 @@ #include "lp5562_reg.h" #include -#include - void lp5562_reset(FuriHalI2cBusHandle* handle) { Reg0D_Reset reg = {.value = 0xFF}; furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x0D, *(uint8_t*)®, LP5562_I2C_TIMEOUT); diff --git a/lib/flipper_application/application_assets.c b/lib/flipper_application/application_assets.c index ec3fc22ee..5fc250257 100644 --- a/lib/flipper_application/application_assets.c +++ b/lib/flipper_application/application_assets.c @@ -19,17 +19,13 @@ #define TAG "FapAssets" -#pragma pack(push, 1) - -typedef struct { +typedef struct FURI_PACKED { uint32_t magic; uint32_t version; uint32_t dirs_count; uint32_t files_count; } FlipperApplicationAssetsHeader; -#pragma pack(pop) - typedef enum { AssetsSignatureResultEqual, AssetsSignatureResultNotEqual, diff --git a/lib/flipper_application/flipper_application.c b/lib/flipper_application/flipper_application.c index 3c4a07f2f..a3509896f 100644 --- a/lib/flipper_application/flipper_application.c +++ b/lib/flipper_application/flipper_application.c @@ -18,7 +18,7 @@ struct FlipperApplication { /********************** Debugger access to loader state **********************/ -LIST_DEF(FlipperApplicationList, const FlipperApplication*, M_POD_OPLIST); +LIST_DEF(FlipperApplicationList, const FlipperApplication*, M_POD_OPLIST); // NOLINT FlipperApplicationList_t flipper_application_loaded_app_list = {0}; static bool flipper_application_loaded_app_list_initialized = false; @@ -277,8 +277,10 @@ static const char* preload_status_strings[] = { [FlipperApplicationPreloadStatusUnspecifiedError] = "Unknown error", [FlipperApplicationPreloadStatusInvalidFile] = "Invalid file", [FlipperApplicationPreloadStatusInvalidManifest] = "Invalid file manifest", - [FlipperApplicationPreloadStatusApiTooOld] = "Update Application to use with this Firmware (ApiTooOld)", - [FlipperApplicationPreloadStatusApiTooNew] = "Update Firmware to use with this Application (ApiTooNew)", + [FlipperApplicationPreloadStatusApiTooOld] = + "Update Application to use with this Firmware (ApiTooOld)", + [FlipperApplicationPreloadStatusApiTooNew] = + "Update Firmware to use with this Application (ApiTooNew)", [FlipperApplicationPreloadStatusTargetMismatch] = "Hardware target mismatch", }; @@ -286,7 +288,8 @@ static const char* load_status_strings[] = { [FlipperApplicationLoadStatusSuccess] = "Success", [FlipperApplicationLoadStatusUnspecifiedError] = "Unknown error", [FlipperApplicationLoadStatusNoFreeMemory] = "Out of memory", - [FlipperApplicationLoadStatusMissingImports] = "Update Firmware to use with this Application (MissingImports)", + [FlipperApplicationLoadStatusMissingImports] = + "Update Firmware to use with this Application (MissingImports)", }; const char* flipper_application_preload_status_to_string(FlipperApplicationPreloadStatus status) { diff --git a/lib/flipper_application/plugins/composite_resolver.c b/lib/flipper_application/plugins/composite_resolver.c index 03dcd95e7..78b611328 100644 --- a/lib/flipper_application/plugins/composite_resolver.c +++ b/lib/flipper_application/plugins/composite_resolver.c @@ -4,7 +4,7 @@ #include #include -LIST_DEF(ElfApiInterfaceList, const ElfApiInterface*, M_POD_OPLIST) +LIST_DEF(ElfApiInterfaceList, const ElfApiInterface*, M_POD_OPLIST) // NOLINT #define M_OPL_ElfApiInterfaceList_t() LIST_OPLIST(ElfApiInterfaceList, M_POD_OPLIST) struct CompositeApiResolver { diff --git a/lib/flipper_application/plugins/plugin_manager.c b/lib/flipper_application/plugins/plugin_manager.c index d0e294220..5caec162a 100644 --- a/lib/flipper_application/plugins/plugin_manager.c +++ b/lib/flipper_application/plugins/plugin_manager.c @@ -11,7 +11,7 @@ #define TAG "PluginManager" -ARRAY_DEF(FlipperApplicationList, FlipperApplication*, M_PTR_OPLIST) +ARRAY_DEF(FlipperApplicationList, FlipperApplication*, M_PTR_OPLIST) // NOLINT #define M_OPL_FlipperApplicationList_t() ARRAY_OPLIST(FlipperApplicationList, M_PTR_OPLIST) struct PluginManager { diff --git a/lib/lfrfid/protocols/protocol_pac_stanley.c b/lib/lfrfid/protocols/protocol_pac_stanley.c index 67bc3bf48..4eabe3659 100644 --- a/lib/lfrfid/protocols/protocol_pac_stanley.c +++ b/lib/lfrfid/protocols/protocol_pac_stanley.c @@ -96,7 +96,7 @@ bool protocol_pac_stanley_decoder_feed(ProtocolPACStanley* protocol, bool level, if(duration > PAC_STANLEY_MAX_TIME) return false; - uint8_t pulses = (uint8_t)round((float)duration / PAC_STANLEY_CYCLE_LENGTH); + uint8_t pulses = (uint8_t)roundf((float)duration / PAC_STANLEY_CYCLE_LENGTH); // Handle last stopbit & preamble (1 sb, 8 bit preamble) if(pulses >= 9 && !protocol->got_preamble) { diff --git a/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.c b/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.c index 751a1c4ff..52ba7e845 100644 --- a/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.c +++ b/lib/nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.c @@ -1,6 +1,6 @@ #include "iso14443_3a_poller_sync.h" -#include "iso14443_3a_poller_i.h" +#include "iso14443_3a_poller_i.h" // IWYU pragma: keep #include #include diff --git a/lib/nfc/protocols/iso14443_3b/iso14443_3b_i.c b/lib/nfc/protocols/iso14443_3b/iso14443_3b_i.c deleted file mode 100644 index cac7ed826..000000000 --- a/lib/nfc/protocols/iso14443_3b/iso14443_3b_i.c +++ /dev/null @@ -1 +0,0 @@ -#include "iso14443_3b_i.h" diff --git a/lib/nfc/protocols/iso14443_4b/iso14443_4b.c b/lib/nfc/protocols/iso14443_4b/iso14443_4b.c index b859f9b8e..6f849b1d4 100644 --- a/lib/nfc/protocols/iso14443_4b/iso14443_4b.c +++ b/lib/nfc/protocols/iso14443_4b/iso14443_4b.c @@ -1,4 +1,4 @@ -#include "iso14443_4b_i.h" +#include "iso14443_4b_i.h" // IWYU pragma: keep #include #include diff --git a/lib/pulse_reader/pulse_reader.c b/lib/pulse_reader/pulse_reader.c index 0fcafe67c..996a37d1e 100644 --- a/lib/pulse_reader/pulse_reader.c +++ b/lib/pulse_reader/pulse_reader.c @@ -1,6 +1,5 @@ #include "pulse_reader.h" -#include #include #include #include diff --git a/lib/signal_reader/signal_reader.c b/lib/signal_reader/signal_reader.c index f457cd29c..8df2d5c72 100644 --- a/lib/signal_reader/signal_reader.c +++ b/lib/signal_reader/signal_reader.c @@ -1,6 +1,5 @@ #include "signal_reader.h" -#include #include #include #include diff --git a/lib/subghz/blocks/const.c b/lib/subghz/blocks/const.c deleted file mode 100644 index 15719b2ac..000000000 --- a/lib/subghz/blocks/const.c +++ /dev/null @@ -1 +0,0 @@ -#include "const.h" diff --git a/lib/subghz/protocols/bin_raw.c b/lib/subghz/protocols/bin_raw.c index a5332ee4e..8f62ccb1f 100644 --- a/lib/subghz/protocols/bin_raw.c +++ b/lib/subghz/protocols/bin_raw.c @@ -529,7 +529,8 @@ static bool bin_raw_type = BinRAWTypeGap; //looking for the last occurrence of gap ind = instance->data_raw_ind - 1; - while((ind > 0) && (DURATION_DIFF(abs(instance->data_raw[ind]), gap) > gap_delta)) { + while((ind > 0) && + (DURATION_DIFF(abs(instance->data_raw[ind]), (int32_t)gap) > gap_delta)) { ind--; } gap_ind = ind; @@ -544,10 +545,10 @@ static bool uint16_t bit_count = 0; do { gap_ind--; - data_temp = (int)(round((float)(instance->data_raw[gap_ind]) / instance->te)); + data_temp = (int)(roundf((float)(instance->data_raw[gap_ind]) / instance->te)); bin_raw_debug("%d ", data_temp); if(data_temp == 0) bit_count++; //there is noise in the package - for(size_t i = 0; i < abs(data_temp); i++) { + for(size_t i = 0; i < (size_t)abs(data_temp); i++) { bit_count++; if(ind) { ind--; @@ -563,7 +564,7 @@ static bool } } //split into full bytes if gap is caught - if(DURATION_DIFF(abs(instance->data_raw[gap_ind]), gap) < gap_delta) { + if(DURATION_DIFF(abs(instance->data_raw[gap_ind]), (int32_t)gap) < gap_delta) { instance->data_markup[data_markup_ind].byte_bias = ind >> 3; instance->data_markup[data_markup_ind++].bit_count = bit_count; bit_count = 0; @@ -807,11 +808,11 @@ static bool bin_raw_debug_tag(TAG, "Sequence analysis without gap\r\n"); ind = 0; for(size_t i = 0; i < instance->data_raw_ind; i++) { - int data_temp = (int)(round((float)(instance->data_raw[i]) / instance->te)); + int data_temp = (int)(roundf((float)(instance->data_raw[i]) / instance->te)); if(data_temp == 0) break; //found an interval 2 times shorter than TE, this is noise bin_raw_debug("%d ", data_temp); - for(size_t k = 0; k < abs(data_temp); k++) { + for(size_t k = 0; k < (size_t)abs(data_temp); k++) { if(data_temp > 0) { subghz_protocol_blocks_set_bit_array( true, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE); diff --git a/lib/subghz/protocols/intertechno_v3.c b/lib/subghz/protocols/intertechno_v3.c index 7fe952995..b9af72a57 100644 --- a/lib/subghz/protocols/intertechno_v3.c +++ b/lib/subghz/protocols/intertechno_v3.c @@ -470,6 +470,6 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString output, "Ch:" CH_PATTERN " Dimm:%d%%\r\n", CNT_TO_CH(instance->generic.cnt), - (int)(6.67 * (float)instance->generic.btn)); + (int)(6.67f * (float)instance->generic.btn)); } } diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 60b394e78..59175de8f 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -267,7 +267,7 @@ void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t instance->generic.data = instance->decoder.decode_data; instance->generic.data_count_bit = instance->decoder.decode_count_bit; - instance->guard_time = round((float)duration / instance->te); + instance->guard_time = roundf((float)duration / instance->te); if(instance->base.callback) instance->base.callback(&instance->base, instance->base.context); diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c index 472a354e3..e50d52ac1 100644 --- a/lib/subghz/protocols/protocol_items.c +++ b/lib/subghz/protocols/protocol_items.c @@ -1,4 +1,4 @@ -#include "protocol_items.h" +#include "protocol_items.h" // IWYU pragma: keep const SubGhzProtocol* subghz_protocol_registry_items[] = { &subghz_protocol_gate_tx, diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 12599891d..b5677f9c2 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -3,10 +3,7 @@ #include "../subghz_file_encoder_worker.h" #include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" #include "../blocks/generic.h" -#include "../blocks/math.h" #include #include diff --git a/lib/subghz/receiver.c b/lib/subghz/receiver.c index c70229a12..88fac4e34 100644 --- a/lib/subghz/receiver.c +++ b/lib/subghz/receiver.c @@ -1,7 +1,6 @@ #include "receiver.h" #include "registry.h" -#include "protocols/protocol_items.h" #include diff --git a/lib/subghz/subghz_setting.c b/lib/subghz/subghz_setting.c index aacf2b4fe..ed1120a20 100644 --- a/lib/subghz/subghz_setting.c +++ b/lib/subghz/subghz_setting.c @@ -1,6 +1,5 @@ #include "subghz_setting.h" -#include "types.h" -//#include "subghz_i.h" +#include "types.h" // IWYU pragma: keep #include #include diff --git a/lib/subghz/transmitter.c b/lib/subghz/transmitter.c index 4f7922c35..20247d339 100644 --- a/lib/subghz/transmitter.c +++ b/lib/subghz/transmitter.c @@ -2,7 +2,6 @@ #include "protocols/base.h" #include "registry.h" -#include "protocols/protocol_items.h" struct SubGhzTransmitter { const SubGhzProtocol* protocol; diff --git a/lib/toolbox/manchester_encoder.c b/lib/toolbox/manchester_encoder.c index 38b94eb86..239e53250 100644 --- a/lib/toolbox/manchester_encoder.c +++ b/lib/toolbox/manchester_encoder.c @@ -1,5 +1,4 @@ #include "manchester_encoder.h" -#include #include void manchester_encoder_reset(ManchesterEncoderState* state) { From 20c4121f25125a3e85820c45037602a7b1648a67 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:04:03 +0300 Subject: [PATCH 2/2] [FL-3832] Use static synchronisation primitives (#3679) * Use static mutex * Add static_assert checks * Use static semaphore * Fix formatting * Use static stream buffer * Use static timer * Use static event group * Increase allocation size for stream buffer * Remove recursive bit from the mutex before freeing * Prevent service tasks from ever returning * Use static threads * Do not realloc memory when changing stack size * Use FuriSemaphore instead of raw FreeRTOS one in rpc_test * Remove redundant includes * Abolish FreeRTOS dynamic allocation * Improve FuriMutex * Improve FuriMessageQueue * Remove redundant comments and parentheses * Clean up code more * Create service threads via a dedicated constructor * Minor code improvements * Update docs for FuriThread, FuriTimer * Fix doxygen typo * Use a bigger buffer for static StreamBuffer * Furi: remove timer control block only when timer thread have completed all operations --------- Co-authored-by: Aleksandr Kutuzov --- .../debug/unit_tests/tests/rpc/rpc_test.c | 43 +- .../debug/unit_tests/unit_test_api_table_i.h | 4 +- applications/services/bt/bt_service/bt.c | 2 + applications/services/desktop/desktop.c | 2 + .../scenes/desktop_scene_pin_timeout.c | 1 - .../desktop/views/desktop_view_pin_timeout.c | 1 - applications/services/dolphin/dolphin.c | 2 + .../services/power/power_service/power.c | 2 + furi/core/event_flag.c | 23 +- furi/core/event_flag.h | 2 +- furi/core/memmgr_heap.c | 4 - furi/core/message_queue.c | 48 +-- furi/core/mutex.c | 133 +++--- furi/core/mutex.h | 2 +- furi/core/semaphore.c | 48 ++- furi/core/semaphore.h | 2 +- furi/core/stream_buffer.c | 49 ++- furi/core/stream_buffer.h | 2 +- furi/core/thread.c | 137 ++++--- furi/core/thread.h | 383 ++++++++++++------ furi/core/timer.c | 92 ++--- furi/core/timer.h | 6 +- furi/flipper.c | 5 +- targets/f18/api_symbols.csv | 4 +- targets/f7/api_symbols.csv | 4 +- targets/f7/furi_hal/furi_hal_serial_control.c | 5 +- targets/f7/furi_hal/furi_hal_usb.c | 3 +- targets/f7/inc/FreeRTOSConfig.h | 2 +- 28 files changed, 584 insertions(+), 427 deletions(-) diff --git a/applications/debug/unit_tests/tests/rpc/rpc_test.c b/applications/debug/unit_tests/tests/rpc/rpc_test.c index fdbfb6c7a..5bc2cc1f8 100644 --- a/applications/debug/unit_tests/tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/tests/rpc/rpc_test.c @@ -1,11 +1,6 @@ -#include -#include #include #include -#include -#include - #include #include #include @@ -40,8 +35,8 @@ static uint32_t command_id = 0; typedef struct { RpcSession* session; FuriStreamBuffer* output_stream; - SemaphoreHandle_t close_session_semaphore; - SemaphoreHandle_t terminate_semaphore; + FuriSemaphore* close_session_semaphore; + FuriSemaphore* terminate_semaphore; uint32_t timeout; } RpcSessionContext; @@ -96,8 +91,8 @@ static void test_rpc_setup(void) { rpc_session[0].output_stream = furi_stream_buffer_alloc(4096, 1); rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback); - rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary(); - rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary(); + rpc_session[0].close_session_semaphore = furi_semaphore_alloc(1, 0); + rpc_session[0].terminate_semaphore = furi_semaphore_alloc(1, 0); rpc_session_set_close_callback(rpc_session[0].session, test_rpc_session_close_callback); rpc_session_set_terminated_callback( rpc_session[0].session, test_rpc_session_terminated_callback); @@ -116,8 +111,8 @@ static void test_rpc_setup_second_session(void) { rpc_session[1].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[1].session, output_bytes_callback); - rpc_session[1].close_session_semaphore = xSemaphoreCreateBinary(); - rpc_session[1].terminate_semaphore = xSemaphoreCreateBinary(); + rpc_session[1].close_session_semaphore = furi_semaphore_alloc(1, 0); + rpc_session[1].terminate_semaphore = furi_semaphore_alloc(1, 0); rpc_session_set_close_callback(rpc_session[1].session, test_rpc_session_close_callback); rpc_session_set_terminated_callback( rpc_session[1].session, test_rpc_session_terminated_callback); @@ -126,13 +121,15 @@ static void test_rpc_setup_second_session(void) { static void test_rpc_teardown(void) { furi_check(rpc_session[0].close_session_semaphore); - xSemaphoreTake(rpc_session[0].terminate_semaphore, 0); + furi_semaphore_acquire(rpc_session[0].terminate_semaphore, 0); rpc_session_close(rpc_session[0].session); - furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY)); + furi_check( + furi_semaphore_acquire(rpc_session[0].terminate_semaphore, FuriWaitForever) == + FuriStatusOk); furi_record_close(RECORD_RPC); furi_stream_buffer_free(rpc_session[0].output_stream); - vSemaphoreDelete(rpc_session[0].close_session_semaphore); - vSemaphoreDelete(rpc_session[0].terminate_semaphore); + furi_semaphore_free(rpc_session[0].close_session_semaphore); + furi_semaphore_free(rpc_session[0].terminate_semaphore); ++command_id; rpc_session[0].output_stream = NULL; rpc_session[0].close_session_semaphore = NULL; @@ -142,12 +139,14 @@ static void test_rpc_teardown(void) { static void test_rpc_teardown_second_session(void) { furi_check(rpc_session[1].close_session_semaphore); - xSemaphoreTake(rpc_session[1].terminate_semaphore, 0); + furi_semaphore_acquire(rpc_session[1].terminate_semaphore, 0); rpc_session_close(rpc_session[1].session); - furi_check(xSemaphoreTake(rpc_session[1].terminate_semaphore, portMAX_DELAY)); + furi_check( + furi_semaphore_acquire(rpc_session[1].terminate_semaphore, FuriWaitForever) == + FuriStatusOk); furi_stream_buffer_free(rpc_session[1].output_stream); - vSemaphoreDelete(rpc_session[1].close_session_semaphore); - vSemaphoreDelete(rpc_session[1].terminate_semaphore); + furi_semaphore_free(rpc_session[1].close_session_semaphore); + furi_semaphore_free(rpc_session[1].terminate_semaphore); ++command_id; rpc_session[1].output_stream = NULL; rpc_session[1].close_session_semaphore = NULL; @@ -204,14 +203,14 @@ static void test_rpc_session_close_callback(void* context) { furi_check(context); RpcSessionContext* callbacks_context = context; - xSemaphoreGive(callbacks_context->close_session_semaphore); + furi_check(furi_semaphore_release(callbacks_context->close_session_semaphore) == FuriStatusOk); } static void test_rpc_session_terminated_callback(void* context) { furi_check(context); RpcSessionContext* callbacks_context = context; - xSemaphoreGive(callbacks_context->terminate_semaphore); + furi_check(furi_semaphore_release(callbacks_context->terminate_semaphore) == FuriStatusOk); } static void test_rpc_print_message_list(MsgList_t msg_list) { @@ -1645,7 +1644,7 @@ static void test_rpc_feed_rubbish_run( test_rpc_add_empty_to_list(expected, PB_CommandStatus_ERROR_DECODE, 0); - furi_check(!xSemaphoreTake(rpc_session[0].close_session_semaphore, 0)); + furi_check(furi_semaphore_acquire(rpc_session[0].close_session_semaphore, 0) != FuriStatusOk); test_rpc_encode_and_feed(input_before, 0); test_send_rubbish(rpc_session[0].session, pattern, pattern_size, size); test_rpc_encode_and_feed(input_after, 0); diff --git a/applications/debug/unit_tests/unit_test_api_table_i.h b/applications/debug/unit_tests/unit_test_api_table_i.h index 8c2fa4687..e6409f3ac 100644 --- a/applications/debug/unit_tests/unit_test_api_table_i.h +++ b/applications/debug/unit_tests/unit_test_api_table_i.h @@ -19,9 +19,9 @@ static constexpr auto unit_tests_api_table = sort(create_array_t( API_METHOD(xQueueSemaphoreTake, BaseType_t, (QueueHandle_t, TickType_t)), API_METHOD(vQueueDelete, void, (QueueHandle_t)), API_METHOD( - xQueueGenericCreate, + xQueueGenericCreateStatic, QueueHandle_t, - (const UBaseType_t, const UBaseType_t, const uint8_t)), + (const UBaseType_t, const UBaseType_t, uint8_t*, StaticQueue_t*, const uint8_t)), API_METHOD( xQueueGenericSend, BaseType_t, diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index 389275b86..59eb86388 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -435,6 +435,8 @@ int32_t bt_srv(void* p) { FURI_LOG_W(TAG, "Skipping start in special boot mode"); ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT); furi_record_create(RECORD_BT, bt); + + furi_thread_suspend(furi_thread_get_current_id()); return 0; } diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 748f9a555..8b0c6d753 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -441,6 +441,8 @@ int32_t desktop_srv(void* p) { if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { FURI_LOG_W(TAG, "Skipping start in special boot mode"); + + furi_thread_suspend(furi_thread_get_current_id()); return 0; } diff --git a/applications/services/desktop/scenes/desktop_scene_pin_timeout.c b/applications/services/desktop/scenes/desktop_scene_pin_timeout.c index 82543a944..ed6f9f12e 100644 --- a/applications/services/desktop/scenes/desktop_scene_pin_timeout.c +++ b/applications/services/desktop/scenes/desktop_scene_pin_timeout.c @@ -1,5 +1,4 @@ #include -#include #include #include "../desktop_i.h" diff --git a/applications/services/desktop/views/desktop_view_pin_timeout.c b/applications/services/desktop/views/desktop_view_pin_timeout.c index f24ecc8ea..2811ba7d2 100644 --- a/applications/services/desktop/views/desktop_view_pin_timeout.c +++ b/applications/services/desktop/views/desktop_view_pin_timeout.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index a838edc60..28c17ec16 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -148,6 +148,8 @@ int32_t dolphin_srv(void* p) { if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { FURI_LOG_W(TAG, "Skipping start in special boot mode"); + + furi_thread_suspend(furi_thread_get_current_id()); return 0; } diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index 557beaf64..278854e13 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -198,6 +198,8 @@ int32_t power_srv(void* p) { if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { FURI_LOG_W(TAG, "Skipping start in special boot mode"); + + furi_thread_suspend(furi_thread_get_current_id()); return 0; } diff --git a/furi/core/event_flag.c b/furi/core/event_flag.c index ccbee93d6..c2e04e2fd 100644 --- a/furi/core/event_flag.c +++ b/furi/core/event_flag.c @@ -8,18 +8,27 @@ #define FURI_EVENT_FLAG_MAX_BITS_EVENT_GROUPS 24U #define FURI_EVENT_FLAG_INVALID_BITS (~((1UL << FURI_EVENT_FLAG_MAX_BITS_EVENT_GROUPS) - 1U)) +struct FuriEventFlag { + StaticEventGroup_t container; +}; + +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriEventFlag, container) == 0); + FuriEventFlag* furi_event_flag_alloc(void) { furi_check(!FURI_IS_IRQ_MODE()); - EventGroupHandle_t handle = xEventGroupCreate(); - furi_check(handle); + FuriEventFlag* instance = malloc(sizeof(FuriEventFlag)); - return ((FuriEventFlag*)handle); + furi_check(xEventGroupCreateStatic(&instance->container) == (EventGroupHandle_t)instance); + + return instance; } void furi_event_flag_free(FuriEventFlag* instance) { furi_check(!FURI_IS_IRQ_MODE()); vEventGroupDelete((EventGroupHandle_t)instance); + free(instance); } uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags) { @@ -43,7 +52,7 @@ uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags) { } /* Return event flags after setting */ - return (rflags); + return rflags; } uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags) { @@ -69,7 +78,7 @@ uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags) { } /* Return event flags before clearing */ - return (rflags); + return rflags; } uint32_t furi_event_flag_get(FuriEventFlag* instance) { @@ -85,7 +94,7 @@ uint32_t furi_event_flag_get(FuriEventFlag* instance) { } /* Return current event flags */ - return (rflags); + return rflags; } uint32_t furi_event_flag_wait( @@ -136,5 +145,5 @@ uint32_t furi_event_flag_wait( } /* Return event flags before clearing */ - return (rflags); + return rflags; } diff --git a/furi/core/event_flag.h b/furi/core/event_flag.h index 7200144cd..fbc3bb004 100644 --- a/furi/core/event_flag.h +++ b/furi/core/event_flag.h @@ -10,7 +10,7 @@ extern "C" { #endif -typedef void FuriEventFlag; +typedef struct FuriEventFlag FuriEventFlag; /** Allocate FuriEventFlag * diff --git a/furi/core/memmgr_heap.c b/furi/core/memmgr_heap.c index 3cee0d377..3a0e2c378 100644 --- a/furi/core/memmgr_heap.c +++ b/furi/core/memmgr_heap.c @@ -56,10 +56,6 @@ task.h is included from an application file. */ #error This feature is broken, logging transport must be replaced with RTT #endif -#if(configSUPPORT_DYNAMIC_ALLOCATION == 0) -#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 -#endif - /* Block sizes must not get too small. */ #define heapMINIMUM_BLOCK_SIZE ((size_t)(xHeapStructSize << 1)) diff --git a/furi/core/message_queue.c b/furi/core/message_queue.c index 6a4e8c324..0454e289b 100644 --- a/furi/core/message_queue.c +++ b/furi/core/message_queue.c @@ -5,14 +5,21 @@ #include #include -struct FuriMessageQueue { - // !!! Semi-Opaque type inheritance, Very Fragile, DO NOT MOVE !!! - StaticQueue_t container; +// Internal FreeRTOS member names +#define uxMessagesWaiting uxDummy4[0] +#define uxLength uxDummy4[1] +#define uxItemSize uxDummy4[2] - // !!! Data buffer, must be last in the structure, DO NOT MOVE !!! +struct FuriMessageQueue { + StaticQueue_t container; uint8_t buffer[]; }; +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriMessageQueue, container) == 0); +// IMPORTANT: buffer MUST be the LAST struct member +static_assert(offsetof(FuriMessageQueue, buffer) == sizeof(FuriMessageQueue)); + FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) { furi_check((furi_kernel_is_irq_or_masked() == 0U) && (msg_count > 0U) && (msg_size > 0U)); @@ -75,8 +82,7 @@ FuriStatus } } - /* Return execution status */ - return (stat); + return stat; } FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uint32_t timeout) { @@ -114,31 +120,19 @@ FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uin } } - return (stat); + return stat; } uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) { furi_check(instance); - uint32_t capacity; - - /* capacity = pxQueue->uxLength */ - capacity = instance->container.uxDummy4[1]; - - /* Return maximum number of messages */ - return (capacity); + return instance->container.uxLength; } uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance) { furi_check(instance); - uint32_t size; - - /* size = pxQueue->uxItemSize */ - size = instance->container.uxDummy4[2]; - - /* Return maximum message size */ - return (size); + return instance->container.uxItemSize; } uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { @@ -153,8 +147,7 @@ uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { count = uxQueueMessagesWaiting(hQueue); } - /* Return number of queued messages */ - return ((uint32_t)count); + return (uint32_t)count; } uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { @@ -166,16 +159,14 @@ uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { if(furi_kernel_is_irq_or_masked() != 0U) { isrm = taskENTER_CRITICAL_FROM_ISR(); - /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ - space = instance->container.uxDummy4[1] - instance->container.uxDummy4[0]; + space = instance->container.uxLength - instance->container.uxMessagesWaiting; taskEXIT_CRITICAL_FROM_ISR(isrm); } else { space = (uint32_t)uxQueueSpacesAvailable((QueueHandle_t)instance); } - /* Return number of available slots */ - return (space); + return space; } FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) { @@ -191,6 +182,5 @@ FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) { (void)xQueueReset(hQueue); } - /* Return execution status */ - return (stat); + return stat; } diff --git a/furi/core/mutex.c b/furi/core/mutex.c index 4fc3099fe..f59ae83ad 100644 --- a/furi/core/mutex.c +++ b/furi/core/mutex.c @@ -5,129 +5,120 @@ #include #include +// Internal FreeRTOS member names +#define ucQueueType ucDummy9 + +struct FuriMutex { + StaticSemaphore_t container; +}; + +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriMutex, container) == 0); + FuriMutex* furi_mutex_alloc(FuriMutexType type) { furi_check(!FURI_IS_IRQ_MODE()); - SemaphoreHandle_t hMutex = NULL; + FuriMutex* instance = malloc(sizeof(FuriMutex)); + + SemaphoreHandle_t hMutex; if(type == FuriMutexTypeNormal) { - hMutex = xSemaphoreCreateMutex(); + hMutex = xSemaphoreCreateMutexStatic(&instance->container); } else if(type == FuriMutexTypeRecursive) { - hMutex = xSemaphoreCreateRecursiveMutex(); + hMutex = xSemaphoreCreateRecursiveMutexStatic(&instance->container); } else { furi_crash(); } - furi_check(hMutex != NULL); + furi_check(hMutex == (SemaphoreHandle_t)instance); - if(type == FuriMutexTypeRecursive) { - /* Set LSB as 'recursive mutex flag' */ - hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U); - } - - /* Return mutex ID */ - return ((FuriMutex*)hMutex); + return instance; } void furi_mutex_free(FuriMutex* instance) { furi_check(!FURI_IS_IRQ_MODE()); furi_check(instance); - vSemaphoreDelete((SemaphoreHandle_t)((uint32_t)instance & ~1U)); + vSemaphoreDelete((SemaphoreHandle_t)instance); + free(instance); } FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout) { furi_check(instance); - SemaphoreHandle_t hMutex; - FuriStatus stat; - uint32_t rmtx; + SemaphoreHandle_t hMutex = (SemaphoreHandle_t)(instance); + const uint8_t mutex_type = instance->container.ucQueueType; - hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); - - /* Extract recursive mutex flag */ - rmtx = (uint32_t)instance & 1U; - - stat = FuriStatusOk; + FuriStatus stat = FuriStatusOk; if(FURI_IS_IRQ_MODE()) { stat = FuriStatusErrorISR; - } else if(hMutex == NULL) { - stat = FuriStatusErrorParameter; - } else { - if(rmtx != 0U) { - if(xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) { - if(timeout != 0U) { - stat = FuriStatusErrorTimeout; - } else { - stat = FuriStatusErrorResource; - } - } - } else { - if(xSemaphoreTake(hMutex, timeout) != pdPASS) { - if(timeout != 0U) { - stat = FuriStatusErrorTimeout; - } else { - stat = FuriStatusErrorResource; - } + + } else if(mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) { + if(xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; } } + + } else if(mutex_type == queueQUEUE_TYPE_MUTEX) { + if(xSemaphoreTake(hMutex, timeout) != pdPASS) { + if(timeout != 0U) { + stat = FuriStatusErrorTimeout; + } else { + stat = FuriStatusErrorResource; + } + } + + } else { + furi_crash(); } - /* Return execution status */ - return (stat); + return stat; } FuriStatus furi_mutex_release(FuriMutex* instance) { furi_check(instance); - SemaphoreHandle_t hMutex; - FuriStatus stat; - uint32_t rmtx; + SemaphoreHandle_t hMutex = (SemaphoreHandle_t)(instance); + const uint8_t mutex_type = instance->container.ucQueueType; - hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); - - /* Extract recursive mutex flag */ - rmtx = (uint32_t)instance & 1U; - - stat = FuriStatusOk; + FuriStatus stat = FuriStatusOk; if(FURI_IS_IRQ_MODE()) { stat = FuriStatusErrorISR; - } else if(hMutex == NULL) { - stat = FuriStatusErrorParameter; - } else { - if(rmtx != 0U) { - if(xSemaphoreGiveRecursive(hMutex) != pdPASS) { - stat = FuriStatusErrorResource; - } - } else { - if(xSemaphoreGive(hMutex) != pdPASS) { - stat = FuriStatusErrorResource; - } + + } else if(mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) { + if(xSemaphoreGiveRecursive(hMutex) != pdPASS) { + stat = FuriStatusErrorResource; } + + } else if(mutex_type == queueQUEUE_TYPE_MUTEX) { + if(xSemaphoreGive(hMutex) != pdPASS) { + stat = FuriStatusErrorResource; + } + + } else { + furi_crash(); } - /* Return execution status */ - return (stat); + return stat; } FuriThreadId furi_mutex_get_owner(FuriMutex* instance) { furi_check(instance); - SemaphoreHandle_t hMutex; + SemaphoreHandle_t hMutex = (SemaphoreHandle_t)instance; + FuriThreadId owner; - hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); - - if(hMutex == NULL) { - owner = 0; - } else if(FURI_IS_IRQ_MODE()) { + if(FURI_IS_IRQ_MODE()) { owner = (FuriThreadId)xSemaphoreGetMutexHolderFromISR(hMutex); } else { owner = (FuriThreadId)xSemaphoreGetMutexHolder(hMutex); } - /* Return owner thread ID */ - return (owner); + return owner; } diff --git a/furi/core/mutex.h b/furi/core/mutex.h index aa55fa7bc..60372a292 100644 --- a/furi/core/mutex.h +++ b/furi/core/mutex.h @@ -16,7 +16,7 @@ typedef enum { FuriMutexTypeRecursive, } FuriMutexType; -typedef void FuriMutex; +typedef struct FuriMutex FuriMutex; /** Allocate FuriMutex * diff --git a/furi/core/semaphore.c b/furi/core/semaphore.c index 503eec472..6413eb65f 100644 --- a/furi/core/semaphore.c +++ b/furi/core/semaphore.c @@ -5,36 +5,43 @@ #include #include +struct FuriSemaphore { + StaticSemaphore_t container; +}; + +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriSemaphore, container) == 0); + FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count) { furi_check(!FURI_IS_IRQ_MODE()); furi_check((max_count > 0U) && (initial_count <= max_count)); - SemaphoreHandle_t hSemaphore = NULL; + FuriSemaphore* instance = malloc(sizeof(FuriSemaphore)); + + SemaphoreHandle_t hSemaphore; + if(max_count == 1U) { - hSemaphore = xSemaphoreCreateBinary(); - if((hSemaphore != NULL) && (initial_count != 0U)) { - if(xSemaphoreGive(hSemaphore) != pdPASS) { - vSemaphoreDelete(hSemaphore); - hSemaphore = NULL; - } - } + hSemaphore = xSemaphoreCreateBinaryStatic(&instance->container); } else { - hSemaphore = xSemaphoreCreateCounting(max_count, initial_count); + hSemaphore = + xSemaphoreCreateCountingStatic(max_count, initial_count, &instance->container); } - furi_check(hSemaphore); + furi_check(hSemaphore == (SemaphoreHandle_t)instance); - /* Return semaphore ID */ - return ((FuriSemaphore*)hSemaphore); + if(max_count == 1U && initial_count != 0U) { + furi_check(xSemaphoreGive(hSemaphore) == pdPASS); + } + + return instance; } void furi_semaphore_free(FuriSemaphore* instance) { furi_check(instance); furi_check(!FURI_IS_IRQ_MODE()); - SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; - - vSemaphoreDelete(hSemaphore); + vSemaphoreDelete((SemaphoreHandle_t)instance); + free(instance); } FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { @@ -58,6 +65,7 @@ FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { portYIELD_FROM_ISR(yield); } } + } else { if(xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) { if(timeout != 0U) { @@ -68,8 +76,7 @@ FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { } } - /* Return execution status */ - return (stat); + return stat; } FuriStatus furi_semaphore_release(FuriSemaphore* instance) { @@ -89,14 +96,14 @@ FuriStatus furi_semaphore_release(FuriSemaphore* instance) { } else { portYIELD_FROM_ISR(yield); } + } else { if(xSemaphoreGive(hSemaphore) != pdPASS) { stat = FuriStatusErrorResource; } } - /* Return execution status */ - return (stat); + return stat; } uint32_t furi_semaphore_get_count(FuriSemaphore* instance) { @@ -111,6 +118,5 @@ uint32_t furi_semaphore_get_count(FuriSemaphore* instance) { count = (uint32_t)uxSemaphoreGetCount(hSemaphore); } - /* Return number of tokens */ - return (count); + return count; } diff --git a/furi/core/semaphore.h b/furi/core/semaphore.h index 19d056bfe..c6b9a1176 100644 --- a/furi/core/semaphore.h +++ b/furi/core/semaphore.h @@ -11,7 +11,7 @@ extern "C" { #endif -typedef void FuriSemaphore; +typedef struct FuriSemaphore FuriSemaphore; /** Allocate semaphore * diff --git a/furi/core/stream_buffer.c b/furi/core/stream_buffer.c index 8bd00d91c..eefda0e79 100644 --- a/furi/core/stream_buffer.c +++ b/furi/core/stream_buffer.c @@ -6,24 +6,42 @@ #include #include +struct FuriStreamBuffer { + StaticStreamBuffer_t container; + uint8_t buffer[]; +}; + +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriStreamBuffer, container) == 0); +// IMPORTANT: buffer MUST be the LAST struct member +static_assert(offsetof(FuriStreamBuffer, buffer) == sizeof(FuriStreamBuffer)); + FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level) { furi_check(size != 0); - StreamBufferHandle_t handle = xStreamBufferCreate(size, trigger_level); - furi_check(handle); + // Actual FreeRTOS usable buffer size seems to be one less + const size_t buffer_size = size + 1; - return handle; + FuriStreamBuffer* stream_buffer = malloc(sizeof(FuriStreamBuffer) + buffer_size); + StreamBufferHandle_t hStreamBuffer = xStreamBufferCreateStatic( + buffer_size, trigger_level, stream_buffer->buffer, &stream_buffer->container); + + furi_check(hStreamBuffer == (StreamBufferHandle_t)stream_buffer); + + return stream_buffer; }; void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer) { furi_check(stream_buffer); - vStreamBufferDelete(stream_buffer); + vStreamBufferDelete((StreamBufferHandle_t)stream_buffer); + free(stream_buffer); }; bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level) { furi_check(stream_buffer); - return xStreamBufferSetTriggerLevel(stream_buffer, trigger_level) == pdTRUE; + return xStreamBufferSetTriggerLevel((StreamBufferHandle_t)stream_buffer, trigger_level) == + pdTRUE; }; size_t furi_stream_buffer_send( @@ -37,10 +55,10 @@ size_t furi_stream_buffer_send( if(FURI_IS_IRQ_MODE()) { BaseType_t yield; - ret = xStreamBufferSendFromISR(stream_buffer, data, length, &yield); + ret = xStreamBufferSendFromISR((StreamBufferHandle_t)stream_buffer, data, length, &yield); portYIELD_FROM_ISR(yield); } else { - ret = xStreamBufferSend(stream_buffer, data, length, timeout); + ret = xStreamBufferSend((StreamBufferHandle_t)stream_buffer, data, length, timeout); } return ret; @@ -57,10 +75,11 @@ size_t furi_stream_buffer_receive( if(FURI_IS_IRQ_MODE()) { BaseType_t yield; - ret = xStreamBufferReceiveFromISR(stream_buffer, data, length, &yield); + ret = + xStreamBufferReceiveFromISR((StreamBufferHandle_t)stream_buffer, data, length, &yield); portYIELD_FROM_ISR(yield); } else { - ret = xStreamBufferReceive(stream_buffer, data, length, timeout); + ret = xStreamBufferReceive((StreamBufferHandle_t)stream_buffer, data, length, timeout); } return ret; @@ -69,33 +88,33 @@ size_t furi_stream_buffer_receive( size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer) { furi_check(stream_buffer); - return xStreamBufferBytesAvailable(stream_buffer); + return xStreamBufferBytesAvailable((StreamBufferHandle_t)stream_buffer); }; size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer) { furi_check(stream_buffer); - return xStreamBufferSpacesAvailable(stream_buffer); + return xStreamBufferSpacesAvailable((StreamBufferHandle_t)stream_buffer); }; bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer) { furi_check(stream_buffer); - return xStreamBufferIsFull(stream_buffer) == pdTRUE; + return xStreamBufferIsFull((StreamBufferHandle_t)stream_buffer) == pdTRUE; }; bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer) { furi_check(stream_buffer); - return (xStreamBufferIsEmpty(stream_buffer) == pdTRUE); + return (xStreamBufferIsEmpty((StreamBufferHandle_t)stream_buffer) == pdTRUE); }; FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer) { furi_check(stream_buffer); - if(xStreamBufferReset(stream_buffer) == pdPASS) { + if(xStreamBufferReset((StreamBufferHandle_t)stream_buffer) == pdPASS) { return FuriStatusOk; } else { return FuriStatusError; } -} \ No newline at end of file +} diff --git a/furi/core/stream_buffer.h b/furi/core/stream_buffer.h index 5ddc49416..3cc9c1b67 100644 --- a/furi/core/stream_buffer.h +++ b/furi/core/stream_buffer.h @@ -19,7 +19,7 @@ extern "C" { #endif -typedef void FuriStreamBuffer; +typedef struct FuriStreamBuffer FuriStreamBuffer; /** * @brief Allocate stream buffer instance. diff --git a/furi/core/thread.c b/furi/core/thread.c index 3ae0b8c25..db4b7bc80 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -27,6 +27,10 @@ struct FuriThreadStdout { }; struct FuriThread { + StaticTask_t container; + TaskHandle_t task_handle; + StackType_t* stack_buffer; + FuriThreadState state; int32_t ret; @@ -41,7 +45,7 @@ struct FuriThread { FuriThreadPriority priority; - TaskHandle_t task_handle; + size_t stack_size; size_t heap_size; FuriThreadStdout output; @@ -50,10 +54,11 @@ struct FuriThread { // this ensures that the size of this structure is minimal bool is_service; bool heap_trace_enabled; - - size_t stack_size; }; +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriThread, container) == 0); + static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size); static int32_t __furi_thread_stdout_flush(FuriThread* thread); @@ -92,6 +97,8 @@ static void furi_thread_body(void* context) { thread->ret = thread->callback(thread->context); + furi_check(!thread->is_service, "Service threads MUST NOT return"); + if(thread->heap_trace_enabled == true) { furi_delay_ms(33); thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)task_handle); @@ -106,13 +113,6 @@ static void furi_thread_body(void* context) { furi_check(thread->state == FuriThreadStateRunning); - if(thread->is_service) { - FURI_LOG_W( - TAG, - "%s service thread TCB memory will not be reclaimed", - thread->name ? thread->name : ""); - } - // flush stdout __furi_thread_stdout_flush(thread); @@ -122,10 +122,8 @@ static void furi_thread_body(void* context) { furi_thread_catch(); } -FuriThread* furi_thread_alloc(void) { - FuriThread* thread = malloc(sizeof(FuriThread)); +static void furi_thread_init_common(FuriThread* thread) { thread->output.buffer = furi_string_alloc(); - thread->is_service = false; FuriThread* parent = NULL; if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { @@ -150,6 +148,32 @@ FuriThread* furi_thread_alloc(void) { } else { thread->heap_trace_enabled = false; } +} + +FuriThread* furi_thread_alloc(void) { + FuriThread* thread = malloc(sizeof(FuriThread)); + + furi_thread_init_common(thread); + + return thread; +} + +FuriThread* furi_thread_alloc_service( + const char* name, + uint32_t stack_size, + FuriThreadCallback callback, + void* context) { + FuriThread* thread = memmgr_alloc_from_pool(sizeof(FuriThread)); + + furi_thread_init_common(thread); + + thread->stack_buffer = memmgr_alloc_from_pool(stack_size); + thread->stack_size = stack_size; + thread->is_service = true; + + furi_thread_set_name(thread, name); + furi_thread_set_callback(thread, callback); + furi_thread_set_context(thread, context); return thread; } @@ -169,15 +193,20 @@ FuriThread* furi_thread_alloc_ex( void furi_thread_free(FuriThread* thread) { furi_check(thread); - - // Ensure that use join before free + // Cannot free a service thread + furi_check(thread->is_service == false); + // Cannot free a non-joined thread furi_check(thread->state == FuriThreadStateStopped); furi_check(thread->task_handle == NULL); - if(thread->name) free(thread->name); - if(thread->appid) free(thread->appid); - furi_string_free(thread->output.buffer); + furi_thread_set_name(thread, NULL); + furi_thread_set_appid(thread, NULL); + if(thread->stack_buffer) { + free(thread->stack_buffer); + } + + furi_string_free(thread->output.buffer); free(thread); } @@ -185,7 +214,9 @@ void furi_thread_set_name(FuriThread* thread, const char* name) { furi_check(thread); furi_check(thread->state == FuriThreadStateStopped); - if(thread->name) free(thread->name); + if(thread->name) { + free(thread->name); + } thread->name = name ? strdup(name) : NULL; } @@ -193,19 +224,28 @@ void furi_thread_set_name(FuriThread* thread, const char* name) { void furi_thread_set_appid(FuriThread* thread, const char* appid) { furi_check(thread); furi_check(thread->state == FuriThreadStateStopped); - if(thread->appid) free(thread->appid); - thread->appid = appid ? strdup(appid) : NULL; -} -void furi_thread_mark_as_service(FuriThread* thread) { - thread->is_service = true; + if(thread->appid) { + free(thread->appid); + } + + thread->appid = appid ? strdup(appid) : NULL; } void furi_thread_set_stack_size(FuriThread* thread, size_t stack_size) { furi_check(thread); furi_check(thread->state == FuriThreadStateStopped); - furi_check(stack_size % 4 == 0); + furi_check(stack_size); furi_check(stack_size <= THREAD_MAX_STACK_SIZE); + furi_check(stack_size % sizeof(StackType_t) == 0); + // Stack size cannot be configured for a thread that has been marked as a service + furi_check(thread->is_service == false); + + if(thread->stack_buffer) { + free(thread->stack_buffer); + } + + thread->stack_buffer = malloc(stack_size); thread->stack_size = stack_size; } @@ -270,24 +310,19 @@ void furi_thread_start(FuriThread* thread) { furi_thread_set_state(thread, FuriThreadStateStarting); - uint32_t stack = thread->stack_size / sizeof(StackType_t); + uint32_t stack_depth = thread->stack_size / sizeof(StackType_t); UBaseType_t priority = thread->priority ? thread->priority : FuriThreadPriorityNormal; - if(thread->is_service) { - thread->task_handle = xTaskCreateStatic( - furi_thread_body, - thread->name, - stack, - thread, - priority, - memmgr_alloc_from_pool(sizeof(StackType_t) * stack), - memmgr_alloc_from_pool(sizeof(StaticTask_t))); - } else { - BaseType_t ret = xTaskCreate( - furi_thread_body, thread->name, stack, thread, priority, &thread->task_handle); - furi_check(ret == pdPASS); - } - furi_check(thread->task_handle); + thread->task_handle = xTaskCreateStatic( + furi_thread_body, + thread->name, + stack_depth, + thread, + priority, + thread->stack_buffer, + &thread->container); + + furi_check(thread->task_handle == (TaskHandle_t)&thread->container); } void furi_thread_cleanup_tcb_event(TaskHandle_t task) { @@ -302,7 +337,9 @@ void furi_thread_cleanup_tcb_event(TaskHandle_t task) { bool furi_thread_join(FuriThread* thread) { furi_check(thread); - + // Cannot join a service thread + furi_check(!thread->is_service); + // Cannot join a thread to itself furi_check(furi_thread_get_current() != thread); // !!! IMPORTANT NOTICE !!! @@ -390,7 +427,7 @@ uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags) { } } /* Return flags after setting */ - return (rflags); + return rflags; } uint32_t furi_thread_flags_clear(uint32_t flags) { @@ -419,7 +456,7 @@ uint32_t furi_thread_flags_clear(uint32_t flags) { } /* Return flags before clearing */ - return (rflags); + return rflags; } uint32_t furi_thread_flags_get(void) { @@ -437,7 +474,7 @@ uint32_t furi_thread_flags_get(void) { } } - return (rflags); + return rflags; } uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout) { @@ -507,7 +544,7 @@ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeo } /* Return flags before clearing */ - return (rflags); + return rflags; } uint32_t furi_thread_enumerate(FuriThreadId* thread_array, uint32_t array_item_count) { @@ -536,7 +573,7 @@ uint32_t furi_thread_enumerate(FuriThreadId* thread_array, uint32_t array_item_c vPortFree(task); } - return (count); + return count; } const char* furi_thread_get_name(FuriThreadId thread_id) { @@ -549,7 +586,7 @@ const char* furi_thread_get_name(FuriThreadId thread_id) { name = pcTaskGetName(hTask); } - return (name); + return name; } const char* furi_thread_get_appid(FuriThreadId thread_id) { @@ -563,7 +600,7 @@ const char* furi_thread_get_appid(FuriThreadId thread_id) { } } - return (appid); + return appid; } uint32_t furi_thread_get_stack_space(FuriThreadId thread_id) { @@ -576,7 +613,7 @@ uint32_t furi_thread_get_stack_space(FuriThreadId thread_id) { sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t)); } - return (sz); + return sz; } static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size) { diff --git a/furi/core/thread.h b/furi/core/thread.h index f21ee9df3..d78272a4d 100644 --- a/furi/core/thread.h +++ b/furi/core/thread.h @@ -1,6 +1,6 @@ /** * @file thread.h - * Furi: Furi Thread API + * @brief Furi: Furi Thread API */ #pragma once @@ -15,14 +15,20 @@ extern "C" { #endif -/** FuriThreadState */ +/** + * @brief Enumeration of possible FuriThread states. + * + * Many of the FuriThread functions MUST ONLY be called when the thread is STOPPED. + */ typedef enum { - FuriThreadStateStopped, - FuriThreadStateStarting, - FuriThreadStateRunning, + FuriThreadStateStopped, /**< Thread is stopped */ + FuriThreadStateStarting, /**< Thread is starting */ + FuriThreadStateRunning, /**< Thread is running */ } FuriThreadState; -/** FuriThreadPriority */ +/** + * @brief Enumeration of possible FuriThread priorities. + */ typedef enum { FuriThreadPriorityNone = 0, /**< Uninitialized, choose system default */ FuriThreadPriorityIdle = 1, /**< Idle priority */ @@ -35,42 +41,85 @@ typedef enum { (FURI_CONFIG_THREAD_MAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */ } FuriThreadPriority; -/** FuriThread anonymous structure */ +/** + * @brief FuriThread opaque type. + */ typedef struct FuriThread FuriThread; -/** FuriThreadId proxy type to OS low level functions */ +/** + * @brief Unique thread identifier type (used by the OS kernel). + */ typedef void* FuriThreadId; -/** FuriThreadCallback Your callback to run in new thread - * @warning never use osThreadExit in FuriThread +/** + * @brief Thread callback function pointer type. + * + * The function to be used as a thread callback MUST follow this signature. + * + * @param[in,out] context pointer to a user-specified object + * @return value to be used as the thread return code */ typedef int32_t (*FuriThreadCallback)(void* context); -/** Write to stdout callback - * @param data pointer to data - * @param size data size @warning your handler must consume everything +/** + * @brief Standard output callback function pointer type. + * + * The function to be used as a standard output callback MUST follow this signature. + * + * @warning The handler MUST process ALL of the provided data before returning. + * + * @param[in] data pointer to the data to be written to the standard out + * @param[in] size size of the data in bytes */ typedef void (*FuriThreadStdoutWriteCallback)(const char* data, size_t size); -/** FuriThread state change callback called upon thread state change - * @param state new thread state - * @param context callback context +/** + * @brief State change callback function pointer type. + * + * The function to be used as a state callback MUST follow this signature. + * + * @param[in] state identifier of the state the thread has transitioned to + * @param[in,out] context pointer to a user-specified object */ typedef void (*FuriThreadStateCallback)(FuriThreadState state, void* context); -/** Allocate FuriThread +/** + * @brief Create a FuriThread instance. * - * @return FuriThread instance + * @return pointer to the created FuriThread instance */ FuriThread* furi_thread_alloc(void); -/** Allocate FuriThread, shortcut version +/** + * @brief Create a FuriThread instance (service mode). + * + * Service threads are more memory efficient, but have + * the following limitations: + * + * - Cannot return from the callback + * - Cannot be joined or freed + * - Stack size cannot be altered + * + * @param[in] name human-readable thread name (can be NULL) + * @param[in] stack_size stack size in bytes (cannot be changed later) + * @param[in] callback pointer to a function to be executed in this thread + * @param[in] context pointer to a user-specified object (will be passed to the callback) + * @return pointer to the created FuriThread instance + */ +FuriThread* furi_thread_alloc_service( + const char* name, + uint32_t stack_size, + FuriThreadCallback callback, + void* context); + +/** + * @brief Create a FuriThread instance w/ extra parameters. * - * @param name - * @param stack_size - * @param callback - * @param context - * @return FuriThread* + * @param[in] name human-readable thread name (can be NULL) + * @param[in] stack_size stack size in bytes (can be changed later) + * @param[in] callback pointer to a function to be executed in this thread + * @param[in] context pointer to a user-specified object (will be passed to the callback) + * @return pointer to the created FuriThread instance */ FuriThread* furi_thread_alloc_ex( const char* name, @@ -78,261 +127,339 @@ FuriThread* furi_thread_alloc_ex( FuriThreadCallback callback, void* context); -/** Release FuriThread +/** + * @brief Delete a FuriThread instance. * - * @warning see furi_thread_join + * The thread MUST be stopped when calling this function. * - * @param thread FuriThread instance + * @warning see furi_thread_join for caveats on stopping a thread. + * + * @param[in,out] thread pointer to the FuriThread instance to be deleted */ void furi_thread_free(FuriThread* thread); -/** Set FuriThread name +/** + * @brief Set the name of a FuriThread instance. * - * @param thread FuriThread instance - * @param name string + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] name human-readable thread name (can be NULL) */ void furi_thread_set_name(FuriThread* thread, const char* name); /** - * @brief Set FuriThread appid + * @brief Set the application ID of a FuriThread instance. + * + * The thread MUST be stopped when calling this function. + * * Technically, it is like a "process id", but it is not a system-wide unique identifier. * All threads spawned by the same app will have the same appid. * - * @param thread - * @param appid + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] appid thread application ID (can be NULL) */ void furi_thread_set_appid(FuriThread* thread, const char* appid); -/** Mark thread as service - * The service cannot be stopped or removed, and cannot exit from the thread body - * - * @param thread - */ -void furi_thread_mark_as_service(FuriThread* thread); - -/** Set FuriThread stack size +/** + * @brief Set the stack size of a FuriThread instance. * - * @param thread FuriThread instance - * @param stack_size stack size in bytes + * The thread MUST be stopped when calling this function. Additionally, it is NOT possible + * to change the stack size of a service thread under any circumstances. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] stack_size stack size in bytes */ void furi_thread_set_stack_size(FuriThread* thread, size_t stack_size); -/** Set FuriThread callback +/** + * @brief Set the user callback function to be executed in a FuriThread. * - * @param thread FuriThread instance - * @param callback FuriThreadCallback, called upon thread run + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] callback pointer to a user-specified function to be executed in this thread */ void furi_thread_set_callback(FuriThread* thread, FuriThreadCallback callback); -/** Set FuriThread context +/** + * @brief Set the callback function context. * - * @param thread FuriThread instance - * @param context pointer to context for thread callback + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] context pointer to a user-specified object (will be passed to the callback, can be NULL) */ void furi_thread_set_context(FuriThread* thread, void* context); -/** Set FuriThread priority +/** + * @brief Set the priority of a FuriThread. * - * @param thread FuriThread instance - * @param priority FuriThreadPriority value + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] priority priority level value */ void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority); -/** Get FuriThread priority +/** + * @brief Get the priority of a FuriThread. * - * @param thread FuriThread instance - * @return FuriThreadPriority value + * @param[in] thread pointer to the FuriThread instance to be queried + * @return priority level value */ FuriThreadPriority furi_thread_get_priority(FuriThread* thread); -/** Set current thread priority +/** + * @brief Set the priority of the current FuriThread. * - * @param priority FuriThreadPriority value + * @param priority priority level value */ void furi_thread_set_current_priority(FuriThreadPriority priority); -/** Get current thread priority +/** + * @brief Get the priority of the current FuriThread. * - * @return FuriThreadPriority value + * @return priority level value */ FuriThreadPriority furi_thread_get_current_priority(void); -/** Set FuriThread state change callback +/** + * Set the callback function to be executed upon a state thransition of a FuriThread. * - * @param thread FuriThread instance - * @param callback state change callback + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] callback pointer to a user-specified callback function */ void furi_thread_set_state_callback(FuriThread* thread, FuriThreadStateCallback callback); -/** Set FuriThread state change context +/** + * @brief Set the state change callback context. * - * @param thread FuriThread instance - * @param context pointer to context + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified + * @param[in] context pointer to a user-specified object (will be passed to the callback, can be NULL) */ void furi_thread_set_state_context(FuriThread* thread, void* context); -/** Get FuriThread state +/** + * @brief Get the state of a FuriThread isntance. * - * @param thread FuriThread instance - * - * @return thread state from FuriThreadState + * @param[in] thread pointer to the FuriThread instance to be queried + * @return thread state value */ FuriThreadState furi_thread_get_state(FuriThread* thread); -/** Start FuriThread +/** + * @brief Start a FuriThread instance. * - * @param thread FuriThread instance + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be started */ void furi_thread_start(FuriThread* thread); -/** Join FuriThread +/** + * @brief Wait for a FuriThread to exit. * - * @warning Use this method only when CPU is not busy(Idle task receives - * control), otherwise it will wait forever. + * The thread callback function must return in order for the FuriThread instance to become joinable. * - * @param thread FuriThread instance + * @warning Use this method only when the CPU is not busy (i.e. when the + * Idle task receives control), otherwise it will wait forever. * - * @return bool + * @param[in] thread pointer to the FuriThread instance to be joined + * @return always true */ bool furi_thread_join(FuriThread* thread); -/** Get FreeRTOS FuriThreadId for FuriThread instance +/** + * @brief Get the unique identifier of a FuriThread instance. * - * @param thread FuriThread instance - * - * @return FuriThreadId or NULL + * @param[in] thread pointer to the FuriThread instance to be queried + * @return unique identifier value or NULL if thread is not running */ FuriThreadId furi_thread_get_id(FuriThread* thread); -/** Enable heap tracing +/** + * @brief Enable heap usage tracing for a FuriThread. * - * @param thread FuriThread instance + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified */ void furi_thread_enable_heap_trace(FuriThread* thread); -/** Disable heap tracing +/** + * @brief Disable heap usage tracing for a FuriThread. * - * @param thread FuriThread instance + * The thread MUST be stopped when calling this function. + * + * @param[in,out] thread pointer to the FuriThread instance to be modified */ void furi_thread_disable_heap_trace(FuriThread* thread); -/** Get thread heap size +/** + * @brief Get heap usage by a FuriThread instance. * - * @param thread FuriThread instance + * The heap trace MUST be enabled before callgin this function. * - * @return size in bytes + * @param[in] thread pointer to the FuriThread instance to be queried + * @return heap usage in bytes */ size_t furi_thread_get_heap_size(FuriThread* thread); -/** Get thread return code +/** + * @brief Get the return code of a FuriThread instance. * - * @param thread FuriThread instance + * This value is equal to the return value of the thread callback function. * - * @return return code + * The thread MUST be stopped when calling this function. + * + * @param[in] thread pointer to the FuriThread instance to be queried + * @return return code value */ int32_t furi_thread_get_return_code(FuriThread* thread); -/** Thread related methods that doesn't involve FuriThread directly */ - -/** Get FreeRTOS FuriThreadId for current thread +/** + * @brief Get the unique identifier of the current FuriThread. * - * @return FuriThreadId or NULL + * @return unique identifier value */ FuriThreadId furi_thread_get_current_id(void); -/** Get FuriThread instance for current thread +/** + * @brief Get the FuriThread instance associated with the current thread. * - * @return pointer to FuriThread or NULL if this thread doesn't belongs to Furi + * @return pointer to a FuriThread instance or NULL if this thread does not belong to Furi */ FuriThread* furi_thread_get_current(void); -/** Return control to scheduler */ +/** + * @brief Return control to the scheduler. + */ void furi_thread_yield(void); +/** + * @brief Set the thread flags of a FuriThread. + * + * Can be used as a simple inter-thread communication mechanism. + * + * @param[in] thread_id unique identifier of the thread to be notified + * @param[in] flags bitmask of thread flags to set + * @return bitmask combination of previous and newly set flags + */ uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags); +/** + * @brief Clear the thread flags of the current FuriThread. + * + * @param[in] flags bitmask of thread flags to clear + * @return bitmask of thread flags before clearing + */ uint32_t furi_thread_flags_clear(uint32_t flags); +/** + * @brief Get the thread flags of the current FuriThread. + * @return current bitmask of thread flags + */ uint32_t furi_thread_flags_get(void); +/** + * @brief Wait for some thread flags to be set. + * + * @see FuriFlag for option and error flags. + * + * @param[in] flags bitmask of thread flags to wait for + * @param[in] options combination of option flags determining the behavior of the function + * @param[in] timeout maximum time to wait in milliseconds (use FuriWaitForever to wait forever) + * @return bitmask combination of received thread and error flags + */ uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout); /** - * @brief Enumerate threads + * @brief Enumerate all threads. * - * @param thread_array array of FuriThreadId, where thread ids will be stored - * @param array_item_count array size - * @return uint32_t threads count + * @param[out] thread_array pointer to the output array (must be properly allocated) + * @param[in] array_item_count output array capacity in elements (NOT bytes) + * @return total thread count (array_item_count or less) */ uint32_t furi_thread_enumerate(FuriThreadId* thread_array, uint32_t array_item_count); /** - * @brief Get thread name + * @brief Get the name of a thread based on its unique identifier. * - * @param thread_id - * @return const char* name or NULL + * @param[in] thread_id unique identifier of the thread to be queried + * @return pointer to a zero-terminated string or NULL */ const char* furi_thread_get_name(FuriThreadId thread_id); /** - * @brief Get thread appid + * @brief Get the application id of a thread based on its unique identifier. * - * @param thread_id - * @return const char* appid + * @param[in] thread_id unique identifier of the thread to be queried + * @return pointer to a zero-terminated string */ const char* furi_thread_get_appid(FuriThreadId thread_id); /** - * @brief Get thread stack watermark + * @brief Get thread stack watermark. * - * @param thread_id - * @return uint32_t + * @param[in] thread_id unique identifier of the thread to be queried + * @return stack watermark value */ uint32_t furi_thread_get_stack_space(FuriThreadId thread_id); -/** Get STDOUT callback for thead +/** + * @brief Get the standard output callback for the current thead. * - * @return STDOUT callback + * @return pointer to the standard out callback function */ FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback(void); -/** Set STDOUT callback for thread +/** Set standard output callback for the current thread. * - * @param callback callback or NULL to clear + * @param[in] callback pointer to the callback function or NULL to clear */ void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback); -/** Write data to buffered STDOUT +/** Write data to buffered standard output. * - * @param data input data - * @param size input data size - * - * @return size_t written data size + * @param[in] data pointer to the data to be written + * @param[in] size data size in bytes + * @return number of bytes that was actually written */ size_t furi_thread_stdout_write(const char* data, size_t size); -/** Flush data to STDOUT +/** + * @brief Flush buffered data to standard output. * - * @return int32_t error code + * @return error code value */ int32_t furi_thread_stdout_flush(void); -/** Suspend thread +/** + * @brief Suspend a thread. + * + * Suspended threads are no more receiving any of the processor time. * - * @param thread_id thread id + * @param[in] thread_id unique identifier of the thread to be suspended */ void furi_thread_suspend(FuriThreadId thread_id); -/** Resume thread +/** + * @brief Resume a thread. * - * @param thread_id thread id + * @param[in] thread_id unique identifier of the thread to be resumed */ void furi_thread_resume(FuriThreadId thread_id); -/** Get thread suspended state +/** + * @brief Test if a thread is suspended. * - * @param thread_id thread id - * @return true if thread is suspended + * @param[in] thread_id unique identifier of the thread to be queried + * @return true if thread is suspended, false otherwise */ bool furi_thread_is_suspended(FuriThreadId thread_id); diff --git a/furi/core/timer.c b/furi/core/timer.c index 671761fca..1ca56f0fa 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -5,56 +5,46 @@ #include #include -typedef struct { - FuriTimerCallback func; - void* context; -} TimerCallback_t; +struct FuriTimer { + StaticTimer_t container; + FuriTimerCallback cb_func; + void* cb_context; + volatile bool can_be_removed; +}; + +// IMPORTANT: container MUST be the FIRST struct member +static_assert(offsetof(FuriTimer, container) == 0); static void TimerCallback(TimerHandle_t hTimer) { - TimerCallback_t* callb; - - /* Retrieve pointer to callback function and context */ - callb = (TimerCallback_t*)pvTimerGetTimerID(hTimer); - - /* Remove dynamic allocation flag */ - callb = (TimerCallback_t*)((uint32_t)callb & ~1U); - - if(callb != NULL) { - callb->func(callb->context); - } + FuriTimer* instance = pvTimerGetTimerID(hTimer); + furi_check(instance); + instance->cb_func(instance->cb_context); } FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context) { furi_check((furi_kernel_is_irq_or_masked() == 0U) && (func != NULL)); - TimerHandle_t hTimer; - TimerCallback_t* callb; - UBaseType_t reload; + FuriTimer* instance = malloc(sizeof(FuriTimer)); - hTimer = NULL; + instance->cb_func = func; + instance->cb_context = context; - /* Dynamic memory allocation is available: if memory for callback and */ - /* its context is not provided, allocate it from dynamic memory pool */ - callb = (TimerCallback_t*)malloc(sizeof(TimerCallback_t)); + const UBaseType_t reload = (type == FuriTimerTypeOnce ? pdFALSE : pdTRUE); + const TimerHandle_t hTimer = xTimerCreateStatic( + NULL, portMAX_DELAY, reload, instance, TimerCallback, &instance->container); - callb->func = func; - callb->context = context; + furi_check(hTimer == (TimerHandle_t)instance); - if(type == FuriTimerTypeOnce) { - reload = pdFALSE; - } else { - reload = pdTRUE; - } + return instance; +} - /* Store callback memory dynamic allocation flag */ - callb = (TimerCallback_t*)((uint32_t)callb | 1U); - // TimerCallback function is always provided as a callback and is used to call application - // specified function with its context both stored in structure callb. - hTimer = xTimerCreate(NULL, portMAX_DELAY, reload, callb, TimerCallback); - furi_check(hTimer); +static void furi_timer_epilogue(void* context, uint32_t arg) { + furi_assert(context); + UNUSED(arg); - /* Return timer ID */ - return ((FuriTimer*)hTimer); + FuriTimer* instance = context; + + instance->can_be_removed = true; } void furi_timer_free(FuriTimer* instance) { @@ -62,26 +52,14 @@ void furi_timer_free(FuriTimer* instance) { furi_check(instance); TimerHandle_t hTimer = (TimerHandle_t)instance; - TimerCallback_t* callb; + furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); + furi_check(xTimerPendFunctionCall(furi_timer_epilogue, instance, 0, portMAX_DELAY) == pdPASS); - callb = (TimerCallback_t*)pvTimerGetTimerID(hTimer); - - if((uint32_t)callb & 1U) { - /* If callback memory was allocated, it is only safe to free it with - * the timer inactive. Send a stop command and wait for the timer to - * be in an inactive state. - */ - furi_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS); - while(furi_timer_is_running(instance)) furi_delay_tick(2); - - /* Callback memory was allocated from dynamic pool, clear flag */ - callb = (TimerCallback_t*)((uint32_t)callb & ~1U); - - /* Return allocated memory to dynamic pool */ - free(callb); + while(!instance->can_be_removed) { + furi_delay_tick(2); } - furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); + free(instance); } FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) { @@ -98,8 +76,7 @@ FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) { stat = FuriStatusErrorResource; } - /* Return execution status */ - return (stat); + return stat; } FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks) { @@ -117,8 +94,7 @@ FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks) { stat = FuriStatusErrorResource; } - /* Return execution status */ - return (stat); + return stat; } FuriStatus furi_timer_stop(FuriTimer* instance) { diff --git a/furi/core/timer.h b/furi/core/timer.h index f8f40c562..2f55001f7 100644 --- a/furi/core/timer.h +++ b/furi/core/timer.h @@ -1,3 +1,7 @@ +/** + * @file timer.h + * @brief Furi software Timer API. + */ #pragma once #include "core/base.h" @@ -13,7 +17,7 @@ typedef enum { FuriTimerTypePeriodic = 1 ///< Repeating timer. } FuriTimerType; -typedef void FuriTimer; +typedef struct FuriTimer FuriTimer; /** Allocate timer * diff --git a/furi/flipper.c b/furi/flipper.c index c7ba3b4fb..6d6215a9d 100644 --- a/furi/flipper.c +++ b/furi/flipper.c @@ -37,12 +37,11 @@ void flipper_init(void) { for(size_t i = 0; i < FLIPPER_SERVICES_COUNT; i++) { FURI_LOG_D(TAG, "Starting service %s", FLIPPER_SERVICES[i].name); - FuriThread* thread = furi_thread_alloc_ex( + FuriThread* thread = furi_thread_alloc_service( FLIPPER_SERVICES[i].name, FLIPPER_SERVICES[i].stack_size, FLIPPER_SERVICES[i].app, NULL); - furi_thread_mark_as_service(thread); furi_thread_set_appid(thread, FLIPPER_SERVICES[i].appid); furi_thread_start(thread); @@ -67,4 +66,4 @@ void vApplicationGetTimerTaskMemory( *tcb_ptr = memmgr_alloc_from_pool(sizeof(StaticTask_t)); *stack_ptr = memmgr_alloc_from_pool(sizeof(StackType_t) * configTIMER_TASK_STACK_DEPTH); *stack_size = configTIMER_TASK_STACK_DEPTH; -} \ No newline at end of file +} diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 7eda31675..b8f77266c 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,63.0,, +Version,+,64.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/cli/cli.h,, @@ -1583,6 +1583,7 @@ Function,+,furi_string_utf8_push,void,"FuriString*, FuriStringUnicodeValue" Function,+,furi_string_vprintf,int,"FuriString*, const char[], va_list" Function,+,furi_thread_alloc,FuriThread*, Function,+,furi_thread_alloc_ex,FuriThread*,"const char*, uint32_t, FuriThreadCallback, void*" +Function,-,furi_thread_alloc_service,FuriThread*,"const char*, uint32_t, FuriThreadCallback, void*" Function,-,furi_thread_disable_heap_trace,void,FuriThread* Function,+,furi_thread_enable_heap_trace,void,FuriThread* Function,+,furi_thread_enumerate,uint32_t,"FuriThreadId*, uint32_t" @@ -1605,7 +1606,6 @@ Function,+,furi_thread_get_state,FuriThreadState,FuriThread* Function,+,furi_thread_get_stdout_callback,FuriThreadStdoutWriteCallback, Function,+,furi_thread_is_suspended,_Bool,FuriThreadId Function,+,furi_thread_join,_Bool,FuriThread* -Function,+,furi_thread_mark_as_service,void,FuriThread* Function,+,furi_thread_resume,void,FuriThreadId Function,+,furi_thread_set_appid,void,"FuriThread*, const char*" Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback" diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index e2e94d063..a2924c3fc 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,63.0,, +Version,+,64.0,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, @@ -1791,6 +1791,7 @@ Function,+,furi_string_utf8_push,void,"FuriString*, FuriStringUnicodeValue" Function,+,furi_string_vprintf,int,"FuriString*, const char[], va_list" Function,+,furi_thread_alloc,FuriThread*, Function,+,furi_thread_alloc_ex,FuriThread*,"const char*, uint32_t, FuriThreadCallback, void*" +Function,-,furi_thread_alloc_service,FuriThread*,"const char*, uint32_t, FuriThreadCallback, void*" Function,-,furi_thread_disable_heap_trace,void,FuriThread* Function,+,furi_thread_enable_heap_trace,void,FuriThread* Function,+,furi_thread_enumerate,uint32_t,"FuriThreadId*, uint32_t" @@ -1813,7 +1814,6 @@ Function,+,furi_thread_get_state,FuriThreadState,FuriThread* Function,+,furi_thread_get_stdout_callback,FuriThreadStdoutWriteCallback, Function,+,furi_thread_is_suspended,_Bool,FuriThreadId Function,+,furi_thread_join,_Bool,FuriThread* -Function,+,furi_thread_mark_as_service,void,FuriThread* Function,+,furi_thread_resume,void,FuriThreadId Function,+,furi_thread_set_appid,void,"FuriThread*, const char*" Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback" diff --git a/targets/f7/furi_hal/furi_hal_serial_control.c b/targets/f7/furi_hal/furi_hal_serial_control.c index d2ab414c2..241716107 100644 --- a/targets/f7/furi_hal/furi_hal_serial_control.c +++ b/targets/f7/furi_hal/furi_hal_serial_control.c @@ -268,9 +268,8 @@ void furi_hal_serial_control_init(void) { furi_hal_serial_control->handles[FuriHalSerialIdLpuart].id = FuriHalSerialIdLpuart; furi_hal_serial_control->queue = furi_message_queue_alloc(8, sizeof(FuriHalSerialControlMessage)); - furi_hal_serial_control->thread = - furi_thread_alloc_ex("SerialControlDriver", 512, furi_hal_serial_control_thread, NULL); - furi_thread_mark_as_service(furi_hal_serial_control->thread); + furi_hal_serial_control->thread = furi_thread_alloc_service( + "SerialControlDriver", 512, furi_hal_serial_control_thread, NULL); furi_thread_set_priority(furi_hal_serial_control->thread, FuriThreadPriorityHighest); furi_hal_serial_control->log_config_serial_id = FuriHalSerialIdMax; // Start control plane thread diff --git a/targets/f7/furi_hal/furi_hal_usb.c b/targets/f7/furi_hal/furi_hal_usb.c index a482940e2..22d1523b6 100644 --- a/targets/f7/furi_hal/furi_hal_usb.c +++ b/targets/f7/furi_hal/furi_hal_usb.c @@ -120,8 +120,7 @@ void furi_hal_usb_init(void) { NVIC_EnableIRQ(USB_HP_IRQn); usb.queue = furi_message_queue_alloc(1, sizeof(UsbApiEventMessage)); - usb.thread = furi_thread_alloc_ex("UsbDriver", 1024, furi_hal_usb_thread, NULL); - furi_thread_mark_as_service(usb.thread); + usb.thread = furi_thread_alloc_service("UsbDriver", 1024, furi_hal_usb_thread, NULL); furi_thread_start(usb.thread); FURI_LOG_I(TAG, "Init OK"); diff --git a/targets/f7/inc/FreeRTOSConfig.h b/targets/f7/inc/FreeRTOSConfig.h index 36800565c..0abce558f 100644 --- a/targets/f7/inc/FreeRTOSConfig.h +++ b/targets/f7/inc/FreeRTOSConfig.h @@ -16,7 +16,7 @@ #define configUSE_PREEMPTION 1 #define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ (SystemCoreClock)