第四章 认识ESP-IDF ESP-IDF是乐鑫科技为其ESP32系列芯片提供的官方开发框架。这个框架主要用于开发、构建和部署基于ESP32的物联网(IoT)应用。我们要写程序控制ESP32芯片,其实最终就是控制它的寄存器,使之工作在我们需要的模式下,ESP-IDF库将大部分寄存器的操作封装成了函数,我们只需要学习和掌握ESP-IDF库函数的结构和用法,就能方便地驱动ESP32工作,以节省开发时间。 本章将分为如下几个小节: 4.1 ESP-IDF简介 4.2 ESP-IDF库框架结构解析 4.3 ESP-IDF与乐鑫芯片 4.4 IDF工程简介
4.1 ESP-IDF简介 ESP-IDF(Espressif IoT Development Framework)是乐鑫(Espressif Systems)为ESP系列芯片开发的物联网开发框架。它支持ESP32、ESP32-S、ESP32-C和ESP32-H系列SoC,基于C/C++语言提供了一个自给自足的SDK,方便用户在这些平台上开发通用应用程序。 一、ESP-IDF特点: (1)免费开源:ESP-IDF 相关资源已在 GitHub 上免费开放。 (2)专业稳定:ESP-IDF发布的版本均经过严格的测试流程,以确保版本稳定,客户可快速实现量产。 (3)功能丰富的软件组件:ESP-IDF 集成了大量的软件组件,包括 RTOS、外设驱动程序、网络栈、多种协议实现技术以及常见应用程序的使用助手。 (4)支持多种IDE开发:Eclipse 和 VSCode 等 IDE,确保其易于开发人员使用。 (5)丰富的文档和示例资源:ESP-IDF 提供详尽的软件组件使用和设计文档,有助于开发人员充分理解 ESP-IDF 功能,并从中挑选最适合构建其应用程序的模块。 (6)支持Windows、Linux 和 macOS 系统平台上开发 ESP32 应用程序提供工具链、API、组件和工作流程(本教程选择Windows系统下开发)。 二、自动化构建系统: 开发者只需要通过简单的命令即可触发整个编译流程。下图为ESP-IDF编译系统流程:
图4.1.1 ESP-IDF编译系统流程 从上述图示可见,项目的工程文件通过集成C项目、中间组件以及工具链,共同编译生成可执行文件。随后,这个可执行文件被下载到ESP32芯片中。ESP32芯片能够通过其监控器功能,向开发者提供实时的反馈信息。这一流程使得开发者能够更有效地监控和管理ESP32芯片的运行状态,从而优化项目的开发过程。 ESP-IDF的编译过程主要基于Make或CMake构建系统,它自动化地处理源代码的编译、链接和生成最终的可执行文件或固件镜像。简单来讲,ESP-IDF可以使用命令的形式进行配置、编译、链接和构建项目,类似于linux的开发方式。整个编译过程通过构建系统自动化完成,开发者只需要通过简单的命令即可触发整个编译流程。 ESP-IDF虽然提供了强大的功能和灵活性,但使用命令编译和构造等操作也存在一些缺点。 ①:学习曲线陡峭。对于初学者来说,ESP-IDF可能具有一定的学习难度。它需要一定的时间来理解其目录结构、编译系统、配置文件以及API等 ②:编译过程繁琐。虽然ESP-IDF提供了命令来编译和构造项目,但编译过程可能会相对繁琐。特别是当项目规模较大或者依赖多个组件时,编译时间可能会延长,这可能会影响开发效率。 ③:缺乏图形化界面。虽然ESP-IDF提供了命令行工具来进行项目构建和调试,但缺乏图形化界面的支持可能会使得某些操作相对不便。对于一些开发者来说,图形化界面可以提供更直观和易于使用的操作体验。 ④:配置复杂。ESP-IDF的配置文件(如sdkconfig)可能相对复杂,特别是对于初学者来说。需要正确配置各种选项和参数,以确保项目能够正确编译和运行。配置错误可能导致编译失败或运行时问题。 对于上述的问题,乐鑫科技提供了一个解决方案,那就是在集成开发环境下开发ESP-IDF,使得开发者更加快速的开发ESP32芯片。下面是乐鑫官方ESP-IDF支持的集成开发环境。
图4.1.2 ESP-IDF支持的集成开发环境 下图为VS Code/Eclipse/Espressif-IDE等IDE的开发ESP-IDF程序流程图。
图4.1.3 开发应用程序流程图 不难发现,图4.1.1的流程和图4.1.3的流程极为相似,唯一不同的是图4.1.3是基于IDE集成开发环境下开发的,但是它们的编译流程是一致的。 本教程中的所有例程都是基于VS Code IDE进行开发的。虽然并未提供基于Eclipse IDE的开发例程,但上图中展示的开发应用程序流程同样适用于VS Code IDE的开发流程。这意味着,无论使用哪种IDE开发ESP-IDF,开发者都可以遵循这一流程来有效地进行应用程序的开发。 三、ESP-IDF在VS Code集成开发环境开发具备那些特点 ①:代码编辑与智能提示。安装了ESP-IDF扩展插件后,VSCode将提供代码高亮、语法检查、自动补全等IDE功能,极大地提高了代码编辑的效率和准确性。插件还提供了对ESP-IDF特定函数和API的智能提示,帮助开发者更快地编写和调试代码。 ②:构建与调试。ESP-IDF扩展插件集成了构建和调试功能,开发者可以直接在VSCode中执行idf.py build等命令来构建项目。还可以通过配置launch.json文件,开发者还可以在VSCode中设置断点、单步执行、查看变量值等调试功能,从而方便地进行程序调试。 ③:项目管理与配置。VSCode支持多项目管理,开发者可以方便地切换和管理不同的ESP-IDF项目。还通过VSCode中的配置文件(如.vscode/settings.json),开发者可以针对每个项目设置特定的构建和调试选项。 ④:集成终端与日志查看。VSCode内置了终端功能,开发者可以直接在VSCode中打开终端并执行ESP-IDF相关的命令。还可以通过集成终端,开发者可以方便地查看构建日志、调试输出等信息,从而快速定位和解决问题。 VSCode与ESP-IDF之间的关系主要体现在VSCode为ESP-IDF提供了一个功能强大的集成开发环境,通过安装和使用ESP-IDF扩展插件,开发者可以更加高效地在VSCode中编写、构建、调试和部署ESP32等Espressif芯片的应用程序。 4.2ESP-IDF库框架结构解析 下面我们从gitee仓库下克隆ESP-IDF物联网开发框架的源代码,并在此分析各个文件的作用。克隆ESP-IDF源码库流程如下图所示。
图4.2.1 克隆ESP-IDF源码库 克隆成功后,在上图路径下找到esp-idf文件夹,此文件夹就是ESP-IDF物联网开发框架的源码库,如下图所示。
图4.2.2 ESP-IDF源码库部分截图 下面作者来讲解一下这些文件夹的作用及特点,如下表所示: 文件名称 | 说明 | | 提供了模块化、可配置、可重用和可扩展的代码组织方式,使得ESP32和其他Espressif芯片的开发变得更加高效和灵活 | docs | ESP-IDF 相关的文档和指南,旨在帮助开发者更好地理解和使用 ESP-IDF | | 为开发者提供了丰富的学习资源、原型开发工具和功能演示。 | | 提供了开发ESP-IDF项目所需的各种工具和脚本,帮助开发者更高效地完成开发、构建和部署任务 |
表4.2.1 esp-idf源码库的框架结构解析 正如图4.1.1所示那样,在编译ESP32的例程时,确保components和tools目录的完整性是非常重要的。components目录包含了项目所需的所有源代码和库文件,而tools目录则提供了编译和链接这些代码所需的工具链,这样才能做到自给自足的构建项目。 4.3 ESP-IDF与乐鑫芯片 每款乐鑫芯片都可能有不同版本,下表总结了乐鑫芯片在 ESP-IDF 各版本中的支持状态,其中“P” 代表已支持,“预览”代表目前处于预览支持状态。预览支持状态通常有时间限制,而且仅适用于测试版芯片。请确保使用与芯片相匹配的 ESP-IDF 版本。 芯片型号 | V4.3 | V4.4 | V5.0 | V5.1 | V5.2 | ESP32 | P | P | P | P | P | ESP32-S2 | P | P | P | P | P | ESP32-C3 | P | P | P | P | P | ESP32-S3 | | P | P | P | P | ESP32-C2 | | | P | P | P | ESP32-C6 | | | | P | P | ESP32-H2 | | | | P | P | ESP32-P4 | | | | | 预览 |
表4.3.1 ESP-IDF 与乐鑫芯片关系表 从上表可知:每款乐鑫芯片都可能有不同版本。建议参考 [ESP-IDF 版本与乐鑫芯片版本兼容性,了解 ESP-IDF 版本与各芯片版本之间的兼容性,作者建议读者最好找到合适的ESP-IDF版本来开发自己的SoC芯片。 对于 2016 年之前发布的乐鑫芯片(包括 ESP8266 和 ESP8285),请参考 [RTOS SDK]。 4.4 IDF工程简介 ESP-IDF工程,特别是ESP-IDF项目,可以看作是由多个不同组件集合而成的工程。这些组件包括ESP-IDF基础库(如libc、ROM bindings等)、Wi-Fi驱动、TCP/IP协议栈、FreeRTOS操作系统、网页服务器、各种传感器驱动(如湿度传感器驱动)以及负责将上述组件整合到一起的主程序等。 ESP-IDF工程借助CMake的可自定义性,创新地采用了“组件”式的设计。整个工程由多个组件组成,每个组件都像是一块积木,共同构建起完整的工程结构。在这些组件中,有一个特殊的组件被称为“main”组件,它包含了用户应用程序的入口函数。 组件之间的关系主要以依赖关系为主,确保了它们之间的有序协作。每个组件都可以拥有单独的配置,这进一步增加了工程的灵活性和可定制性。在ESP-IDF中,用户可以明确地指定和配置每个组件。构建系统会在ESP-IDF目录、项目目录以及用户自定义的组件目录(如存在)中查找所有的组件。这一过程允许用户通过文本菜单系统对ESP-IDF项目中使用的每个组件进行配置。当所有组件的配置完成后,构建系统便会开始编译整个项目,确保所有组件能够按照预期的方式协同工作,从而生成最终的工程成果。这种设计不仅简化了工程的开发和维护,也提高了开发效率。 1,ESP32工程有如下重要概念: ①:项目(Project)特指一个目录,其中包含了构建可执行应用程序所需的全部文件和配置,以及其他支持型文件,例如分区表、数据/文件系统分区和引导程序。 ②:项目配置 保存在项目根目录下名为sdkconfig的文件中,可以通过 idf.py menuconfig 进行修改,且一个项目只能包含一个项目配置。 ③:应用程序是由ESP-IDF构建得到的可执行文件。一个项目通常会构建两个应用程序:项目应用程序(可执行的主文件,即用户自定义的固件)和引导程序(启动并初始化项目应用程序)。 ④:组件(Components)是模块化且独立的代码,会被编译成静态库(.a 文件)并链接到应用程序。部分组件由 ESP-IDF 官方提供,其他组件则来源于其它开源项目。 ⑤:目标(Target)特指运行构建后应用程序的硬件设备。ESP-IDF 当前仅支持 esp32 和 esp32s2 以及 esp32s3 这三个硬件目标。 请注意,以下内容并不属于项目的组成部分: ①:ESP-IDF 并不是项目的一部分,它独立于项目,通过 IDF_PATH 环境变量(保存 esp-idf 目录的路径)链接到项目,从而将 IDF 框架与项目分离。 ②:交叉编译工具链并不是项目的组成部分,它应该被安装在系统 PATH 环境变量中。 2,ESP32项目工程分析 下面作者以sample_project示例(D:\ESP32\Espressif\frameworks\esp-idf-v5.1.2\examples\get-started\sample_project路径下找到)为例,来讲解基础工程的构建项目原理。sample_project工程目录如下图所示:
图5.3.9 test_1项目的文件结构 ①:顶层项目 CMakeLists.txt 文件,这是 CMake 用于学习如何构建项目的主要文件,可以在这个文件中设置项目全局的 CMake 变量。顶层项目 CMakeLists.txt 文件会导入 /tools/cmake/project.cmake 文件,由它负责实现构建系统的其余部分。该文件最后会设置项目的名称,并定义该项目。每个项目都有一个顶层 CMakeLists.txt 文件,包含整个项目的构建设置。默认情况下,项目 CMakeLists。 文件会非常小,如下代码所示: /* 必须放在 CMakeLists.txt 文件的第一行, 它会告诉 CMake 构建该项目所需要的最小版本号。ESP-IDF 支持 CMake 3.16 或更高的版本 */ cmake_minimum_required(VERSION 3.16) /* 会导入 CMake 的其余功能来完成配置项目、检索组件等任务 */ include($ENV{IDF_PATH}/tools/cmake/project.cmake) /* 会创建项目本身,并指定项目名称 */ project(myProject) ②:main目录是一个特殊的组件,它包含两个文件,它们分别为CMakeLists.txt和mian.c文件。其中main.c定义了程序入口函数app_main(),而CMakeLists.txt文件是将组件添加到构建系统中,如下图所示: idf_component_register(SRCS "main.c" INCLUDE_DIRS ".") 通过调用 idf_component_register函数,开发者可以将组件添加到构建系统中。在此过程中,SRCS 代表源文件列表,其中包括 .c、.cpp、.cc、.S 等类型的文件,这些源文件都将被编译并整合进组件库中。另外,INCLUDE_DIRS 指的是目录列表,这些目录中的路径将被添加到所有需要该组件(包括主组件)的全局 include 搜索路径中,确保在编译过程中能够正确找到相关的头文件。注意:若该组件需要依赖其他的驱动代码,可使用REQUIRES设置依赖库,具体内容请参考ESP-IDF编程指南的组件依赖章节。 ③:“sdkconfig” 项目配置文件,执行 idf.py menuconfig 时会创建或更新此文件,文件中保存了项目中所有组件(包括 ESP-IDF 本身)的配置信息。 sdkconfig 文件可能会也可能不会被添加到项目的源码管理系统中。 从上述内容可以得知以下总结:子层的CMakeLists.txt文件负责将对应层的组件整合进构建系统当中,而sdkconfig文件则用于设置构建过程中所需的多种配置选项(该编译哪些代码,不该编译哪些代码)。同时,顶层的CMakeLists.txt文件不仅指定了CMake的版本,还通过引用ESP-IDF路径下的project.cmake文件来指导整个项目的构建流程。这些文件共同协作,确保项目能够顺利构建和配置。最终,项目构建完成后会生成一个build文件夹,其中包含了临时目标文件、库文件以及最终输出的二进制文件。
|