esp_err: Use separate code path for ESP_ERROR_CHECK assertion
* Minimum code size overhead * Makes function safe to use when flash cache is disabled Builds on #339 https://github.com/espressif/esp-idf/pull/339
This commit is contained in:
parent
50f414f54c
commit
8ab96b13af
4 changed files with 53 additions and 14 deletions
|
@ -11,10 +11,10 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
#ifndef __ESP_ERR_H__
|
#pragma once
|
||||||
#define __ESP_ERR_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -40,22 +40,38 @@ typedef int32_t esp_err_t;
|
||||||
|
|
||||||
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
|
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
|
||||||
|
|
||||||
|
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn));
|
||||||
|
|
||||||
|
#ifndef __ASSERT_FUNC
|
||||||
|
/* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which
|
||||||
|
uses /usr/include/assert.h or equivalent.
|
||||||
|
*/
|
||||||
|
#ifdef __ASSERT_FUNCTION
|
||||||
|
#define __ASSERT_FUNC __ASSERT_FUNCTION /* used in glibc assert.h */
|
||||||
|
#else
|
||||||
|
#define __ASSERT_FUNC "??"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Macro which can be used to check the error code,
|
* Macro which can be used to check the error code,
|
||||||
* and terminate the program in case the code is not ESP_OK.
|
* and terminate the program in case the code is not ESP_OK.
|
||||||
* Prints the failed statement to serial output.
|
* Prints the error code, error location, and the failed statement to serial output.
|
||||||
*
|
*
|
||||||
* Note: this macro is not safe to use if flash cache
|
* Disabled if assertions are disabled.
|
||||||
* may be disabled.
|
|
||||||
*/
|
*/
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define ESP_ERROR_CHECK(x)
|
#define ESP_ERROR_CHECK(x) do { (x); } while (0)
|
||||||
#else
|
#else
|
||||||
#define ESP_ERROR_CHECK(x) do { esp_err_t rc = (x); if (rc != ESP_OK) { ESP_LOGE("err", "esp_err_t = %d", rc); assert(0 && #x);} } while(0);
|
#define ESP_ERROR_CHECK(x) do { \
|
||||||
|
esp_err_t rc = (x); \
|
||||||
|
if (rc != ESP_OK) { \
|
||||||
|
_esp_error_check_failed(rc, __FILE__, __LINE__, \
|
||||||
|
__ASSERT_FUNC, #x); \
|
||||||
|
} \
|
||||||
|
} while(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ESP_ERR_H__ */
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_core_dump.h"
|
#include "esp_core_dump.h"
|
||||||
|
#include "esp_spi_flash.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
|
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
|
||||||
|
@ -107,11 +108,8 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, s
|
||||||
|
|
||||||
static bool abort_called;
|
static bool abort_called;
|
||||||
|
|
||||||
void abort()
|
static __attribute__((noreturn)) inline void invoke_abort()
|
||||||
{
|
{
|
||||||
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
|
||||||
ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
|
|
||||||
#endif
|
|
||||||
abort_called = true;
|
abort_called = true;
|
||||||
while(1) {
|
while(1) {
|
||||||
__asm__ ("break 0,0");
|
__asm__ ("break 0,0");
|
||||||
|
@ -119,6 +117,14 @@ void abort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void abort()
|
||||||
|
{
|
||||||
|
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||||
|
ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
|
||||||
|
#endif
|
||||||
|
invoke_abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *edesc[] = {
|
static const char *edesc[] = {
|
||||||
"IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError",
|
"IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError",
|
||||||
|
@ -441,4 +447,11 @@ void esp_clear_watchpoint(int no)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
|
||||||
|
{
|
||||||
|
ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at 0x%08x\n", rc, (intptr_t)__builtin_return_address(0) - 3);
|
||||||
|
if (spi_flash_cache_enabled()) { // strings may be in flash cache
|
||||||
|
ets_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
|
||||||
|
}
|
||||||
|
invoke_abort();
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ TEST_PROGRAM=test_nvs
|
||||||
all: $(TEST_PROGRAM)
|
all: $(TEST_PROGRAM)
|
||||||
|
|
||||||
SOURCE_FILES = \
|
SOURCE_FILES = \
|
||||||
|
esp_error_check_stub.cpp \
|
||||||
$(addprefix ../src/, \
|
$(addprefix ../src/, \
|
||||||
nvs_types.cpp \
|
nvs_types.cpp \
|
||||||
nvs_api.cpp \
|
nvs_api.cpp \
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "catch.hpp"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
|
||||||
|
{
|
||||||
|
printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at %p\n", rc, __builtin_return_address(0));
|
||||||
|
printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
|
||||||
|
abort();
|
||||||
|
}
|
Loading…
Reference in a new issue