Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
		
						commit
						bb9b52ad3e
					
				
							
								
								
									
										4
									
								
								.vscode/example/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.vscode/example/launch.json
									
									
									
									
										vendored
									
									
								
							| @ -9,6 +9,10 @@ | ||||
|             "type": "command", | ||||
|             "command": "shellCommand.execute", | ||||
|             "args": { | ||||
|                 "useSingleResult": true, | ||||
|                 "env": { | ||||
|                     "PATH": "${workspaceFolder};${env:PATH}" | ||||
|                 }, | ||||
|                 "command": "./fbt get_blackmagic", | ||||
|                 "description": "Get Blackmagic device", | ||||
|             } | ||||
|  | ||||
							
								
								
									
										13
									
								
								SConstruct
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								SConstruct
									
									
									
									
									
								
							| @ -44,6 +44,8 @@ distenv = coreenv.Clone( | ||||
|         "target extended-remote ${GDBREMOTE}", | ||||
|         "-ex", | ||||
|         "set confirm off", | ||||
|         "-ex", | ||||
|         "set pagination off", | ||||
|     ], | ||||
|     GDBOPTS_BLACKMAGIC=[ | ||||
|         "-ex", | ||||
| @ -234,10 +236,19 @@ distenv.PhonyTarget( | ||||
| distenv.PhonyTarget( | ||||
|     "debug_other", | ||||
|     "${GDBPYCOM}", | ||||
|     GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ', | ||||
|     GDBOPTS="${GDBOPTS_BASE}", | ||||
|     GDBREMOTE="${OPENOCD_GDB_PIPE}", | ||||
|     GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ', | ||||
| ) | ||||
| 
 | ||||
| distenv.PhonyTarget( | ||||
|     "debug_other_blackmagic", | ||||
|     "${GDBPYCOM}", | ||||
|     GDBOPTS="${GDBOPTS_BASE}  ${GDBOPTS_BLACKMAGIC}", | ||||
|     GDBREMOTE="$${BLACKMAGIC_ADDR}", | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| # Just start OpenOCD | ||||
| distenv.PhonyTarget( | ||||
|     "openocd", | ||||
|  | ||||
| @ -1,48 +1,87 @@ | ||||
| #include "../nfc_i.h" | ||||
| 
 | ||||
| void nfc_scene_mf_classic_keys_list_submenu_callback(void* context, uint32_t index) { | ||||
|     Nfc* nfc = context; | ||||
| #define NFC_SCENE_MF_CLASSIC_KEYS_LIST_MAX (100) | ||||
| 
 | ||||
| void nfc_scene_mf_classic_keys_list_submenu_callback(void* context, uint32_t index) { | ||||
|     furi_assert(context); | ||||
| 
 | ||||
|     Nfc* nfc = context; | ||||
|     view_dispatcher_send_custom_event(nfc->view_dispatcher, index); | ||||
| } | ||||
| 
 | ||||
| void nfc_scene_mf_classic_keys_list_popup_callback(void* context) { | ||||
|     furi_assert(context); | ||||
| 
 | ||||
|     Nfc* nfc = context; | ||||
|     view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); | ||||
| } | ||||
| 
 | ||||
| void nfc_scene_mf_classic_keys_list_prepare(Nfc* nfc, MfClassicDict* dict) { | ||||
|     Submenu* submenu = nfc->submenu; | ||||
|     uint32_t index = 0; | ||||
|     string_t temp_key; | ||||
|     string_init(temp_key); | ||||
| 
 | ||||
|     submenu_set_header(submenu, "Select key to delete:"); | ||||
|     while(mf_classic_dict_get_next_key_str(dict, temp_key)) { | ||||
|         char* current_key = (char*)malloc(sizeof(char) * 13); | ||||
|         strncpy(current_key, string_get_cstr(temp_key), 12); | ||||
|         MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); | ||||
|         FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); | ||||
|         submenu_add_item( | ||||
|             submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc); | ||||
|     } | ||||
|     string_clear(temp_key); | ||||
| } | ||||
| 
 | ||||
| void nfc_scene_mf_classic_keys_list_on_enter(void* context) { | ||||
|     Nfc* nfc = context; | ||||
|     Submenu* submenu = nfc->submenu; | ||||
|     MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeUser); | ||||
|     uint32_t index = 0; | ||||
|     string_t temp_key; | ||||
|     MfClassicUserKeys_init(nfc->mfc_key_strs); | ||||
|     string_init(temp_key); | ||||
|     if(dict) { | ||||
|         mf_classic_dict_rewind(dict); | ||||
|         while(mf_classic_dict_get_next_key_str(dict, temp_key)) { | ||||
|             char* current_key = (char*)malloc(sizeof(char) * 13); | ||||
|             strncpy(current_key, string_get_cstr(temp_key), 12); | ||||
|             MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); | ||||
|             FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); | ||||
|             submenu_add_item( | ||||
|                 submenu, | ||||
|                 current_key, | ||||
|                 index++, | ||||
|                 nfc_scene_mf_classic_keys_list_submenu_callback, | ||||
|                 nfc); | ||||
|         uint32_t total_user_keys = mf_classic_dict_get_total_keys(dict); | ||||
|         if(total_user_keys < NFC_SCENE_MF_CLASSIC_KEYS_LIST_MAX) { | ||||
|             nfc_scene_mf_classic_keys_list_prepare(nfc, dict); | ||||
|             view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||
|         } else { | ||||
|             popup_set_header(nfc->popup, "Too many keys!", 64, 0, AlignCenter, AlignTop); | ||||
|             popup_set_text( | ||||
|                 nfc->popup, | ||||
|                 "Edit user dictionary\nwith file browser", | ||||
|                 64, | ||||
|                 12, | ||||
|                 AlignCenter, | ||||
|                 AlignTop); | ||||
|             popup_set_callback(nfc->popup, nfc_scene_mf_classic_keys_list_popup_callback); | ||||
|             popup_set_context(nfc->popup, nfc); | ||||
|             popup_set_timeout(nfc->popup, 3000); | ||||
|             popup_enable_timeout(nfc->popup); | ||||
|             view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); | ||||
|         } | ||||
|         mf_classic_dict_free(dict); | ||||
|     } else { | ||||
|         popup_set_header( | ||||
|             nfc->popup, "Failed to load dictionary", 64, 32, AlignCenter, AlignCenter); | ||||
|         popup_set_callback(nfc->popup, nfc_scene_mf_classic_keys_list_popup_callback); | ||||
|         popup_set_context(nfc->popup, nfc); | ||||
|         popup_set_timeout(nfc->popup, 3000); | ||||
|         popup_enable_timeout(nfc->popup); | ||||
|         view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); | ||||
|     } | ||||
|     submenu_set_header(submenu, "Select key to delete:"); | ||||
|     mf_classic_dict_free(dict); | ||||
|     string_clear(temp_key); | ||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||
| } | ||||
| 
 | ||||
