From 66c3265a2691c29f7e9cd4b9cfcc8eea32612e37 Mon Sep 17 00:00:00 2001 From: Wang Zi Yan Date: Thu, 8 Jun 2023 16:32:26 +0800 Subject: [PATCH] Docs: Translate api-conventions.rst --- docs/en/api-reference/api-conventions.rst | 71 +++++---- docs/zh_CN/api-reference/api-conventions.rst | 152 ++++++++++++++++++- 2 files changed, 186 insertions(+), 37 deletions(-) diff --git a/docs/en/api-reference/api-conventions.rst b/docs/en/api-reference/api-conventions.rst index 2bd376b5bbfb..710e0e2a9c30 100644 --- a/docs/en/api-reference/api-conventions.rst +++ b/docs/en/api-reference/api-conventions.rst @@ -1,5 +1,6 @@ API Conventions =============== +:link_to_translation:`zh_CN:[中文]` .. highlight:: c @@ -7,28 +8,28 @@ This document describes conventions and assumptions common to ESP-IDF Applicatio ESP-IDF provides several kinds of programming interfaces: -* C functions, structures, enums, type definitions and preprocessor macros declared in public header files of ESP-IDF components. Various pages in the API Reference section of the programming guide contain descriptions of these functions, structures and types. -* Build system functions, predefined variables and options. These are documented in the :ref:`build system guide`. -* :doc:`Kconfig ` options can can be used in code and in the build system (CMakeLists.txt) files. -* :doc:`Host tools <../api-guides/tools/index>` and their command line parameters are also part of ESP-IDF interface. +* C functions, structures, enums, type definitions, and preprocessor macros declared in public header files of ESP-IDF components. Various pages in the API Reference section of the programming guide contain descriptions of these functions, structures, and types. +* Build system functions, predefined variables, and options. These are documented in the :ref:`ESP-IDF CMake Build System API `. +* :doc:`Kconfig ` options can be used in code and in the build system (``CMakeLists.txt``) files. +* :doc:`Host tools <../api-guides/tools/index>` and their command line parameters are also part of the ESP-IDF interfaces. -ESP-IDF consists of components written specifically for ESP-IDF as well as third-party libraries. In some cases, an ESP-IDF-specific wrapper is added to the third-party library, providing an interface that is either simpler or better integrated with the rest of ESP-IDF facilities. In other cases, the original API of the third-party library is presented to the application developers. +ESP-IDF is made up of multiple components where these components either contain code specifically written for ESP chips, or contain a third-party library (i.e., a third-party component). In some cases, third-party components will contain an "ESP-IDF specific" wrapper in order to provide an interface that is either simpler or better integrated with the rest of ESP-IDF's features. In other cases, third-party components will present the original API of the underlying library directly. -Following sections explain some of the aspects of ESP-IDF APIs and their usage. +The following sections explain some of the aspects of ESP-IDF APIs and their usage. -Error handling +Error Handling -------------- -Most ESP-IDF APIs return error codes defined with ``esp_err_t`` type. See :doc:`Error Handling <../api-guides/error-handling>` section for more information about error handling approaches. :doc:`Error Code Reference ` contains the list of error codes returned by ESP-IDF components. +Most ESP-IDF APIs return error codes defined with the :cpp:type:`esp_err_t` type. See :doc:`Error Handling <../api-guides/error-handling>` section for more information about error handling approaches. :doc:`Error Codes Reference ` contains the list of error codes returned by ESP-IDF components. .. _api_reference_config_structures: -Configuration structures +Configuration Structures ------------------------ -.. important:: Correct initialization of configuration structures is an important part in making the application compatible with future versions of ESP-IDF. +.. important:: Correct initialization of configuration structures is an important part of making the application compatible with future versions of ESP-IDF. -Most initialization or configuration functions in ESP-IDF take as an argument a pointer to a configuration structure. For example:: +Most initialization, configuration, and installation functions in ESP-IDF (typically named ``..._init()``, ``..._config()``, and ``..._install()``) take a configuration structure pointer as an argument. For example:: const esp_timer_create_args_t my_timer_args = { .callback = &my_timer_callback, @@ -38,7 +39,7 @@ Most initialization or configuration functions in ESP-IDF take as an argument a esp_timer_handle_t my_timer; esp_err_t err = esp_timer_create(&my_timer_args, &my_timer); -Initialization functions never store the pointer to the configuration structure, so it is safe to allocate the structure on the stack. +These functions never store the pointer to the configuration structure, so it is safe to allocate the structure on the stack. The application must initialize all fields of the structure. The following is incorrect:: @@ -47,14 +48,14 @@ The application must initialize all fields of the structure. The following is in /* Incorrect! Fields .arg and .name are not initialized */ esp_timer_create(&my_timer_args, &my_timer); -Most ESP-IDF examples use C99 `designated initializers`_ for structure initialization, since they provide a concise way of setting a subset of fields, and zero-initializing the remaining fields:: +Most ESP-IDF examples use C99 `designated initializers`_ for structure initialization since they provide a concise way of setting a subset of fields, and zero-initializing the remaining fields:: const esp_timer_create_args_t my_timer_args = { .callback = &my_timer_callback, /* Correct, fields .arg and .name are zero-initialized */ }; -The C++ language supports designated initializers syntax, too, but the initializers must be in the order of declaration. When using ESP-IDF APIs in C++ code, you may consider using the following pattern:: +The C++ language supports designated initializer syntax, too, but the initializers must be in the order of declaration. When using ESP-IDF APIs in C++ code, you may consider using the following pattern:: /* Correct, fields .dispatch_method, .name and .skip_unhandled_events are zero-initialized */ const esp_timer_create_args_t my_timer_args = { @@ -68,21 +69,19 @@ The C++ language supports designated initializers syntax, too, but the initializ // .callback = &my_timer_callback, //}; -For more information on designated initializers, see :ref:`Designated initializers `. Note that C++ language versions older than C++20 (not the default in the current version of ESP-IDF) do not support designated initializers. If you have to compile code with an older C++ standard than C++20, you may use GCC extensions to produce the following pattern:: +For more information on designated initializers, see :ref:`cplusplus_designated_initializers`. Note that C++ language versions older than C++20, which are not the default in the current version of ESP-IDF, do not support designated initializers. If you have to compile code with an older C++ standard than C++20, you may use GCC extensions to produce the following pattern:: esp_timer_create_args_t my_timer_args = {}; /* All the fields are zero-initialized */ my_timer_args.callback = &my_timer_callback; -Default initializers +Default Initializers ^^^^^^^^^^^^^^^^^^^^ For some configuration structures, ESP-IDF provides macros for setting default values of fields:: httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - /* HTTPD_DEFAULT_CONFIG expands to a designated initializer. - Now all fields are set to the default values. - Any field can still be modified: */ + /* HTTPD_DEFAULT_CONFIG expands to a designated initializer. Now all fields are set to the default values, and any field can still be modified: */ config.server_port = 8081; httpd_handle_t server; esp_err_t err = httpd_start(&server, &config); @@ -94,58 +93,58 @@ It is recommended to use default initializer macros whenever they are provided f Private APIs ------------ -Certain header files in ESP-IDF contain APIs intended to be used only in ESP-IDF source code, and not by the applications. Such header files often contain ``private`` or ``esp_private`` in their name or path. Certain components, such as :doc:`hal <../api-guides/hardware-abstraction>` only contain private APIs. +Certain header files in ESP-IDF contain APIs intended to be used only in ESP-IDF source code rather than by the applications. Such header files often contain ``private`` or ``esp_private`` in their name or path. Certain components, such as :doc:`hal <../api-guides/hardware-abstraction>` only contain private APIs. Private APIs may be removed or changed in an incompatible way between minor or patch releases. .. _api_reference_example_components: -Components in example projects +Components in Example Projects ------------------------------ -ESP-IDF examples contain a variety of projects demonstrating usage of ESP-IDF APIs. In order to reduce code duplication in the examples, a few common helpers are defined inside components that are used by multiple examples. This includes components located in :example:`common_components` directory, as well as some of the components located in the examples themselves. These components are not considered to be part of the ESP-IDF API. +ESP-IDF examples contain a variety of projects demonstrating the usage of ESP-IDF APIs. In order to reduce code duplication in the examples, a few common helpers are defined inside components that are used by multiple examples. This includes components located in :example:`common_components` directory, as well as some of the components located in the examples themselves. These components are not considered to be part of the ESP-IDF API. -It is not recommended to reference these components directly in custom projects (via ``EXTRA_COMPONENT_DIRS`` build system variable), as they may change significantly between ESP-IDF versions. When starting a new project based on an ESP-IDF example, copy both the project and the common components it depends on out of ESP-IDF, and treat the common components as part of the project. Note that the common components are written with examples in mind, and might not include all the error handling required for production applications. Take time to read the code and understand if it applicable to your use case. +It is not recommended to reference these components directly in custom projects (via ``EXTRA_COMPONENT_DIRS`` build system variable), as they may change significantly between ESP-IDF versions. When starting a new project based on an ESP-IDF example, copy both the project and the common components it depends on out of ESP-IDF, and treat the common components as part of the project. Note that the common components are written with examples in mind, and might not include all the error handling required for production applications. Before using, take time to read the code and understand if it is applicable to your use case. API Stability ------------- -ESP-IDF uses `Semantic Versioning `_ as explained in the :ref:`versions page`. +ESP-IDF uses `Semantic Versioning `_ as explained in the :ref:`Versioning Scheme `. Minor and bugfix releases of ESP-IDF guarantee compatibility with previous releases. The sections below explain different aspects and limitations to compatibility. -Source level compatibility +Source-level Compatibility ^^^^^^^^^^^^^^^^^^^^^^^^^^ -ESP-IDF guarantees source level compatibility of C functions, structures, enums, type definitions and preprocessor macros declared in public header files of ESP-IDF components. Source level compatibility implies that the application can be recompiled with the newer version of ESP-IDF without changes. +ESP-IDF guarantees source-level compatibility of C functions, structures, enums, type definitions, and preprocessor macros declared in public header files of ESP-IDF components. Source-level compatibility implies that the application source code can be recompiled with the newer version of ESP-IDF without changes. -The following changes are allowed between minor versions and do not break source level compatibility: +The following changes are allowed between minor versions and do not break source-level compatibility: -* Deprecating functions (using the ``deprecated`` attribute) and header files (using a preprocessor ``#warning``). Deprecations are listed in ESP-IDF relese notes. It is recommended to update the source code to use the newer functions or files that replace the deprecated ones, however this is not mandatory. Deprecated functions and files can be removed in major versions of ESP-IDF. +* Deprecating functions (using the ``deprecated`` attribute) and header files (using a preprocessor ``#warning``). Deprecations are listed in ESP-IDF release notes. It is recommended to update the source code to use the newer functions or files that replace the deprecated ones, however, this is not mandatory. Deprecated functions and files can be removed from major versions of ESP-IDF. * Renaming components, moving source and header files between components — provided that the build system ensures that correct files are still found. -* Renaming Kconfig options. Kconfig system :ref:`renaming mechanism ` ensures that the original Kconfig option names can still be used by the application in ``sdkconfig`` file, CMake files and source code. +* Renaming Kconfig options. Kconfig system's :ref:`backward compatibility ` ensures that the original Kconfig option names can still be used by the application in ``sdkconfig`` file, CMake files, and source code. -Lack of binary compatibility +Lack of Binary Compatibility ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -ESP-IDF does not guarantee binary compatibility between releases. This means that if a precompiled library is built with one ESP-IDF version, it is not guaranteed to work the same way with the next minor or bugfix release. The following are the possible changes that keep source level compatibility but not binary compatibility: +ESP-IDF does not guarantee binary compatibility between releases. This means that if a precompiled library is built with one ESP-IDF version, it is not guaranteed to work the same way with the next minor or bugfix release. The following are the possible changes that keep source-level compatibility but not binary compatibility: * Changing numerical values for C enum members. * Adding new structure members or changing the order of members. See :ref:`api_reference_config_structures` for tips that help ensure compatibility. * Replacing an ``extern`` function with a ``static inline`` one with the same signature, or vice versa. * Replacing a function-like macro with a compatible C function. -Other exceptions from compatibility +Other Exceptions from Compatibility ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -While we try to make upgrading to a new ESP-IDF version easy, there are parts of ESP-IDF that may change between minor versions in an incompatible way. We appreciate issue reports about any unintended breaking changes that don't fall into the categories below. +While we try to make upgrading to a new ESP-IDF version easy, there are parts of ESP-IDF that may change between minor versions in an incompatible way. We appreciate issuing reports about any unintended breaking changes that don't fall into the categories below. * :ref:`api_reference_private_apis`. * :ref:`api_reference_example_components`. * Features clearly marked as "beta", "preview", or "experimental". -* Changes made to mitigate security issues or to replace insecure default behaviors with a secure ones. -* Features which were never functional. For example, if it was never possible to use a certain function or an enumeration value, it may get renamed (as part of fixing it) or removed. This includes software features which depend on non-functional chip hardware features. -* Unexpected or undefined behavior (for example, due to missing validation of argument ranges) that is not documented explicitly may be fixed/changed. +* Changes made to mitigate security issues or to replace insecure default behaviors with secure ones. +* Features that were never functional. For example, if it was never possible to use a certain function or an enumeration value, it may get renamed (as part of fixing it) or removed. This includes software features that depend on non-functional chip hardware features. +* Unexpected or undefined behavior that is not documented explicitly may be fixed/changed, such as due to missing validation of argument ranges. * Location of :doc:`Kconfig ` options in menuconfig. * Location and names of example projects. diff --git a/docs/zh_CN/api-reference/api-conventions.rst b/docs/zh_CN/api-reference/api-conventions.rst index 90d6a5e63f8c..51a99bb69051 100644 --- a/docs/zh_CN/api-reference/api-conventions.rst +++ b/docs/zh_CN/api-reference/api-conventions.rst @@ -1 +1,151 @@ -.. include:: ../../en/api-reference/api-conventions.rst +API 约定 +=============== +:link_to_translation:`en:[English]` + +.. highlight:: c + +本文介绍了 ESP-IDF 应用程序编程接口 (API) 中常见的约定和假设。 + +ESP-IDF 提供了几种编程接口: + +* 在 ESP-IDF 组件的公共头文件中声明的 C 函数、结构体、枚举、类型定义和预处理器宏。编程指南的 API 参考部分描述了这些函数、结构体和类型。 +* 编译系统函数、预定义变量和选项,详情请参阅 :ref:`ESP-IDF CMake 构建系统 API `。 +* :doc:`Kconfig ` 选项,可用于代码及编译系统文件 (``CMakeLists.txt``)。 +* :doc:`主机工具 <../api-guides/tools/index>` 及其命令行参数。 + +ESP-IDF 由多个组件组成,组件中包含专门为 ESP 芯片编写的代码或第三方库(即第三方组件)。对于某些第三方库,ESP-IDF 提供专用的包装器和接口,以简化对第三方库的使用,或提高其与 ESP-IDF 其他功能的兼容性。某些情况下,第三方组件将直接呈现底层库的原始 API。 + +以下各节介绍了部分 ESP-IDF API 及其使用的相关内容。 + +错误处理 +-------------- + +多数 ESP-IDF API 会返回由 :cpp:type:`esp_err_t` 类型定义的错误代码。有关出错处理的更多信息,请参阅 :doc:`错误处理 <../api-guides/error-handling>` 部分。有关 ESP-IDF 组件返回的错误代码列表,请参阅 :doc:`错误代码参考 `。 + +.. _api_reference_config_structures: + +配置结构体 +------------------------ + +.. important:: 为确保应用程序与未来 ESP-IDF 版本的兼容性,请正确初始化配置结构体。 + +多数 ESP-IDF 中的初始化、配置和安装函数(通常以 ``..._init()``、 ``..._config()`` 和 ``..._install()`` 命名)都需要一个指向配置结构体的指针作为参数。例如:: + + const esp_timer_create_args_t my_timer_args = { + .callback = &my_timer_callback, + .arg = callback_arg, + .name = "my_timer" + }; + esp_timer_handle_t my_timer; + esp_err_t err = esp_timer_create(&my_timer_args, &my_timer); + +初始化函数不会存储指向配置结构体的指针,因此在栈上分配结构体是安全的。 + +应用程序必须初始化结构体的所有字段,以下为错误示例:: + + esp_timer_create_args_t my_timer_args; + my_timer_args.callback = &my_timer_callback; + /* 错误! 字段 .arg 和 .name 未初始化 */ + esp_timer_create(&my_timer_args, &my_timer); + +大多数 ESP-IDF 示例使用 C99 的 `指定初始化器`_ 来完成结构体初始化,从而以简洁的方式设置子集字段,并将剩余字段初始化为零:: + + const esp_timer_create_args_t my_timer_args = { + .callback = &my_timer_callback, + /* 正确,字段 .arg 和 .name 已初始化为零 */ + }; + +C++ 语言同样支持指定初始化器语法,但初始化器必须遵循声明顺序。在 C++ 代码中使用 ESP-IDF API 时,可以考虑使用以下模式:: + + /* 正确:.dispatch_method、.name 以及 .skip_unhandled_events 初始化为零 */ + const esp_timer_create_args_t my_timer_args = { + .callback = &my_timer_callback, + .arg = &my_arg, + }; + + ///* 错误:esp_timer_create_args_t 中,.arg 在 .callback 之后声明 */ + //const esp_timer_create_args_t my_timer_args = { + // .arg = &my_arg, + // .callback = &my_timer_callback, + //}; + +了解指定初始化器的更多信息,请参见 :ref:`cplusplus_designated_initializers`。注意,C++20 之前的 C++ 语言不是当前 ESP-IDF 的默认版本,不支持指定初始化器。如需使用 C++20 之前的 C++ 标准编译代码,可以借助 GCC 扩展生成以下模式:: + + esp_timer_create_args_t my_timer_args = {}; + /* 所有字段初始化为零 */ + my_timer_args.callback = &my_timer_callback; + +默认初始化器 +^^^^^^^^^^^^^^^^^^^^ + +ESP-IDF 为某些配置结构体提供了用于设置字段默认值的宏:: + + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + /* HTTPD_DEFAULT_CONFIG 扩展到一个指定的初始化器。此时,所有字段均已设置为默认值,且支持编辑:*/ + config.server_port = 8081; + httpd_handle_t server; + esp_err_t err = httpd_start(&server, &config); + +当特定配置结构体提供了默认初始化器宏时,推荐使用该默认初始化器宏。 + +.. _api_reference_private_apis: + +私有 API +------------ + +在 ESP-IDF 中,某些头文件包含的 API 仅限于在 ESP-IDF 源代码中使用,不支持在应用程序中使用。此类头文件的名称或路径通常带有 ``private`` 或 ``esp_private``。某些组件(如 :doc:`hal <../api-guides/hardware-abstraction>`)则仅包含私有 API。 + +私有 API 可能在次要或补丁版本之间以不兼容的方式被删除或更改。 + +.. _api_reference_example_components: + +示例项目组件 +------------------------------ + +ESP-IDF 示例中提供了一系列演示 ESP-IDF API 使用方式的工程。为避免在各个示例中重复引用相同的代码片段,示例的常用组件中定义了一些通用辅助工具。这些常用组件包括 :example:`common_components` 目录下的组件和示例本身的部分组件,它们不属于 ESP-IDF API 的范畴。 + +不建议在自定义项目中通过 ``EXTRA_COMPONENT_DIRS`` 编译系统变量直接引用这些组件,因为在不同的 ESP-IDF 版本中,组件可能存在显著变化。基于 ESP-IDF 示例开始新项目时,需将项目及其所依赖的公共组件从 ESP-IDF 中复制出来,并将公共组件视为项目的一部分。请注意,公共组件是针对示例编写的,可能不包括生产应用程序所需的所有出错处理。在使用前,需阅读代码并判断它是否适用于所需用例。 + +API 稳定性 +------------- + +ESP-IDF 使用 `语义版本管理办法 `_ ,详情请参阅 :ref:`版本管理 `。 + +ESP-IDF 的次要版本和错误修复版本会保证与过往版本的兼容性。以下各节解释了兼容性的不同方面和限制。 + +源代码级别兼容性 +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ESP-IDF 确保在 ESP-IDF 组件的公共头文件中声明的 C 函数、结构体、枚举、类型定义和预处理宏的源代码级别兼容性。源代码级别兼容性意味着应用程序无需修改即可在新版本的 ESP-IDF 上重新编译。 + +以下在次要版本之间的更改不会破坏源代码级别兼容性: + +* 使用 ``deprecated`` 属性废弃函数、使用预处理器 ``#warning`` 废弃头文件。废弃功能已在 ESP-IDF 发布说明中列出。建议更新源代码以使用替换被废弃的函数或文件的新函数或文件。ESP-IDF 的主要版本将移除废弃的函数和文件。 +* 重命名组件,在组件间移动源代码和头文件,但需确保编译系统仍可以找到正确的文件。 +* 重命名 Kconfig 选项。Kconfig 系统的 :ref:`向后兼容性 ` 确保应用程序在 ``sdkconfig`` 文件、CMake 文件和源代码中仍然可以使用原始的 Kconfig 选项名称。 + +缺少二进制兼容性 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ESP-IDF 无法确保版本间的二进制兼容性。这意味着,如果使用某个 ESP-IDF 版本构建了一个预编译库,在下一个次要或错误修复版本中,无法确保该库将以相同方式运行。以下更改可以保持源代码级别兼容性,但不保证二进制兼容性: + +* 更改 C 枚举成员的数值。 +* 添加新的结构体成员或更改成员顺序。关于有助于确保兼容性的提示,请参阅 :ref:`api_reference_config_structures`。 +* 用具有相同签名的 ``static inline`` 函数替换 ``extern`` 函数,反之亦然。 +* 用兼容的 C 函数替换类似于函数的宏。 + +其他不兼容情况 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +尽管我们致力于让 ESP-IDF 版本升级更加容易,但是在次要版本之间,ESP-IDF 的某些部分可能会以不兼容的方式发生更改。如有不属于下列情况的意外重大更新,欢迎向我们发送报告: + +* :ref:`api_reference_private_apis`。 +* :ref:`api_reference_example_components`。 +* 明确标记为 "beta"、"preview" 或 "experimental" 的功能。 +* 为缓解安全问题做出的更改,或以更安全的行为取代不安全的默认行为的更改。 +* 从未运行成功的功能。例如,如果某个函数或枚举值从未成功使用,则可能会以修复的形式将其重命名或删除。这包括依赖于非功能芯片硬件功能的软件功能。 +* 未明确记录的意外或未定义行为可能会被修复或更改,如缺少参数范围验证。 +* 在菜单配置中 :doc:`Kconfig ` 选项的位置。 +* 示例项目的位置和名称。 + +.. _指定初始化器: https://en.cppreference.com/w/c/language/struct_initialization