From f8af0c1509245e1bce3d9651a138db8490d69c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Sun, 23 Oct 2022 00:21:10 +0900 Subject: [PATCH] [FL-2892] Gui: update statusbar attention icon and better crash handling (#1908) * Gui: update statusbar attention icon * Furi: snapshot registers on crash and restore in halt * Furi: document check routines --- applications/services/gui/gui.c | 4 +- assets/icons/StatusBar/Alert_9x8.png | Bin 0 -> 3611 bytes assets/icons/StatusBar/Hidden_window_9x8.png | Bin 0 -> 3604 bytes firmware/targets/f7/api_symbols.csv | 9 ++-- furi/core/check.c | 45 ++++++++++++----- furi/core/check.h | 49 ++++++++++++++----- 6 files changed, 78 insertions(+), 29 deletions(-) create mode 100644 assets/icons/StatusBar/Alert_9x8.png create mode 100644 assets/icons/StatusBar/Hidden_window_9x8.png diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c index 0535b32b..8c5ed91a 100644 --- a/applications/services/gui/gui.c +++ b/applications/services/gui/gui.c @@ -152,7 +152,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { } // Extra notification if(need_attention) { - width = icon_get_width(&I_Attention_5x8); + width = icon_get_width(&I_Hidden_window_9x8); // Prepare work area background canvas_frame_set( gui->canvas, @@ -166,7 +166,7 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) { // Draw Icon canvas_frame_set( gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT); - canvas_draw_icon(gui->canvas, 0, 0, &I_Attention_5x8); + canvas_draw_icon(gui->canvas, 0, 0, &I_Hidden_window_9x8); // Recalculate next position left_used += (width + 2); x += (width + 2); diff --git a/assets/icons/StatusBar/Alert_9x8.png b/assets/icons/StatusBar/Alert_9x8.png new file mode 100644 index 0000000000000000000000000000000000000000..d03f107ef1e957fdc15c896c2f65d52ec691f9b3 GIT binary patch literal 3611 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 T?I80e8v&Rb+u+JDu3`TM+ZHm< literal 0 HcmV?d00001 diff --git a/assets/icons/StatusBar/Hidden_window_9x8.png b/assets/icons/StatusBar/Hidden_window_9x8.png new file mode 100644 index 0000000000000000000000000000000000000000..d6fc2b326d03d5b6a3dbabb1d5ed3a8a0140d35f GIT binary patch literal 3604 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 M%FN!h6ytIA-_)%w8UO$Q literal 0 HcmV?d00001 diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index d0dfcbfa..188cd748 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,3.6,, +Version,+,4.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -260,6 +260,8 @@ Function,-,__eprintf,void,"const char*, const char*, unsigned int, const char*" Function,+,__errno,int*, Function,-,__fpclassifyd,int,double Function,-,__fpclassifyf,int,float +Function,+,__furi_crash,void, +Function,+,__furi_halt,void, Function,-,__getdelim,ssize_t,"char**, size_t*, int, FILE*" Function,-,__getline,ssize_t,"char**, size_t*, FILE*" Function,-,__isinfd,int,double @@ -891,7 +893,6 @@ Function,-,ftello,off_t,FILE* Function,-,ftrylockfile,int,FILE* Function,-,funlockfile,void,FILE* Function,-,funopen,FILE*,"const void*, int (*)(void*, char*, int), int (*)(void*, const char*, int), fpos_t (*)(void*, fpos_t, int), int (*)(void*)" -Function,+,furi_crash,void,const char* Function,+,furi_delay_ms,void,uint32_t Function,+,furi_delay_tick,void,uint32_t Function,+,furi_delay_until_tick,FuriStatus,uint32_t @@ -1308,7 +1309,6 @@ Function,+,furi_hal_version_uid,const uint8_t*, Function,+,furi_hal_version_uid_size,size_t, Function,-,furi_hal_vibro_init,void, Function,+,furi_hal_vibro_on,void,_Bool -Function,+,furi_halt,void,const char* Function,-,furi_init,void, Function,+,furi_kernel_get_tick_frequency,uint32_t, Function,+,furi_kernel_lock,int32_t, @@ -2674,6 +2674,7 @@ Variable,+,A_iButton_14,const Icon, Variable,-,ITM_RxBuffer,volatile int32_t, Variable,+,I_125_10px,const Icon, Variable,+,I_ActiveConnection_50x64,const Icon, +Variable,+,I_Alert_9x8,const Icon, Variable,+,I_ArrowC_1_36x36,const Icon, Variable,+,I_ArrowDownEmpty_14x15,const Icon, Variable,+,I_ArrowDownFilled_14x15,const Icon, @@ -2741,6 +2742,7 @@ Variable,+,I_HeatHi_25x27,const Icon, Variable,+,I_HeatHi_hvr_25x27,const Icon, Variable,+,I_HeatLo_25x27,const Icon, Variable,+,I_HeatLo_hvr_25x27,const Icon, +Variable,+,I_Hidden_window_9x8,const Icon, Variable,+,I_InfraredArrowDown_4x8,const Icon, Variable,+,I_InfraredArrowUp_4x8,const Icon, Variable,+,I_InfraredLearnShort_128x31,const Icon, @@ -2841,6 +2843,7 @@ Variable,+,I_update_10px,const Icon, Variable,-,MSIRangeTable,const uint32_t[16], Variable,-,SmpsPrescalerTable,const uint32_t[4][6], Variable,+,SystemCoreClock,uint32_t, +Variable,+,__furi_check_message,const char*, Variable,+,_ctype_,const char[], Variable,+,_global_impure_ptr,_reent*, Variable,+,_impure_ptr,_reent*, diff --git a/furi/core/check.c b/furi/core/check.c index 613b52f4..ed38038a 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -11,6 +11,9 @@ #include #include +PLACE_IN_SECTION("MB_MEM2") const char* __furi_check_message = NULL; +PLACE_IN_SECTION("MB_MEM2") uint32_t __furi_check_registers[12] = {0}; + extern size_t xPortGetTotalHeapSize(void); extern size_t xPortGetFreeHeapSize(void); extern size_t xPortGetMinimumEverFreeHeapSize(void); @@ -52,8 +55,10 @@ static void __furi_print_name(bool isr) { } } -static FURI_NORETURN void __furi_halt() { +static FURI_NORETURN void __furi_halt_mcu() { + register const void* r12 asm ("r12") = (void*)__furi_check_registers; asm volatile( + "ldm r12, {r0-r11} \n" #ifdef FURI_DEBUG "bkpt 0x00 \n" #endif @@ -61,22 +66,29 @@ static FURI_NORETURN void __furi_halt() { "wfi \n" "b loop%= \n" : - : + : "r" (r12) : "memory"); __builtin_unreachable(); } -FURI_NORETURN void furi_crash(const char* message) { +FURI_NORETURN void __furi_crash() { + register const void* r12 asm ("r12") = (void*)__furi_check_registers; + asm volatile( + "stm r12, {r0-r11} \n" + : + : "r" (r12) + : "memory"); + bool isr = FURI_IS_ISR(); __disable_irq(); - if(message == NULL) { - message = "Fatal Error"; + if(__furi_check_message == NULL) { + __furi_check_message = "Fatal Error"; } furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); __furi_print_name(isr); - furi_hal_console_puts(message); + furi_hal_console_puts(__furi_check_message); if(!isr) { __furi_print_stack_info(); @@ -86,9 +98,9 @@ FURI_NORETURN void furi_crash(const char* 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_halt(); + __furi_halt_mcu(); #else - furi_hal_rtc_set_fault_data((uint32_t)message); + furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message); furi_hal_console_puts("\r\nRebooting system.\r\n"); furi_hal_console_puts("\033[0m\r\n"); furi_hal_power_reset(); @@ -96,18 +108,25 @@ FURI_NORETURN void furi_crash(const char* message) { __builtin_unreachable(); } -FURI_NORETURN void furi_halt(const char* message) { +FURI_NORETURN void __furi_halt() { + register const void* r12 asm ("r12") = (void*)__furi_check_registers; + asm volatile( + "stm r12, {r0-r11} \n" + : + : "r" (r12) + : "memory"); + bool isr = FURI_IS_ISR(); __disable_irq(); - if(message == NULL) { - message = "System halt requested."; + if(__furi_check_message == NULL) { + __furi_check_message = "System halt requested."; } furi_hal_console_puts("\r\n\033[0;31m[HALT]"); __furi_print_name(isr); - furi_hal_console_puts(message); + furi_hal_console_puts(__furi_check_message); furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n"); furi_hal_console_puts("\033[0m\r\n"); - __furi_halt(); + __furi_halt_mcu(); } diff --git a/furi/core/check.h b/furi/core/check.h index 30efdf01..e77891f7 100644 --- a/furi/core/check.h +++ b/furi/core/check.h @@ -8,25 +8,52 @@ extern "C" { #define FURI_NORETURN noreturn #endif +/** Pointer to pass message to __furi_crash and __furi_halt */ +extern const char* __furi_check_message; + +/** Crash system */ +FURI_NORETURN void __furi_crash(); + +/** Halt system */ +FURI_NORETURN void __furi_halt(); + +/** Crash system with message. Show message after reboot. */ +#define furi_crash(message) \ + do { \ + __furi_check_message = message; \ + __furi_crash(); \ + } while(0) + +/** Halt system with message. */ +#define furi_halt(message) \ + do { \ + __furi_check_message = message; \ + __furi_halt(); \ + } while(0) + /** Check condition and crash if check failed */ -#define furi_check(__e) ((__e) ? (void)0 : furi_crash("furi_check failed\r\n")) +#define furi_check(__e) \ + do { \ + if ((__e) == 0) { \ + furi_crash("furi_check failed\r\n"); \ + } \ + } while(0) /** Only in debug build: Assert condition and crash if assert failed */ #ifdef FURI_DEBUG -#define furi_assert(__e) ((__e) ? (void)0 : furi_crash("furi_assert failed\r\n")) +#define furi_assert(__e) \ + do { \ + if ((__e) == 0) { \ + furi_crash("furi_assert failed\r\n"); \ + } \ + } while(0) #else -#define furi_assert(__e) \ - do { \ - ((void)(__e)); \ +#define furi_assert(__e) \ + do { \ + ((void)(__e)); \ } while(0) #endif -/** Crash system */ -FURI_NORETURN void furi_crash(const char* message); - -/** Halt system */ -FURI_NORETURN void furi_halt(const char* message); - #ifdef __cplusplus } #endif