diff --git a/.sublime-project b/.sublime-project index 4912c9974..5d751aaf6 100644 --- a/.sublime-project +++ b/.sublime-project @@ -10,7 +10,7 @@ "clangd": { "initializationOptions": { "clangd.compile-commands-dir": "build/latest", - "clangd.header-insertion": null, + "clangd.header-insertion": "never", "clangd.query-driver": "**", "clangd.clang-tidy": true, }, diff --git a/applications/debug/blink_test/blink_test.c b/applications/debug/blink_test/blink_test.c index 7dd2c9e96..638878da2 100644 --- a/applications/debug/blink_test/blink_test.c +++ b/applications/debug/blink_test/blink_test.c @@ -1,4 +1,3 @@ -#include #include #include diff --git a/applications/debug/ccid_test/ccid_test_app.c b/applications/debug/ccid_test/ccid_test_app.c index be7f7f9e6..6993901d2 100644 --- a/applications/debug/ccid_test/ccid_test_app.c +++ b/applications/debug/ccid_test/ccid_test_app.c @@ -72,7 +72,6 @@ CcidTestApp* ccid_test_app_alloc(void) { //message queue app->event_queue = furi_message_queue_alloc(8, sizeof(CcidTestAppEvent)); - furi_check(app->event_queue); view_port_input_callback_set(app->view_port, ccid_test_app_input_callback, app->event_queue); return app; diff --git a/applications/debug/keypad_test/keypad_test.c b/applications/debug/keypad_test/keypad_test.c index 9e8881def..bc4036120 100644 --- a/applications/debug/keypad_test/keypad_test.c +++ b/applications/debug/keypad_test/keypad_test.c @@ -64,16 +64,9 @@ static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { int32_t keypad_test_app(void* p) { UNUSED(p); FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); - furi_check(event_queue); - KeypadTestState state = {{false, false, false, false, false}, 0, 0, 0, 0, 0, NULL}; state.mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!state.mutex) { - FURI_LOG_E(TAG, "cannot create mutex"); - return 0; - } - ViewPort* view_port = view_port_alloc(); view_port_draw_callback_set(view_port, keypad_test_render_callback, &state); diff --git a/applications/debug/text_box_element_test/text_box_element_test.c b/applications/debug/text_box_element_test/text_box_element_test.c index 2b9475d2b..8002f14b6 100644 --- a/applications/debug/text_box_element_test/text_box_element_test.c +++ b/applications/debug/text_box_element_test/text_box_element_test.c @@ -74,16 +74,8 @@ static void text_box_test_input_callback(InputEvent* input_event, void* ctx) { int32_t text_box_element_test_app(void* p) { UNUSED(p); FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); - furi_check(event_queue); - TextBoxTestState state = {.idx = 0, .mutex = NULL}; state.mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - if(!state.mutex) { - FURI_LOG_E(TAG, "Cannot create mutex"); - return 0; - } - ViewPort* view_port = view_port_alloc(); view_port_draw_callback_set(view_port, text_box_test_render_callback, &state); diff --git a/applications/debug/unit_tests/test_runner.c b/applications/debug/unit_tests/test_runner.c index 6af807086..517a4fd24 100644 --- a/applications/debug/unit_tests/test_runner.c +++ b/applications/debug/unit_tests/test_runner.c @@ -72,6 +72,9 @@ void test_runner_free(TestRunner* instance) { free(instance); } +#define TEST_RUNNER_TMP_DIR EXT_PATH(".tmp") +#define TEST_RUNNER_TMP_UNIT_TESTS_DIR TEST_RUNNER_TMP_DIR "/unit_tests" + static bool test_runner_run_plugin(TestRunner* instance, const char* path) { furi_assert(instance); @@ -128,6 +131,16 @@ static void test_runner_run_internal(TestRunner* instance) { File* directory = storage_file_alloc(instance->storage); do { + if(!storage_simply_mkdir(instance->storage, TEST_RUNNER_TMP_DIR)) { + FURI_LOG_E(TAG, "Cannot create dir %s", TEST_RUNNER_TMP_DIR); + break; + } + + if(!storage_simply_mkdir(instance->storage, TEST_RUNNER_TMP_UNIT_TESTS_DIR)) { + FURI_LOG_E(TAG, "Cannot create dir %s", TEST_RUNNER_TMP_UNIT_TESTS_DIR); + break; + } + if(!storage_dir_open(directory, PLUGINS_PATH)) { FURI_LOG_E(TAG, "Failed to open directory %s", PLUGINS_PATH); break; 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 03a9e5ab0..d26acf577 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 @@ -4,8 +4,8 @@ #include #include "../test.h" // IWYU pragma: keep +#define TEST_DIR_NAME EXT_PATH(".tmp/unit_tests/ff") #define TEST_DIR TEST_DIR_NAME "/" -#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp") static const char* test_filetype = "Flipper File test"; static const uint32_t test_version = 666; 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 a6e1b7700..de6964cbe 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 @@ -298,7 +298,8 @@ MU_TEST(flipper_format_string_test) { MU_TEST(flipper_format_file_test) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - mu_check(flipper_format_file_open_always(flipper_format, EXT_PATH("flipper.fff"))); + mu_check( + flipper_format_file_open_always(flipper_format, EXT_PATH(".tmp/unit_tests/flipper.fff"))); Stream* stream = flipper_format_get_raw_stream(flipper_format); mu_check(flipper_format_write_header_cstr(flipper_format, test_filetype, test_version)); diff --git a/applications/debug/unit_tests/tests/rpc/rpc_test.c b/applications/debug/unit_tests/tests/rpc/rpc_test.c index 5bc2cc1f8..f5b9e762d 100644 --- a/applications/debug/unit_tests/tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/tests/rpc/rpc_test.c @@ -46,8 +46,8 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS]; #define MAX_RECEIVE_OUTPUT_TIMEOUT 3000 #define MAX_NAME_LENGTH 255 #define MAX_DATA_SIZE 512u // have to be exact as in rpc_storage.c +#define TEST_DIR_NAME EXT_PATH(".tmp/unit_tests/rpc") #define TEST_DIR TEST_DIR_NAME "/" -#define TEST_DIR_NAME EXT_PATH("unit_tests_tmp") #define MD5SUM_SIZE 16 #define PING_REQUEST 0 diff --git a/applications/debug/unit_tests/tests/stream/stream_test.c b/applications/debug/unit_tests/tests/stream/stream_test.c index ad41c08ec..4f1ba2fd7 100644 --- a/applications/debug/unit_tests/tests/stream/stream_test.c +++ b/applications/debug/unit_tests/tests/stream/stream_test.c @@ -15,6 +15,8 @@ static const char* stream_test_left_data = "There are two cardinal human sins "; static const char* stream_test_right_data = "from which all others derive: impatience and indolence."; +#define FILESTREAM_PATH EXT_PATH(".tmp/unit_tests/filestream.str") + MU_TEST_1(stream_composite_subtest, Stream* stream) { const size_t data_size = 128; uint8_t data[data_size]; @@ -304,15 +306,14 @@ MU_TEST(stream_composite_test) { // test file stream Storage* storage = furi_record_open(RECORD_STORAGE); stream = file_stream_alloc(storage); - mu_check( - file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check(file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_composite_subtest, stream); stream_free(stream); // test buffered file stream stream = buffered_file_stream_alloc(storage); - mu_check(buffered_file_stream_open( - stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check( + buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_composite_subtest, stream); stream_free(stream); furi_record_close(RECORD_STORAGE); @@ -346,7 +347,7 @@ MU_TEST(stream_write_read_save_load_test) { mu_check(stream_seek(stream_orig, 0, StreamOffsetFromStart)); mu_assert_int_eq( strlen(stream_test_data), - stream_save_to_file(stream_orig, storage, EXT_PATH("filestream.str"), FSOM_CREATE_ALWAYS)); + stream_save_to_file(stream_orig, storage, FILESTREAM_PATH, FSOM_CREATE_ALWAYS)); stream_free(stream_copy); stream_free(stream_orig); @@ -354,8 +355,7 @@ MU_TEST(stream_write_read_save_load_test) { // load from file, read Stream* stream_new = string_stream_alloc(); mu_assert_int_eq( - strlen(stream_test_data), - stream_load_from_file(stream_new, storage, EXT_PATH("filestream.str"))); + strlen(stream_test_data), stream_load_from_file(stream_new, storage, FILESTREAM_PATH)); MU_RUN_TEST_1(stream_read_subtest, stream_new); stream_free(stream_new); @@ -396,15 +396,14 @@ MU_TEST(stream_split_test) { // test file stream Storage* storage = furi_record_open(RECORD_STORAGE); stream = file_stream_alloc(storage); - mu_check( - file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check(file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_split_subtest, stream); stream_free(stream); // test buffered stream stream = buffered_file_stream_alloc(storage); - mu_check(buffered_file_stream_open( - stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check( + buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); MU_RUN_TEST_1(stream_split_subtest, stream); stream_free(stream); @@ -424,8 +423,8 @@ MU_TEST(stream_buffered_write_after_read_test) { Storage* storage = furi_record_open(RECORD_STORAGE); Stream* stream = buffered_file_stream_alloc(storage); - mu_check(buffered_file_stream_open( - stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check( + buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); mu_assert_int_eq(strlen(stream_test_data), stream_write_cstring(stream, stream_test_data)); mu_check(stream_rewind(stream)); mu_assert_int_eq(prefix_len, stream_read(stream, (uint8_t*)buf, prefix_len)); @@ -458,8 +457,8 @@ MU_TEST(stream_buffered_large_file_test) { // write test data to file Stream* stream = buffered_file_stream_alloc(storage); - mu_check(buffered_file_stream_open( - stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); + mu_check( + buffered_file_stream_open(stream, FILESTREAM_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); mu_assert_int_eq(0, stream_size(stream)); mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data)); mu_assert_int_eq(furi_string_size(input_data), stream_size(stream)); diff --git a/applications/debug/usb_mouse/usb_mouse.c b/applications/debug/usb_mouse/usb_mouse.c index 6e716e69a..2b7710451 100644 --- a/applications/debug/usb_mouse/usb_mouse.c +++ b/applications/debug/usb_mouse/usb_mouse.c @@ -40,7 +40,6 @@ static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) { int32_t usb_mouse_app(void* p) { UNUSED(p); FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(UsbMouseEvent)); - furi_check(event_queue); ViewPort* view_port = view_port_alloc(); FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); diff --git a/applications/main/nfc/helpers/mf_user_dict.c b/applications/main/nfc/helpers/mf_user_dict.c index 1a019cf59..9410c8537 100644 --- a/applications/main/nfc/helpers/mf_user_dict.c +++ b/applications/main/nfc/helpers/mf_user_dict.c @@ -17,7 +17,6 @@ MfUserDict* mf_user_dict_alloc(size_t max_keys_to_load) { KeysDict* dict = keys_dict_alloc( NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey)); - furi_assert(dict); size_t dict_keys_num = keys_dict_get_total_keys(dict); instance->keys_num = MIN(max_keys_to_load, dict_keys_num); @@ -69,7 +68,6 @@ bool mf_user_dict_delete_key(MfUserDict* instance, uint32_t index) { KeysDict* dict = keys_dict_alloc( NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey)); - furi_assert(dict); bool key_delete_success = keys_dict_delete_key(dict, instance->keys_arr[index].data, sizeof(MfClassicKey)); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c index 44f9963af..eaa054149 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys.c @@ -16,19 +16,15 @@ void nfc_scene_mf_classic_keys_on_enter(void* context) { uint32_t flipper_dict_keys_total = 0; KeysDict* dict = keys_dict_alloc( NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, KeysDictModeOpenExisting, sizeof(MfClassicKey)); - if(dict) { - flipper_dict_keys_total = keys_dict_get_total_keys(dict); - keys_dict_free(dict); - } + flipper_dict_keys_total = keys_dict_get_total_keys(dict); + keys_dict_free(dict); // Load user dict keys total uint32_t user_dict_keys_total = 0; dict = keys_dict_alloc( NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey)); - if(dict) { - user_dict_keys_total = keys_dict_get_total_keys(dict); - keys_dict_free(dict); - } + user_dict_keys_total = keys_dict_get_total_keys(dict); + keys_dict_free(dict); FuriString* temp_str = furi_string_alloc(); widget_add_string_element( diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_add.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_add.c index 4111cca81..a963f44ac 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_add.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_add.c @@ -31,7 +31,6 @@ bool nfc_scene_mf_classic_keys_add_on_event(void* context, SceneManagerEvent eve // Add key to dict KeysDict* dict = keys_dict_alloc( NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey)); - furi_assert(dict); MfClassicKey key = {}; memcpy(key.data, instance->byte_input_store, sizeof(MfClassicKey)); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index 679dafaf1..b96a22db6 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -344,7 +344,6 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); instance->stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); - furi_check(instance->stream); SubGhzEnvironment* environment = subghz_cli_environment_init(); @@ -425,7 +424,6 @@ void subghz_cli_command_rx_raw(Cli* cli, FuriString* args, void* context) { SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); instance->stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); - furi_check(instance->stream); // Configure radio furi_hal_subghz_reset(); diff --git a/applications/services/cli/cli.c b/applications/services/cli/cli.c index 7ba704219..709d69768 100644 --- a/applications/services/cli/cli.c +++ b/applications/services/cli/cli.c @@ -19,7 +19,6 @@ Cli* cli_alloc(void) { cli->session = NULL; cli->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - furi_check(cli->mutex); cli->idle_sem = furi_semaphore_alloc(1, 0); diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index 28c17ec16..4a75241e6 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -99,8 +99,8 @@ void dolphin_event_send_async(Dolphin* dolphin, DolphinEvent* event) { void dolphin_event_send_wait(Dolphin* dolphin, DolphinEvent* event) { furi_assert(dolphin); furi_assert(event); + event->flag = furi_event_flag_alloc(); - furi_check(event->flag); furi_check( furi_message_queue_put(dolphin->event_queue, event, FuriWaitForever) == FuriStatusOk); furi_check( diff --git a/applications/services/gui/modules/popup.c b/applications/services/gui/modules/popup.c index 45014f6f4..5c9c75e4a 100644 --- a/applications/services/gui/modules/popup.c +++ b/applications/services/gui/modules/popup.c @@ -112,7 +112,6 @@ Popup* popup_alloc(void) { Popup* popup = malloc(sizeof(Popup)); popup->view = view_alloc(); popup->timer = furi_timer_alloc(popup_timer_callback, FuriTimerTypeOnce, popup); - furi_assert(popup->timer); popup->timer_period_in_ms = 1000; popup->timer_enabled = false; diff --git a/applications/services/gui/view.c b/applications/services/gui/view.c index a35c2fa38..51d023543 100644 --- a/applications/services/gui/view.c +++ b/applications/services/gui/view.c @@ -78,7 +78,6 @@ void view_allocate_model(View* view, ViewModelType type, size_t size) { } else if(view->model_type == ViewModelTypeLocking) { ViewModelLocking* model = malloc(sizeof(ViewModelLocking)); model->mutex = furi_mutex_alloc(FuriMutexTypeRecursive); - furi_check(model->mutex); model->data = malloc(size); view->model = model; } else { diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index 0f3008a36..aae53cd2a 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -90,8 +90,6 @@ static void render_callback(Canvas* canvas, void* ctx) { int32_t passport_app(void* p) { UNUSED(p); FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); - furi_assert(semaphore); - ViewPort* view_port = view_port_alloc(); Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); diff --git a/applications/system/snake_game/snake_game.c b/applications/system/snake_game/snake_game.c index a7765f945..aee9fd16d 100644 --- a/applications/system/snake_game/snake_game.c +++ b/applications/system/snake_game/snake_game.c @@ -327,12 +327,6 @@ int32_t snake_game_app(void* p) { snake_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!snake_state->mutex) { - FURI_LOG_E("SnakeGame", "cannot create mutex\r\n"); - free(snake_state); - return 255; - } - ViewPort* view_port = view_port_alloc(); view_port_draw_callback_set(view_port, snake_game_render_callback, snake_state); view_port_input_callback_set(view_port, snake_game_input_callback, event_queue); diff --git a/furi/core/common_defines.h b/furi/core/common_defines.h index beb9f6519..0f6230c19 100644 --- a/furi/core/common_defines.h +++ b/furi/core/common_defines.h @@ -67,6 +67,14 @@ void __furi_critical_exit(__FuriCriticalInfo info); #define FURI_CHECK_RETURN __attribute__((__warn_unused_result__)) #endif +#ifndef FURI_NAKED +#define FURI_NAKED __attribute__((naked)) +#endif + +#ifndef FURI_DEFAULT +#define FURI_DEFAULT(x) __attribute__((weak, alias(x))) +#endif + #ifdef __cplusplus } #endif diff --git a/furi/core/memmgr_heap.c b/furi/core/memmgr_heap.c index 3a0e2c378..3827ddde3 100644 --- a/furi/core/memmgr_heap.c +++ b/furi/core/memmgr_heap.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -63,8 +64,6 @@ task.h is included from an application file. */ #define heapBITS_PER_BYTE ((size_t)8) /* Heap start end symbols provided by linker */ -extern const void __heap_start__; -extern const void __heap_end__; uint8_t* ucHeap = (uint8_t*)&__heap_start__; /* Define the linked list structure. This is used to link free blocks in order diff --git a/furi/core/message_queue.h b/furi/core/message_queue.h index a055a05f1..4c5b5af3c 100644 --- a/furi/core/message_queue.h +++ b/furi/core/message_queue.h @@ -4,7 +4,7 @@ */ #pragma once -#include "core/base.h" +#include "base.h" #ifdef __cplusplus extern "C" { diff --git a/furi/core/pubsub.c b/furi/core/pubsub.c index 0fdd5d02d..7c1730632 100644 --- a/furi/core/pubsub.c +++ b/furi/core/pubsub.c @@ -20,7 +20,6 @@ FuriPubSub* furi_pubsub_alloc(void) { FuriPubSub* pubsub = malloc(sizeof(FuriPubSub)); pubsub->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - furi_assert(pubsub->mutex); FuriPubSubSubscriptionList_init(pubsub->items); diff --git a/furi/core/record.c b/furi/core/record.c index 6c44df846..fa384369a 100644 --- a/furi/core/record.c +++ b/furi/core/record.c @@ -39,7 +39,6 @@ static void furi_record_erase(const char* name, FuriRecordData* record_data) { void furi_record_init(void) { furi_record = malloc(sizeof(FuriRecord)); furi_record->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - furi_check(furi_record->mutex); FuriRecordDataDict_init(furi_record->records); } diff --git a/furi/core/timer.h b/furi/core/timer.h index 2f55001f7..00056db18 100644 --- a/furi/core/timer.h +++ b/furi/core/timer.h @@ -4,7 +4,7 @@ */ #pragma once -#include "core/base.h" +#include "base.h" #ifdef __cplusplus extern "C" { diff --git a/scripts/fbt_tools/fbt_hwtarget.py b/scripts/fbt_tools/fbt_hwtarget.py index a3b0d4a78..cce247098 100644 --- a/scripts/fbt_tools/fbt_hwtarget.py +++ b/scripts/fbt_tools/fbt_hwtarget.py @@ -76,7 +76,9 @@ class HardwareTargetLoader: self._processTargetDefinitions(inherited_target) def gatherSources(self): - sources = [self.startup_script] + sources = [] + if self.startup_script: + sources.append(self.startup_script) seen_filenames = set(self.excluded_sources) # print("Layers: ", self.layered_target_dirs) for target_dir in self.layered_target_dirs: diff --git a/targets/f7/application_ext.ld b/targets/f7/application_ext.ld index 01bb021b6..b6496290a 100644 --- a/targets/f7/application_ext.ld +++ b/targets/f7/application_ext.ld @@ -1,54 +1,47 @@ FORCE_COMMON_ALLOCATION -SECTIONS -{ - .text 0x00000000 : ALIGN(4) - { - *(.text) - *(.stub) - *(.text*) - *(.text.*) - *(.text._*) +SECTIONS { + .text 0x00000000 : ALIGN(4) { + *(.text) + *(.stub) + *(.text*) + *(.text.*) + *(.text._*) - KEEP (*(.init)) - KEEP (*(.fini)) - } + KEEP (*(.init)) + KEEP (*(.fini)) + } - .rodata : - { - *(.rodata) - *(.rodata1) - *(.rodata.*) - } + .rodata : { + *(.rodata) + *(.rodata1) + *(.rodata.*) + } - .data : - { - *(.data) - *(.data1) - *(.data.*) - } + .data : { + *(.data) + *(.data1) + *(.data.*) + } - .bss : - { - *(.bss) - *(.bss*) - *(.sbss) - *(.sbss*) - *(COMMON) - } + .bss : { + *(.bss) + *(.bss*) + *(.sbss) + *(.sbss*) + *(COMMON) + } - .ARM.attributes : - { - *(.ARM.attributes) - *(.ARM.attributes.*) - } + .ARM.attributes : { + *(.ARM.attributes) + *(.ARM.attributes.*) + } - /DISCARD/ : - { - *(.comment) - *(.comment.*) - *(.llvmbc) - *(.llvmcmd) - } + /DISCARD/ : { + *(.comment) + *(.comment.*) + *(.llvmbc) + *(.llvmcmd) + } } diff --git a/targets/f7/furi_hal/furi_hal.c b/targets/f7/furi_hal/furi_hal.c index 3a58fe196..7424b5e82 100644 --- a/targets/f7/furi_hal/furi_hal.c +++ b/targets/f7/furi_hal/furi_hal.c @@ -63,10 +63,11 @@ void furi_hal_init(void) { void furi_hal_switch(void* address) { __set_BASEPRI(0); - asm volatile("ldr r3, [%0] \n" - "msr msp, r3 \n" - "ldr r3, [%1] \n" - "mov pc, r3 \n" + // This code emulates system reset: sets MSP and calls Reset ISR + asm volatile("ldr r3, [%0] \n" // Load SP from new vector to r3 + "msr msp, r3 \n" // Set MSP from r3 + "ldr r3, [%1] \n" // Load Reset Handler address to r3 + "mov pc, r3 \n" // Set PC from r3 (jump to Reset ISR) : : "r"(address), "r"(address + 0x4) : "r3"); diff --git a/targets/f7/furi_hal/furi_hal_flash.c b/targets/f7/furi_hal/furi_hal_flash.c index 9cf64acc5..8999edaed 100644 --- a/targets/f7/furi_hal/furi_hal_flash.c +++ b/targets/f7/furi_hal/furi_hal_flash.c @@ -8,6 +8,7 @@ #include #include +#include #include @@ -53,9 +54,6 @@ (((__VALUE__) >= FLASH_BASE) && ((__VALUE__) <= (FLASH_BASE + FLASH_SIZE - 8UL)) && \ (((__VALUE__) % 8UL) == 0UL)) -/* Free flash space borders, exported by linker */ -extern const void __free_flash_start__; - size_t furi_hal_flash_get_base(void) { return FLASH_BASE; } diff --git a/targets/f7/furi_hal/furi_hal_interrupt.c b/targets/f7/furi_hal/furi_hal_interrupt.c index 5c2c315ef..5d6680ac2 100644 --- a/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/targets/f7/furi_hal/furi_hal_interrupt.c @@ -67,13 +67,12 @@ const IRQn_Type furi_hal_interrupt_irqn[FuriHalInterruptIdMax] = { [FuriHalInterruptIdLpUart1] = LPUART1_IRQn, }; -__attribute__((always_inline)) static inline void - furi_hal_interrupt_call(FuriHalInterruptId index) { +FURI_ALWAYS_STATIC_INLINE void furi_hal_interrupt_call(FuriHalInterruptId index) { furi_check(furi_hal_interrupt_isr[index].isr); furi_hal_interrupt_isr[index].isr(furi_hal_interrupt_isr[index].context); } -__attribute__((always_inline)) static inline void +FURI_ALWAYS_STATIC_INLINE void furi_hal_interrupt_enable(FuriHalInterruptId index, uint16_t priority) { NVIC_SetPriority( furi_hal_interrupt_irqn[index], @@ -81,23 +80,19 @@ __attribute__((always_inline)) static inline void NVIC_EnableIRQ(furi_hal_interrupt_irqn[index]); } -__attribute__((always_inline)) static inline void - furi_hal_interrupt_clear_pending(FuriHalInterruptId index) { +FURI_ALWAYS_STATIC_INLINE void furi_hal_interrupt_clear_pending(FuriHalInterruptId index) { NVIC_ClearPendingIRQ(furi_hal_interrupt_irqn[index]); } -__attribute__((always_inline)) static inline void - furi_hal_interrupt_get_pending(FuriHalInterruptId index) { +FURI_ALWAYS_STATIC_INLINE void furi_hal_interrupt_get_pending(FuriHalInterruptId index) { NVIC_GetPendingIRQ(furi_hal_interrupt_irqn[index]); } -__attribute__((always_inline)) static inline void - furi_hal_interrupt_set_pending(FuriHalInterruptId index) { +FURI_ALWAYS_STATIC_INLINE void furi_hal_interrupt_set_pending(FuriHalInterruptId index) { NVIC_SetPendingIRQ(furi_hal_interrupt_irqn[index]); } -__attribute__((always_inline)) static inline void - furi_hal_interrupt_disable(FuriHalInterruptId index) { +FURI_ALWAYS_STATIC_INLINE void furi_hal_interrupt_disable(FuriHalInterruptId index) { NVIC_DisableIRQ(furi_hal_interrupt_irqn[index]); } @@ -279,11 +274,11 @@ void MemManage_Handler(void) { // from 0x00 to 1MB, see FuriHalMpuRegionNULL furi_crash("NULL pointer dereference"); } else { - // write or read of MPU region 1 (FuriHalMpuRegionStack) + // write or read of MPU region 1 (FuriHalMpuRegionThreadStack) furi_crash("MPU fault, possibly stack overflow"); } } else if(FURI_BIT(SCB->CFSR, SCB_CFSR_MSTKERR_Pos)) { - // push to stack on MPU region 1 (FuriHalMpuRegionStack) + // push to stack on MPU region 1 (FuriHalMpuRegionThreadStack) furi_crash("MemManage fault, possibly stack overflow"); } @@ -318,9 +313,6 @@ void USB_LP_IRQHandler(void) { #endif } -void USB_HP_IRQHandler(void) { -} - void IPCC_C1_TX_IRQHandler(void) { HW_IPCC_Tx_Handler(); } @@ -347,4 +339,4 @@ void USART1_IRQHandler(void) { void LPUART1_IRQHandler(void) { furi_hal_interrupt_call(FuriHalInterruptIdLpUart1); -} \ No newline at end of file +} diff --git a/targets/f7/furi_hal/furi_hal_mpu.c b/targets/f7/furi_hal/furi_hal_mpu.c index 16724c975..5fe3ab66b 100644 --- a/targets/f7/furi_hal/furi_hal_mpu.c +++ b/targets/f7/furi_hal/furi_hal_mpu.c @@ -1,6 +1,8 @@ #include #include +#include + #define FURI_HAL_MPU_ATTRIBUTES \ (LL_MPU_ACCESS_BUFFERABLE | LL_MPU_ACCESS_CACHEABLE | LL_MPU_ACCESS_SHAREABLE | \ LL_MPU_TEX_LEVEL1 | LL_MPU_INSTRUCTION_ACCESS_ENABLE) @@ -12,6 +14,10 @@ void furi_hal_mpu_init(void) { // NULL pointer dereference protection furi_hal_mpu_protect_no_access(FuriHalMpuRegionNULL, 0x00, FuriHalMPURegionSize1MB); + furi_hal_mpu_protect_no_access( + FuriHalMpuRegionMainStack, + (uint32_t)(&_stack_end - &_stack_size), + FuriHalMPURegionSize32B); } void furi_hal_mpu_enable(void) { @@ -62,5 +68,5 @@ void furi_hal_mpu_set_stack_protection(uint32_t* stack) { if(stack_ptr < (uint32_t)stack) stack_ptr += (mask + 1); furi_hal_mpu_protect_read_only( - FuriHalMpuRegionStack, stack_ptr, FURI_HAL_MPU_STACK_PROTECT_REGION); + FuriHalMpuRegionThreadStack, stack_ptr, FURI_HAL_MPU_STACK_PROTECT_REGION); } \ No newline at end of file diff --git a/targets/f7/inc/stm32wb55_linker.h b/targets/f7/inc/stm32wb55_linker.h new file mode 100644 index 000000000..4b56a11be --- /dev/null +++ b/targets/f7/inc/stm32wb55_linker.h @@ -0,0 +1,34 @@ +/** + * @file stm32wb55_linker.h + * + * Linker defined symbols. Used in various part of firmware to understand + * hardware boundaries. + * + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +extern const void _stack_end; /**< end of stack */ +extern const void _stack_size; /**< stack size */ + +extern const void _sidata; /**< data initial value start */ +extern const void _sdata; /**< data start */ +extern const void _edata; /**< data end */ + +extern const void _sbss; /**< bss start */ +extern const void _ebss; /**< bss end */ + +extern const void _sMB_MEM2; /**< RAM2a start */ +extern const void _eMB_MEM2; /**< RAM2a end */ + +extern const void __heap_start__; /**< RAM1 Heap start */ +extern const void __heap_end__; /**< RAM1 Heap end */ + +extern const void __free_flash_start__; /**< Free Flash space start */ + +#ifdef __cplusplus +} +#endif diff --git a/targets/f7/inc/stm32wb55_startup.h b/targets/f7/inc/stm32wb55_startup.h new file mode 100644 index 000000000..712388576 --- /dev/null +++ b/targets/f7/inc/stm32wb55_startup.h @@ -0,0 +1,94 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int main(void); +extern void __libc_init_array(void); + +void Default_Handler(void); + +#define DEFAULT FURI_DEFAULT("Default_Handler") + +/* 15 Unmask-able ISR */ +DEFAULT void NMI_Handler(void); +DEFAULT void HardFault_Handler(void); +DEFAULT void MemManage_Handler(void); +DEFAULT void BusFault_Handler(void); +DEFAULT void UsageFault_Handler(void); +DEFAULT void SVC_Handler(void); +DEFAULT void DebugMon_Handler(void); +DEFAULT void PendSV_Handler(void); +DEFAULT void SysTick_Handler(void); + +/* 63 Mask-able ISR */ +DEFAULT void WWDG_IRQHandler(void); +DEFAULT void PVD_PVM_IRQHandler(void); +DEFAULT void TAMP_STAMP_LSECSS_IRQHandler(void); +DEFAULT void RTC_WKUP_IRQHandler(void); +DEFAULT void FLASH_IRQHandler(void); +DEFAULT void RCC_IRQHandler(void); +DEFAULT void EXTI0_IRQHandler(void); +DEFAULT void EXTI1_IRQHandler(void); +DEFAULT void EXTI2_IRQHandler(void); +DEFAULT void EXTI3_IRQHandler(void); +DEFAULT void EXTI4_IRQHandler(void); +DEFAULT void DMA1_Channel1_IRQHandler(void); +DEFAULT void DMA1_Channel2_IRQHandler(void); +DEFAULT void DMA1_Channel3_IRQHandler(void); +DEFAULT void DMA1_Channel4_IRQHandler(void); +DEFAULT void DMA1_Channel5_IRQHandler(void); +DEFAULT void DMA1_Channel6_IRQHandler(void); +DEFAULT void DMA1_Channel7_IRQHandler(void); +DEFAULT void ADC1_IRQHandler(void); +DEFAULT void USB_HP_IRQHandler(void); +DEFAULT void USB_LP_IRQHandler(void); +DEFAULT void C2SEV_PWR_C2H_IRQHandler(void); +DEFAULT void COMP_IRQHandler(void); +DEFAULT void EXTI9_5_IRQHandler(void); +DEFAULT void TIM1_BRK_IRQHandler(void); +DEFAULT void TIM1_UP_TIM16_IRQHandler(void); +DEFAULT void TIM1_TRG_COM_TIM17_IRQHandler(void); +DEFAULT void TIM1_CC_IRQHandler(void); +DEFAULT void TIM2_IRQHandler(void); +DEFAULT void PKA_IRQHandler(void); +DEFAULT void I2C1_EV_IRQHandler(void); +DEFAULT void I2C1_ER_IRQHandler(void); +DEFAULT void I2C3_EV_IRQHandler(void); +DEFAULT void I2C3_ER_IRQHandler(void); +DEFAULT void SPI1_IRQHandler(void); +DEFAULT void SPI2_IRQHandler(void); +DEFAULT void USART1_IRQHandler(void); +DEFAULT void LPUART1_IRQHandler(void); +DEFAULT void SAI1_IRQHandler(void); +DEFAULT void TSC_IRQHandler(void); +DEFAULT void EXTI15_10_IRQHandler(void); +DEFAULT void RTC_Alarm_IRQHandler(void); +DEFAULT void CRS_IRQHandler(void); +DEFAULT void PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler(void); +DEFAULT void IPCC_C1_RX_IRQHandler(void); +DEFAULT void IPCC_C1_TX_IRQHandler(void); +DEFAULT void HSEM_IRQHandler(void); +DEFAULT void LPTIM1_IRQHandler(void); +DEFAULT void LPTIM2_IRQHandler(void); +DEFAULT void LCD_IRQHandler(void); +DEFAULT void QUADSPI_IRQHandler(void); +DEFAULT void AES1_IRQHandler(void); +DEFAULT void AES2_IRQHandler(void); +DEFAULT void RNG_IRQHandler(void); +DEFAULT void FPU_IRQHandler(void); +DEFAULT void DMA2_Channel1_IRQHandler(void); +DEFAULT void DMA2_Channel2_IRQHandler(void); +DEFAULT void DMA2_Channel3_IRQHandler(void); +DEFAULT void DMA2_Channel4_IRQHandler(void); +DEFAULT void DMA2_Channel5_IRQHandler(void); +DEFAULT void DMA2_Channel6_IRQHandler(void); +DEFAULT void DMA2_Channel7_IRQHandler(void); +DEFAULT void DMAMUX1_OVR_IRQHandler(void); + +#ifdef __cplusplus +} +#endif diff --git a/targets/f7/src/stm32wb55_startup.c b/targets/f7/src/stm32wb55_startup.c new file mode 100644 index 000000000..1c1cfdcc3 --- /dev/null +++ b/targets/f7/src/stm32wb55_startup.c @@ -0,0 +1,199 @@ +#include +#include +#include + +/** System Core Clock speed + * + * CPU1: M4 on MSI clock after startup (4MHz). + * Modified by RCC LL HAL. + */ +uint32_t SystemCoreClock = 4000000UL; + +/** AHB Prescaler Table. Used by RCC LL HAL */ +const uint32_t AHBPrescTable[16UL] = + {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL}; +/** APB Prescaler Table. Used by RCC LL HAL */ +const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL}; +/** MSI Range Table. Used by RCC LL HAL */ +const uint32_t MSIRangeTable[16UL] = { + 100000UL, + 200000UL, + 400000UL, + 800000UL, + 1000000UL, + 2000000UL, + 4000000UL, + 8000000UL, + 16000000UL, + 24000000UL, + 32000000UL, + 48000000UL, + 0UL, + 0UL, + 0UL, + 0UL}; /* 0UL values are incorrect cases */ + +/** MCU Initialization Routine. Part of ST HAL convention, so we keep it.*/ +void SystemInit(void) { + // Set ISR Vector location +#if defined(VECT_TAB_SRAM) + // Point ISR Vector to SRAM + SCB->VTOR = SRAM1_BASE; +#else + // Point ISR Vector to 0x0, which is mapped to 0x08000000(Flash) + SCB->VTOR = 0x0; +#endif + +#if(__FPU_PRESENT == 1) && (__FPU_USED == 1) + // Enable access to FPU + SCB->CPACR |= + ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */ +#endif + + // Reset the RCC clock configuration to the default reset state + // Set MSION bit + RCC->CR |= RCC_CR_MSION; + // Reset CFGR register + RCC->CFGR = 0x00070000U; + // Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits + RCC->CR &= (uint32_t)0xFAF6FEFBU; + // Reset LSI1 and LSI2 bits + RCC->CSR &= (uint32_t)0xFFFFFFFAU; + // Reset HSI48ON bit + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + // Reset PLLCFGR register + RCC->PLLCFGR = 0x22041000U; +#if defined(STM32WB55xx) || defined(STM32WB5Mxx) + // Reset PLLSAI1CFGR register + RCC->PLLSAI1CFGR = 0x22041000U; +#endif + // Reset HSEBYP bit + RCC->CR &= 0xFFFBFFFFU; + // Disable all RCC related interrupts + RCC->CIER = 0x00000000; +} + +void Default_Handler(void) { + furi_crash("NotImplemented"); +} + +/** Start your journey here */ +FURI_NAKED void Reset_Handler(void) { + // Funny thing: SP and MSP are set to _stack_end if we came here after MCU reset + // Now, what if we came from boot loader? Lets set SP to _stack_end again. + // By the way Furi stage loader doing it too, but we don't know who called us. + asm volatile("ldr r0, =_stack_end"); + asm volatile("mov sp, r0"); + + // ST chip initialization routine + SystemInit(); + + // Copy data section from flash + memcpy((void*)&_sdata, &_sidata, &_edata - &_sdata); + + // Wipe BSS + memset((void*)&_sbss, 0x00, &_ebss - &_sbss); + + // Core2 related quirks: wipe MB_MEM2 section + memset((void*)&_sMB_MEM2, 0x00, &_eMB_MEM2 - &_sMB_MEM2); + + // libc init array + __libc_init_array(); + + // Our main + main(); + + // You should never exit from main, but we'll catch you if you do + furi_crash("WhyExit?"); +} + +/** ISR type */ +typedef void (*element_t)(void); + +/** System initialization vector. Contains: main stack end address, 15 pointers + * to unmask-able ISR and 63 to mask-able ISR. */ +PLACE_IN_SECTION(".isr_vector") +const element_t reset_vector[] = { + /* Main stack top */ + (element_t)&_stack_end, + /* 15 Unmaskable ISR */ + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemManage_Handler, + BusFault_Handler, + UsageFault_Handler, + NULL, + NULL, + NULL, + NULL, + SVC_Handler, + DebugMon_Handler, + NULL, + PendSV_Handler, + SysTick_Handler, + /* 63 Maskable ISR */ + WWDG_IRQHandler, + PVD_PVM_IRQHandler, + TAMP_STAMP_LSECSS_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Channel1_IRQHandler, + DMA1_Channel2_IRQHandler, + DMA1_Channel3_IRQHandler, + DMA1_Channel4_IRQHandler, + DMA1_Channel5_IRQHandler, + DMA1_Channel6_IRQHandler, + DMA1_Channel7_IRQHandler, + ADC1_IRQHandler, + USB_HP_IRQHandler, + USB_LP_IRQHandler, + C2SEV_PWR_C2H_IRQHandler, + COMP_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_IRQHandler, + TIM1_UP_TIM16_IRQHandler, + TIM1_TRG_COM_TIM17_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + PKA_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + LPUART1_IRQHandler, + SAI1_IRQHandler, + TSC_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + CRS_IRQHandler, + PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler, + IPCC_C1_RX_IRQHandler, + IPCC_C1_TX_IRQHandler, + HSEM_IRQHandler, + LPTIM1_IRQHandler, + LPTIM2_IRQHandler, + LCD_IRQHandler, + QUADSPI_IRQHandler, + AES1_IRQHandler, + AES2_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + DMA2_Channel1_IRQHandler, + DMA2_Channel2_IRQHandler, + DMA2_Channel3_IRQHandler, + DMA2_Channel4_IRQHandler, + DMA2_Channel5_IRQHandler, + DMA2_Channel6_IRQHandler, + DMA2_Channel7_IRQHandler, + DMAMUX1_OVR_IRQHandler, +}; diff --git a/targets/f7/src/system_stm32wbxx.c b/targets/f7/src/system_stm32wbxx.c deleted file mode 100644 index 77430fda8..000000000 --- a/targets/f7/src/system_stm32wbxx.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "stm32wbxx.h" - -/*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ -/* #define VECT_TAB_SRAM */ - -#ifndef VECT_TAB_OFFSET -#define VECT_TAB_OFFSET \ - 0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ -#endif - -#define VECT_TAB_BASE_ADDRESS \ - SRAM1_BASE /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ - -/* The SystemCoreClock variable is updated in three ways: - 1) by calling CMSIS function SystemCoreClockUpdate() - 2) by calling HAL API function HAL_RCC_GetHCLKFreq() - 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency - Note: If you use this function to configure the system clock; then there - is no need to call the 2 first functions listed above, since SystemCoreClock - variable is updated automatically. - */ -uint32_t SystemCoreClock = 4000000UL; /*CPU1: M4 on MSI clock after startup (4MHz)*/ - -const uint32_t AHBPrescTable[16UL] = - {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL}; - -const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL}; - -const uint32_t MSIRangeTable[16UL] = { - 100000UL, - 200000UL, - 400000UL, - 800000UL, - 1000000UL, - 2000000UL, - 4000000UL, - 8000000UL, - 16000000UL, - 24000000UL, - 32000000UL, - 48000000UL, - 0UL, - 0UL, - 0UL, - 0UL}; /* 0UL values are incorrect cases */ - -/** - * @brief Setup the microcontroller system. - * @param None - * @retval None - */ -void SystemInit(void) { - /* Configure the Vector Table location add offset address ------------------*/ -#if defined(VECT_TAB_SRAM) && defined(VECT_TAB_BASE_ADDRESS) - /* program in SRAMx */ - SCB->VTOR = VECT_TAB_BASE_ADDRESS | - VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAMx for CPU1 */ -#else /* program in FLASH */ - SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ -#endif - -/* FPU settings ------------------------------------------------------------*/ -#if(__FPU_PRESENT == 1) && (__FPU_USED == 1) - SCB->CPACR |= - ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */ -#endif - - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set MSION bit */ - RCC->CR |= RCC_CR_MSION; - - /* Reset CFGR register */ - RCC->CFGR = 0x00070000U; - - /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */ - RCC->CR &= (uint32_t)0xFAF6FEFBU; - - /*!< Reset LSI1 and LSI2 bits */ - RCC->CSR &= (uint32_t)0xFFFFFFFAU; - - /*!< Reset HSI48ON bit */ - RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x22041000U; - -#if defined(STM32WB55xx) || defined(STM32WB5Mxx) - /* Reset PLLSAI1CFGR register */ - RCC->PLLSAI1CFGR = 0x22041000U; -#endif - - /* Reset HSEBYP bit */ - RCC->CR &= 0xFFFBFFFFU; - - /* Disable all interrupts */ - RCC->CIER = 0x00000000; -} diff --git a/targets/f7/src/update.c b/targets/f7/src/update.c index 261adb5ca..d15474e52 100644 --- a/targets/f7/src/update.c +++ b/targets/f7/src/update.c @@ -109,7 +109,7 @@ static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest memmove((void*)(SRAM1_BASE), img, stat.fsize); LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SRAM); - furi_hal_switch((void*)SRAM1_BASE); + furi_hal_switch(0x0); return true; } while(false); diff --git a/targets/f7/startup_stm32wb55xx_cm4.s b/targets/f7/startup_stm32wb55xx_cm4.s deleted file mode 100644 index c5c2b3fc3..000000000 --- a/targets/f7/startup_stm32wb55xx_cm4.s +++ /dev/null @@ -1,444 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32wb55xx_cm4.s - * @author MCD Application Team - * @brief STM32WB55xx devices vector table GCC toolchain. - * This module performs: - * - Set the initial SP - * - Set the initial PC == Reset_Handler, - * - Set the vector table entries with the exceptions ISR address - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M4 processor is in Thread mode, - * priority is Privileged, and the Stack is set to Main. - ****************************************************************************** - * @attention - * - * Copyright (c) 2019-2021 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - - .syntax unified - .cpu cortex-m4 - .fpu softvfp - .thumb - -.global g_pfnVectors -.global Default_Handler - -/* start address for the initialization values of the .data section. -defined in linker script */ -.word _sidata -/* start address for the .data section. defined in linker script */ -.word _sdata -/* end address for the .data section. defined in linker script */ -.word _edata -/* start address for the .bss section. defined in linker script */ -.word _sbss -/* end address for the .bss section. defined in linker script */ -.word _ebss -/* start address for the .MB_MEM2 section. defined in linker script */ -.word _sMB_MEM2 -/* end address for the .MB_MEM2 section. defined in linker script */ -.word _eMB_MEM2 - -/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ -.macro INIT_BSS start, end - ldr r0, =\start - ldr r1, =\end - movs r3, #0 - bl LoopFillZerobss -.endm - -/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ -.macro INIT_DATA start, end, src - ldr r0, =\start - ldr r1, =\end - ldr r2, =\src - movs r3, #0 - bl LoopCopyDataInit -.endm - -.section .text.data_initializers -CopyDataInit: - ldr r4, [r2, r3] - str r4, [r0, r3] - adds r3, r3, #4 - -LoopCopyDataInit: - adds r4, r0, r3 - cmp r4, r1 - bcc CopyDataInit - bx lr - -FillZerobss: - str r3, [r0] - adds r0, r0, #4 - -LoopFillZerobss: - cmp r0, r1 - bcc FillZerobss - bx lr - - .section .text.Reset_Handler - .weak Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - ldr r0, =_estack - mov sp, r0 /* set stack pointer */ -/* Call the clock system intitialization function.*/ - bl SystemInit - -/* Copy the data segment initializers from flash to SRAM */ - INIT_DATA _sdata, _edata, _sidata - -/* Zero fill the bss segments. */ - INIT_BSS _sbss, _ebss - INIT_BSS _sMB_MEM2, _eMB_MEM2 - -/* Call static constructors */ - bl __libc_init_array -/* Call the application s entry point.*/ - bl main - -LoopForever: - b LoopForever - -.size Reset_Handler, .-Reset_Handler - -/** - * @brief This is the code that gets called when the processor receives an - * unexpected interrupt. This simply enters an infinite loop, preserving - * the system state for examination by a debugger. - * - * @param None - * @retval None -*/ - .section .text.Default_Handler,"ax",%progbits -Default_Handler: -Infinite_Loop: - b Infinite_Loop - .size Default_Handler, .-Default_Handler -/****************************************************************************** -* -* The minimal vector table for a Cortex-M4. Note that the proper constructs -* must be placed on this to ensure that it ends up at physical address -* 0x0000.0000. -* -******************************************************************************/ - .section .isr_vector,"a",%progbits - .type g_pfnVectors, %object - .size g_pfnVectors, .-g_pfnVectors - - -g_pfnVectors: - .word _estack - .word Reset_Handler - .word NMI_Handler - .word HardFault_Handler - .word MemManage_Handler - .word BusFault_Handler - .word UsageFault_Handler - .word 0 - .word 0 - .word 0 - .word 0 - .word SVC_Handler - .word DebugMon_Handler - .word 0 - .word PendSV_Handler - .word SysTick_Handler - .word WWDG_IRQHandler - .word PVD_PVM_IRQHandler - .word TAMP_STAMP_LSECSS_IRQHandler - .word RTC_WKUP_IRQHandler - .word FLASH_IRQHandler - .word RCC_IRQHandler - .word EXTI0_IRQHandler - .word EXTI1_IRQHandler - .word EXTI2_IRQHandler - .word EXTI3_IRQHandler - .word EXTI4_IRQHandler - .word DMA1_Channel1_IRQHandler - .word DMA1_Channel2_IRQHandler - .word DMA1_Channel3_IRQHandler - .word DMA1_Channel4_IRQHandler - .word DMA1_Channel5_IRQHandler - .word DMA1_Channel6_IRQHandler - .word DMA1_Channel7_IRQHandler - .word ADC1_IRQHandler - .word USB_HP_IRQHandler - .word USB_LP_IRQHandler - .word C2SEV_PWR_C2H_IRQHandler - .word COMP_IRQHandler - .word EXTI9_5_IRQHandler - .word TIM1_BRK_IRQHandler - .word TIM1_UP_TIM16_IRQHandler - .word TIM1_TRG_COM_TIM17_IRQHandler - .word TIM1_CC_IRQHandler - .word TIM2_IRQHandler - .word PKA_IRQHandler - .word I2C1_EV_IRQHandler - .word I2C1_ER_IRQHandler - .word I2C3_EV_IRQHandler - .word I2C3_ER_IRQHandler - .word SPI1_IRQHandler - .word SPI2_IRQHandler - .word USART1_IRQHandler - .word LPUART1_IRQHandler - .word SAI1_IRQHandler - .word TSC_IRQHandler - .word EXTI15_10_IRQHandler - .word RTC_Alarm_IRQHandler - .word CRS_IRQHandler - .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .word IPCC_C1_RX_IRQHandler - .word IPCC_C1_TX_IRQHandler - .word HSEM_IRQHandler - .word LPTIM1_IRQHandler - .word LPTIM2_IRQHandler - .word LCD_IRQHandler - .word QUADSPI_IRQHandler - .word AES1_IRQHandler - .word AES2_IRQHandler - .word RNG_IRQHandler - .word FPU_IRQHandler - .word DMA2_Channel1_IRQHandler - .word DMA2_Channel2_IRQHandler - .word DMA2_Channel3_IRQHandler - .word DMA2_Channel4_IRQHandler - .word DMA2_Channel5_IRQHandler - .word DMA2_Channel6_IRQHandler - .word DMA2_Channel7_IRQHandler - .word DMAMUX1_OVR_IRQHandler - -/******************************************************************************* -* -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override -* this definition. -* -*******************************************************************************/ - .weak NMI_Handler - .thumb_set NMI_Handler,Default_Handler - - .weak HardFault_Handler - .thumb_set HardFault_Handler,Default_Handler - - .weak MemManage_Handler - .thumb_set MemManage_Handler,Default_Handler - - .weak BusFault_Handler - .thumb_set BusFault_Handler,Default_Handler - - .weak UsageFault_Handler - .thumb_set UsageFault_Handler,Default_Handler - - .weak SVC_Handler - .thumb_set SVC_Handler,Default_Handler - - .weak DebugMon_Handler - .thumb_set DebugMon_Handler,Default_Handler - - .weak PendSV_Handler - .thumb_set PendSV_Handler,Default_Handler - - .weak SysTick_Handler - .thumb_set SysTick_Handler,Default_Handler - - .weak WWDG_IRQHandler - .thumb_set WWDG_IRQHandler,Default_Handler - - .weak PVD_PVM_IRQHandler - .thumb_set PVD_PVM_IRQHandler,Default_Handler - - .weak TAMP_STAMP_LSECSS_IRQHandler - .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler - - .weak RTC_WKUP_IRQHandler - .thumb_set RTC_WKUP_IRQHandler,Default_Handler - - .weak FLASH_IRQHandler - .thumb_set FLASH_IRQHandler,Default_Handler - - .weak RCC_IRQHandler - .thumb_set RCC_IRQHandler,Default_Handler - - .weak EXTI0_IRQHandler - .thumb_set EXTI0_IRQHandler,Default_Handler - - .weak EXTI1_IRQHandler - .thumb_set EXTI1_IRQHandler,Default_Handler - - .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler - - .weak EXTI3_IRQHandler - .thumb_set EXTI3_IRQHandler,Default_Handler - - .weak EXTI4_IRQHandler - .thumb_set EXTI4_IRQHandler,Default_Handler - - .weak DMA1_Channel1_IRQHandler - .thumb_set DMA1_Channel1_IRQHandler,Default_Handler - - .weak DMA1_Channel2_IRQHandler - .thumb_set DMA1_Channel2_IRQHandler,Default_Handler - - .weak DMA1_Channel3_IRQHandler - .thumb_set DMA1_Channel3_IRQHandler,Default_Handler - - .weak DMA1_Channel4_IRQHandler - .thumb_set DMA1_Channel4_IRQHandler,Default_Handler - - .weak DMA1_Channel5_IRQHandler - .thumb_set DMA1_Channel5_IRQHandler,Default_Handler - - .weak DMA1_Channel6_IRQHandler - .thumb_set DMA1_Channel6_IRQHandler,Default_Handler - - .weak DMA1_Channel7_IRQHandler - .thumb_set DMA1_Channel7_IRQHandler,Default_Handler - - .weak ADC1_IRQHandler - .thumb_set ADC1_IRQHandler,Default_Handler - - .weak USB_HP_IRQHandler - .thumb_set USB_HP_IRQHandler,Default_Handler - - .weak USB_LP_IRQHandler - .thumb_set USB_LP_IRQHandler,Default_Handler - - .weak C2SEV_PWR_C2H_IRQHandler - .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler - - .weak COMP_IRQHandler - .thumb_set COMP_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_IRQHandler - .thumb_set TIM1_BRK_IRQHandler,Default_Handler - - .weak TIM1_UP_TIM16_IRQHandler - .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_TIM17_IRQHandler - .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_IRQHandler,Default_Handler - - .weak TIM2_IRQHandler - .thumb_set TIM2_IRQHandler,Default_Handler - - .weak PKA_IRQHandler - .thumb_set PKA_IRQHandler,Default_Handler - - .weak I2C1_EV_IRQHandler - .thumb_set I2C1_EV_IRQHandler,Default_Handler - - .weak I2C1_ER_IRQHandler - .thumb_set I2C1_ER_IRQHandler,Default_Handler - - .weak I2C3_EV_IRQHandler - .thumb_set I2C3_EV_IRQHandler,Default_Handler - - .weak I2C3_ER_IRQHandler - .thumb_set I2C3_ER_IRQHandler,Default_Handler - - .weak SPI1_IRQHandler - .thumb_set SPI1_IRQHandler,Default_Handler - - .weak SPI2_IRQHandler - .thumb_set SPI2_IRQHandler,Default_Handler - - .weak USART1_IRQHandler - .thumb_set USART1_IRQHandler,Default_Handler - - .weak LPUART1_IRQHandler - .thumb_set LPUART1_IRQHandler,Default_Handler - - .weak SAI1_IRQHandler - .thumb_set SAI1_IRQHandler,Default_Handler - - .weak TSC_IRQHandler - .thumb_set TSC_IRQHandler,Default_Handler - - .weak EXTI15_10_IRQHandler - .thumb_set EXTI15_10_IRQHandler,Default_Handler - - .weak RTC_Alarm_IRQHandler - .thumb_set RTC_Alarm_IRQHandler,Default_Handler - - .weak CRS_IRQHandler - .thumb_set CRS_IRQHandler,Default_Handler - - .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler - .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler - - .weak IPCC_C1_RX_IRQHandler - .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler - - .weak IPCC_C1_TX_IRQHandler - .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler - - .weak HSEM_IRQHandler - .thumb_set HSEM_IRQHandler,Default_Handler - - .weak LPTIM1_IRQHandler - .thumb_set LPTIM1_IRQHandler,Default_Handler - - .weak LPTIM2_IRQHandler - .thumb_set LPTIM2_IRQHandler,Default_Handler - - .weak LCD_IRQHandler - .thumb_set LCD_IRQHandler,Default_Handler - - .weak QUADSPI_IRQHandler - .thumb_set QUADSPI_IRQHandler,Default_Handler - - .weak AES1_IRQHandler - .thumb_set AES1_IRQHandler,Default_Handler - - .weak AES2_IRQHandler - .thumb_set AES2_IRQHandler,Default_Handler - - .weak RNG_IRQHandler - .thumb_set RNG_IRQHandler,Default_Handler - - .weak FPU_IRQHandler - .thumb_set FPU_IRQHandler,Default_Handler - - .weak DMA2_Channel1_IRQHandler - .thumb_set DMA2_Channel1_IRQHandler,Default_Handler - - .weak DMA2_Channel2_IRQHandler - .thumb_set DMA2_Channel2_IRQHandler,Default_Handler - - .weak DMA2_Channel3_IRQHandler - .thumb_set DMA2_Channel3_IRQHandler,Default_Handler - - .weak DMA2_Channel4_IRQHandler - .thumb_set DMA2_Channel4_IRQHandler,Default_Handler - - .weak DMA2_Channel5_IRQHandler - .thumb_set DMA2_Channel5_IRQHandler,Default_Handler - - .weak DMA2_Channel6_IRQHandler - .thumb_set DMA2_Channel6_IRQHandler,Default_Handler - - .weak DMA2_Channel7_IRQHandler - .thumb_set DMA2_Channel7_IRQHandler,Default_Handler - - .weak DMAMUX1_OVR_IRQHandler - .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/f7/stm32wb55xx_flash.ld b/targets/f7/stm32wb55xx_flash.ld index df4c5b726..3fb789645 100644 --- a/targets/f7/stm32wb55xx_flash.ld +++ b/targets/f7/stm32wb55xx_flash.ld @@ -1,198 +1,134 @@ -/** -***************************************************************************** -** -** File : stm32wb55xx_flash.ld -** -** Abstract : System Workbench Minimal System calls file -** -** For more information about which c-functions -** need which of these lowlevel functions -** please consult the Newlib libc-manual -** -** Environment : System Workbench for MCU -** -** Distribution: The file is distributed “as is,” without any warranty -** of any kind. -** -***************************************************************************** -** -**

© COPYRIGHT(c) 2019 Ac6

-** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** 1. Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** 3. Neither the name of Ac6 nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -***************************************************************************** -*/ - -/* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ -_estack = 0x20030000; /* end of RAM */ +_stack_end = 0x20030000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x400; /* required amount of heap */ -_Min_Stack_Size = 0x1000; /* required amount of stack */ +_stack_size = 0x1000; /* required amount of stack */ -/* Specify the memory areas */ -MEMORY -{ -FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K -RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 -RAM2A (xrw) : ORIGIN = 0x20030000, LENGTH = 10K -RAM2B (xrw) : ORIGIN = 0x20038000, LENGTH = 10K +MEMORY { + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 + RAM2A (xrw) : ORIGIN = 0x20030000, LENGTH = 10K + RAM2B (xrw) : ORIGIN = 0x20038000, LENGTH = 10K } -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into FLASH */ - .isr_vector : - { +SECTIONS { + /* The startup code goes first into FLASH */ + .isr_vector : { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : { + . = ALIGN(4); + *lib*.a:*(.text .text.*) /* code from libraries before apps */ + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(*_DRIVER_CONTEXT) + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM1 AT> FLASH + + /* Uninitialized data section */ . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >FLASH + .bss : { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *lib*.a:*(.text .text.*) /* code from libraries before apps */ - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM1 - KEEP (*(.init)) - KEEP (*(.fini)) + /* User_heap_stack section, used to check that there is enough RAM left */ + /* DSECT: https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_linker_special_section_types.html */ + ._user_heap_stack(DSECT) : { + . = ALIGN(8); + __heap_start__ = .; + . = ORIGIN(RAM1) + LENGTH(RAM1) - _stack_size; + __heap_end__ = .; + . = . + _stack_size; + . = ALIGN(8); + } >RAM1 - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >FLASH + /* Free Flash space, that can be used for internal storage */ + .free_flash(DSECT) : { + __free_flash_start__ = .; + . = ORIGIN(FLASH) + LENGTH(FLASH); + } >FLASH - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >FLASH + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - *(*_DRIVER_CONTEXT) - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM1 AT> FLASH - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM1 - - /* User_heap_stack section, used to check that there is enough RAM left */ - /* DSECT: https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_linker_special_section_types.html */ - ._user_heap_stack(DSECT): - { - . = ALIGN(8); - __heap_start__ = .; - . = ORIGIN(RAM1) + LENGTH(RAM1) - _Min_Stack_Size; - __heap_end__ = .; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM1 - - /* Free Flash space, that can be used for internal storage */ - .free_flash(DSECT): - { - __free_flash_start__ = .; - . = ORIGIN(FLASH) + LENGTH(FLASH); - } >FLASH - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } - ._sram2a_start : { . = ALIGN(4); __sram2a_start__ = .; } >RAM2A - MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM2A - MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM2A - MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A - ._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A - ._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B + .ARM.attributes 0 : { *(.ARM.attributes) } + ._sram2a_start : { . = ALIGN(4); __sram2a_start__ = .; } >RAM2A + MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM2A + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM2A + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A + ._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A + ._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B } - - diff --git a/targets/f7/stm32wb55xx_ram_fw.ld b/targets/f7/stm32wb55xx_ram_fw.ld index 0ac9be4df..cae30b6e9 100644 --- a/targets/f7/stm32wb55xx_ram_fw.ld +++ b/targets/f7/stm32wb55xx_ram_fw.ld @@ -1,196 +1,132 @@ -/** -***************************************************************************** -** -** File : stm32wb55xx_ram_fw.ld -** -** Abstract : System Workbench Minimal System calls file -** -** For more information about which c-functions -** need which of these lowlevel functions -** please consult the Newlib libc-manual -** -** Environment : System Workbench for MCU -** -** Distribution: The file is distributed “as is,” without any warranty -** of any kind. -** -***************************************************************************** -** -**

© COPYRIGHT(c) 2019 Ac6

-** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** 1. Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** 3. Neither the name of Ac6 nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -***************************************************************************** -*/ - -/* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ -_estack = 0x20030000; /* end of RAM */ +_stack_end = 0x20030000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x400; /* required amount of heap */ -_Min_Stack_Size = 0x1000; /* required amount of stack */ +_stack_size = 0x1000; /* required amount of stack */ -/* Specify the memory areas */ -MEMORY -{ -FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K -RAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 0x30000 -RAM2A (xrw) : ORIGIN = 0x20030000, LENGTH = 10K -RAM2B (xrw) : ORIGIN = 0x20038000, LENGTH = 10K +MEMORY { + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + RAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 0x30000 + RAM2A (xrw) : ORIGIN = 0x20030000, LENGTH = 10K + RAM2B (xrw) : ORIGIN = 0x20038000, LENGTH = 10K } -/* Define output sections */ -SECTIONS -{ - /* The startup code goes first into FLASH */ - .isr_vector : - { +SECTIONS { + /* The startup code goes first into FLASH */ + .isr_vector : { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >RAM1 + + /* The program code and other data goes into FLASH */ + .text : { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >RAM1 + + /* Constant data goes into FLASH */ + .rodata : { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >RAM1 + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >RAM1 + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >RAM1 + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >RAM1 + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >RAM1 + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM1 AT> RAM1 + + /* Uninitialized data section */ . = ALIGN(4); - KEEP(*(.isr_vector)) /* Startup code */ - . = ALIGN(4); - } >RAM1 + .bss : { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) - /* The program code and other data goes into FLASH */ - .text : - { - . = ALIGN(4); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM1 - KEEP (*(.init)) - KEEP (*(.fini)) + /* User_heap_stack section, used to check that there is enough RAM left */ + /* DSECT: https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_linker_special_section_types.html */ + ._user_heap_stack(DSECT) : { + . = ALIGN(8); + __heap_start__ = .; + . = ORIGIN(RAM1) + LENGTH(RAM1) - _stack_size; + __heap_end__ = .; + . = . + _stack_size; + . = ALIGN(8); + } >RAM1 - . = ALIGN(4); - _etext = .; /* define a global symbols at end of code */ - } >RAM1 + /* Free Flash space, that can be used for internal storage */ + /*.free_flash(DSECT) : { + __free_flash_start__ = .; + . = ORIGIN(FLASH) + LENGTH(FLASH); + } >FLASH*/ - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(4); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(4); - } >RAM1 + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >RAM1 - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >RAM1 - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >RAM1 - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >RAM1 - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM1 AT> RAM1 - - - /* Uninitialized data section */ - . = ALIGN(4); - .bss : - { - /* This is used by the startup in order to initialize the .bss secion */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(4); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >RAM1 - - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack(DSECT) : - { - . = ALIGN(8); - __heap_start__ = .; - . = ORIGIN(RAM1) + LENGTH(RAM1) - _Min_Stack_Size; - __heap_end__ = .; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >RAM1 - - /* Free Flash space, that can be used for internal storage */ - /*.free_flash(DSECT): - { - __free_flash_start__ = .; - . = ORIGIN(FLASH) + LENGTH(FLASH); - } >FLASH*/ - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } - ._sram2a_start : { . = ALIGN(4); __sram2a_start__ = .; } >RAM2A - MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM2A - MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM2A - MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A - ._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A - ._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B + .ARM.attributes 0 : { *(.ARM.attributes) } + ._sram2a_start : { . = ALIGN(4); __sram2a_start__ = .; } >RAM2A + MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM2A + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM2A + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A + ._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A + ._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B } - - diff --git a/targets/f7/target.json b/targets/f7/target.json index eae92a5cd..665864d7d 100644 --- a/targets/f7/target.json +++ b/targets/f7/target.json @@ -13,7 +13,6 @@ "ble_glue/services", "ble_glue/profiles" ], - "startup_script": "startup_stm32wb55xx_cm4.s", "linker_script_flash": "stm32wb55xx_flash.ld", "linker_script_ram": "stm32wb55xx_ram_fw.ld", "linker_script_app": "application_ext.ld", diff --git a/targets/furi_hal_include/furi_hal.h b/targets/furi_hal_include/furi_hal.h index 719df0275..cf483553f 100644 --- a/targets/furi_hal_include/furi_hal.h +++ b/targets/furi_hal_include/furi_hal.h @@ -55,9 +55,15 @@ void furi_hal_deinit_early(void); /** Init FuriHal */ void furi_hal_init(void); -/** Transfer execution to address +/** Jump to the void* * - * @param[in] address pointer to new executable + * Allow your code to transfer control to another firmware. + * + * @warning This code doesn't reset system before jump. Call it only from + * main thread, no kernel should be running. Ensure that no + * peripheral blocks active and no interrupts are pending. + * + * @param address The System Vector address(start of your new firmware) */ void furi_hal_switch(void* address); diff --git a/targets/furi_hal_include/furi_hal_mpu.h b/targets/furi_hal_include/furi_hal_mpu.h index 7a5759c17..1d91b123d 100644 --- a/targets/furi_hal_include/furi_hal_mpu.h +++ b/targets/furi_hal_include/furi_hal_mpu.h @@ -14,8 +14,9 @@ extern "C" { typedef enum { FuriHalMpuRegionNULL = 0x00, // region 0 used to protect null pointer dereference - FuriHalMpuRegionStack = 0x01, // region 1 used to protect stack - FuriHalMpuRegion2 = 0x02, + FuriHalMpuRegionMainStack = 0x01, // region 1 used to protect Main Stack + FuriHalMpuRegionThreadStack = + 0x02, // region 2 used to protect currently executed RTOS Thread Stack FuriHalMpuRegion3 = 0x03, FuriHalMpuRegion4 = 0x04, FuriHalMpuRegion5 = 0x05,