返回

ESP-IDF 笔记

目录

构建系统

构建系统

项目结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
my_project/
├── CMakeLists.txt           项目整体的定义入口
├── Makefile                 用于调用 CMake 构建的简单包装
├── sdkconfig                通过 menuconfig 设置的构建选项
├── build/                   构建产物(自动生成)
├── main/
   ├── CMakeLists.txt       定义此目录下的构建目标(例如 main.c
   └── main.c               应用程序的入口点
   └── Kconfig.projbuild    项目专属定义
├── components/              自定义组件存放目录
   └── my_led_driver/
       ├── CMakeLists.txt   自定义组件的构建配置
       ├── my_led_driver.c
       ├── Kconfig          自定义组件定义
       └── include/
           └── my_led_driver.h

cmake

项目 CMakeLists 文件

1
2
3
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(myProject)
1
2
3
4
5
6
7
8
9
COMPONENT_DIRS:组件的搜索目录,默认为 IDF_PATH/components、 PROJECT_DIR/components、和 EXTRA_COMPONENT_DIRS。如果你不想在这些位置搜索组件,请覆盖此变量。

EXTRA_COMPONENT_DIRS:用于搜索组件的其它可选目录列表。路径可以是相对于项目目录的相对路径,也可以是绝对路径。

COMPONENTS:用于指定要构建到项目中的组件名称列表,默认为 COMPONENT_DIRS 目录下检索到的所有组件。使用此变量可以“精简”项目,从而缩短构建时间。请注意,如果一个组件通过 COMPONENT_REQUIRES 指定了它依赖的另一个组件,则会自动将其添加到 COMPONENTS 中,所以 COMPONENTS 列表可能会非常短。另外,还可以通过设置 MINIMAL_BUILD 构建属性 来指定 COMPONENTS 中的 main 组件。

BOOTLOADER_IGNORE_EXTRA_COMPONENT:可选组件列表,位于 bootloader_components/ 目录中,引导加载程序编译时会忽略该列表中的组件。使用这一变量可以将一个组件有条件地包含在项目中。

BOOTLOADER_EXTRA_COMPONENT_DIRS:可选的附加路径列表,引导加载程序编译时将从这些路径中搜索要编译的组件。注意,这是一个构建属性。

组件 CMakeLists 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
idf_component_register(SRCS "foo.c" "bar.c"
INCLUDE_DIRS "include" REQUIRES mbedtls)

idf_component_register(SRCS "car.c"
                  INCLUDE_DIRS "."
                  REQUIRES engine)

idf_component_register(SRCS "engine.c"
                  INCLUDE_DIRS "include"
                  PRIV_REQUIRES spark_plug)

idf_component_register(SRCS "spark_plug.c"
                  INCLUDE_DIRS ".")
1
2
3
4
5
6
7
8
9
COMPONENT_DIR:组件目录,即包含 CMakeLists.txt 文件的绝对路径,它与 CMAKE_CURRENT_SOURCE_DIR 变量一样,路径中不能包含空格。

COMPONENT_NAME:组件名,与组件目录名相同。

COMPONENT_ALIAS:库别名,由构建系统在内部为组件创建。

COMPONENT_LIB:库名,由构建系统在内部为组件创建。

COMPONENT_VERSION:组件版本,由 idf_component.yml 指定并由 IDF 组件管理器设置。
1
2
3
4
// 全局
REQUIRES 需要包含所有在当前组件的 公共 头文件里 #include 的头文件所在的组件。
// 组件依赖的
PRIV_REQUIRES 需要包含被当前组件的源文件 #include 的头文件所在的组件(除非已经被设置在了 REQUIRES 中)。以及是当前组件正常工作必须要链接的组件。

特殊

嵌入二进制数据
1
2
3
4
5
idf_component_register(...
                       EMBED_TXTFILES server_root_cert.pem)

extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[]   asm("_binary_server_root_cert_pem_end");
Bootloader

引导加载程序是 /components/bootloader/subproject 内部独特的“子项目”,它有自己的项目 CMakeLists.txt 文件,能够构建独立于主项目的 .ELF 和 .BIN 文件,同时它又与主项目共享配置和构建目录。

子项目通过 /components/bootloader/project_include.cmake 文件作为外部项目插入到项目的顶层,主构建进程会运行子项目的 CMake,包括查找组件(主项目使用的组件的子集),生成引导加载程序专用的配置文件(从主 sdkconfig 文件中派生)。

使用第三方 CMake 项目
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 注册组件
idf_component_register(...)

# 设置 `foo` 项目中的一些 CMake 变量,以控制 `foo` 的构建过程
set(FOO_BUILD_STATIC OFF)
set(FOO_BUILD_TESTS OFF)

# 创建并导入第三方库目标
add_subdirectory(foo)

# 将 `foo` 目标公开链接至 `main` 组件
target_link_libraries(main PUBLIC foo)
外部库中使用 ESP-IDF 组件
1
2
3
4
5
6
add_library(foo bar.c fizz.cpp buzz.cpp)

if(ESP_PLATFORM)
  # 在 ESP-IDF 中、bar.c 需要包含 spi_flash 组件中的 esp_flash.h
  target_link_libraries(foo PRIVATE idf::spi_flash)
endif()

sdkconfig(用于配置 Kconfig)

  • 板子或芯片相关 芯片类型(ESP32/ESP32-S3 等)
  • 外设功能 启用 UART、SPI、I2C、Wi-Fi、BLE 等
  • FreeRTOS 配置 任务数、栈大小、Tick 周期等
  • 日志输出 LOG_LEVEL 的设置(DEBUG、INFO、WARN 等)
  • 各组件配置 例如是否使用 SPIFFS、Wi-Fi 的最大连接数等
  • 条件编译

Kconfig

用于生成自定义sdkconfig配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
config ENABLE_LCD_OUTPUT
    bool "Enable LCD output."
    help
        Select this if your board has a LCD.

config ENABLE_LCD_CONSOLE
    bool "Output console text to LCD"
    depends on ENABLE_LCD_OUTPUT
    help
        Select this to output debugging output to the lcd

config ENABLE_LCD_PLOT
    bool "Output temperature plots to LCD"
    depends on ENABLE_LCD_OUTPUT
    help
        Select this to output temperature plots
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
if(CONFIG_ENABLE_LCD_OUTPUT)
   set(srcs lcd-real.c lcd-spi.c)
else()
   set(srcs lcd-dummy.c)
endif()

# 如果启用了控制台或绘图功能,则需要加入字体
if(CONFIG_ENABLE_LCD_CONSOLE OR CONFIG_ENABLE_LCD_PLOT)
   list(APPEND srcs "font.c")
endif()

idf_component_register(SRCS "${srcs}"
                    ...)

idf.py 命令

1
2
3
4
5
6
7
idf.py set-target esp32
idf.py menuconfig

idf.py build
idf.py -p PORT flash

idf.py -p PORT monitor

API

API 约定

esp_err_t

分区表

1
2
3
4
5
# ESP-IDF Partition Table
# Name,   Type, SubType, Offset,  Size,   Flags
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 1M,

分区表

OTA

OTA

封装

MQTT

电源管理

电源管理

NVSFlash

SPIFFS

Licensed under CC BY-NC-SA 4.0