组件管理和使用

[English]

想象你正在开发一个复杂的应用程序,它需要涉及多个功能模块,例如网络通信、传感器读取、屏幕驱动。如果你将所有功能都写在一个大文件中,代码会变得冗长且难以维护。这时,组件就起到了模块化的作用。

每个组件专注于一个特定的功能领域,这样,每个组件都可以单独开发、测试和维护。通过将功能拆分为组件,你可以在多个项目中重复使用这些功能,无需重复编写代码。这样既节省了开发时间,又提高了开发效率。同时项目的结构也会变得更加的清晰。

IDF 组件

ESP-IDF 组件是一个可重用的代码包,组件在构建时会被编译成静态库,可以被其他组件或者应用程序链接。这样就可以在多个项目中使用。

一个完整的组件一般包含:

  • 源代码

  • 头文件

  • CMakeLists.txt

    • 定义源代码和头文件

    • 定义依赖关系

    • 注册组件

    • 配置可选特性

    • CMake 构建描述文件,用于描述组件的构建配置和依赖关系,用于指示编译器如何编译、链接和构建组件。

  • idf_component.yml

    • 组件管理器描述文件,它列出了需要引用的其他组件及其版本信息。这样,在构建项目时,ESP-IDF 的组件管理器会根据这些描述,自动下载并集成所需的组件,以确保项目的依赖关系得到满足。

组件依赖

编译各个组件时,ESP-IDF 系统会递归评估其依赖项。这意味着每个组件都需要声明它所依赖的组件,即 “requires”。

依赖是指一个软件项目所依赖的其他软件库、模块或组件,这些依赖项是构建和运行项目所必需的。软件项目通常会使用其他已经存在的代码或库来实现特定功能或提供某些服务,而不是从头开始编写所有的代码。这些外部的代码或库就是项目的依赖项。

依赖的作用是为了促进代码的重用、降低开发成本、加快开发速度和提高软件质量。使用现有的依赖项可以避免重复造轮子

常见的依赖项包括:

  • 第三方库

  • 框架和组件

  • 运行时环境

寻找组件

  1. IDF 中包含了一些基础功能组件,可以在 components 目录下找到

  2. idf-extra-components 包含了一些 IDF 补充组件

  3. esp-iot-solution 提供了一些外设驱动组件

  4. esp-registry 中可以搜索到乐鑫维护的组件和第三方上传的组件

  5. 寻找第三方组件库

组件管理器(Component Manager)

组件管理器 是指用于管理组件的工具或系统。在 IDF 中,组件管理器提供了一组命令 用于添加、移除、下载、管理组件,以便在项目中重用已有的功能模块。

使用组件管理器添加组件

  1. esp-registry 找到工程所需的组件

  2. 使用终端进入工程目录的根文件夹,执行 idf.py add-dependency "[命名空间]/<组件名>[版本号]"

    • 这条指令将自动添加一个条目到 main/idf_component.yml,若文件不存在将自动创建

    • 命名空间:可选,默认从 espressif (大小写不敏感)

    • 组件名:必须,组件的名称,例如 usb_stream (大小写不敏感)

    • 版本号:可选,默认为 * 代表任意版本。首次添加组件时,会自动下载最新版本

  3. 运行 idf.py build

备注

  • 无需对工程 CMakeLists.txt 进行额外修改,可以直接在工程源代码中 include 组件的公共头文件、编译并链接组件的静态库

  • 用户无法直接修改 managed_components 中的组件,因为组件管理器会自动检测组件 Hash 值、并恢复更改。

  • 除了使用指令 idf.py add-dependency ,用户也可以直接修改 idf_component.yml 文件,手动修改组件条目。

使用本地的组件

在组件管理器描述文件 idf_component.yml 中,按照下方示例,添加本地组件地址

dependencies:
    idf: ">=4.4.1"
    cmake_utilities: "0.*"
    iot_usbh_modem:
        version: "0.1.*"
        override_path: "../../../../../components/usb/iot_usbh_modem"

从 Git 仓库拉取组件

在组件管理器描述文件 idf_component.yml 中,按照下方示例,添加组件在 Github 的地址

