本帖最后由 RCSN 于 2020-5-15 22:29 编辑
楼主在Linux下(国产linux发行版--deepin深度系统)使用SDK开发,对于怎么构建开发环境平台,这里不详细说明。先大概说明:
一、开发准备:esp-idf安装与获取设置
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html
二、编译 ESP-IDF 需要以下软件包:
CentOS 7:
sudo yum install git wget flex bison gperf python cmake ninja-build ccache dfu-util
Ubuntu 和 Debian:
sudo apt-get install git wget flex bison gperf python python-pip python-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util
Arch:
sudo pacman -S --needed gcc git make flex bison gperf python-pip python-pyserial cmake ninja ccache dfu-util
使用 ESP-IDF 需要 CMake 3.5 或以上版本。较早版本的 Linux 可能需要升级才能向后移植仓库,或安装 “cmake3” 软件包,而不是安装 “cmake”。
三、Cmake介绍
乐鑫官方文档也很详细得介绍了cmake构建系统,我觉得乐鑫好在与文档比较齐全,API也极其开放。
https://docs.espressif.com/projects/esp-idf/zh_CN/v3.3.1/api-guides/build-system-cmake.html
由于esp32s2是款新MCU,乐鑫最新版本也是cmake构建,如果要用其SDK进行开发,学习cmake也是很有必要
ESP-IDF V4.0 及之后版本的默认构建系统为 CMake。而且未来可能不会继续支持基于 GNU Make 的构建系统。
Esp32中,所有的工程都会依赖与ESP-IDF,一个 ESP-IDF 项目可以看作是多个不同组件的集合
例如一个显示当前湿度的网页服务器会包含以下组件:
- {IDF_TARGET_NAME} 基础库,包括 libc、ROM bindings 等
- Wi-Fi 驱动
- TCP/IP 协议栈
- FreeRTOS 操作系统
- 网页服务器
- 湿度传感器的驱动
- 负责将上述组件整合到一起的主程序
在比如自己开发的个工程,也可以按照自己的的componment构建,比如形状识别上的工程就是如图所示:
在这里有自建的组件components,里面也包含了相关识别算法以及camera相关驱动
ESP-IDF 可以显式地指定和配置每个组件。在构建项目的时候,构建系统会前往 ESP-IDF 目录、项目目录和用户自定义目录(可选)中查找所有组件,允许用户通过文本菜单系统配置 ESP-IDF 项目中用到的每个组件。在所有组件配置结束后,构建系统开始编译整个项目。
楼主也是第一次用cmake构建系统,ESP-IDF 的 CMake 构建系统不同寻常,为了减少样板文件,该系统封装了 CMake 的许多功能。大部分都用idf.py即可完成大量cmake编译等工作,也相当是个集成了 CMake 的 IDE,所以在构建自己工程的时候,仅需将项目 ``CMakeLists.txt`` 文件的路径告诉 IDE 即可。
那么我们就以一个实例利用esp-idf用cmake来构建自己的工程,这里使用的是形状识别例子,
示例项目的目录树结构可能如下所示::
- myProject/
- CMakeLists.txt
- sdkconfig
- components/ - component1/ - CMakeLists.txt
- Kconfig
- src1.c
- component2/ - CMakeLists.txt
- Kconfig
- src1.c
- include/ - component2.h
- main/ - src1.c
- src2.c
- build/
该示例项目 ``myproject`` 包含以下组成部分:
顶层项目 CMakeLists.txt 文件,这是 CMake 用于学习如何构建项目的主要文件,可以在这个文件中设置项目全局的 CMake 变量。顶层项目 CMakeLists.txt 文件会导入 :idf_file:`/tools/cmake/project.cmake` 文件,由它负责实现构建系统的其余部分。该文件最后会设置项目的名称,并定义该项目。
- ``sdkconfig`` 项目配置文件,执行 ``idf.py menuconfig`` 时会创建或更新此文件,文件中保存了项目中所有组件(包括 ESP-IDF 本身)的配置信息。 ``sdkconfig`` 文件可能会也可能不会被添加到项目的源码管理系统中。
可选的 ``component`` 目录中包含了项目的部分自定义组件,并不是每个项目都需要这种自定义组件,但它组件有助于构建可复用的代码或者导入第三方(不属于 ESP-IDF)的组件。
``main`` 目录是一个特殊的 ``伪组件``,包含项目本身的源代码。``main`` 是默认名称,CMake 变量 ``COMPONENT_DIRS`` 默认包含此组件,但您可以修改此变量。或者,您也可以在顶层 CMakeLists.txt 中设置 ``EXTRA_COMPONENT_DIRS`` 变量以查找其他指定位置处的组件,比如COMPONENT_REQUIRES。如果项目中源文件较多,建议将其归于组件中,而不是全部放在 ``main`` 中。
- ``build`` 目录是存放构建输出的地方,如果没有此目录,``idf.py`` 会自动创建。CMake 会配置项目,并在此目录下生成临时的构建文件。随后,在主构建进程的运行期间,该目录还会保存临时目标文件、库文件以及最终输出的二进制文件。此目录通常不会添加到项目的源码管理系统中,也不会随项目源码一同发布。Bulid生成的中间文件较大,打包的时候建议clean掉。
每个组件目录都包含一个 ``CMakeLists.txt`` 文件,里面会定义一些变量以控制该组件的构建过程,以及其与整个项目的集成。
``COMPONENT_DIRS``:组件的搜索目录,默认为 ``${IDF_PATH}/components``、``${PROJECT_PATH}/components`` 和 ``EXTRA_COMPONENT_DIRS``。如果您不想在这些位置搜索组件,请覆盖此变量。
``EXTRA_COMPONENT_DIRS``:用于搜索组件的其它可选目录列表。路径可以是相对于项目目录的相对路径,也可以是绝对路径。
``COMPONENTS``:要构建进项目中的组件名称列表,默认为 ``COMPONENT_DIRS`` 目录下检索到的所有组件。使用此变量可以“精简”项目以缩短构建时间。请注意,如果一个组件通过 ``COMPONENT_REQUIRES`` 指定了它依赖的另一个组件,则会自动将其添加到 ``COMPONENTS`` 中,所以 ``COMPONENTS`` 列表可能会非常短。
``COMPONENT_REQUIRES_COMMON``:每个组件都需要的通用组件列表,这些通用组件会自动添加到每个组件的 ``COMPONENT_PRIV_REQUIRES`` 列表中以及项目的 ``COMPONENTS`` 列表中。默认情况下,此变量设置为 ESP-IDF 项目所需的最小核心“系统”组件集。通常您无需在项目中更改此变量。
以上变量中的路径可以是绝对路径,或者是相对于项目目录的相对路径
``COMPONENT_SRCS`` 是用空格分隔的源文件列表(``*.c``,``*.cpp``,``*.cc``,``*.S``),里面所有的源文件都将会编译进组件库中。
``COMPONENT_ADD_INCLUDEDIRS`` 是用空格分隔的目录列表,里面的路径会被添加到所有需要该组件的组件(包括 main 组件)全局 include 搜索路径中。
``register_component()`` 使用上述设置的变量将组件添加到构建系统中,构建生成与组件同名的库,并最终被链接到应用程序中。如果因为使用了 `CMake 中的 if 命令 <cmake if_>`_ 或类似命令而跳过了这一步,那么该组件将不会被添加到构建系统中。
- ``COMPONENT_REQUIRES`` 需要包含所有被当前组件的公共头文件 `#include` 的头文件所在的组件。
- ``COMPONENT_PRIV_REQUIRES`` 需要包含被当前组件的源文件 `#include` 的头文件所在的组件(除非已经被设置在了 ``COMPONENT_PRIV_REQUIRES`` 中)。或者是当前组件正常工作必须要链接的组件。
- ``COMPONENT_REQUIRES``、``COMPONENT_PRIV_REQUIRES`` 需要在调用 ``register_component()`` 之前设置。
- ``COMPONENT_REQUIRES`` 和 ``COMPONENT_PRIV_REQUIRES`` 的值不能依赖于任何配置选项(``CONFIG_xxx``),这是因为在配置加载之前,依赖关系就已经被展开。其它组件变量(比如 ``COMPONENT_SRCS`` 和 ``COMPONENT_ADD_INCLUDEDIRS``)可以依赖配置选择。
- 如果当前组件除了 ``COMPONENT_REQUIRES_COMMON`` 中设置的通用组件(比如 RTOS、libc 等)外,并不依赖其它组件,那么上述两个 ``REQUIRES`` 变量可以为空。
构建完毕需要进行编译,那么也就是组件依赖编译。在这里需要说明下几个cmake需要用到专用词说明
编译各个组件时,ESP-IDF 系统会递归评估其组件。
每个组件的源文件都会使用以下路径中的头文件进行编译:
- 当前组件的
``COMPONENT_ADD_INCLUDEDIRS`` 和 ``COMPONENT_PRIV_INCLUDEDIRS``。
- 当前组件的 ``COMPONENT_REQUIRES`` 和 ``COMPONENT_PRIV_REQUIRES`` 变量指定的其他组件(即当前组件的所有公共和私有依赖项)所设置的 ``COMPONENT_ADD_INCLUDEDIRS``。
- 所有组件的 ``COMPONENT_REQUIRES`` 做递归操作,即该组件递归运算后的所有公共依赖项。
编写完毕之后,编译之前最好设置下目标, idf.py set-target esp32s2,此后不再需要配置。查询串口 ls /dev/tty*,开放串口权限 sudo chmod 777 /dev/ttyUSB0, 编译 idf.py build, 烧录 idf.py –p /dev/ttyUSB0 flash。按照上面的链接所作即可