# 错误代码和辅助函数

[English]

本节列出了 ESP-IDF 中常见错误代码的定义，以及部分与错误处理相关的辅助函数。

有关 ESP-IDF 中错误代码的基本信息，请参阅 错误处理。

有关 ESP-IDF 定义的错误代码的完整列表，请参阅 错误代码参考。

## 注册错误码

ESP-IDF 使用可组合的错误码注册系统，在构建时自动从所有组件中收集错误码定义。这使得 `esp_err_to_name()` 和 `esp_err_to_name_r()` 能够查找整个项目中定义的错误码，而无需手动维护中央注册表。

### 工作原理

错误码在链接时通过名为 `.esp_err_msg_tbl` 的链接器段进行注册。在组件的头文件中定义错误码后，需要将这些头文件注册到构建系统中，构建系统将会：

1. 在构建过程中提取错误码定义

2. 生成 C 代码，将错误码放入 `.esp_err_msg_tbl` 段

3. 自动将生成的 C 代码链接到应用程序中

链接器会将所有组件中的错误码条目收集到一个数组中，供 `esp_err_to_name()` 在运行时查找。

### 注册组件的错误码

要注册组件中的错误码，请在组件的 `CMakeLists.txt` 中添加以下内容：

    idf_define_esp_err_codes(HEADERS include/my_component.h)

将 `include/my_component.h` 替换为包含错误码定义的头文件路径。可以指定多个头文件：

    idf_define_esp_err_codes(HEADERS
        include/my_api.h
        include/my_driver.h
    )

构建系统将自动处理这些头文件，并注册所有符合错误码命名规则的 `#define` 指令（通常以 `ESP_ERR_` 或类似前缀开头）。

### 示例

在组件的头文件 `include/my_component.h` 中：

    #pragma once

    #include "esp_err.h"

    #define ESP_ERR_MY_COMPONENT_BASE    0x7000
    #define ESP_ERR_MY_COMPONENT_INIT    (ESP_ERR_MY_COMPONENT_BASE + 1)  /*!< Component initialization failed */
    #define ESP_ERR_MY_COMPONENT_BUSY    (ESP_ERR_MY_COMPONENT_BASE + 2)  /*!< Component is busy */

在组件的 `CMakeLists.txt` 中：

    idf_component_register(SRCS "my_component.c"
                          INCLUDE_DIRS "include"
                          PRIV_REQUIRES esp_common)

    # Register error codes
    idf_define_esp_err_codes(HEADERS include/my_component.h)

构建项目后，调用 `esp_err_to_name(ESP_ERR_MY_COMPONENT_INIT)` 将返回字符串 `"ESP_ERR_MY_COMPONENT_INIT"`。

备注

大多数 ESP-IDF 组件的错误码已经完成注册，只有在为自定义组件注册错误码，或向现有组件添加新错误码时，才需要添加 `idf_define_esp_err_codes()`。

## API 参考

### Header File

- components/esp_common/include/esp_check.h

- This header file can be included with:

  >     #include "esp_check.h"

### Macros

ESP_RETURN_ON_ERROR(x, log_tag, format, ...)

  Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns. In the future, we want to switch to C++20. We also want to become compatible with clang. Hence, we provide two versions of the following macros. The first one is using the GNU extension ##__VA_ARGS__. The second one is using the C++20 feature VA_OPT(,). This allows users to compile their code with standard C++20 enabled instead of the GNU extension. Below C++20, we haven't found any good alternative to using ##__VA_ARGS__. Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns.

ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...)

  A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.

ESP_RETURN_VOID_ON_ERROR(x, log_tag, format, ...)

  Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns. This macro is used when the function returns void.

ESP_RETURN_VOID_ON_ERROR_ISR(x, log_tag, format, ...)

  A version of ESP_RETURN_VOID_ON_ERROR() macro that can be called from ISR.

ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...)

  Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message, sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.

ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...)

  A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.

ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...)

  Macro which can be used to check the condition. If the condition is not 'true', it prints the message and returns with the supplied 'err_code'.

ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...)

  A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.

ESP_RETURN_VOID_ON_FALSE(a, log_tag, format, ...)

  Macro which can be used to check the condition. If the condition is not 'true', it prints the message and returns without a value.

ESP_RETURN_VOID_ON_FALSE_ISR(a, log_tag, format, ...)

  A version of ESP_RETURN_VOID_ON_FALSE() macro that can be called from ISR.

ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...)

  Macro which can be used to check the condition. If the condition is not 'true', it prints the message, sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.

ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...)

  A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.

