Line data Source code
1 : #include "AP_InternalError_config.h"
2 :
3 : #if AP_INTERNALERROR_ENABLED
4 :
5 : #include "AP_InternalError.h"
6 :
7 : #include <AP_HAL/HAL.h>
8 : #include <AP_HAL/Util.h>
9 :
10 : #include <stdio.h>
11 :
12 : extern const AP_HAL::HAL &hal;
13 :
14 : // actually create the instance:
15 : static AP_InternalError instance;
16 :
17 49 : void AP_InternalError::error(const AP_InternalError::error_t e, uint16_t line) {
18 : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL && defined(HAL_DEBUG_BUILD)
19 1 : switch (e) {
20 1 : case AP_InternalError::error_t::watchdog_reset:
21 : case AP_InternalError::error_t::main_loop_stuck:
22 : case AP_InternalError::error_t::params_restored:
23 : // don't panic on these to facilitate watchdog testing
24 1 : break;
25 0 : default:
26 : char buffer[50];
27 0 : AP::internalerror().error_to_string(buffer, ARRAY_SIZE(buffer), e);
28 0 : AP_HAL::panic("AP_InternalError::error_t::%s", buffer);
29 : }
30 : #endif
31 : #if CONFIG_HAL_BOARD == HAL_BOARD_ESP32
32 : if (e == AP_InternalError::error_t::imu_reset) return;// don't worry about this for esp32
33 : #endif
34 49 : internal_errors |= uint32_t(e);
35 49 : total_error_count++;
36 49 : last_line = line;
37 :
38 49 : hal.util->persistent_data.internal_errors = internal_errors;
39 49 : hal.util->persistent_data.internal_error_count = total_error_count;
40 49 : hal.util->persistent_data.internal_error_last_line = line;
41 49 : }
42 :
43 : static const char * const error_bit_descriptions[] {
44 : "mapfailure", // logger_mapfailure
45 : "miss_struct", // logger_missing_logstructure
46 : "write_mssfmt", // logger_logwrite_missingfmt
47 : "many_deletes", // logger_too_many_deletions
48 : "bad_getfile", // logger_bad_getfilename
49 : "panic",
50 : "flush_no_sem", // logger_flushing_without_sem
51 : "bad_curr_blk", // logger_bad_current_block
52 : "blkcnt_bad", // logger_blockcount_mismatch
53 : "dq_failure", // logger_dequeue_failure
54 : "cnstring_nan", // constraining_nan
55 : "watchdog_rst", // watchdog_reset
56 : "iomcu_reset",
57 : "iomcu_fail",
58 : "spi_fail",
59 : "main_loop_stk", // main_loop_stuck
60 : "gcs_bad_link", // gcs_bad_missionprotocol_link
61 : "bitmask_range",
62 : "gcs_offset",
63 : "i2c_isr",
64 : "flow_of_ctrl", // flow_of_control
65 : "sfs_recursion", // switch_full_sector_recursion
66 : "bad_rotation",
67 : "stack_ovrflw", // stack_overflow
68 : "imu_reset", // imu_reset
69 : "gpio_isr",
70 : "mem_guard",
71 : "dma_fail",
72 : "params_restored",
73 : "invalid arguments",
74 : };
75 :
76 : static_assert((1U<<(ARRAY_SIZE(error_bit_descriptions))) == uint32_t(AP_InternalError::error_t::__LAST__), "too few descriptions for bits");
77 :
78 0 : void AP_InternalError::error_to_string(char *buffer, const uint16_t len, error_t error_code) const
79 : {
80 0 : uint32_t temp = log2f(int(error_code));
81 0 : strncpy(buffer, error_bit_descriptions[temp], len - 1);
82 0 : }
83 :
84 40 : void AP_InternalError::errors_as_string(uint8_t *buffer, const uint16_t len) const
85 : {
86 40 : buffer[0] = 0;
87 40 : uint32_t buffer_used = 0;
88 40 : const char *format = "%s"; // no comma before the first item
89 1240 : for (uint8_t i=0; i<ARRAY_SIZE(error_bit_descriptions); i++) {
90 1200 : if (buffer_used >= len) {
91 0 : break;
92 : }
93 1200 : if (internal_errors & (1U<<i)) {
94 40 : const int written = hal.util->snprintf((char*)&buffer[buffer_used],
95 40 : len-buffer_used,
96 : format,
97 40 : error_bit_descriptions[i]);
98 40 : format = ",%s"; // once we write something, need commas thereafter
99 :
100 40 : if (written < 0) {
101 0 : break;
102 : }
103 40 : buffer_used += written;
104 : }
105 : }
106 40 : }
107 :
108 : namespace AP {
109 :
110 44215519 : AP_InternalError &internalerror()
111 : {
112 44215519 : return instance;
113 : }
114 :
115 : };
116 : #endif // AP_INTERNALERROR_ENABLED
|