Line data Source code
1 : /* 2 : AP_InternalError holds information about "should not happen" errors 3 : that have occured within ArduPilot. This covers things like code 4 : paths that should not be crossed or pointers being null when they 5 : really, really shouldn't be. It does NOT cover things like losing 6 : GPS lock at inopportune times - that's just bad luck, not bad 7 : programming. 8 : 9 : This program is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : This program is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU General Public License for more details. 18 : 19 : You should have received a copy of the GNU General Public License 20 : along with this program. If not, see <http://www.gnu.org/licenses/>. 21 : */ 22 : 23 : #pragma once 24 : 25 : #include "AP_InternalError_config.h" 26 : 27 : #if AP_INTERNALERROR_ENABLED 28 : 29 : #include <stdint.h> 30 : 31 : class AP_InternalError { 32 : public: 33 : // internal error counters. Do not set these unless it is a 34 : // *true* internal error - a thread locking up, a codepath which 35 : // should never be taken, a code-sanity-check failing, that sort 36 : // of thing. Examples of what NOT to put in here - sd card 37 : // filling up, bad input received from GCS, GPS unit was working 38 : // and now is not. 39 : 40 : // note that this map is an internal ArduPilot fixture and is 41 : // prone to change at regular intervals. The meanings of these 42 : // bits can change day-to-day. 43 : enum class error_t : uint32_t { // Hex Decimal 44 : logger_mapfailure = (1U << 0), // 0x00001 1 45 : logger_missing_logstructure = (1U << 1), // 0x00002 2 46 : logger_logwrite_missingfmt = (1U << 2), // 0x00004 4 47 : logger_too_many_deletions = (1U << 3), // 0x00008 8 48 : logger_bad_getfilename = (1U << 4), // 0x00010 16 49 : panic = (1U << 5), // 0x00020 32 50 : logger_flushing_without_sem = (1U << 6), // 0x00040 64 51 : logger_bad_current_block = (1U << 7), // 0x00080 128 52 : logger_blockcount_mismatch = (1U << 8), // 0x00100 256 53 : logger_dequeue_failure = (1U << 9), // 0x00200 512 54 : constraining_nan = (1U << 10), // 0x00400 1024 55 : watchdog_reset = (1U << 11), // 0x00800 2048 56 : iomcu_reset = (1U << 12), // 0x01000 4096 57 : iomcu_fail = (1U << 13), // 0x02000 8192 58 : spi_fail = (1U << 14), // 0x04000 16384 59 : main_loop_stuck = (1U << 15), // 0x08000 32768 60 : gcs_bad_missionprotocol_link= (1U << 16), // 0x10000 65536 61 : bitmask_range = (1U << 17), // 0x20000 131072 62 : gcs_offset = (1U << 18), // 0x40000 262144 63 : i2c_isr = (1U << 19), // 0x80000 524288 64 : flow_of_control = (1U << 20), //0x100000 1048576 for generic we-should-never-get-here situations 65 : switch_full_sector_recursion= (1U << 21), //0x200000 2097152 66 : bad_rotation = (1U << 22), //0x400000 4194304 67 : stack_overflow = (1U << 23), //0x800000 8388608 68 : imu_reset = (1U << 24), //0x1000000 16777216 69 : gpio_isr = (1U << 25), //0x2000000 33554432 70 : mem_guard = (1U << 26), //0x4000000 67108864 71 : dma_fail = (1U << 27), //0x8000000 134217728 72 : params_restored = (1U << 28), //0x10000000 268435456 73 : invalid_arg_or_result = (1U << 29), //0x20000000 536870912 74 : __LAST__ = (1U << 30), // used only for sanity check 75 : }; 76 : 77 : // if you've changed __LAST__ to be 32, then you will want to 78 : // rejig the way we do sanity checks as we don't want to move to a 79 : // 64-bit type for error_t: 80 : static_assert(sizeof(error_t) == 4, "error_t should be 32-bit type"); 81 : 82 18697 : uint16_t last_error_line() const { return last_line; } 83 : 84 : void error(const AP_InternalError::error_t error, uint16_t line); 85 : 86 : // fill buffer with a description of the exceptions present in 87 : // internal errors. buffer will always be null-terminated. 88 : void errors_as_string(uint8_t *buffer, uint16_t len) const; 89 : 90 : // convert an error code to a string 91 : void error_to_string(char *buffer, uint16_t len, error_t error_code) const; 92 : 93 1135604 : uint32_t count() const { return total_error_count; } 94 : 95 : // internal_errors - return mask of internal errors seen 96 43061129 : uint32_t errors() const { 97 43061129 : return internal_errors; 98 : } 99 : 100 : private: 101 : 102 : // bitmask holding errors from internal_error_t 103 : uint32_t internal_errors; 104 : 105 : uint32_t total_error_count; 106 : uint16_t last_line; 107 : }; 108 : 109 : namespace AP { 110 : AP_InternalError &internalerror(); 111 : }; 112 : 113 : #define INTERNAL_ERROR(error_number) \ 114 : AP::internalerror().error(error_number, __AP_LINE__); 115 : 116 : // INTERNAL_ERROR_IN_SITL: like INTERNAL_ERROR but only raises the 117 : // error when running in SITL. Use this for conditions that indicate 118 : // a programming error but are not expected to occur on real hardware. 119 : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL 120 : #define INTERNAL_ERROR_IN_SITL(error_number) INTERNAL_ERROR(error_number) 121 : #else 122 : #define INTERNAL_ERROR_IN_SITL(error_number) 123 : #endif 124 : 125 : #else // AP_INTERNALERROR_ENABLED is false 126 : #define INTERNAL_ERROR(error_number) 127 : #define INTERNAL_ERROR_IN_SITL(error_number) 128 : #endif // AP_INTERNALERROR_ENABLED