| bool nfc_scene_mf_classic_keys_list_on_event(void* context, SceneManagerEvent event) { | ||||
|     Nfc* nfc = context; | ||||
|     bool consumed = false; | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         scene_manager_set_scene_state( | ||||
|             nfc->scene_manager, NfcSceneMfClassicKeysDelete, event.event); | ||||
|         scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysDelete); | ||||
|         consumed = true; | ||||
|         if(event.event == NfcCustomEventViewExit) { | ||||
|             consumed = scene_manager_previous_scene(nfc->scene_manager); | ||||
|         } else { | ||||
|             scene_manager_set_scene_state( | ||||
|                 nfc->scene_manager, NfcSceneMfClassicKeysDelete, event.event); | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysDelete); | ||||
|             consumed = true; | ||||
|         } | ||||
|     } | ||||
|     return consumed; | ||||
| } | ||||
| @ -57,4 +96,5 @@ void nfc_scene_mf_classic_keys_list_on_exit(void* context) { | ||||
|     } | ||||
|     MfClassicUserKeys_clear(nfc->mfc_key_strs); | ||||
|     submenu_reset(nfc->submenu); | ||||
|     popup_reset(nfc->popup); | ||||
| } | ||||
|  | ||||
| @ -7,6 +7,13 @@ enum SubmenuIndex { | ||||
|     SubmenuIndexDynamic, // dynamic indexes start here
 | ||||
| }; | ||||
| 
 | ||||
