[FL-2432], [FL-2487] Rework bt keys load and save (#1139)
* bt keys: rework load and save with saved_struct * bt: rename bt keys storage functions * furi_hal_nfc: allow context switch during emilation * bt settings: rework with saved struct * infrared: replace file worker with dialogs and storage * Core, Loader: fix thread allocation tracking, much better, so wow. Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									df66f4f6ba
								
							
						
					
					
						commit
						7c692a9f36
					
				| @ -320,7 +320,7 @@ int32_t bt_srv() { | |||||||
|     Bt* bt = bt_alloc(); |     Bt* bt = bt_alloc(); | ||||||
| 
 | 
 | ||||||
|     // Read keys
 |     // Read keys
 | ||||||
|     if(!bt_load_key_storage(bt)) { |     if(!bt_keys_storage_load(bt)) { | ||||||
|         FURI_LOG_W(TAG, "Failed to load bonding keys"); |         FURI_LOG_W(TAG, "Failed to load bonding keys"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -365,11 +365,11 @@ int32_t bt_srv() { | |||||||
|             // Display PIN code
 |             // Display PIN code
 | ||||||
|             bt_pin_code_show(bt, message.data.pin_code); |             bt_pin_code_show(bt, message.data.pin_code); | ||||||
|         } else if(message.type == BtMessageTypeKeysStorageUpdated) { |         } else if(message.type == BtMessageTypeKeysStorageUpdated) { | ||||||
|             bt_save_key_storage(bt); |             bt_keys_storage_save(bt); | ||||||
|         } else if(message.type == BtMessageTypeSetProfile) { |         } else if(message.type == BtMessageTypeSetProfile) { | ||||||
|             bt_change_profile(bt, &message); |             bt_change_profile(bt, &message); | ||||||
|         } else if(message.type == BtMessageTypeForgetBondedDevices) { |         } else if(message.type == BtMessageTypeForgetBondedDevices) { | ||||||
|             bt_delete_key_storage(bt); |             bt_keys_storage_delete(bt); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return 0; |     return 0; | ||||||
|  | |||||||
| @ -1,46 +1,47 @@ | |||||||
| #include "bt_keys_storage.h" | #include "bt_keys_storage.h" | ||||||
|  | 
 | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <file_worker.h> | #include <lib/toolbox/saved_struct.h> | ||||||
| 
 | 
 | ||||||
| #define BT_KEYS_STORAGE_TAG "bt keys storage" |  | ||||||
| #define BT_KEYS_STORAGE_PATH "/int/bt.keys" | #define BT_KEYS_STORAGE_PATH "/int/bt.keys" | ||||||
|  | #define BT_KEYS_STORAGE_VERSION (0) | ||||||
|  | #define BT_KEYS_STORAGE_MAGIC (0x18) | ||||||
| 
 | 
 | ||||||
| bool bt_load_key_storage(Bt* bt) { | bool bt_keys_storage_load(Bt* bt) { | ||||||
|     furi_assert(bt); |     furi_assert(bt); | ||||||
| 
 |  | ||||||
|     bool file_loaded = false; |     bool file_loaded = false; | ||||||
|     furi_hal_bt_get_key_storage_buff(&bt->bt_keys_addr_start, &bt->bt_keys_size); |  | ||||||
| 
 | 
 | ||||||
|     FileWorker* file_worker = file_worker_alloc(true); |     furi_hal_bt_get_key_storage_buff(&bt->bt_keys_addr_start, &bt->bt_keys_size); | ||||||
|     if(file_worker_open(file_worker, BT_KEYS_STORAGE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { |  | ||||||
|     furi_hal_bt_nvm_sram_sem_acquire(); |     furi_hal_bt_nvm_sram_sem_acquire(); | ||||||
|         if(file_worker_read(file_worker, bt->bt_keys_addr_start, bt->bt_keys_size)) { |     file_loaded = saved_struct_load( | ||||||
|             file_loaded = true; |         BT_KEYS_STORAGE_PATH, | ||||||
|         } |         bt->bt_keys_addr_start, | ||||||
|  |         bt->bt_keys_size, | ||||||
|  |         BT_KEYS_STORAGE_MAGIC, | ||||||
|  |         BT_KEYS_STORAGE_VERSION); | ||||||
|     furi_hal_bt_nvm_sram_sem_release(); |     furi_hal_bt_nvm_sram_sem_release(); | ||||||
|     } | 
 | ||||||
|     file_worker_free(file_worker); |  | ||||||
|     return file_loaded; |     return file_loaded; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool bt_save_key_storage(Bt* bt) { | bool bt_keys_storage_save(Bt* bt) { | ||||||
|     furi_assert(bt); |     furi_assert(bt); | ||||||
|     furi_assert(bt->bt_keys_addr_start); |     furi_assert(bt->bt_keys_addr_start); | ||||||
| 
 |  | ||||||
|     bool file_saved = false; |     bool file_saved = false; | ||||||
|     FileWorker* file_worker = file_worker_alloc(true); | 
 | ||||||
|     if(file_worker_open(file_worker, BT_KEYS_STORAGE_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS)) { |  | ||||||
|     furi_hal_bt_nvm_sram_sem_acquire(); |     furi_hal_bt_nvm_sram_sem_acquire(); | ||||||
|         if(file_worker_write(file_worker, bt->bt_keys_addr_start, bt->bt_keys_size)) { |     file_saved = saved_struct_save( | ||||||
|             file_saved = true; |         BT_KEYS_STORAGE_PATH, | ||||||
|         } |         bt->bt_keys_addr_start, | ||||||
|  |         bt->bt_keys_size, | ||||||
|  |         BT_KEYS_STORAGE_MAGIC, | ||||||
|  |         BT_KEYS_STORAGE_VERSION); | ||||||
|     furi_hal_bt_nvm_sram_sem_release(); |     furi_hal_bt_nvm_sram_sem_release(); | ||||||
|     } | 
 | ||||||
|     file_worker_free(file_worker); |  | ||||||
|     return file_saved; |     return file_saved; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool bt_delete_key_storage(Bt* bt) { | bool bt_keys_storage_delete(Bt* bt) { | ||||||
|     furi_assert(bt); |     furi_assert(bt); | ||||||
|     bool delete_succeed = false; |     bool delete_succeed = false; | ||||||
|     bool bt_is_active = furi_hal_bt_is_active(); |     bool bt_is_active = furi_hal_bt_is_active(); | ||||||
|  | |||||||
| @ -2,8 +2,8 @@ | |||||||
| 
 | 
 | ||||||
| #include "bt_i.h" | #include "bt_i.h" | ||||||
| 
 | 
 | ||||||
| bool bt_load_key_storage(Bt* bt); | bool bt_keys_storage_load(Bt* bt); | ||||||
| 
 | 
 | ||||||
| bool bt_save_key_storage(Bt* bt); | bool bt_keys_storage_save(Bt* bt); | ||||||
| 
 | 
 | ||||||
| bool bt_delete_key_storage(Bt* bt); | bool bt_keys_storage_delete(Bt* bt); | ||||||
|  | |||||||
| @ -1,50 +1,22 @@ | |||||||
| #include "bt_settings.h" | #include "bt_settings.h" | ||||||
| #include <furi.h> |  | ||||||
| #include <file_worker.h> |  | ||||||
| 
 | 
 | ||||||
| #define TAG "BtSettings" | #include <furi.h> | ||||||
|  | #include <lib/toolbox/saved_struct.h> | ||||||
|  | 
 | ||||||
| #define BT_SETTINGS_PATH "/int/bt.settings" | #define BT_SETTINGS_PATH "/int/bt.settings" | ||||||
|  | #define BT_SETTINGS_VERSION (0) | ||||||
|  | #define BT_SETTINGS_MAGIC (0x19) | ||||||
| 
 | 
 | ||||||
| bool bt_settings_load(BtSettings* bt_settings) { | bool bt_settings_load(BtSettings* bt_settings) { | ||||||
|     furi_assert(bt_settings); |     furi_assert(bt_settings); | ||||||
|     bool file_loaded = false; |  | ||||||
|     BtSettings settings = {}; |  | ||||||
| 
 | 
 | ||||||
|     FURI_LOG_I(TAG, "Loading settings from \"%s\"", BT_SETTINGS_PATH); |     return saved_struct_load( | ||||||
|     FileWorker* file_worker = file_worker_alloc(true); |         BT_SETTINGS_PATH, bt_settings, sizeof(BtSettings), BT_SETTINGS_MAGIC, BT_SETTINGS_VERSION); | ||||||
|     if(file_worker_open(file_worker, BT_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { |  | ||||||
|         if(file_worker_read(file_worker, &settings, sizeof(settings))) { |  | ||||||
|             file_loaded = true; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     file_worker_free(file_worker); |  | ||||||
| 
 |  | ||||||
|     if(file_loaded) { |  | ||||||
|         FURI_LOG_I(TAG, "Settings load success"); |  | ||||||
|         if(settings.version != BT_SETTINGS_VERSION) { |  | ||||||
|             FURI_LOG_E(TAG, "Settings version mismatch"); |  | ||||||
|         } else { |  | ||||||
|             osKernelLock(); |  | ||||||
|             *bt_settings = settings; |  | ||||||
|             osKernelUnlock(); |  | ||||||
|         } |  | ||||||
|     } else { |  | ||||||
|         FURI_LOG_E(TAG, "Settings load failed"); |  | ||||||
|     } |  | ||||||
|     return file_loaded; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool bt_settings_save(BtSettings* bt_settings) { | bool bt_settings_save(BtSettings* bt_settings) { | ||||||
|     furi_assert(bt_settings); |     furi_assert(bt_settings); | ||||||
|     bool result = false; |  | ||||||
| 
 | 
 | ||||||
|     FileWorker* file_worker = file_worker_alloc(true); |     return saved_struct_save( | ||||||
|     if(file_worker_open(file_worker, BT_SETTINGS_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS)) { |         BT_SETTINGS_PATH, bt_settings, sizeof(BtSettings), BT_SETTINGS_MAGIC, BT_SETTINGS_VERSION); | ||||||
|         if(file_worker_write(file_worker, bt_settings, sizeof(BtSettings))) { |  | ||||||
|             FURI_LOG_I(TAG, "Settings saved to \"%s\"", BT_SETTINGS_PATH); |  | ||||||
|             result = true; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     file_worker_free(file_worker); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,10 +3,7 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| #define BT_SETTINGS_VERSION (0) |  | ||||||
| 
 |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t version; |  | ||||||
|     bool enabled; |     bool enabled; | ||||||
| } BtSettings; | } BtSettings; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -49,12 +49,14 @@ int32_t InfraredApp::run(void* args) { | |||||||
| InfraredApp::InfraredApp() { | InfraredApp::InfraredApp() { | ||||||
|     furi_check(InfraredAppRemoteManager::max_button_name_length < get_text_store_size()); |     furi_check(InfraredAppRemoteManager::max_button_name_length < get_text_store_size()); | ||||||
|     notification = static_cast<NotificationApp*>(furi_record_open("notification")); |     notification = static_cast<NotificationApp*>(furi_record_open("notification")); | ||||||
|  |     dialogs = static_cast<DialogsApp*>(furi_record_open("dialogs")); | ||||||
|     infrared_worker = infrared_worker_alloc(); |     infrared_worker = infrared_worker_alloc(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| InfraredApp::~InfraredApp() { | InfraredApp::~InfraredApp() { | ||||||
|     infrared_worker_free(infrared_worker); |     infrared_worker_free(infrared_worker); | ||||||
|     furi_record_close("notification"); |     furi_record_close("notification"); | ||||||
|  |     furi_record_close("dialogs"); | ||||||
|     for(auto& [key, scene] : scenes) delete scene; |     for(auto& [key, scene] : scenes) delete scene; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -248,6 +250,10 @@ void InfraredApp::notify_blink_green() { | |||||||
|     notification_message(notification, &sequence); |     notification_message(notification, &sequence); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | DialogsApp* InfraredApp::get_dialogs() { | ||||||
|  |     return dialogs; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void InfraredApp::notify_green_on() { | void InfraredApp::notify_green_on() { | ||||||
|     notification_message(notification, &sequence_set_only_green_255); |     notification_message(notification, &sequence_set_only_green_255); | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ | |||||||
| #include <forward_list> | #include <forward_list> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <notification/notification_messages.h> | #include <notification/notification_messages.h> | ||||||
|  | #include <dialogs/dialogs.h> | ||||||
| #include <infrared_worker.h> | #include <infrared_worker.h> | ||||||
| 
 | 
 | ||||||
| #include "scene/infrared_app_scene.h" | #include "scene/infrared_app_scene.h" | ||||||
| @ -228,6 +229,9 @@ public: | |||||||
|     /** Blink green light */ |     /** Blink green light */ | ||||||
|     void notify_blink_green(); |     void notify_blink_green(); | ||||||
| 
 | 
 | ||||||
|  |     /** Get Dialogs instance */ | ||||||
|  |     DialogsApp* get_dialogs(); | ||||||
|  | 
 | ||||||
|     /** Text input callback
 |     /** Text input callback
 | ||||||
|  * |  * | ||||||
|  * @param context - context to pass to callback |  * @param context - context to pass to callback | ||||||
| @ -286,6 +290,8 @@ private: | |||||||
| 
 | 
 | ||||||
|     /** Notification instance */ |     /** Notification instance */ | ||||||
|     NotificationApp* notification; |     NotificationApp* notification; | ||||||
|  |     /** Dialogs instance */ | ||||||
|  |     DialogsApp* dialogs; | ||||||
|     /** View manager instance */ |     /** View manager instance */ | ||||||
|     InfraredAppViewManager view_manager; |     InfraredAppViewManager view_manager; | ||||||
|     /** Remote manager instance */ |     /** Remote manager instance */ | ||||||
|  | |||||||
| @ -5,7 +5,6 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| #include <m-string.h> | #include <m-string.h> | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <file_worker_cpp.h> |  | ||||||
| 
 | 
 | ||||||
| void InfraredAppBruteForce::add_record(int index, const char* name) { | void InfraredAppBruteForce::add_record(int index, const char* name) { | ||||||
|     records[name].index = index; |     records[name].index = index; | ||||||
|  | |||||||
| @ -1,4 +1,3 @@ | |||||||
| #include <file_worker_cpp.h> |  | ||||||
| #include <flipper_format/flipper_format.h> | #include <flipper_format/flipper_format.h> | ||||||
| #include "infrared_app_remote_manager.h" | #include "infrared_app_remote_manager.h" | ||||||
| #include "infrared/helpers/infrared_parser.h" | #include "infrared/helpers/infrared_parser.h" | ||||||
| @ -22,26 +21,34 @@ std::string InfraredAppRemoteManager::make_full_name( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string InfraredAppRemoteManager::find_vacant_remote_name(const std::string& name) { | std::string InfraredAppRemoteManager::find_vacant_remote_name(const std::string& name) { | ||||||
|     bool exist = true; |     std::string result_name; | ||||||
|     FileWorkerCpp file_worker; |     Storage* storage = static_cast<Storage*>(furi_record_open("storage")); | ||||||
| 
 | 
 | ||||||
|     if(!file_worker.is_file_exist( |     FS_Error error = storage_common_stat( | ||||||
|            make_full_name(InfraredApp::infrared_directory, name).c_str(), &exist)) { |         storage, make_full_name(InfraredApp::infrared_directory, name).c_str(), NULL); | ||||||
|         return std::string(); |  | ||||||
|     } else if(!exist) { |  | ||||||
|         return name; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|  |     if(error == FSE_NOT_EXIST) { | ||||||
|  |         result_name = name; | ||||||
|  |     } else if(error != FSE_OK) { | ||||||
|  |         result_name = std::string(); | ||||||
|  |     } else { | ||||||
|         /* if suggested name is occupied, try another one (name2, name3, etc) */ |         /* if suggested name is occupied, try another one (name2, name3, etc) */ | ||||||
|         uint32_t i = 1; |         uint32_t i = 1; | ||||||
|     bool file_worker_result = false; |  | ||||||
|         std::string new_name; |         std::string new_name; | ||||||
|         do { |         do { | ||||||
|             new_name = make_full_name(InfraredApp::infrared_directory, name + std::to_string(++i)); |             new_name = make_full_name(InfraredApp::infrared_directory, name + std::to_string(++i)); | ||||||
|         file_worker_result = file_worker.is_file_exist(new_name.c_str(), &exist); |             error = storage_common_stat(storage, new_name.c_str(), NULL); | ||||||
|     } while(file_worker_result && exist); |         } while(error == FSE_OK); | ||||||
| 
 | 
 | ||||||
|     return !exist ? name + std::to_string(i) : std::string(); |         if(error == FSE_NOT_EXIST) { | ||||||
|  |             result_name = name + std::to_string(i); | ||||||
|  |         } else { | ||||||
|  |             result_name = std::string(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     furi_record_close("storage"); | ||||||
|  |     return result_name; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool InfraredAppRemoteManager::add_button(const char* button_name, const InfraredAppSignal& signal) { | bool InfraredAppRemoteManager::add_button(const char* button_name, const InfraredAppSignal& signal) { | ||||||
| @ -84,12 +91,14 @@ const InfraredAppSignal& InfraredAppRemoteManager::get_button_data(size_t index) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool InfraredAppRemoteManager::delete_remote() { | bool InfraredAppRemoteManager::delete_remote() { | ||||||
|     bool result; |     Storage* storage = static_cast<Storage*>(furi_record_open("storage")); | ||||||
|     FileWorkerCpp file_worker; |  | ||||||
|     result = file_worker.remove(make_full_name(remote->path, remote->name).c_str()); |  | ||||||
| 
 | 
 | ||||||
|  |     FS_Error error = | ||||||
|  |         storage_common_remove(storage, make_full_name(remote->path, remote->name).c_str()); | ||||||
|     reset_remote(); |     reset_remote(); | ||||||
|     return result; | 
 | ||||||
|  |     furi_record_close("storage"); | ||||||
|  |     return (error == FSE_OK || error == FSE_NOT_EXIST); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void InfraredAppRemoteManager::reset_remote() { | void InfraredAppRemoteManager::reset_remote() { | ||||||
| @ -129,14 +138,15 @@ bool InfraredAppRemoteManager::rename_remote(const char* str) { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     FileWorkerCpp file_worker; |     Storage* storage = static_cast<Storage*>(furi_record_open("storage")); | ||||||
|  | 
 | ||||||
|     std::string old_filename = make_full_name(remote->path, remote->name); |     std::string old_filename = make_full_name(remote->path, remote->name); | ||||||
|     std::string new_filename = make_full_name(remote->path, new_name); |     std::string new_filename = make_full_name(remote->path, new_name); | ||||||
|     bool result = file_worker.rename(old_filename.c_str(), new_filename.c_str()); |     FS_Error error = storage_common_rename(storage, old_filename.c_str(), new_filename.c_str()); | ||||||
| 
 |  | ||||||
|     remote->name = new_name; |     remote->name = new_name; | ||||||
| 
 | 
 | ||||||
|     return result; |     furi_record_close("storage"); | ||||||
|  |     return (error == FSE_OK || error == FSE_EXIST); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool InfraredAppRemoteManager::rename_button(uint32_t index, const char* str) { | bool InfraredAppRemoteManager::rename_button(uint32_t index, const char* str) { | ||||||
| @ -155,11 +165,10 @@ size_t InfraredAppRemoteManager::get_number_of_buttons() { | |||||||
| 
 | 
 | ||||||
| bool InfraredAppRemoteManager::store(void) { | bool InfraredAppRemoteManager::store(void) { | ||||||
|     bool result = false; |     bool result = false; | ||||||
|     FileWorkerCpp file_worker; |  | ||||||
| 
 |  | ||||||
|     if(!file_worker.mkdir(InfraredApp::infrared_directory)) return false; |  | ||||||
| 
 |  | ||||||
|     Storage* storage = static_cast<Storage*>(furi_record_open("storage")); |     Storage* storage = static_cast<Storage*>(furi_record_open("storage")); | ||||||
|  | 
 | ||||||
|  |     if(!storage_simply_mkdir(storage, InfraredApp::infrared_directory)) return false; | ||||||
|  | 
 | ||||||
|     FlipperFormat* ff = flipper_format_file_alloc(storage); |     FlipperFormat* ff = flipper_format_file_alloc(storage); | ||||||
| 
 | 
 | ||||||
|     FURI_LOG_I( |     FURI_LOG_I( | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| #include <gui/modules/dialog_ex.h> | #include <gui/modules/dialog_ex.h> | ||||||
| #include <file_worker_cpp.h> |  | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <dolphin/dolphin.h> | #include <dolphin/dolphin.h> | ||||||
| 
 | 
 | ||||||
| @ -88,13 +87,8 @@ bool InfraredAppSceneLearnSuccess::on_event(InfraredApp* app, InfraredAppEvent* | |||||||
|             break; |             break; | ||||||
|         case DialogExResultRight: { |         case DialogExResultRight: { | ||||||
|             consumed = true; |             consumed = true; | ||||||
|             FileWorkerCpp file_worker; |  | ||||||
|             if(!button_pressed) { |             if(!button_pressed) { | ||||||
|                 if(file_worker.check_errors()) { |  | ||||||
|                 app->switch_to_next_scene(InfraredApp::Scene::LearnEnterName); |                 app->switch_to_next_scene(InfraredApp::Scene::LearnEnterName); | ||||||
|                 } else { |  | ||||||
|                     app->switch_to_previous_scene(); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -1,12 +1,10 @@ | |||||||
| #include "../infrared_app.h" | #include "../infrared_app.h" | ||||||
| #include "infrared/infrared_app_event.h" | #include "infrared/infrared_app_event.h" | ||||||
| #include <text_store.h> | #include <text_store.h> | ||||||
| #include <file_worker_cpp.h> |  | ||||||
| 
 | 
 | ||||||
| void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) { | void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) { | ||||||
|     furi_assert(app); |     furi_assert(app); | ||||||
| 
 | 
 | ||||||
|     FileWorkerCpp file_worker; |  | ||||||
|     bool result = false; |     bool result = false; | ||||||
|     bool file_select_result; |     bool file_select_result; | ||||||
|     auto remote_manager = app->get_remote_manager(); |     auto remote_manager = app->get_remote_manager(); | ||||||
| @ -15,13 +13,15 @@ void InfraredAppSceneRemoteList::on_enter(InfraredApp* app) { | |||||||
|         last_selected_remote.size() ? last_selected_remote.c_str() : nullptr; |         last_selected_remote.size() ? last_selected_remote.c_str() : nullptr; | ||||||
|     auto filename_ts = |     auto filename_ts = | ||||||
|         std::make_unique<TextStore>(InfraredAppRemoteManager::max_remote_name_length); |         std::make_unique<TextStore>(InfraredAppRemoteManager::max_remote_name_length); | ||||||
|  |     DialogsApp* dialogs = app->get_dialogs(); | ||||||
| 
 | 
 | ||||||
|     InfraredAppViewManager* view_manager = app->get_view_manager(); |     InfraredAppViewManager* view_manager = app->get_view_manager(); | ||||||
|     ButtonMenu* button_menu = view_manager->get_button_menu(); |     ButtonMenu* button_menu = view_manager->get_button_menu(); | ||||||
|     button_menu_reset(button_menu); |     button_menu_reset(button_menu); | ||||||
|     view_manager->switch_to(InfraredAppViewManager::ViewId::ButtonMenu); |     view_manager->switch_to(InfraredAppViewManager::ViewId::ButtonMenu); | ||||||
| 
 | 
 | ||||||
|     file_select_result = file_worker.file_select( |     file_select_result = dialog_file_select_show( | ||||||
|  |         dialogs, | ||||||
|         InfraredApp::infrared_directory, |         InfraredApp::infrared_directory, | ||||||
|         InfraredApp::infrared_extension, |         InfraredApp::infrared_extension, | ||||||
|         filename_ts->text, |         filename_ts->text, | ||||||
|  | |||||||
| @ -239,26 +239,11 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con | |||||||
|         event.type = LoaderEventTypeApplicationStarted; |         event.type = LoaderEventTypeApplicationStarted; | ||||||
|         furi_pubsub_publish(loader_instance->pubsub, &event); |         furi_pubsub_publish(loader_instance->pubsub, &event); | ||||||
|         furi_hal_power_insomnia_enter(); |         furi_hal_power_insomnia_enter(); | ||||||
| 
 |  | ||||||
|         // Snapshot current memory usage
 |  | ||||||
|         instance->free_heap_size = memmgr_get_free_heap(); |  | ||||||
|     } else if(thread_state == FuriThreadStateStopped) { |     } else if(thread_state == FuriThreadStateStopped) { | ||||||
|         /*
 |  | ||||||
|          * Current Leak Sanitizer assumes that memory is allocated and freed |  | ||||||
|          * inside one thread. Timers are allocated in one task, but freed in |  | ||||||
|          * Timer-Task thread, and xTimerDelete() just put command to queue. |  | ||||||
|          * To avoid some bad cases there are few fixes: |  | ||||||
|          * 1) delay for Timer to process commands |  | ||||||
|          * 2) there are 'heap diff' which shows difference in heap before task |  | ||||||
|          * started and after task completed. In process of leakage monitoring |  | ||||||
|          * both values should be taken into account. |  | ||||||
|          */ |  | ||||||
|         furi_hal_delay_ms(20); |  | ||||||
|         int heap_diff = instance->free_heap_size - memmgr_get_free_heap(); |  | ||||||
|         FURI_LOG_I( |         FURI_LOG_I( | ||||||
|             TAG, |             TAG, | ||||||
|             "Application thread stopped. Heap allocation balance: %d. Thread allocation balance: %d.", |             "Application thread stopped. Free heap: %d. Thread allocation balance: %d.", | ||||||
|             heap_diff, |             memmgr_get_free_heap(), | ||||||
|             furi_thread_get_heap_size(instance->application_thread)); |             furi_thread_get_heap_size(instance->application_thread)); | ||||||
| 
 | 
 | ||||||
|         if(loader_instance->application_arguments) { |         if(loader_instance->application_arguments) { | ||||||
|  | |||||||
| @ -30,7 +30,6 @@ struct Loader { | |||||||
|     Submenu* debug_menu; |     Submenu* debug_menu; | ||||||
|     Submenu* settings_menu; |     Submenu* settings_menu; | ||||||
| 
 | 
 | ||||||
|     size_t free_heap_size; |  | ||||||
|     volatile uint8_t lock_count; |     volatile uint8_t lock_count; | ||||||
| 
 | 
 | ||||||
|     FuriPubSub* pubsub; |     FuriPubSub* pubsub; | ||||||
|  | |||||||
| @ -171,9 +171,18 @@ size_t memmgr_heap_get_thread_memory(osThreadId_t thread_id) { | |||||||
|                 !MemmgrHeapAllocDict_end_p(alloc_dict_it); |                 !MemmgrHeapAllocDict_end_p(alloc_dict_it); | ||||||
|                 MemmgrHeapAllocDict_next(alloc_dict_it)) { |                 MemmgrHeapAllocDict_next(alloc_dict_it)) { | ||||||
|                 MemmgrHeapAllocDict_itref_t* data = MemmgrHeapAllocDict_ref(alloc_dict_it); |                 MemmgrHeapAllocDict_itref_t* data = MemmgrHeapAllocDict_ref(alloc_dict_it); | ||||||
|  |                 if(data->key != 0) { | ||||||
|  |                     uint8_t* puc = (uint8_t*)data->key; | ||||||
|  |                     puc -= xHeapStructSize; | ||||||
|  |                     BlockLink_t* pxLink = (void*)puc; | ||||||
|  | 
 | ||||||
|  |                     if((pxLink->xBlockSize & xBlockAllocatedBit) != 0 && | ||||||
|  |                        pxLink->pxNextFreeBlock == NULL) { | ||||||
|                         leftovers += data->value; |                         leftovers += data->value; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         memmgr_heap_thread_trace_depth--; |         memmgr_heap_thread_trace_depth--; | ||||||
|     } |     } | ||||||
|     (void)xTaskResumeAll(); |     (void)xTaskResumeAll(); | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ static void furi_thread_body(void* context) { | |||||||
|     thread->ret = thread->callback(thread->context); |     thread->ret = thread->callback(thread->context); | ||||||
| 
 | 
 | ||||||
|     if(thread->heap_trace_enabled == true) { |     if(thread->heap_trace_enabled == true) { | ||||||
|  |         osDelay(33); | ||||||
|         thread->heap_size = memmgr_heap_get_thread_memory(thread_id); |         thread->heap_size = memmgr_heap_get_thread_memory(thread_id); | ||||||
|         memmgr_heap_disable_thread_trace(thread_id); |         memmgr_heap_disable_thread_trace(thread_id); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -230,7 +230,7 @@ bool furi_hal_nfc_listen( | |||||||
|             rfalNfcDeactivate(true); |             rfalNfcDeactivate(true); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         osThreadYield(); |         osDelay(1); | ||||||
|     } |     } | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| @ -498,7 +498,7 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { | |||||||
|         } else { |         } else { | ||||||
|             start = DWT->CYCCNT; |             start = DWT->CYCCNT; | ||||||
|         } |         } | ||||||
|         osThreadYield(); |         osDelay(1); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) { |     if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich