From 050fb6a63fb1e8ede5176ee54cc236b5ae727a5e Mon Sep 17 00:00:00 2001 From: dongheng Date: Thu, 21 Mar 2019 17:23:30 +0800 Subject: [PATCH] feat(esp8266): Add esp-idf error number description Commit ID: f49e2afe --- components/esp8266/Kconfig | 10 + components/esp8266/include/esp_err.h | 64 ++- components/esp8266/source/esp_err_to_name.c | 426 ++++++++++++++++++++ components/freertos/port/esp8266/panic.c | 26 +- tools/gen_esp_err_to_name.py | 52 ++- 5 files changed, 538 insertions(+), 40 deletions(-) create mode 100644 components/esp8266/source/esp_err_to_name.c diff --git a/components/esp8266/Kconfig b/components/esp8266/Kconfig index 050f6d85..9fd29c50 100644 --- a/components/esp8266/Kconfig +++ b/components/esp8266/Kconfig @@ -258,6 +258,16 @@ config ESP8266_BOOT_COPY_APP Enable this option, when it is that "OTA1" application is to run after update by OTA, bootloader will copy "OTA1" application to "OTA0" partition and run "OTA0". +config ESP_ERR_TO_NAME_LOOKUP + bool "Enable lookup of error code strings" + default "y" + help + Functions esp_err_to_name() and esp_err_to_name_r() return string + representations of error codes from a pre-generated lookup table. + This option can be used to turn off the use of the look-up table in + order to save memory but this comes at the price of sacrificing + distinguishable (meaningful) output string representations. + endmenu menu WIFI diff --git a/components/esp8266/include/esp_err.h b/components/esp8266/include/esp_err.h index f1fd783d..f1414357 100644 --- a/components/esp8266/include/esp_err.h +++ b/components/esp8266/include/esp_err.h @@ -24,24 +24,23 @@ extern "C" { typedef int32_t esp_err_t; /* Definitions for error constants. */ +#define ESP_OK 0 /*!< esp_err_t value indicating success (no error) */ +#define ESP_FAIL -1 /*!< Generic esp_err_t code indicating failure */ -#define ESP_OK 0 -#define ESP_FAIL -1 +#define ESP_ERR_NO_MEM 0x101 /*!< Out of memory */ +#define ESP_ERR_INVALID_ARG 0x102 /*!< Invalid argument */ +#define ESP_ERR_INVALID_STATE 0x103 /*!< Invalid state */ +#define ESP_ERR_INVALID_SIZE 0x104 /*!< Invalid size */ +#define ESP_ERR_NOT_FOUND 0x105 /*!< Requested resource not found */ +#define ESP_ERR_NOT_SUPPORTED 0x106 /*!< Operation or feature not supported */ +#define ESP_ERR_TIMEOUT 0x107 /*!< Operation timed out */ +#define ESP_ERR_INVALID_RESPONSE 0x108 /*!< Received response was invalid */ +#define ESP_ERR_INVALID_CRC 0x109 /*!< CRC or checksum was invalid */ +#define ESP_ERR_INVALID_VERSION 0x10A /*!< Version was invalid */ +#define ESP_ERR_INVALID_MAC 0x10B /*!< MAC address was invalid */ -#define ESP_ERR_NO_MEM 0x101 -#define ESP_ERR_INVALID_ARG 0x102 -#define ESP_ERR_INVALID_STATE 0x103 -#define ESP_ERR_INVALID_SIZE 0x104 -#define ESP_ERR_NOT_FOUND 0x105 -#define ESP_ERR_NOT_SUPPORTED 0x106 -#define ESP_ERR_TIMEOUT 0x107 -#define ESP_ERR_INVALID_RESPONSE 0x108 -#define ESP_ERR_INVALID_CRC 0x109 -#define ESP_ERR_INVALID_VERSION 0x10A -#define ESP_ERR_INVALID_MAC 0x10B - -#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ -#define ESP_ERR_MESH_BASE 0x4000 /*!< Starting number of MESH error codes */ +#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ +#define ESP_ERR_MESH_BASE 0x4000 /*!< Starting number of MESH error codes */ /** * @brief Returns string for esp_err_t error codes @@ -76,8 +75,12 @@ const char *esp_err_to_name(esp_err_t code); */ const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen); +/** @cond */ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn)); +/** @cond */ +void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression); + #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. @@ -88,6 +91,7 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha #define __ASSERT_FUNC "??" #endif #endif +/** @endcond */ /** * Macro which can be used to check the error code, @@ -101,6 +105,13 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha esp_err_t __err_rc = (x); \ (void) sizeof(__err_rc); \ } while(0); +#elif defined(CONFIG_OPTIMIZATION_ASSERTIONS_SILENT) +#define ESP_ERROR_CHECK(x) do { \ + esp_err_t __err_rc = (x); \ + if (__err_rc != ESP_OK) { \ + abort(); \ + } \ + } while(0); #else #define ESP_ERROR_CHECK(x) do { \ esp_err_t __err_rc = (x); \ @@ -111,6 +122,27 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha } while(0); #endif +/** + * Macro which can be used to check the error code. Prints the error code, error location, and the failed statement to + * serial output. + * In comparison with ESP_ERROR_CHECK(), this prints the same error message but isn't terminating the program. + */ +#ifdef NDEBUG +#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \ + esp_err_t __err_rc = (x); \ + __err_rc; \ + }) +#else +#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \ + esp_err_t __err_rc = (x); \ + if (__err_rc != ESP_OK) { \ + _esp_error_check_failed_without_abort(__err_rc, __ESP_FILE__, __LINE__, \ + __ASSERT_FUNC, #x); \ + } \ + __err_rc; \ + }) +#endif //NDEBUG + #ifdef __cplusplus } #endif diff --git a/components/esp8266/source/esp_err_to_name.c b/components/esp8266/source/esp_err_to_name.c new file mode 100644 index 00000000..7e1b7680 --- /dev/null +++ b/components/esp8266/source/esp_err_to_name.c @@ -0,0 +1,426 @@ +//Do not edit this file because it is autogenerated by gen_esp_err_to_name.py + +#include +#if __has_include("esp_err.h") +#include "esp_err.h" +#endif +#if __has_include("esp_http_client.h") +#include "esp_http_client.h" +#endif +#if __has_include("esp_http_server.h") +#include "esp_http_server.h" +#endif +#if __has_include("esp_image_format.h") +#include "esp_image_format.h" +#endif +#if __has_include("esp_now.h") +#include "esp_now.h" +#endif +#if __has_include("esp_ota_ops.h") +#include "esp_ota_ops.h" +#endif +#if __has_include("esp_ping.h") +#include "esp_ping.h" +#endif +#if __has_include("esp_wifi.h") +#include "esp_wifi.h" +#endif +#if __has_include("esp_wps.h") +#include "esp_wps.h" +#endif +#if __has_include("nvs.h") +#include "nvs.h" +#endif +#if __has_include("spi_flash.h") +#include "spi_flash.h" +#endif +#if __has_include("tcpip_adapter.h") +#include "tcpip_adapter.h" +#endif + +#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP +#define ERR_TBL_IT(err) {err, #err} + +typedef struct { + esp_err_t code; + const char *msg; +} esp_err_msg_t; + +static const esp_err_msg_t esp_err_msg_table[] = { + // components/esp8266/include/esp_err.h +# ifdef ESP_FAIL + ERR_TBL_IT(ESP_FAIL), /* -1 Generic esp_err_t code indicating failure */ +# endif +# ifdef ESP_OK + ERR_TBL_IT(ESP_OK), /* 0 esp_err_t value indicating success (no error) */ +# endif +# ifdef ESP_ERR_NO_MEM + ERR_TBL_IT(ESP_ERR_NO_MEM), /* 257 0x101 Out of memory */ +# endif +# ifdef ESP_ERR_INVALID_ARG + ERR_TBL_IT(ESP_ERR_INVALID_ARG), /* 258 0x102 Invalid argument */ +# endif +# ifdef ESP_ERR_INVALID_STATE + ERR_TBL_IT(ESP_ERR_INVALID_STATE), /* 259 0x103 Invalid state */ +# endif +# ifdef ESP_ERR_INVALID_SIZE + ERR_TBL_IT(ESP_ERR_INVALID_SIZE), /* 260 0x104 Invalid size */ +# endif +# ifdef ESP_ERR_NOT_FOUND + ERR_TBL_IT(ESP_ERR_NOT_FOUND), /* 261 0x105 Requested resource not found */ +# endif +# ifdef ESP_ERR_NOT_SUPPORTED + ERR_TBL_IT(ESP_ERR_NOT_SUPPORTED), /* 262 0x106 Operation or feature not supported */ +# endif +# ifdef ESP_ERR_TIMEOUT + ERR_TBL_IT(ESP_ERR_TIMEOUT), /* 263 0x107 Operation timed out */ +# endif +# ifdef ESP_ERR_INVALID_RESPONSE + ERR_TBL_IT(ESP_ERR_INVALID_RESPONSE), /* 264 0x108 Received response was invalid */ +# endif +# ifdef ESP_ERR_INVALID_CRC + ERR_TBL_IT(ESP_ERR_INVALID_CRC), /* 265 0x109 CRC or checksum was invalid */ +# endif +# ifdef ESP_ERR_INVALID_VERSION + ERR_TBL_IT(ESP_ERR_INVALID_VERSION), /* 266 0x10a Version was invalid */ +# endif +# ifdef ESP_ERR_INVALID_MAC + ERR_TBL_IT(ESP_ERR_INVALID_MAC), /* 267 0x10b MAC address was invalid */ +# endif + // components/nvs_flash/include/nvs.h +# ifdef ESP_ERR_NVS_BASE + ERR_TBL_IT(ESP_ERR_NVS_BASE), /* 4352 0x1100 Starting number of error codes */ +# endif +# ifdef ESP_ERR_NVS_NOT_INITIALIZED + ERR_TBL_IT(ESP_ERR_NVS_NOT_INITIALIZED), /* 4353 0x1101 The storage driver is not initialized */ +# endif +# ifdef ESP_ERR_NVS_NOT_FOUND + ERR_TBL_IT(ESP_ERR_NVS_NOT_FOUND), /* 4354 0x1102 Id namespace doesn’t exist yet and mode is + NVS_READONLY */ +# endif +# ifdef ESP_ERR_NVS_TYPE_MISMATCH + ERR_TBL_IT(ESP_ERR_NVS_TYPE_MISMATCH), /* 4355 0x1103 The type of set or get operation doesn't + match the type of value stored in NVS */ +# endif +# ifdef ESP_ERR_NVS_READ_ONLY + ERR_TBL_IT(ESP_ERR_NVS_READ_ONLY), /* 4356 0x1104 Storage handle was opened as read only */ +# endif +# ifdef ESP_ERR_NVS_NOT_ENOUGH_SPACE + ERR_TBL_IT(ESP_ERR_NVS_NOT_ENOUGH_SPACE), /* 4357 0x1105 There is not enough space in the underlying + storage to save the value */ +# endif +# ifdef ESP_ERR_NVS_INVALID_NAME + ERR_TBL_IT(ESP_ERR_NVS_INVALID_NAME), /* 4358 0x1106 Namespace name doesn’t satisfy constraints */ +# endif +# ifdef ESP_ERR_NVS_INVALID_HANDLE + ERR_TBL_IT(ESP_ERR_NVS_INVALID_HANDLE), /* 4359 0x1107 Handle has been closed or is NULL */ +# endif +# ifdef ESP_ERR_NVS_REMOVE_FAILED + ERR_TBL_IT(ESP_ERR_NVS_REMOVE_FAILED), /* 4360 0x1108 The value wasn’t updated because flash write + operation has failed. The value was written + however, and update will be finished after + re-initialization of nvs, provided that + flash operation doesn’t fail again. */ +# endif +# ifdef ESP_ERR_NVS_KEY_TOO_LONG + ERR_TBL_IT(ESP_ERR_NVS_KEY_TOO_LONG), /* 4361 0x1109 Key name is too long */ +# endif +# ifdef ESP_ERR_NVS_PAGE_FULL + ERR_TBL_IT(ESP_ERR_NVS_PAGE_FULL), /* 4362 0x110a Internal error; never returned by nvs_ API + functions */ +# endif +# ifdef ESP_ERR_NVS_INVALID_STATE + ERR_TBL_IT(ESP_ERR_NVS_INVALID_STATE), /* 4363 0x110b NVS is in an inconsistent state due to a + previous error. Call nvs_flash_init and + nvs_open again, then retry. */ +# endif +# ifdef ESP_ERR_NVS_INVALID_LENGTH + ERR_TBL_IT(ESP_ERR_NVS_INVALID_LENGTH), /* 4364 0x110c String or blob length is not sufficient to + store data */ +# endif +# ifdef ESP_ERR_NVS_NO_FREE_PAGES + ERR_TBL_IT(ESP_ERR_NVS_NO_FREE_PAGES), /* 4365 0x110d NVS partition doesn't contain any empty + pages. This may happen if NVS partition was + truncated. Erase the whole partition and + call nvs_flash_init again. */ +# endif +# ifdef ESP_ERR_NVS_VALUE_TOO_LONG + ERR_TBL_IT(ESP_ERR_NVS_VALUE_TOO_LONG), /* 4366 0x110e String or blob length is longer than + supported by the implementation */ +# endif +# ifdef ESP_ERR_NVS_PART_NOT_FOUND + ERR_TBL_IT(ESP_ERR_NVS_PART_NOT_FOUND), /* 4367 0x110f Partition with specified name is not found + in the partition table */ +# endif + // components/app_update/include/esp_ota_ops.h +# ifdef ESP_ERR_OTA_BASE + ERR_TBL_IT(ESP_ERR_OTA_BASE), /* 5376 0x1500 Base error code for ota_ops api */ +# endif +# ifdef ESP_ERR_OTA_PARTITION_CONFLICT + ERR_TBL_IT(ESP_ERR_OTA_PARTITION_CONFLICT), /* 5377 0x1501 Error if request was to write or erase the + current running partition */ +# endif +# ifdef ESP_ERR_OTA_SELECT_INFO_INVALID + ERR_TBL_IT(ESP_ERR_OTA_SELECT_INFO_INVALID), /* 5378 0x1502 Error if OTA data partition contains invalid + content */ +# endif +# ifdef ESP_ERR_OTA_VALIDATE_FAILED + ERR_TBL_IT(ESP_ERR_OTA_VALIDATE_FAILED), /* 5379 0x1503 Error if OTA app image is invalid */ +# endif + // components/bootloader_support/include/esp_image_format.h +# ifdef ESP_ERR_IMAGE_BASE + ERR_TBL_IT(ESP_ERR_IMAGE_BASE), /* 8192 0x2000 */ +# endif +# ifdef ESP_ERR_IMAGE_FLASH_FAIL + ERR_TBL_IT(ESP_ERR_IMAGE_FLASH_FAIL), /* 8193 0x2001 */ +# endif +# ifdef ESP_ERR_IMAGE_INVALID + ERR_TBL_IT(ESP_ERR_IMAGE_INVALID), /* 8194 0x2002 */ +# endif + // components/esp8266/include/esp_err.h +# ifdef ESP_ERR_WIFI_BASE + ERR_TBL_IT(ESP_ERR_WIFI_BASE), /* 12288 0x3000 Starting number of WiFi error codes */ +# endif + // components/esp8266/include/esp_wifi.h +# ifdef ESP_ERR_WIFI_NOT_INIT + ERR_TBL_IT(ESP_ERR_WIFI_NOT_INIT), /* 12289 0x3001 WiFi driver was not installed by esp_wifi_init */ +# endif +# ifdef ESP_ERR_WIFI_NOT_STARTED + ERR_TBL_IT(ESP_ERR_WIFI_NOT_STARTED), /* 12290 0x3002 WiFi driver was not started by esp_wifi_start */ +# endif +# ifdef ESP_ERR_WIFI_NOT_STOPPED + ERR_TBL_IT(ESP_ERR_WIFI_NOT_STOPPED), /* 12291 0x3003 WiFi driver was not stopped by esp_wifi_stop */ +# endif +# ifdef ESP_ERR_WIFI_IF + ERR_TBL_IT(ESP_ERR_WIFI_IF), /* 12292 0x3004 WiFi interface error */ +# endif +# ifdef ESP_ERR_WIFI_MODE + ERR_TBL_IT(ESP_ERR_WIFI_MODE), /* 12293 0x3005 WiFi mode error */ +# endif +# ifdef ESP_ERR_WIFI_STATE + ERR_TBL_IT(ESP_ERR_WIFI_STATE), /* 12294 0x3006 WiFi internal state error */ +# endif +# ifdef ESP_ERR_WIFI_CONN + ERR_TBL_IT(ESP_ERR_WIFI_CONN), /* 12295 0x3007 WiFi internal control block of station or + soft-AP error */ +# endif +# ifdef ESP_ERR_WIFI_NVS + ERR_TBL_IT(ESP_ERR_WIFI_NVS), /* 12296 0x3008 WiFi internal NVS module error */ +# endif +# ifdef ESP_ERR_WIFI_MAC + ERR_TBL_IT(ESP_ERR_WIFI_MAC), /* 12297 0x3009 MAC address is invalid */ +# endif +# ifdef ESP_ERR_WIFI_SSID + ERR_TBL_IT(ESP_ERR_WIFI_SSID), /* 12298 0x300a SSID is invalid */ +# endif +# ifdef ESP_ERR_WIFI_PASSWORD + ERR_TBL_IT(ESP_ERR_WIFI_PASSWORD), /* 12299 0x300b Password is invalid */ +# endif +# ifdef ESP_ERR_WIFI_TIMEOUT + ERR_TBL_IT(ESP_ERR_WIFI_TIMEOUT), /* 12300 0x300c Timeout error */ +# endif +# ifdef ESP_ERR_WIFI_WAKE_FAIL + ERR_TBL_IT(ESP_ERR_WIFI_WAKE_FAIL), /* 12301 0x300d WiFi is in sleep state(RF closed) and wakeup fail */ +# endif +# ifdef ESP_ERR_WIFI_WOULD_BLOCK + ERR_TBL_IT(ESP_ERR_WIFI_WOULD_BLOCK), /* 12302 0x300e The caller would block */ +# endif +# ifdef ESP_ERR_WIFI_NOT_CONNECT + ERR_TBL_IT(ESP_ERR_WIFI_NOT_CONNECT), /* 12303 0x300f Station still in disconnect status */ +# endif +# ifdef ESP_ERR_WIFI_PM_MODE_OPEN + ERR_TBL_IT(ESP_ERR_WIFI_PM_MODE_OPEN), /* 12306 0x3012 Wifi is in min/max modem sleep mode */ +# endif +# ifdef ESP_ERR_WIFI_FPM_MODE + ERR_TBL_IT(ESP_ERR_WIFI_FPM_MODE), /* 12307 0x3013 Have not enable fpm mode */ +# endif + // components/esp8266/include/esp_wps.h +# ifdef ESP_ERR_WIFI_REGISTRAR + ERR_TBL_IT(ESP_ERR_WIFI_REGISTRAR), /* 12339 0x3033 WPS registrar is not supported */ +# endif +# ifdef ESP_ERR_WIFI_WPS_TYPE + ERR_TBL_IT(ESP_ERR_WIFI_WPS_TYPE), /* 12340 0x3034 WPS type error */ +# endif +# ifdef ESP_ERR_WIFI_WPS_SM + ERR_TBL_IT(ESP_ERR_WIFI_WPS_SM), /* 12341 0x3035 WPS state machine is not initialized */ +# endif + // components/esp8266/include/esp_now.h +# ifdef ESP_ERR_ESPNOW_BASE + ERR_TBL_IT(ESP_ERR_ESPNOW_BASE), /* 12388 0x3064 ESPNOW error number base. */ +# endif +# ifdef ESP_ERR_ESPNOW_NOT_INIT + ERR_TBL_IT(ESP_ERR_ESPNOW_NOT_INIT), /* 12389 0x3065 ESPNOW is not initialized. */ +# endif +# ifdef ESP_ERR_ESPNOW_ARG + ERR_TBL_IT(ESP_ERR_ESPNOW_ARG), /* 12390 0x3066 Invalid argument */ +# endif +# ifdef ESP_ERR_ESPNOW_NO_MEM + ERR_TBL_IT(ESP_ERR_ESPNOW_NO_MEM), /* 12391 0x3067 Out of memory */ +# endif +# ifdef ESP_ERR_ESPNOW_FULL + ERR_TBL_IT(ESP_ERR_ESPNOW_FULL), /* 12392 0x3068 ESPNOW peer list is full */ +# endif +# ifdef ESP_ERR_ESPNOW_NOT_FOUND + ERR_TBL_IT(ESP_ERR_ESPNOW_NOT_FOUND), /* 12393 0x3069 ESPNOW peer is not found */ +# endif +# ifdef ESP_ERR_ESPNOW_INTERNAL + ERR_TBL_IT(ESP_ERR_ESPNOW_INTERNAL), /* 12394 0x306a Internal error */ +# endif +# ifdef ESP_ERR_ESPNOW_EXIST + ERR_TBL_IT(ESP_ERR_ESPNOW_EXIST), /* 12395 0x306b ESPNOW peer has existed */ +# endif +# ifdef ESP_ERR_ESPNOW_IF + ERR_TBL_IT(ESP_ERR_ESPNOW_IF), /* 12396 0x306c Interface error */ +# endif + // components/esp8266/include/esp_err.h +# ifdef ESP_ERR_MESH_BASE + ERR_TBL_IT(ESP_ERR_MESH_BASE), /* 16384 0x4000 Starting number of MESH error codes */ +# endif + // components/tcpip_adapter/include/tcpip_adapter.h +# ifdef ESP_ERR_TCPIP_ADAPTER_BASE + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_BASE), /* 20480 0x5000 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS), /* 20481 0x5001 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY), /* 20482 0x5002 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED), /* 20483 0x5003 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED), /* 20484 0x5004 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED), /* 20485 0x5005 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_NO_MEM + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_NO_MEM), /* 20486 0x5006 */ +# endif +# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED + ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED), /* 20487 0x5007 */ +# endif + // components/lwip/include/lwip/apps/esp_ping.h +# ifdef ESP_ERR_PING_BASE + ERR_TBL_IT(ESP_ERR_PING_BASE), /* 24576 0x6000 */ +# endif +# ifdef ESP_ERR_PING_INVALID_PARAMS + ERR_TBL_IT(ESP_ERR_PING_INVALID_PARAMS), /* 24577 0x6001 */ +# endif +# ifdef ESP_ERR_PING_NO_MEM + ERR_TBL_IT(ESP_ERR_PING_NO_MEM), /* 24578 0x6002 */ +# endif + // components/esp_http_client/include/esp_http_client.h +# ifdef ESP_ERR_HTTP_BASE + ERR_TBL_IT(ESP_ERR_HTTP_BASE), /* 28672 0x7000 Starting number of HTTP error codes */ +# endif +# ifdef ESP_ERR_HTTP_MAX_REDIRECT + ERR_TBL_IT(ESP_ERR_HTTP_MAX_REDIRECT), /* 28673 0x7001 The error exceeds the number of HTTP redirects */ +# endif +# ifdef ESP_ERR_HTTP_CONNECT + ERR_TBL_IT(ESP_ERR_HTTP_CONNECT), /* 28674 0x7002 Error open the HTTP connection */ +# endif +# ifdef ESP_ERR_HTTP_WRITE_DATA + ERR_TBL_IT(ESP_ERR_HTTP_WRITE_DATA), /* 28675 0x7003 Error write HTTP data */ +# endif +# ifdef ESP_ERR_HTTP_FETCH_HEADER + ERR_TBL_IT(ESP_ERR_HTTP_FETCH_HEADER), /* 28676 0x7004 Error read HTTP header from server */ +# endif +# ifdef ESP_ERR_HTTP_INVALID_TRANSPORT + ERR_TBL_IT(ESP_ERR_HTTP_INVALID_TRANSPORT), /* 28677 0x7005 There are no transport support for the input + scheme */ +# endif +# ifdef ESP_ERR_HTTP_CONNECTING + ERR_TBL_IT(ESP_ERR_HTTP_CONNECTING), /* 28678 0x7006 HTTP connection hasn't been established yet */ +# endif +# ifdef ESP_ERR_HTTP_EAGAIN + ERR_TBL_IT(ESP_ERR_HTTP_EAGAIN), /* 28679 0x7007 Mapping of errno EAGAIN to esp_err_t */ +# endif + // components/esp_http_server/include/esp_http_server.h +# ifdef ESP_ERR_HTTPD_BASE + ERR_TBL_IT(ESP_ERR_HTTPD_BASE), /* 32768 0x8000 Starting number of HTTPD error codes */ +# endif +# ifdef ESP_ERR_HTTPD_HANDLERS_FULL + ERR_TBL_IT(ESP_ERR_HTTPD_HANDLERS_FULL), /* 32769 0x8001 All slots for registering URI handlers have + been consumed */ +# endif +# ifdef ESP_ERR_HTTPD_HANDLER_EXISTS + ERR_TBL_IT(ESP_ERR_HTTPD_HANDLER_EXISTS), /* 32770 0x8002 URI handler with same method and target URI + already registered */ +# endif +# ifdef ESP_ERR_HTTPD_INVALID_REQ + ERR_TBL_IT(ESP_ERR_HTTPD_INVALID_REQ), /* 32771 0x8003 Invalid request pointer */ +# endif +# ifdef ESP_ERR_HTTPD_RESULT_TRUNC + ERR_TBL_IT(ESP_ERR_HTTPD_RESULT_TRUNC), /* 32772 0x8004 Result string truncated */ +# endif +# ifdef ESP_ERR_HTTPD_RESP_HDR + ERR_TBL_IT(ESP_ERR_HTTPD_RESP_HDR), /* 32773 0x8005 Response header field larger than supported */ +# endif +# ifdef ESP_ERR_HTTPD_RESP_SEND + ERR_TBL_IT(ESP_ERR_HTTPD_RESP_SEND), /* 32774 0x8006 Error occured while sending response packet */ +# endif +# ifdef ESP_ERR_HTTPD_ALLOC_MEM + ERR_TBL_IT(ESP_ERR_HTTPD_ALLOC_MEM), /* 32775 0x8007 Failed to dynamically allocate memory for + resource */ +# endif +# ifdef ESP_ERR_HTTPD_TASK + ERR_TBL_IT(ESP_ERR_HTTPD_TASK), /* 32776 0x8008 Failed to launch server task/thread */ +# endif + // components/spi_flash/include/spi_flash.h +# ifdef ESP_ERR_FLASH_BASE + ERR_TBL_IT(ESP_ERR_FLASH_BASE), /* 65552 0x10010 */ +# endif +# ifdef ESP_ERR_FLASH_OP_FAIL + ERR_TBL_IT(ESP_ERR_FLASH_OP_FAIL), /* 65553 0x10011 */ +# endif +# ifdef ESP_ERR_FLASH_OP_TIMEOUT + ERR_TBL_IT(ESP_ERR_FLASH_OP_TIMEOUT), /* 65554 0x10012 */ +# endif +}; +#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP + +static const char esp_unknown_msg[] = +#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP + "ERROR"; +#else + "UNKNOWN ERROR"; +#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP + +const char *esp_err_to_name(esp_err_t code) +{ +#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP + int i; + + for (i = 0; i < sizeof(esp_err_msg_table)/sizeof(esp_err_msg_table[0]); ++i) { + if (esp_err_msg_table[i].code == code) { + return esp_err_msg_table[i].msg; + } + } +#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP + + return esp_unknown_msg; +} + +const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen) +{ +#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP + int i; + + for (i = 0; i < sizeof(esp_err_msg_table)/sizeof(esp_err_msg_table[0]); ++i) { + if (esp_err_msg_table[i].code == code) { + strlcpy(buf, esp_err_msg_table[i].msg, buflen); + return buf; + } + } +#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP + + if (strerror_r(code, buf, buflen) == 0) { + return buf; + } + + snprintf(buf, buflen, "%s 0x%x(%d)", esp_unknown_msg, code, code); + + return buf; +} diff --git a/components/freertos/port/esp8266/panic.c b/components/freertos/port/esp8266/panic.c index b5cd083a..2d39756c 100644 --- a/components/freertos/port/esp8266/panic.c +++ b/components/freertos/port/esp8266/panic.c @@ -182,9 +182,27 @@ void __attribute__((noreturn)) panicHandler(void *frame, int wdt) panic_info(frame, wdt); } -void __attribute__((noreturn)) _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) +static void esp_error_check_failed_print(const char *msg, 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); + ets_printf("%s failed: esp_err_t 0x%x", msg, rc); +#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP + ets_printf(" (%s)", esp_err_to_name(rc)); +#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP + ets_printf(" at 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3); + + // ESP8266 put main FreeRTOS code at flash + //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); + //} +} + +void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression) +{ + esp_error_check_failed_print("ESP_ERROR_CHECK_WITHOUT_ABORT", rc, file, line, function, expression); +} + +void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) +{ + esp_error_check_failed_print("ESP_ERROR_CHECK", rc, file, line, function, expression); abort(); -} \ No newline at end of file +} diff --git a/tools/gen_esp_err_to_name.py b/tools/gen_esp_err_to_name.py index 2beb5ac9..ba77ecee 100755 --- a/tools/gen_esp_err_to_name.py +++ b/tools/gen_esp_err_to_name.py @@ -40,17 +40,18 @@ import textwrap import functools # list files here which should not be parsed -ignore_files = [ 'components/mdns/test_afl_fuzz_host/esp32_compat.h' ] +ignore_files = ['components/mdns/test_afl_fuzz_host/esp32_compat.h'] # add directories here which should not be parsed -ignore_dirs = ( 'examples' ) +ignore_dirs = ('examples') # macros from here have higher priorities in case of collisions -priority_headers = [ 'components/esp32/include/esp_err.h' ] +priority_headers = ['components/esp32/include/esp_err.h'] + +err_dict = collections.defaultdict(list) # identified errors are stored here; mapped by the error code +rev_err_dict = dict() # map of error string to error code +unproc_list = list() # errors with unknown codes which depend on other errors -err_dict = collections.defaultdict(list) #identified errors are stored here; mapped by the error code -rev_err_dict = dict() #map of error string to error code -unproc_list = list() #errors with unknown codes which depend on other errors class ErrItem(object): """ @@ -62,13 +63,14 @@ class ErrItem(object): - rel_str - (optional) error string which is a base for the error - rel_off - (optional) offset in relation to the base error """ - def __init__(self, name, file, include_as = None, comment = "", rel_str = "", rel_off = 0): + def __init__(self, name, file, include_as=None, comment="", rel_str="", rel_off=0): self.name = name self.file = file self.include_as = include_as self.comment = comment self.rel_str = rel_str self.rel_off = rel_off + def __str__(self): ret = self.name + " from " + self.file if (self.rel_str != ""): @@ -76,6 +78,7 @@ class ErrItem(object): if self.comment != "": ret += " // " + self.comment return ret + def __cmp__(self, other): if self.file in priority_headers and other.file not in priority_headers: return -1 @@ -99,6 +102,7 @@ class ErrItem(object): else: return 0 + class InputError(RuntimeError): """ Represents and error on the input @@ -106,6 +110,7 @@ class InputError(RuntimeError): def __init__(self, p, e): super(InputError, self).__init__(p + ": " + e) + def process(line, idf_path, include_as): """ Process a line of text from file idf_path (relative to IDF project). @@ -129,18 +134,18 @@ def process(line, idf_path, include_as): m = re.search(r'/\*!<(.+?(?=\*/))', todo_str) if m: comment = m.group(1).strip() - todo_str = todo_str[:m.start()].strip() # keep just the part before the comment + todo_str = todo_str[:m.start()].strip() # keep just the part before the comment # identify possible parentheses () m = re.search(r'\((.+)\)', todo_str) if m: - todo_str = m.group(1) #keep what is inside the parentheses + todo_str = m.group(1) # keep what is inside the parentheses # identify BASE error code, e.g. from the form BASE + 0x01 m = re.search(r'\s*(\w+)\s*\+(.+)', todo_str) if m: - related = m.group(1) # BASE - todo_str = m.group(2) # keep and process only what is after "BASE +" + related = m.group(1) # BASE + todo_str = m.group(2) # keep and process only what is after "BASE +" # try to match a hexadecimal number m = re.search(r'0x([0-9A-Fa-f]+)', todo_str) @@ -153,8 +158,8 @@ def process(line, idf_path, include_as): num = int(m.group(1), 10) elif re.match(r'\w+', todo_str): # It is possible that there is no number, e.g. #define ERROR BASE - related = todo_str # BASE error - num = 0 # (BASE + 0) + related = todo_str # BASE error + num = 0 # (BASE + 0) else: raise InputError(idf_path, "Cannot parse line %s" % line) @@ -168,6 +173,7 @@ def process(line, idf_path, include_as): # Store the information available now and compute the error code later unproc_list.append(ErrItem(words[1], idf_path, include_as, comment, related, num)) + def process_remaining_errors(): """ Create errors which could not be processed before because the error code @@ -180,7 +186,6 @@ def process_remaining_errors(): for item in unproc_list: if item.rel_str in rev_err_dict: base_num = rev_err_dict[item.rel_str] - base = err_dict[base_num][0] num = base_num + item.rel_off err_dict[num].append(ErrItem(item.name, item.file, item.include_as, item.comment)) rev_err_dict[item.name] = num @@ -189,6 +194,7 @@ def process_remaining_errors(): del unproc_list[:] + def path_to_include(path): """ Process the path (relative to the IDF project) in a form which can be used @@ -207,7 +213,8 @@ def path_to_include(path): # no include in the path -> use just the filename return os.path.basename(path) else: - return os.sep.join(spl_path[i+1:]) # subdirectories and filename in "include" + return os.sep.join(spl_path[i + 1:]) # subdirectories and filename in "include" + def print_warning(error_list, error_code): """ @@ -217,6 +224,7 @@ def print_warning(error_list, error_code): for e in error_list: print(" " + str(e)) + def max_string_width(): max = 0 for k in err_dict: @@ -226,6 +234,7 @@ def max_string_width(): max = x return max + def generate_c_output(fin, fout): """ Writes the output to fout based on th error dictionary err_dict and @@ -247,7 +256,7 @@ def generate_c_output(fin, fout): include_list = list(includes) include_list.sort() - max_width = max_string_width() + 17 + 1 # length of " ERR_TBL_IT()," with spaces is 17 + max_width = max_string_width() + 17 + 1 # length of " ERR_TBL_IT()," with spaces is 17 max_decdig = max(len(str(k)) for k in err_dict) for line in fin: @@ -271,7 +280,7 @@ def generate_c_output(fin, fout): fout.write("# ifdef %s\n" % e.name) fout.write(table_line) hexnum_length = 0 - if k > 0: # negative number and zero should be only ESP_FAIL and ESP_OK + if k > 0: # negative number and zero should be only ESP_FAIL and ESP_OK hexnum = " 0x%x" % k hexnum_length = len(hexnum) fout.write(hexnum) @@ -280,7 +289,7 @@ def generate_c_output(fin, fout): fout.write(" %s" % e.comment) else: indent = " " * (len(table_line) + hexnum_length + 1) - w = textwrap.wrap(e.comment, width=120, initial_indent = indent, subsequent_indent = indent) + w = textwrap.wrap(e.comment, width=120, initial_indent=indent, subsequent_indent=indent) # this couldn't be done with initial_indent because there is no initial_width option fout.write(" %s" % w[0].strip()) for i in range(1, len(w)): @@ -289,6 +298,7 @@ def generate_c_output(fin, fout): else: fout.write(line) + def generate_rst_output(fout): for k in sorted(err_dict.keys()): v = err_dict[k][0] @@ -301,6 +311,7 @@ def generate_rst_output(fout): fout.write(': {}'.format(v.comment)) fout.write('\n\n') + def main(): if 'IDF_PATH' in os.environ: idf_path = os.environ['IDF_PATH'] @@ -308,8 +319,8 @@ def main(): idf_path = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) parser = argparse.ArgumentParser(description='ESP32 esp_err_to_name lookup generator for esp_err_t') - parser.add_argument('--c_input', help='Path to the esp_err_to_name.c.in template input.', default=idf_path + '/components/esp32/esp_err_to_name.c.in') - parser.add_argument('--c_output', help='Path to the esp_err_to_name.c output.', default=idf_path + '/components/esp32/esp_err_to_name.c') + parser.add_argument('--c_input', help='Path to the esp_err_to_name.c.in template input.', default=idf_path + '/components/esp8266/source/esp_err_to_name.c.in') + parser.add_argument('--c_output', help='Path to the esp_err_to_name.c output.', default=idf_path + '/components/esp8266/source/esp_err_to_name.c') parser.add_argument('--rst_output', help='Generate .rst output and save it into this file') args = parser.parse_args() @@ -348,5 +359,6 @@ def main(): with open(args.c_input, 'r', encoding='utf-8') as fin, open(args.c_output, 'w', encoding='utf-8') as fout: generate_c_output(fin, fout) + if __name__ == "__main__": main()