ESP_RETURN_ON_ERROR_CLEANUP(x, ...)

  Evaluate an esp_err_t expression, run cleanup on error, and return.

  Evaluates `x` once and stores the result in a local variable `err_rc_`. If the result is not ESP_OK, the macro:

  - executes the code passed in `__VA_ARGS__` (e.g., cleanup functions or logging),

  - returns `err_rc_` from the current function. The cleanup code can freely use `err_rc_`.

  Example:

      esp_err_t initialize_device(void)
      {
      // Simple case: single cleanup action
          ESP_RETURN_ON_ERROR_CLEANUP(open_device("/dev/adc0"), close_device());

      // Multiple cleanup actions
          ESP_RETURN_ON_ERROR_CLEANUP(
              allocate_buffer(4096),
              free_buffer(),
              close_device(),
              printf("Failed to initialize sensor: %s\n", esp_err_to_name(err_rc_))
          );

      // Complex cleanup with conditional logic and ESP_LOG logging
          ESP_RETURN_ON_ERROR_CLEANUP(
              calibrate_sensor(),
      do {
      if (err_rc_ == ESP_ERR_INVALID_STATE) {
                     ESP_LOGE(TAG, "Sensor in invalid state during calibration");}
                  }
                  free_buffer();
                  close_device();
                  ESP_LOGE(TAG, "Drop connection");
              } while (0)
          );

      return ESP_OK;
      }

### Header File

- components/esp_common/include/esp_err.h

- This header file can be included with:

  >     #include "esp_err.h"

### Functions

const char *esp_err_to_name(esp_err_t code)

  Returns string for esp_err_t error codes.

  This function finds the error code in a lookup-table populated at link time and returns its string representation.

  Components register their error codes by calling idf_define_esp_err_codes() in their CMakeLists.txt. The build system extracts error codes from the specified headers and generates entries placed in the .esp_err_msg_tbl linker section.

  参数:

    code -- esp_err_t error code

  返回:

    string error message

const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen)

  Returns string for esp_err_t and system error codes.

  This function finds the error code in a lookup-table populated at link time and returns its string representation. If the error code is not found then it is attempted to be found among system errors.

  Components register their error codes by calling idf_define_esp_err_codes() in their CMakeLists.txt.

  参数:

    - code -- esp_err_t error code

    - buf -- [out] buffer where the error message should be written

    - buflen -- Size of buffer buf. At most buflen bytes are written into the buf buffer (including the terminating null byte).

  返回:

    buf containing the string error message

### Macros

ESP_OK

  esp_err_t value indicating success (no error)

ESP_FAIL

  Generic esp_err_t code indicating failure

ESP_ERR_NO_MEM

  Out of memory

ESP_ERR_INVALID_ARG

  Invalid argument

ESP_ERR_INVALID_STATE

  Invalid state

ESP_ERR_INVALID_SIZE

  Invalid size

ESP_ERR_NOT_FOUND

  Requested resource not found

ESP_ERR_NOT_SUPPORTED

  Operation or feature not supported

ESP_ERR_TIMEOUT

  Operation timed out

ESP_ERR_INVALID_RESPONSE

  Received response was invalid

ESP_ERR_INVALID_CRC

  CRC or checksum was invalid

ESP_ERR_INVALID_VERSION

  Version was invalid

ESP_ERR_INVALID_MAC

  MAC address was invalid

ESP_ERR_NOT_FINISHED

  Operation has not fully completed

ESP_ERR_NOT_ALLOWED

  Operation is not allowed

ESP_ERR_WIFI_BASE

  Starting number of WiFi error codes

ESP_ERR_MESH_BASE

  Starting number of MESH error codes

ESP_ERR_FLASH_BASE

  Starting number of flash error codes

ESP_ERR_HW_CRYPTO_BASE

  Starting number of HW cryptography module error codes

ESP_ERR_MEMPROT_BASE

  Starting number of Memory Protection API error codes

ESP_ERROR_CHECK(x)

  Macro which can be used to check the error code, and terminate the program in case the code is not ESP_OK. Prints the error code, error location, and the failed statement to serial output.

  Disabled if assertions are disabled.

ESP_ERROR_CHECK_WITHOUT_ABORT(x)

  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.

### Type Definitions

typedef int esp_err_t

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。