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); | ||||
|     } | ||||
| 
 | ||||
|     if(furi_hal_rtc_get_fault_data()) { | ||||
|         scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault); | ||||
|     } | ||||
| 
 | ||||
|     view_dispatcher_run(desktop->view_dispatcher); | ||||
|     furi_pubsub_unsubscribe(dolphin_pubsub, dolphin_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, pinsetup, PinSetup) | ||||
| 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 "furi-hal-task.h" | ||||
| #include <furi-hal-console.h> | ||||
| #include <furi-hal-rtc.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| void __furi_print_name(void) { | ||||
| __attribute__((always_inline)) inline static void __furi_print_name() { | ||||
|     if(task_is_isr_context()) { | ||||
|         furi_hal_console_puts("[ISR] "); | ||||
|     } else { | ||||
| @ -18,18 +19,34 @@ void __furi_print_name(void) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void __furi_abort(void) { | ||||
|     __disable_irq(); | ||||
|     asm("bkpt 1"); | ||||
|     while(1) { | ||||
|     } | ||||
| __attribute__((always_inline)) inline static void __furi_halt() { | ||||
|     asm volatile("bkpt 0x00  \n" | ||||
|                  "loop:      \n" | ||||
|                  "wfi        \n" | ||||
|                  "b loop     \n" | ||||
|                  : | ||||
|                  : | ||||
|                  : "memory"); | ||||
| } | ||||
| 
 | ||||
| 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_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("\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
 | ||||
| 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
 | ||||
| standard names. */ | ||||
|  | ||||
| @ -30,8 +30,7 @@ int main(void) { | ||||
| } | ||||
| 
 | ||||
| void Error_Handler(void) { | ||||
|     asm("bkpt 1"); | ||||
|     while(1) {} | ||||
|     furi_crash("ErrorHandler"); | ||||
| } | ||||
| 
 | ||||
| #ifdef  USE_FULL_ASSERT | ||||
|  | ||||
| @ -182,25 +182,19 @@ void NMI_Handler(void) { | ||||
| } | ||||
| 
 | ||||
| void HardFault_Handler(void) { | ||||
|     if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) { | ||||
|         __asm("bkpt 1"); | ||||
|     } | ||||
|     while (1) {} | ||||
|     furi_crash("HardFault"); | ||||
| } | ||||
| 
 | ||||
| void MemManage_Handler(void) { | ||||
|     __asm("bkpt 1"); | ||||
|     while (1) {} | ||||
|     furi_crash("MemManage"); | ||||
| } | ||||
| 
 | ||||
| void BusFault_Handler(void) { | ||||
|     __asm("bkpt 1"); | ||||
|     while (1) {} | ||||
|     furi_crash("BusFault"); | ||||
| } | ||||
| 
 | ||||
| void UsageFault_Handler(void) { | ||||
|     __asm("bkpt 1"); | ||||
|     while (1) {} | ||||
|     furi_crash("UsageFault"); | ||||
| } | ||||
| 
 | ||||
| void DebugMon_Handler(void) { | ||||
|  | ||||
| @ -140,6 +140,5 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | ||||
| } | ||||
| 
 | ||||
| void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) { | ||||
|     asm("bkpt 1"); | ||||
|     while(1) {}; | ||||
|     furi_crash("StackOverflow"); | ||||
| } | ||||
|  | ||||
| @ -153,3 +153,11 @@ bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime) { | ||||
| 
 | ||||
|     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
 | ||||
| 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
 | ||||
| standard names. */ | ||||
|  | ||||
| @ -30,8 +30,7 @@ int main(void) { | ||||
| } | ||||
| 
 | ||||
| void Error_Handler(void) { | ||||
|     asm("bkpt 1"); | ||||
|     while(1) {} | ||||
|     furi_crash("ErrorHandler"); | ||||
| } | ||||
| 
 | ||||
| #ifdef  USE_FULL_ASSERT | ||||
|  | ||||
| @ -182,25 +182,19 @@ void NMI_Handler(void) { | ||||
| } | ||||
| 
 | ||||
| void HardFault_Handler(void) { | ||||
|     if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) { | ||||
|         __asm("bkpt 1"); | ||||
|     } | ||||
|     while (1) {} | ||||
|     furi_crash("HardFault"); | ||||
| } | ||||
| 
 | ||||
| void MemManage_Handler(void) { | ||||
|     __asm("bkpt 1"); | ||||
|     while (1) {} | ||||
|     furi_crash("MemManage"); | ||||
| } | ||||
| 
 | ||||
| void BusFault_Handler(void) { | ||||
|     __asm("bkpt 1"); | ||||
|     while (1) {} | ||||
|     furi_crash("BusFault"); | ||||
| } | ||||
| 
 | ||||
| void UsageFault_Handler(void) { | ||||
|     __asm("bkpt 1"); | ||||
|     while (1) {} | ||||
|     furi_crash("UsageFault"); | ||||
| } | ||||
| 
 | ||||
| void DebugMon_Handler(void) { | ||||
|  | ||||
| @ -140,6 +140,5 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | ||||
| } | ||||
| 
 | ||||
| void vApplicationStackOverflowHook(TaskHandle_t xTask, char * pcTaskName) { | ||||
|     asm("bkpt 1"); | ||||
|     while(1) {}; | ||||
|     furi_crash("StackOverflow"); | ||||
| } | ||||
|  | ||||
| @ -153,3 +153,11 @@ bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime) { | ||||
| 
 | ||||
|     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, | ||||
|     FuriHalRtcRegisterSystemVersion, | ||||
|     FuriHalRtcRegisterLfsFingerprint, | ||||
|     FuriHalRtcRegisterFaultData, | ||||
| } FuriHalRtcRegister; | ||||
| 
 | ||||
| /** Initialize RTC subsystem */ | ||||
| @ -62,6 +63,10 @@ void furi_hal_rtc_get_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 | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -58,7 +58,6 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t | ||||
|     } | ||||
| 
 | ||||
|     if(!ret) { | ||||
|         asm("bkpt 1"); | ||||
|         return HAL_ERROR; | ||||
|     } else { | ||||
|         return HAL_OK; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Albert Kharisov
						Albert Kharisov