diff --git a/libraries/AP_InternalError/AP_InternalError.cpp b/libraries/AP_InternalError/AP_InternalError.cpp
new file mode 100644
index 0000000000..2718f252f7
--- /dev/null
+++ b/libraries/AP_InternalError/AP_InternalError.cpp
@@ -0,0 +1,21 @@
+#include "AP_InternalError.h"
+
+// actually create the instance:
+static AP_InternalError instance;
+
+void AP_InternalError::error(const AP_InternalError::error_t e) {
+#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
+ AP_HAL::panic("internal error %u", uint8_t(e));
+#endif
+ internal_errors |= uint32_t(e);
+}
+
+
+namespace AP {
+
+AP_InternalError &internalerror()
+{
+ return instance;
+}
+
+};
diff --git a/libraries/AP_InternalError/AP_InternalError.h b/libraries/AP_InternalError/AP_InternalError.h
new file mode 100644
index 0000000000..50abaf5df7
--- /dev/null
+++ b/libraries/AP_InternalError/AP_InternalError.h
@@ -0,0 +1,63 @@
+/*
+ AP_InternalError holds information about "should not happen" errors
+ that have occured within ArduPilot. This covers things like code
+ paths that should not be crossed or pointers being null when they
+ really, really shouldn't be. It does NOT cover things like losing
+ GPS lock at inopportune times - that's just bad luck, not bad
+ programming.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+
+class AP_InternalError {
+public:
+ // internal error counters. Do not set these unless it is a
+ // *true* internal error - a thread locking up, a codepath which
+ // should never be taken, a code-sanity-check failing, that sort
+ // of thing. Examples of what NOT to put in here - sd card
+ // filling up, bad input received from GCS, GPS unit was working
+ // and now is not.
+ enum class error_t {
+ logger_mapfailure = (1U << 0),
+ logger_missing_logstructure = (1U << 1),
+ logger_logwrite_missingfmt = (1U << 2),
+ logger_too_many_deletions = (1U << 3),
+ logger_bad_getfilename = (1U << 4),
+ logger_stopping_without_sem = (1U << 5),
+ logger_flushing_without_sem = (1U << 6),
+ logger_bad_current_block = (1U << 7),
+ logger_blockcount_mismatch = (1U << 8),
+ logger_dequeue_failure = (1U << 9),
+ };
+
+ void error(const AP_InternalError::error_t error);
+
+ // internal_errors - return mask of internal errors seen
+ uint32_t errors() const {
+ return internal_errors;
+ }
+
+private:
+
+ // bitmask holding errors from internal_error_t
+ uint32_t internal_errors;
+};
+
+namespace AP {
+ AP_InternalError &internalerror();
+};