| void nfc_scene_mf_desfire_popup_callback(void* context) { | ||||
|     furi_assert(context); | ||||
| 
 | ||||
|     Nfc* nfc = context; | ||||
|     view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); | ||||
| } | ||||
| 
 | ||||
| MifareDesfireApplication* nfc_scene_mf_desfire_app_get_app(Nfc* nfc) { | ||||
|     uint32_t app_idx = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp) >> | ||||
|                        1; | ||||
| @ -25,46 +32,45 @@ void nfc_scene_mf_desfire_app_submenu_callback(void* context, uint32_t index) { | ||||
| 
 | ||||
| void nfc_scene_mf_desfire_app_on_enter(void* context) { | ||||
|     Nfc* nfc = context; | ||||
|     Submenu* submenu = nfc->submenu; | ||||
|     MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); | ||||
|     if(!app) { | ||||
|         popup_set_icon(nfc->popup, 5, 5, &I_WarningDolphin_45x42); | ||||
|         popup_set_header(nfc->popup, "Internal Error!", 55, 12, AlignLeft, AlignBottom); | ||||
|         popup_set_text( | ||||
|             nfc->popup, | ||||
|             "No app selected.\nThis should\nnever happen,\nplease file a bug.", | ||||
|             55, | ||||
|             15, | ||||
|             AlignLeft, | ||||
|             AlignTop); | ||||
|         popup_set_header(nfc->popup, "Empty card!", 55, 12, AlignLeft, AlignBottom); | ||||
|         popup_set_callback(nfc->popup, nfc_scene_mf_desfire_popup_callback); | ||||
|         popup_set_context(nfc->popup, nfc); | ||||
|         popup_set_timeout(nfc->popup, 3000); | ||||
|         popup_enable_timeout(nfc->popup); | ||||
|         popup_set_text(nfc->popup, "No application\nfound.", 55, 15, AlignLeft, AlignTop); | ||||
|         view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); | ||||
|         FURI_LOG_E(TAG, "Bad state. No app selected?"); | ||||
|         return; | ||||
|     } | ||||
|     } else { | ||||
|         text_box_set_font(nfc->text_box, TextBoxFontHex); | ||||
|         submenu_add_item( | ||||
|             nfc->submenu, | ||||
|             "App info", | ||||
|             SubmenuIndexAppInfo, | ||||
|             nfc_scene_mf_desfire_app_submenu_callback, | ||||
|             nfc); | ||||
| 
 | ||||
|     text_box_set_font(nfc->text_box, TextBoxFontHex); | ||||
| 
 | ||||
|     submenu_add_item( | ||||
|         submenu, "App info", SubmenuIndexAppInfo, nfc_scene_mf_desfire_app_submenu_callback, nfc); | ||||
| 
 | ||||
|     uint16_t cap = NFC_TEXT_STORE_SIZE; | ||||
|     char* buf = nfc->text_store; | ||||
|     int idx = SubmenuIndexDynamic; | ||||
|     for(MifareDesfireFile* file = app->file_head; file; file = file->next) { | ||||
|         int size = snprintf(buf, cap, "File %d", file->id); | ||||
|         if(size < 0 || size >= cap) { | ||||
|             FURI_LOG_W( | ||||
|                 TAG, | ||||
|                 "Exceeded NFC_TEXT_STORE_SIZE when preparing file id strings; menu truncated"); | ||||
|             break; | ||||
|         uint16_t cap = NFC_TEXT_STORE_SIZE; | ||||
|         char* buf = nfc->text_store; | ||||
|         int idx = SubmenuIndexDynamic; | ||||
|         for(MifareDesfireFile* file = app->file_head; file; file = file->next) { | ||||
|             int size = snprintf(buf, cap, "File %d", file->id); | ||||
|             if(size < 0 || size >= cap) { | ||||
|                 FURI_LOG_W( | ||||
|                     TAG, | ||||
|                     "Exceeded NFC_TEXT_STORE_SIZE when preparing file id strings; menu truncated"); | ||||
|                 break; | ||||
|             } | ||||
|             char* label = buf; | ||||
|             cap -= size + 1; | ||||
|             buf += size + 1; | ||||
|             submenu_add_item( | ||||
|                 nfc->submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc); | ||||
|         } | ||||
|         char* label = buf; | ||||
|         cap -= size + 1; | ||||
|         buf += size + 1; | ||||
|         submenu_add_item(submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc); | ||||
|     } | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||
|         view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { | ||||
| @ -73,26 +79,30 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { | ||||
|     uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp); | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); | ||||
|         TextBox* text_box = nfc->text_box; | ||||
|         string_reset(nfc->text_box_store); | ||||
|         if(event.event == SubmenuIndexAppInfo) { | ||||
|             mf_df_cat_application_info(app, nfc->text_box_store); | ||||
|         if(event.event == NfcCustomEventViewExit) { | ||||
|             consumed = scene_manager_previous_scene(nfc->scene_manager); | ||||
|         } else { | ||||
|             uint16_t index = event.event - SubmenuIndexDynamic; | ||||
|             MifareDesfireFile* file = app->file_head; | ||||
|             for(int i = 0; file && i < index; i++) { | ||||
|                 file = file->next; | ||||
|             MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); | ||||
|             TextBox* text_box = nfc->text_box; | ||||
|             string_reset(nfc->text_box_store); | ||||
|             if(event.event == SubmenuIndexAppInfo) { | ||||
|                 mf_df_cat_application_info(app, nfc->text_box_store); | ||||
|             } else { | ||||
|                 uint16_t index = event.event - SubmenuIndexDynamic; | ||||
|                 MifareDesfireFile* file = app->file_head; | ||||
|                 for(int i = 0; file && i < index; i++) { | ||||
|                     file = file->next; | ||||
|                 } | ||||
|                 if(!file) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 mf_df_cat_file(file, nfc->text_box_store); | ||||
|             } | ||||
|             if(!file) { | ||||
|                 return false; | ||||
|             } | ||||
|             mf_df_cat_file(file, nfc->text_box_store); | ||||
|             text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); | ||||
|             scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); | ||||
|             view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); | ||||
|             consumed = true; | ||||
|         } | ||||
|         text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); | ||||
|         scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); | ||||
|         view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); | ||||
|         consumed = true; | ||||
|     } else if(event.type == SceneManagerEventTypeBack) { | ||||
|         if(state & 1) { | ||||
|             view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||
| @ -108,6 +118,7 @@ void nfc_scene_mf_desfire_app_on_exit(void* context) { | ||||
|     Nfc* nfc = context; | ||||
| 
 | ||||
|     // Clear views
 | ||||
|     popup_reset(nfc->popup); | ||||
|     text_box_reset(nfc->text_box); | ||||
|     string_reset(nfc->text_box_store); | ||||
|     submenu_reset(nfc->submenu); | ||||
|  | ||||
| @ -22,15 +22,11 @@ void desktop_scene_slideshow_on_enter(void* context) { | ||||
| bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) { | ||||
|     Desktop* desktop = (Desktop*)context; | ||||
|     bool consumed = false; | ||||
|     Storage* storage = NULL; | ||||
|     Power* power = NULL; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         switch(event.event) { | ||||
|         case DesktopSlideshowCompleted: | ||||
|             storage = furi_record_open(RECORD_STORAGE); | ||||
|             storage_common_remove(storage, SLIDESHOW_FS_PATH); | ||||
|             furi_record_close(RECORD_STORAGE); | ||||
|             scene_manager_previous_scene(desktop->scene_manager); | ||||
|             consumed = true; | ||||
|             break; | ||||
| @ -50,4 +46,8 @@ bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void desktop_scene_slideshow_on_exit(void* context) { | ||||
|     UNUSED(context); | ||||
| 
 | ||||
|     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||
|     storage_common_remove(storage, SLIDESHOW_FS_PATH); | ||||
|     furi_record_close(RECORD_STORAGE); | ||||
| } | ||||
|  | ||||
| @ -49,7 +49,7 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. | ||||
| - `flash` - flash attached device with OpenOCD over ST-Link | ||||
| - `flash_usb`, `flash_usb_full` - build, upload and install update package to device over USB. See details on `updater_package`, `updater_minpackage`  | ||||
| - `debug` - build and flash firmware, then attach with gdb with firmware's .elf loaded | ||||
| - `debug_other` - attach gdb without loading any .elf. Allows to manually add external elf files with `add-symbol-file` in gdb | ||||
| - `debug_other`, `debug_other_blackmagic` - attach gdb without loading any .elf. Allows to manually add external elf files with `add-symbol-file` in gdb | ||||
| - `updater_debug` - attach gdb with updater's .elf loaded | ||||
| - `blackmagic` - debug firmware with Blackmagic probe (WiFi dev board) | ||||
| - `openocd` - just start OpenOCD | ||||
|  | ||||
| @ -76,19 +76,8 @@ to exclude the API function. */ | ||||
| #define INCLUDE_xTaskGetSchedulerState 1 | ||||
| #define INCLUDE_xTimerPendFunctionCall 1 | ||||
| 
 | ||||
| /* CMSIS-RTOS V2 flags */ | ||||
| #define configUSE_OS2_THREAD_SUSPEND_RESUME 1 | ||||
| #define configUSE_OS2_THREAD_ENUMERATE 1 | ||||
| #define configUSE_OS2_THREAD_FLAGS 1 | ||||
| #define configUSE_OS2_TIMER 1 | ||||
| #define configUSE_OS2_MUTEX 1 | ||||
| 
 | ||||
| // NEVER TO BE USED, because of their hard realtime nature
 | ||||
| // #define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
 | ||||
| 
 | ||||
| /* CMSIS-RTOS */ | ||||
| /* Furi-specific */ | ||||
| #define configTASK_NOTIFICATION_ARRAY_ENTRIES 2 | ||||
| #define CMSIS_TASK_NOTIFY_INDEX 1 | ||||
| 
 | ||||
| extern __attribute__((__noreturn__)) void furi_thread_catch(); | ||||
| #define configTASK_RETURN_ADDRESS (furi_thread_catch + 2) | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| entry,status,name,type,params | ||||
| Version,+,1.7,, | ||||
| Version,+,1.9,, | ||||
| Header,+,applications/services/bt/bt_service/bt.h,, | ||||
| Header,+,applications/services/cli/cli.h,, | ||||
| Header,+,applications/services/cli/cli_vcp.h,, | ||||
| @ -157,29 +157,29 @@ Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_REG_InitTypeDef*" | ||||
| Function,-,LL_ADC_REG_StructInit,void,LL_ADC_REG_InitTypeDef* | ||||
| Function,-,LL_ADC_StructInit,void,LL_ADC_InitTypeDef* | ||||
| Function,-,LL_COMP_DeInit,ErrorStatus,COMP_TypeDef* | ||||
| Function,-,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, LL_COMP_InitTypeDef*" | ||||
| Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, LL_COMP_InitTypeDef*" | ||||
| Function,-,LL_COMP_StructInit,void,LL_COMP_InitTypeDef* | ||||
| Function,-,LL_CRC_DeInit,ErrorStatus,CRC_TypeDef* | ||||
| Function,-,LL_CRS_DeInit,ErrorStatus, | ||||
| Function,-,LL_DMA_DeInit,ErrorStatus,"DMA_TypeDef*, uint32_t" | ||||
| Function,-,LL_DMA_Init,ErrorStatus,"DMA_TypeDef*, uint32_t, LL_DMA_InitTypeDef*" | ||||
| Function,+,LL_DMA_DeInit,ErrorStatus,"DMA_TypeDef*, uint32_t" | ||||
| Function,+,LL_DMA_Init,ErrorStatus,"DMA_TypeDef*, uint32_t, LL_DMA_InitTypeDef*" | ||||
| Function,-,LL_DMA_StructInit,void,LL_DMA_InitTypeDef* | ||||
| Function,-,LL_EXTI_DeInit,ErrorStatus, | ||||
| Function,-,LL_EXTI_Init,ErrorStatus,LL_EXTI_InitTypeDef* | ||||
| Function,-,LL_EXTI_StructInit,void,LL_EXTI_InitTypeDef* | ||||
| Function,-,LL_GPIO_DeInit,ErrorStatus,GPIO_TypeDef* | ||||
| Function,-,LL_GPIO_Init,ErrorStatus,"GPIO_TypeDef*, LL_GPIO_InitTypeDef*" | ||||
| Function,+,LL_GPIO_Init,ErrorStatus,"GPIO_TypeDef*, LL_GPIO_InitTypeDef*" | ||||
| Function,-,LL_GPIO_StructInit,void,LL_GPIO_InitTypeDef* | ||||
| Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef* | ||||
| Function,-,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*" | ||||
| Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*" | ||||
| Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef* | ||||
| Function,-,LL_Init1msTick,void,uint32_t | ||||
| Function,-,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef* | ||||
| Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef* | ||||
| Function,-,LL_LPTIM_Disable,void,LPTIM_TypeDef* | ||||
| Function,-,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, LL_LPTIM_InitTypeDef*" | ||||
| Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, LL_LPTIM_InitTypeDef*" | ||||
| Function,-,LL_LPTIM_StructInit,void,LL_LPTIM_InitTypeDef* | ||||
| Function,-,LL_LPUART_DeInit,ErrorStatus,USART_TypeDef* | ||||
| Function,-,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, LL_LPUART_InitTypeDef*" | ||||
| Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, LL_LPUART_InitTypeDef*" | ||||
| Function,-,LL_LPUART_StructInit,void,LL_LPUART_InitTypeDef* | ||||
| Function,-,LL_PKA_DeInit,ErrorStatus,PKA_TypeDef* | ||||
| Function,-,LL_PKA_Init,ErrorStatus,"PKA_TypeDef*, LL_PKA_InitTypeDef*" | ||||
| @ -193,14 +193,14 @@ Function,-,LL_RCC_GetADCClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetCLK48ClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetI2CClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetLPTIMClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetLPUARTClockFreq,uint32_t,uint32_t | ||||
| Function,+,LL_RCC_GetLPUARTClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetRFWKPClockFreq,uint32_t, | ||||
| Function,-,LL_RCC_GetRNGClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetRTCClockFreq,uint32_t, | ||||
| Function,-,LL_RCC_GetSAIClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetSMPSClockFreq,uint32_t, | ||||
| Function,-,LL_RCC_GetSystemClocksFreq,void,LL_RCC_ClocksTypeDef* | ||||
| Function,-,LL_RCC_GetUSARTClockFreq,uint32_t,uint32_t | ||||
| Function,+,LL_RCC_GetUSARTClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RCC_GetUSBClockFreq,uint32_t,uint32_t | ||||
| Function,-,LL_RNG_DeInit,ErrorStatus,RNG_TypeDef* | ||||
| Function,-,LL_RNG_Init,ErrorStatus,"RNG_TypeDef*, LL_RNG_InitTypeDef*" | ||||
| @ -212,21 +212,21 @@ Function,-,LL_RTC_ALMB_StructInit,void,LL_RTC_AlarmTypeDef* | ||||
| Function,-,LL_RTC_DATE_Init,ErrorStatus,"RTC_TypeDef*, uint32_t, LL_RTC_DateTypeDef*" | ||||
| Function,-,LL_RTC_DATE_StructInit,void,LL_RTC_DateTypeDef* | ||||
| Function,-,LL_RTC_DeInit,ErrorStatus,RTC_TypeDef* | ||||
| Function,-,LL_RTC_EnterInitMode,ErrorStatus,RTC_TypeDef* | ||||
| Function,+,LL_RTC_EnterInitMode,ErrorStatus,RTC_TypeDef* | ||||
| Function,-,LL_RTC_ExitInitMode,ErrorStatus,RTC_TypeDef* | ||||
| Function,-,LL_RTC_Init,ErrorStatus,"RTC_TypeDef*, LL_RTC_InitTypeDef*" | ||||
| Function,+,LL_RTC_Init,ErrorStatus,"RTC_TypeDef*, LL_RTC_InitTypeDef*" | ||||
| Function,-,LL_RTC_StructInit,void,LL_RTC_InitTypeDef* | ||||
| Function,-,LL_RTC_TIME_Init,ErrorStatus,"RTC_TypeDef*, uint32_t, LL_RTC_TimeTypeDef*" | ||||
| Function,-,LL_RTC_TIME_StructInit,void,LL_RTC_TimeTypeDef* | ||||
| Function,-,LL_RTC_WaitForSynchro,ErrorStatus,RTC_TypeDef* | ||||
| Function,-,LL_SPI_DeInit,ErrorStatus,SPI_TypeDef* | ||||
| Function,-,LL_SPI_Init,ErrorStatus,"SPI_TypeDef*, LL_SPI_InitTypeDef*" | ||||
| Function,+,LL_SPI_Init,ErrorStatus,"SPI_TypeDef*, LL_SPI_InitTypeDef*" | ||||
| Function,-,LL_SPI_StructInit,void,LL_SPI_InitTypeDef* | ||||
| Function,-,LL_SetFlashLatency,ErrorStatus,uint32_t | ||||
| Function,-,LL_SetSystemCoreClock,void,uint32_t | ||||
| Function,+,LL_SetSystemCoreClock,void,uint32_t | ||||
| Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_BDTR_InitTypeDef*" | ||||
| Function,-,LL_TIM_BDTR_StructInit,void,LL_TIM_BDTR_InitTypeDef* | ||||
| Function,-,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef* | ||||
| Function,+,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef* | ||||
| Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_ENCODER_InitTypeDef*" | ||||
| Function,-,LL_TIM_ENCODER_StructInit,void,LL_TIM_ENCODER_InitTypeDef* | ||||
| Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_HALLSENSOR_InitTypeDef*" | ||||
| @ -240,7 +240,7 @@ Function,-,LL_TIM_StructInit,void,LL_TIM_InitTypeDef* | ||||
| Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, LL_USART_ClockInitTypeDef*" | ||||
| Function,-,LL_USART_ClockStructInit,void,LL_USART_ClockInitTypeDef* | ||||
| Function,-,LL_USART_DeInit,ErrorStatus,USART_TypeDef* | ||||
| Function,-,LL_USART_Init,ErrorStatus,"USART_TypeDef*, LL_USART_InitTypeDef*" | ||||
| Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, LL_USART_InitTypeDef*" | ||||
| Function,-,LL_USART_StructInit,void,LL_USART_InitTypeDef* | ||||
| Function,-,LL_mDelay,void,uint32_t | ||||
| Function,-,SystemCoreClockUpdate,void, | ||||
| @ -1353,8 +1353,10 @@ Function,+,furi_thread_get_name,const char*,FuriThreadId | ||||
| Function,+,furi_thread_get_return_code,int32_t,FuriThread* | ||||
| Function,+,furi_thread_get_stack_space,uint32_t,FuriThreadId | ||||
| Function,+,furi_thread_get_state,FuriThreadState,FuriThread* | ||||
| Function,+,furi_thread_is_suspended,_Bool,FuriThreadId | ||||
| Function,+,furi_thread_join,_Bool,FuriThread* | ||||
| Function,+,furi_thread_mark_as_service,void,FuriThread* | ||||
| Function,+,furi_thread_resume,void,FuriThreadId | ||||
| Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback" | ||||
| Function,+,furi_thread_set_context,void,"FuriThread*, void*" | ||||
| Function,+,furi_thread_set_name,void,"FuriThread*, const char*" | ||||
| @ -1366,6 +1368,7 @@ Function,+,furi_thread_set_stdout_callback,_Bool,FuriThreadStdoutWriteCallback | ||||
| Function,+,furi_thread_start,void,FuriThread* | ||||
| Function,+,furi_thread_stdout_flush,int32_t, | ||||
| Function,+,furi_thread_stdout_write,size_t,"const char*, size_t" | ||||
| Function,+,furi_thread_suspend,void,FuriThreadId | ||||
| Function,+,furi_thread_yield,void, | ||||
| Function,+,furi_timer_alloc,FuriTimer*,"FuriTimerCallback, FuriTimerType, void*" | ||||
| Function,+,furi_timer_free,void,FuriTimer* | ||||
|  | ||||
| 
 | 
| @ -89,7 +89,9 @@ static void furi_thread_body(void* context) { | ||||
| 
 | ||||
|     if(thread->is_service) { | ||||
|         FURI_LOG_E( | ||||
|             "Service", "%s thread exited. Thread memory cannot be reclaimed.", thread->name); | ||||
|             "Service", | ||||
|             "%s thread exited. Thread memory cannot be reclaimed.", | ||||
|             thread->name ? thread->name : "<unknown service>"); | ||||
|     } | ||||
| 
 | ||||
|     // clear thread local storage
 | ||||
| @ -515,4 +517,23 @@ size_t furi_thread_stdout_write(const char* data, size_t size) { | ||||
| 
 | ||||
| int32_t furi_thread_stdout_flush() { | ||||
|     return __furi_thread_stdout_flush(furi_thread_get_current()); | ||||
| } | ||||
| } | ||||
| 
 | ||||
| void furi_thread_suspend(FuriThreadId thread_id) { | ||||
|     TaskHandle_t hTask = (TaskHandle_t)thread_id; | ||||
|     vTaskSuspend(hTask); | ||||
| } | ||||
| 
 | ||||
| void furi_thread_resume(FuriThreadId thread_id) { | ||||
|     TaskHandle_t hTask = (TaskHandle_t)thread_id; | ||||
|     if(FURI_IS_IRQ_MODE()) { | ||||
|         xTaskResumeFromISR(hTask); | ||||
|     } else { | ||||
|         vTaskResume(hTask); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool furi_thread_is_suspended(FuriThreadId thread_id) { | ||||
|     TaskHandle_t hTask = (TaskHandle_t)thread_id; | ||||
|     return eTaskGetState(hTask) == eSuspended; | ||||
| } | ||||
|  | ||||
| @ -236,6 +236,25 @@ size_t furi_thread_stdout_write(const char* data, size_t size); | ||||
|  */ | ||||
| int32_t furi_thread_stdout_flush(); | ||||
| 
 | ||||
| /** Suspend thread
 | ||||
|  *  | ||||
|  * @param thread_id thread id | ||||
|  */ | ||||
| void furi_thread_suspend(FuriThreadId thread_id); | ||||
| 
 | ||||
| /** Resume thread
 | ||||
|  *  | ||||
|  * @param thread_id thread id | ||||
|  */ | ||||
| void furi_thread_resume(FuriThreadId thread_id); | ||||
| 
 | ||||
| /** Get thread suspended state
 | ||||
|  *  | ||||
|  * @param thread_id thread id | ||||
|  * @return true if thread is suspended | ||||
|  */ | ||||
| bool furi_thread_is_suspended(FuriThreadId thread_id); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aleksandr Kutuzov
						Aleksandr Kutuzov