Much better crash handling. So wow.
* Furi, FuriHal, Desktop: much better crash handling. So wow. * FuriHal: add missing include in FreeRTOSConfig.h Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									475fa91ba6
								
							
						
					
					
						commit
						5b1f50e63a
					
				| @ -176,6 +176,10 @@ int32_t desktop_srv(void* p) { | |||||||
|         scene_manager_next_scene(desktop->scene_manager, DesktopSceneHwMismatch); |         scene_manager_next_scene(desktop->scene_manager, DesktopSceneHwMismatch); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if(furi_hal_rtc_get_fault_data()) { | ||||||
|  |         scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     view_dispatcher_run(desktop->view_dispatcher); |     view_dispatcher_run(desktop->view_dispatcher); | ||||||
|     furi_pubsub_unsubscribe(dolphin_pubsub, dolphin_subscription); |     furi_pubsub_unsubscribe(dolphin_pubsub, dolphin_subscription); | ||||||
|     furi_pubsub_unsubscribe(storage_pubsub, storage_subscription); |     furi_pubsub_unsubscribe(storage_pubsub, storage_subscription); | ||||||
|  | |||||||
| @ -6,3 +6,4 @@ ADD_SCENE(desktop, first_start, FirstStart) | |||||||
| ADD_SCENE(desktop, hw_mismatch, HwMismatch) | ADD_SCENE(desktop, hw_mismatch, HwMismatch) | ||||||
| ADD_SCENE(desktop, pinsetup, PinSetup) | ADD_SCENE(desktop, pinsetup, PinSetup) | ||||||
| ADD_SCENE(desktop, levelup, LevelUp) | ADD_SCENE(desktop, levelup, LevelUp) | ||||||
|  | ADD_SCENE(desktop, fault, Fault) | ||||||
|  | |||||||
							
								
								
									
										49
									
								
								applications/desktop/scenes/desktop_scene_fault.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								applications/desktop/scenes/desktop_scene_fault.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | #include "../desktop_i.h" | ||||||
|  | 
 | ||||||
|  | #define DesktopFaultEventExit 0x00FF00FF | ||||||
|  | 
 | ||||||
|  | void desktop_scene_fault_callback(void* context) { | ||||||
|  |     Desktop* desktop = (Desktop*)context; | ||||||
|  |     view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopFaultEventExit); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void desktop_scene_fault_on_enter(void* context) { | ||||||
|  |     Desktop* desktop = (Desktop*)context; | ||||||
|  | 
 | ||||||
|  |     Popup* popup = desktop->hw_mismatch_popup; | ||||||
|  |     popup_set_context(popup, desktop); | ||||||
|  |     popup_set_header( | ||||||
|  |         popup, | ||||||
|  |         "Flipper crashed\n and was rebooted", | ||||||
|  |         60, | ||||||
|  |         14 + STATUS_BAR_Y_SHIFT, | ||||||
|  |         AlignCenter, | ||||||
|  |         AlignCenter); | ||||||
|  | 
 | ||||||
|  |     char* message = (char*)furi_hal_rtc_get_fault_data(); | ||||||
|  |     popup_set_text(popup, message, 60, 37 + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter); | ||||||
|  |     popup_set_callback(popup, desktop_scene_fault_callback); | ||||||
|  |     view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewHwMismatch); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool desktop_scene_fault_on_event(void* context, SceneManagerEvent event) { | ||||||
|  |     Desktop* desktop = (Desktop*)context; | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         switch(event.event) { | ||||||
|  |         case DesktopFaultEventExit: | ||||||
|  |             scene_manager_previous_scene(desktop->scene_manager); | ||||||
|  |             consumed = true; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void desktop_scene_fault_on_exit(void* context) { | ||||||
|  |     furi_hal_rtc_set_fault_data(0); | ||||||
|  | } | ||||||
| @ -1,9 +1,10 @@ | |||||||
| #include "check.h" | #include "check.h" | ||||||
| #include "furi-hal-task.h" | #include "furi-hal-task.h" | ||||||
| #include <furi-hal-console.h> | #include <furi-hal-console.h> | ||||||
|  | #include <furi-hal-rtc.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| void __furi_print_name(void) { | __attribute__((always_inline)) inline static void __furi_print_name() { | ||||||
|     if(task_is_isr_context()) { |     if(task_is_isr_context()) { | ||||||
|         furi_hal_console_puts("[ISR] "); |         furi_hal_console_puts("[ISR] "); | ||||||
|     } else { |     } else { | ||||||
| @ -18,18 +19,34 @@ void __furi_print_name(void) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void __furi_abort(void) { | __attribute__((always_inline)) inline static void __furi_halt() { | ||||||
|     __disable_irq(); |     asm volatile("bkpt 0x00  \n" | ||||||
|     asm("bkpt 1"); |                  "loop:      \n" | ||||||
|     while(1) { |                  "wfi        \n" | ||||||
|     } |                  "b loop     \n" | ||||||
|  |                  : | ||||||
|  |                  : | ||||||
|  |                  : "memory"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_crash(const char* message) { | void furi_crash(const char* message) { | ||||||
|  |     __disable_irq(); | ||||||
|  | 
 | ||||||
|  |     if(message == NULL) { | ||||||
|  |         message = "Fatal Error"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); |     furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); | ||||||
|     __furi_print_name(); |     __furi_print_name(); | ||||||
|     furi_hal_console_puts(message ? message : "Programming Error"); |     furi_hal_console_puts(message); | ||||||
|  | #ifdef FURI_DEBUG | ||||||
|     furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); |     furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); | ||||||
|     furi_hal_console_puts("\033[0m\r\n"); |     furi_hal_console_puts("\033[0m\r\n"); | ||||||
|     __furi_abort(); |     __furi_halt(); | ||||||
|  | #else | ||||||
|  |     furi_hal_rtc_set_fault_data((uint32_t)message); | ||||||
|  |     furi_hal_console_puts("\r\nRebooting system.\r\n"); | ||||||
|  |     furi_hal_console_puts("\033[0m\r\n"); | ||||||
|  |     NVIC_SystemReset(); | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  | |||||||
| @ -119,7 +119,8 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ | |||||||
| 
 | 
 | ||||||
| /* Normal assert() semantics without relying on the provision of an assert.h
 | /* Normal assert() semantics without relying on the provision of an assert.h
 | ||||||
| header file. */ | header file. */ | ||||||
| #define configASSERT( x ) if ((x) == 0) { taskDISABLE_INTERRUPTS(); asm("bkpt 1"); for( ;; ); } | #include <furi/check.h> | ||||||
|  | #define configASSERT( x ) if ((x) == 0) { furi_crash("FreeRTOS Assert"); } | ||||||
| 
 | 
 | ||||||
| /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
 | /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
 | ||||||
| standard names. */ | standard names. */ | ||||||
|  | |||||||
| @ -30,8 +30,7 @@ int main(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Error_Handler(void) { | void Error_Handler(void) { | ||||||
|     asm("bkpt 1"); |     furi_crash("ErrorHandler"); | ||||||
|     while(1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef  USE_FULL_ASSERT | #ifdef  USE_FULL_ASSERT | ||||||
|  | |||||||
| @ -182,25 +182,19 @@ void NMI_Handler(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HardFault_Handler(void) { | void HardFault_Handler(void) { | ||||||
|     if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) { |     furi_crash("HardFault"); | ||||||
|         __asm("bkpt 1"); |  | ||||||
|     } |  | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemManage_Handler(void) { | void MemManage_Handler(void) { | ||||||
|     __asm("bkpt 1"); |     furi_crash("MemManage"); | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BusFault_Handler(void) { | void BusFault_Handler(void) { | ||||||
|     __asm("bkpt 1"); |     furi_crash("BusFault"); | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UsageFault_Handler(void) { | void UsageFault_Handler(void) { | ||||||
|     __asm("bkpt 1"); |     furi_crash("UsageFault"); | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DebugMon_Handler(void) { | void DebugMon_Handler(void) { | ||||||
|  | |||||||
| @ -140,6 +140,5 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) { | void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) { | ||||||
|     asm("bkpt 1"); |     furi_crash("StackOverflow"); | ||||||
|     while(1) {}; |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -153,3 +153,11 @@ bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime) { | |||||||
| 
 | 
 | ||||||
|     return !invalid; |     return !invalid; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void furi_hal_rtc_set_fault_data(uint32_t value) { | ||||||
|  |     furi_hal_rtc_set_register(FuriHalRtcRegisterFaultData, value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32_t furi_hal_rtc_get_fault_data() { | ||||||
|  |     return furi_hal_rtc_get_register(FuriHalRtcRegisterFaultData); | ||||||
|  | } | ||||||
|  | |||||||
| @ -119,7 +119,8 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ | |||||||
| 
 | 
 | ||||||
| /* Normal assert() semantics without relying on the provision of an assert.h
 | /* Normal assert() semantics without relying on the provision of an assert.h
 | ||||||
| header file. */ | header file. */ | ||||||
| #define configASSERT( x ) if ((x) == 0) { taskDISABLE_INTERRUPTS(); asm("bkpt 1"); for( ;; ); } | #include <furi/check.h> | ||||||
|  | #define configASSERT( x ) if ((x) == 0) { furi_crash("FreeRTOS Assert"); } | ||||||
| 
 | 
 | ||||||
| /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
 | /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
 | ||||||
| standard names. */ | standard names. */ | ||||||
|  | |||||||
| @ -30,8 +30,7 @@ int main(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Error_Handler(void) { | void Error_Handler(void) { | ||||||
|     asm("bkpt 1"); |     furi_crash("ErrorHandler"); | ||||||
|     while(1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef  USE_FULL_ASSERT | #ifdef  USE_FULL_ASSERT | ||||||
|  | |||||||
| @ -182,25 +182,19 @@ void NMI_Handler(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HardFault_Handler(void) { | void HardFault_Handler(void) { | ||||||
|     if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) { |     furi_crash("HardFault"); | ||||||
|         __asm("bkpt 1"); |  | ||||||
|     } |  | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemManage_Handler(void) { | void MemManage_Handler(void) { | ||||||
|     __asm("bkpt 1"); |     furi_crash("MemManage"); | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BusFault_Handler(void) { | void BusFault_Handler(void) { | ||||||
|     __asm("bkpt 1"); |     furi_crash("BusFault"); | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UsageFault_Handler(void) { | void UsageFault_Handler(void) { | ||||||
|     __asm("bkpt 1"); |     furi_crash("UsageFault"); | ||||||
|     while (1) {} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DebugMon_Handler(void) { | void DebugMon_Handler(void) { | ||||||
|  | |||||||
| @ -140,6 +140,5 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) { | void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) { | ||||||
|     asm("bkpt 1"); |     furi_crash("StackOverflow"); | ||||||
|     while(1) {}; |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -153,3 +153,11 @@ bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime) { | |||||||
| 
 | 
 | ||||||
|     return !invalid; |     return !invalid; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void furi_hal_rtc_set_fault_data(uint32_t value) { | ||||||
|  |     furi_hal_rtc_set_register(FuriHalRtcRegisterFaultData, value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32_t furi_hal_rtc_get_fault_data() { | ||||||
|  |     return furi_hal_rtc_get_register(FuriHalRtcRegisterFaultData); | ||||||
|  | } | ||||||
|  | |||||||
| @ -37,6 +37,7 @@ typedef enum { | |||||||
|     FuriHalRtcRegisterSystem, |     FuriHalRtcRegisterSystem, | ||||||
|     FuriHalRtcRegisterSystemVersion, |     FuriHalRtcRegisterSystemVersion, | ||||||
|     FuriHalRtcRegisterLfsFingerprint, |     FuriHalRtcRegisterLfsFingerprint, | ||||||
|  |     FuriHalRtcRegisterFaultData, | ||||||
| } FuriHalRtcRegister; | } FuriHalRtcRegister; | ||||||
| 
 | 
 | ||||||
| /** Initialize RTC subsystem */ | /** Initialize RTC subsystem */ | ||||||
| @ -62,6 +63,10 @@ void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime); | |||||||
| 
 | 
 | ||||||
| bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime); | bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime); | ||||||
| 
 | 
 | ||||||
|  | void furi_hal_rtc_set_fault_data(uint32_t value); | ||||||
|  | 
 | ||||||
|  | uint32_t furi_hal_rtc_get_fault_data(); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -58,7 +58,6 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(!ret) { |     if(!ret) { | ||||||
|         asm("bkpt 1"); |  | ||||||
|         return HAL_ERROR; |         return HAL_ERROR; | ||||||
|     } else { |     } else { | ||||||
|         return HAL_OK; |         return HAL_OK; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Albert Kharisov
						Albert Kharisov