dependencies:
    esp-gsl:
        git: https://github.com/leeebo/esp-gsl.git
        version: "*"
    button:
        git: https://github.com/espressif/esp-iot-solution.git
        path: components/button
        version: "*"

更新组件

  1. 将组件管理器描述文件 idf_component.yml 中的组件版本号修改为要更新到的目标版本

  2. 删除工程文件中的 managed_componentsdependencies.lock

  3. 执行 idf.py build 或手动执行 idf.py reconfigure

删除组件

  1. 删除 idf_component.yml 中的组件条目

  2. 删除 buildmanaged_componentsdependencies.lock

  3. 执行 idf.py build

开发组件(进阶)

  1. 创建一个组件目录,和 ESP-IDF 组件要求一致,编写对应的 CMakeLists.txt 文件

  2. 添加 idf_component.yml 文件,添加组件信息,IDF 版本要求,指定依赖的其他组件

  3. 添加 license.txt 文件,添加组件的许可证信息。许可证信息用于明确告知其他开发者或用户,在使用该组件时需要遵守的条款和条件。这样可以确保组件的使用和分发是合法的,并明确组件作者对其作品的版权和授权情况。许可证信息一般包含在一个名为 license.txt 或 LICENSE 的文件中,其中包含了以下内容:

    • 许可证类型: 明确指定组件的许可证类型,例如MIT许可证、Apache许可证、GPL许可证等。不同类型的许可证有不同的条款和条件,开发者和用户需要遵守相应的许可证规定。

    • 版权信息: 注明组件的版权归属权,即组件的作者或版权持有人。版权信息通常包括作者的姓名、组织或公司名称,以及版权年份。

    • 免责声明: 可能包含免责声明,声明组件的作者或版权持有人对组件使用可能引起的任何损失或责任不承担责任。

    • 权限和限制: 明确指定在何种条件下可以使用和分发该组件,以及禁止的行为或限制。

    • 开源许可: 如果组件是开源软件,许可证信息应该包含相应的开源许可条款,如开源代码的共享、修改、分发等规则。

  4. 添加 README.md 文件,添加组件的简介、简单的使用说明

  5. 添加 CHANGELOG.md 文件,添加组件的版本更新记录

    • 用于记录组件版本更新记录的文档。它通常包含了组件每个版本的变更内容、改进、修复和新增功能等信息。开发者和用户可以通过查阅CHANGELOG.md文件了解组件的版本更新历史,以便更好地了解组件的发展和使用。

  6. 添加 test_apps 目录,添加组件的测试用例

    • 组件的自检工具,可以确保组件的质量和稳定性,对于组件的开发和维护非常重要

    • 里面包含了应用程序都针对组件的不同方面或功能进行测试

  7. 添加 examples 目录

    • 为组件提供示例代码,以展示组件的基本用法和功能

    • 或在 idf_component.yml 中指定 examples 路径,添加组件的示例代码

发布组件

发布在 ESP-Registry

ESP-Registry 是乐鑫提供的中央仓库,为开发者提供了一个便捷的方式来发现和下载用于工程项目中的组件

  1. 在 ESP-Registry 注册账号 - 通过 Github 账号授权就可以在 ESP-Registry 上完成注册

  2. 注册账号后,点击右上角用户名,选择 Tokens

  3. 在这个界面点击 Create 就可以创建一个 Token

  4. 把刚才创建的 Token 注册到环境变量 IDF_COMPONENT_API_TOKEN

  5. 使用 idf.py upload-component 命令上传组件到 ESP 组件注册库 - idf.py upload-component --namespace [YOUR_NAMESPACE] --name test_cmp - YOUR_NAMESPACE:esp-registry 用户名,在 profile 中可以看到 - test_cmp:上传组件的名称

  6. 上传完成后,组件就可以在 ESP-Registry 上查看了。

发布在 Github 仓库

如果只想发布到 Github 仓库,可以按照组件开发规范,直接将组件发布到自己的 Github 仓库。其他开发者可以用前面 从 Git 仓库拉取组件 的方式来拉取这个组件。

相关链接