check.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "check.h"
  2. #include "common_defines.h"
  3. #include <furi_hal_console.h>
  4. #include <furi_hal_power.h>
  5. #include <furi_hal_rtc.h>
  6. #include <stdio.h>
  7. #include <FreeRTOS.h>
  8. #include <task.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. PLACE_IN_SECTION("MB_MEM2") const char* __furi_check_message = NULL;
  12. PLACE_IN_SECTION("MB_MEM2") uint32_t __furi_check_registers[12] = {0};
  13. /** Load r12 value to __furi_check_message and store registers to __furi_check_registers */
  14. #define GET_MESSAGE_AND_STORE_REGISTERS() \
  15. asm volatile("ldr r11, =__furi_check_message \n" \
  16. "str r12, [r11] \n" \
  17. "ldr r12, =__furi_check_registers \n" \
  18. "stm r12, {r0-r11} \n" \
  19. : \
  20. : \
  21. : "memory");
  22. // Restore registers and halt MCU
  23. #define RESTORE_REGISTERS_AND_HALT_MCU() \
  24. asm volatile("ldr r12, =__furi_check_registers \n" \
  25. "ldm r12, {r0-r11} \n" \
  26. "loop%=: \n" \
  27. "bkpt 0x00 \n" \
  28. "wfi \n" \
  29. "b loop%= \n" \
  30. : \
  31. : \
  32. : "memory");
  33. extern size_t xPortGetTotalHeapSize(void);
  34. extern size_t xPortGetFreeHeapSize(void);
  35. extern size_t xPortGetMinimumEverFreeHeapSize(void);
  36. static void __furi_put_uint32_as_text(uint32_t data) {
  37. char tmp_str[] = "-2147483648";
  38. itoa(data, tmp_str, 10);
  39. furi_hal_console_puts(tmp_str);
  40. }
  41. static void __furi_print_stack_info() {
  42. furi_hal_console_puts("\r\n\tstack watermark: ");
  43. __furi_put_uint32_as_text(uxTaskGetStackHighWaterMark(NULL) * 4);
  44. }
  45. static void __furi_print_heap_info() {
  46. furi_hal_console_puts("\r\n\t heap total: ");
  47. __furi_put_uint32_as_text(xPortGetTotalHeapSize());
  48. furi_hal_console_puts("\r\n\t heap free: ");
  49. __furi_put_uint32_as_text(xPortGetFreeHeapSize());
  50. furi_hal_console_puts("\r\n\t heap watermark: ");
  51. __furi_put_uint32_as_text(xPortGetMinimumEverFreeHeapSize());
  52. }
  53. static void __furi_print_name(bool isr) {
  54. if(isr) {
  55. furi_hal_console_puts("[ISR ");
  56. __furi_put_uint32_as_text(__get_IPSR());
  57. furi_hal_console_puts("] ");
  58. } else {
  59. const char* name = pcTaskGetName(NULL);
  60. if(name == NULL) {
  61. furi_hal_console_puts("[main] ");
  62. } else {
  63. furi_hal_console_puts("[");
  64. furi_hal_console_puts(name);
  65. furi_hal_console_puts("] ");
  66. }
  67. }
  68. }
  69. FURI_NORETURN void __furi_crash() {
  70. __disable_irq();
  71. GET_MESSAGE_AND_STORE_REGISTERS();
  72. bool isr = FURI_IS_IRQ_MODE();
  73. if(__furi_check_message == NULL) {
  74. __furi_check_message = "Fatal Error";
  75. }
  76. furi_hal_console_puts("\r\n\033[0;31m[CRASH]");
  77. __furi_print_name(isr);
  78. furi_hal_console_puts(__furi_check_message);
  79. if(!isr) {
  80. __furi_print_stack_info();
  81. }
  82. __furi_print_heap_info();
  83. #ifdef FURI_DEBUG
  84. furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n");
  85. furi_hal_console_puts("\033[0m\r\n");
  86. RESTORE_REGISTERS_AND_HALT_MCU();
  87. #else
  88. furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message);
  89. furi_hal_console_puts("\r\nRebooting system.\r\n");
  90. furi_hal_console_puts("\033[0m\r\n");
  91. furi_hal_power_reset();
  92. #endif
  93. __builtin_unreachable();
  94. }
  95. FURI_NORETURN void __furi_halt() {
  96. __disable_irq();
  97. GET_MESSAGE_AND_STORE_REGISTERS();
  98. bool isr = FURI_IS_IRQ_MODE();
  99. if(__furi_check_message == NULL) {
  100. __furi_check_message = "System halt requested.";
  101. }
  102. furi_hal_console_puts("\r\n\033[0;31m[HALT]");
  103. __furi_print_name(isr);
  104. furi_hal_console_puts(__furi_check_message);
  105. furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n");
  106. furi_hal_console_puts("\033[0m\r\n");
  107. RESTORE_REGISTERS_AND_HALT_MCU();
  108. __builtin_unreachable();
  109. }