IDF 前端工具 - idf.py
idf.py
命令行工具提供了一个前端界面,管理工程构建、工程部署及工程调试等操作。该前端界面使用多项工具,如:
CMake 用于配置要构建的工程。
Ninja 用于构建工程。
esptool.py 用于烧录目标芯片。
第五步:开始使用 ESP-IDF 吧 简要介绍了设置 idf.py
以配置、构建及烧录工程的操作流程。
重要
idf.py
应在 ESP-IDF 工程目录下运行,即包含 CMakeLists.txt
文件的目录。旧版本工程,即包含 Makefile
的目录,与 idf.py
不兼容。
常用命令
创建新工程:create-project
idf.py create-project <project name>
此命令将创建一个新的 ESP-IDF 工程。此外,使用 --path
选项可指定工程创建路径。
创建新组件:create-component
idf.py create-component <component name>
此命令将创建一个新的组件,包含构建所需的最基本文件集。使用 -C
选项可指定组件创建目录。有关组件的更多信息,请参阅 组件 CMakeLists 文件。
选择目标芯片:set-target
ESP-IDF 支持多个目标芯片,运行 idf.py --list-targets
查看当前 ESP-IDF 版本支持的所有目标芯片。
idf.py set-target <target>
此命令将设置当前工程的目标芯片。
重要
idf.py set-target
将清除 build 目录,并重新生成 sdkconfig
文件,原来的 sdkconfig
文件保存为 sdkconfig.old
。
备注
idf.py set-target
命令与以下操作效果相同:
清除 build 目录 (
idf.py fullclean
)删除 sdkconfig 文件 (
mv sdkconfig sdkconfig.old
)使用新的目标芯片重新配置工程 (
idf.py -DIDF_TARGET=esp32 reconfigure
)
所需的 IDF_TARGET
还可以作为环境变量(如 export IDF_TARGET=esp32s2
)或 CMake 变量(如将 -DIDF_TARGET=esp32s2
作为 CMake 或 idf.py
的参数)传递。在经常使用同类芯片的情况下,设置环境变量将使操作更加便利。
要给指定工程设定 IDF_TARGET
的默认值,请将 CONFIG_IDF_TARGET
选项添加到该工程的 sdkconfig.defaults
文件(如 CONFIG_IDF_TARGET="esp32s2"
)。若未通过使用环境变量、CMake 变量或 idf.py set-target
命令等方法指定 IDF_TARGET
,则默认使用该选项的值。
若未通过以上任一方法设置目标芯片,构建系统将默认使用 esp32
。
构建工程:build
idf.py build
此命令将构建当前目录下的工程,具体步骤如下:
构建是增量行为,因此若上次构建结束后,源文件或配置并未发生更改,则不会执行任何操作。
此外,使用 app
、bootloader
或 partition-table
参数运行此命令,可选择仅构建应用程序、引导加载程序或分区表。
清除构建输出:clean
idf.py clean
此命令可清除 build 目录中的构建输出文件,下次构建时,工程将完全重新构建。注意,使用此选项不会删除 build 文件夹内的 CMake 配置输出。
删除所有构建内容:fullclean
idf.py fullclean
此命令将删除所有 build 目录下的内容,包括 CMake 配置输出。下次构建时,CMake 将重新配置其输出。注意,此命令将递归删除 build 目录下的 所有 文件(工程配置将保留),请谨慎使用。
烧录工程:flash
idf.py flash
此命令将在需要时自动构建工程,随后将其烧录到目标芯片。使用 -p
和 -b
选项可分别设置串口名称和烧录程序的波特率。
备注
环境变量 ESPPORT
和 ESPBAUD
可分别设置 -p
和 -b
选项的默认值,在命令行上设置这些选项的参数可覆盖默认值。
idf.py
在内部使用 esptool.py
的 write_flash
命令来烧录目标设备。通过 --extra-args
选项传递额外的参数,并配置烧录过程。例如,要 写入到外部 SPI flash 芯片,请使用以下命令: idf.py flash --extra-args="--spi-connection <CLK>,<Q>,<D>,<HD>,<CS>"
。要查看所有可用参数,请运行 esptool.py write_flash --help
或查看 esptool.py 文档。
与 build
命令类似,使用 app
、bootloader
或 partition-table
参数运行此命令,可选择仅烧录应用程序、引导加载程序或分区表。
合并二进制文件:merge-bin
idf.py merge-bin [-o output-file] [-f format] [<format-specific-options>]
在某些情况下(例如将文件传输到另一台机器,且不借助 ESP-IDF 对其进行烧录),只烧录一个文件比烧录 idf.py build
生成的多个文件更为便捷。
idf.py merge-bin
命令会根据项目配置合并引导加载程序、分区表、应用程序本身以及其他分区(如果有的话),并在 build 文件夹中创建一个二进制文件 merged-binary.[bin|hex]
,之后可对其进行烧录。
合并后的文件的输出格式可以是二进制 (raw),IntelHex (hex) 以及 UF2 (uf2)。
uf2 二进制文件也可以通过 idf.py uf2 生成。idf.py uf2
命令在功能上与 idf.py merge-bin -f uf2
命令等效,而将二进制文件合并成上述各种格式时,idf.py merge-bin
命令更具灵活性与可选性。
用法示例:
idf.py merge-bin -o my-merged-binary.bin -f raw
还有一些特定格式的选项,如下所示:
仅针对 raw 格式:
--flash-offset
:此选项创建的合并二进制文件应在指定偏移处进行烧录,而不是在标准偏移地址 0x0 处。--fill-flash-size
:设置此选项,系统将在最终的二进制文件中添加 FF 字节直至文件大小与 flash 大小等同,从而确保烧录范围能够完整地覆盖整个 flash 芯片,且在烧录时整个 flash 芯片都被重写。
仅针对 uf2 格式:
--md5-disable
:该选项会在每个数据块的末尾禁用 MD5 校验和。在与 tinyuf2 等工具进行集成时,可以启用此选项。
错误处理提示
idf.py
使用存储在 tools/idf_py_actions/hints.yml 中的提示数据库,当找到与给定错误相匹配的提示时,idf.py
会打印该提示以尝试提供解决方案。目前,错误处理提示不支持 menuconfig 对象。
若无需该功能,可以通过 idf.py
的 --no-hints
参数关闭提示。
重要提示
多个 idf.py
命令可以在同一行命令中组合使用。例如,idf.py -p COM4 clean flash monitor
可以清除源代码树、编译工程、并将其烧录到目标芯片,随后运行串行监视器。
在同一调用中,多个 idf.py
命令的顺序并不重要,它们将自动以正确的程序执行,以使全部操作生效(例如先构建后烧录、先擦除后烧录)。
idf.py
会尝试将未知命令作为构建系统目标执行。
命令 idf.py
支持 bash、zsh 和 fish shell 的 shell 自动补全。
调用命令 export
为 idf.py
启用自动补全(第四步:设置环境变量),按 TAB 键启动自动补全。输入 idf.py -
并按 TAB 键以自动补全选项。
预计未来版本将支持 PowerShell 自动补全。
高级命令
打开文档:docs
idf.py docs
此命令将在浏览器中打开工程目标芯片和 ESP-IDF 版本对应的文档。
显示大小:Size
idf.py size
此命令将显示应用程序大小,包括占用的 RAM 和 flash 及各部分(如 .bss)的大小。
idf.py size-components
此命令将显示工程中各个组件的应用程序大小。
idf.py size-files
该命令将显示工程中每个源文件的大小。
选项
--format
指定输出格式,可输出text
、csv
、json
格式,默认格式为text
。--output-file
可选参数,可以指定命令输出文件的文件名,而非标准输出。
重新配置工程:reconfigure
idf.py reconfigure
此命令将重新运行 CMake。正常情况下并不会用到该命令,因为一般无需重新运行 CMake,但如果从源代码树中添加或删除了文件,或需要修改 CMake 缓存变量时,将有必要使用该命令。例如,idf.py -DNAME='VALUE' reconfigure
可将变量 NAME
在 CMake 缓存中设置为值 VALUE
。
清除 Python 字节码:python-clean
idf.py python-clean
此命令将从 ESP-IDF 目录中删除生成的 Python 字节码。字节码在切换 ESP-IDF 和 Python 版本时可能会引起问题,建议在切换 Python 版本后运行此命令。
生成 UF2 二进制文件:uf2
idf.py uf2
此命令将在 build 目录中生成一个 UF2(USB 烧录格式) 二进制文件 uf2.bin
,该文件包含所有烧录目标芯片所必需的二进制文件,即引导加载程序、应用程序和分区表。
在 ESP 芯片上运行 ESP USB Bridge 项目将创建一个 USB 大容量存储设备,用户可以将生成的 UF2 文件复制到该 USB 设备中,桥接 MCU 将使用该文件来烧录目标 MCU。这一操作十分简单,只需将文件复制(或“拖放”)到文件资源管理器访问的公开磁盘中即可。
如需仅为应用程序生成 UF2 二进制文件,即不包含引导加载程序和分区表,请使用 uf2-app
命令。
idf.py uf2
命令在功能上与 上述 idf.py merge-bin -f uf2
命令等效。而将二进制文件合并为除 uf2 以外的各种格式时,idf.py merge-bin
命令更具灵活性和可选性。
idf.py uf2-app
读取 Otadata 分区:read-otadata
idf.py read-otadata
此命令将打印 otadata
分区的内容,该分区存储当前所选 OTA 应用程序分区的信息。有关 otadata
分区的更多信息,请参阅 空中升级 (OTA)。
全局选项
运行 idf.py --help
列出所有可用的根级别选项。要列出特定子命令的选项,请运行 idf.py <command> --help
,如 idf.py monitor --help
。部分常用选项如下:
-C <dir>
支持从默认的当前工作目录覆盖工程目录。-B <dir>
支持从工程目录的默认build
子目录覆盖 build 目录。
重要
注意,某些旧版本 CCache 在某些平台上存在 bug,因此如果文件没有按预期重新构建,可禁用 CCache 并重新构建。可以通过将环境变量 IDF_CCACHE_ENABLE
设置为非零值来默认启用 CCache。
-v
会使idf.py
和构建系统生成详细的构建输出,有助于调试构建错误。--cmake-warn-uninitialized
(或-w
)将使 CMake 只显示在工程目录中发现的变量未初始化的警告,该选项仅控制 CMake 内部的 CMake 变量警告,不控制其他类型的构建警告。将环境变量IDF_CMAKE_WARN_UNINITIALIZED
设置为非零值,可永久启用该选项。--no-hints
用于禁用有关错误处理的提示并禁用捕获输出。
通过 @file
传递参数
可以通过文件向 idf.py
传递多个参数。该文件或文件路径须在开头使用 @
进行标注。文件中的参数支持通过换行或空格分隔,并按其在 idf.py 命令行中的顺序扩展。
例如,当前有文件 custom_flash.txt:
flash --baud 115200
运行命令:idf.py @custom_flash.txt monitor
文件中的参数可以与额外的命令行参数结合使用,也支持同时使用带有 @
标注的多个文件。例如,另有一个文件 another_config.txt
,此时,可以通过指定 idf.py @custom_flash.txt @another_config.txt monitor
同时使用两个文件。
关于参数文件的更多示例,如通过 @filename 创建配置文件概要,请参阅 多个构建配置示例 。
扩展 idf.py
idf.py
支持扩展功能。通过项目中的扩展文件以及参与构建的组件中的扩展文件,可以增加额外的子命令、全局选项和回调函数;通过暴露入口点的外部 Python 包,可以提供新的扩展功能。
参与构建的组件:在项目根目录,或注册在项目
CMakeLists.txt
中的组件根目录,放置名为idf_ext.py
的文件,该文件会在项目配置完成后得到识别。运行idf.py build
或idf.py reconfigure
,新添加的命令即可生效。Python 入口点:对于任何已安装的 Python 包,在
idf_extension
组中定义入口点后,就可以提供扩展功能。只要安装了 Python 包就可以使用扩展功能,无需重新构建项目。
重要
扩展不能定义与 idf.py
命令同名的子命令或选项。系统会检查自定义的动作和选项名称是否存在冲突,不允许覆盖默认命令,如有冲突会打印警告。对于 Python 入口点,必须使用唯一标识符,否则会忽略重复的入口点名称并发出警告。
扩展文件示例
扩展文件需要定义一个 action_extensions
函数,用于返回扩展的动作或选项。组件扩展 idf_ext.py
和基于包的扩展(例如 <package_name>_ext.py
)使用相同的结构,如下所示:
from typing import Any
import click
def action_extensions(base_actions: dict, project_path: str) -> dict:
def hello_test(subcommand_name: str, ctx: click.Context, global_args: dict, **action_args: Any) -> None:
message = action_args.get('message')
print(f"Running action: {subcommand_name}. Message: {message}")
def global_callback_detail(ctx: click.Context, global_args: dict, tasks: list) -> None:
if getattr(global_args, 'detail', False):
print(f"About to execute {len(tasks)} task(s): {[t.name for t in tasks]}")
return {
"version": "1",
"global_options": [
{
"names": ["--detail", "-d"],
"is_flag": True,
"help": "Enable detailed output",
}
],
"global_action_callbacks": [global_callback_detail],
"actions": {
"hello": {
"callback": hello_test,
"short_help": "Hello from component",
"help": "Test command from component extension",
"options": [
{
"names": ["--message", "-m"],
"help": "Custom message to display",
"default": "Hi there!",
"type": str,
}
]
},
},
}
扩展 API 参考
action_extensions
函数接收两个参数: base_actions
表示当前已注册的所有命令, project_path
表示项目的绝对路径。该函数返回一个包含最多四个键的字典:
version
:表示扩展接口版本。当前 API 版本为1
。此键为必填项。global_options
:一组全局选项,适用于所有命令。每个选项都是一个字典,包含names
、help
、type
、is_flag
、scope
等字段。global_action_callbacks
:表示一组全局回调函数,在执行任何任务之前都会调用一次。每个全局回调函数接受三个参数:ctx
:即 click contextglobal_args
:所有可用的全局参数tasks
:将要执行的任务列表。任务指的是运行idf.py
时所调用的具体动作或子命令
actions
:子命令字典,用于定义新的子命令。每个子命令都有一个callback
函数,并且可以包含options
、arguments
、dependencies
等。每个回调函数接受三到四个参数:subcommand_name
:命令的名称(在多个命令共享同一回调时很有用)ctx
:即 click contextglobal_args
:所有可用的全局参数**action_args
:传递给该子命令的具体参数,可选
基本用法示例
通过项目组件提供扩展
在项目根目录或某个已注册的组件目录下创建
idf_ext.py
(例如components/my_component/idf_ext.py
)。实现内容可参考上面的扩展文件示例。运行
idf.py build
或idf.py reconfigure
加载新命令,然后执行idf.py --help
即可看到新扩展。
通过 Python 包入口点提供扩展
使用上述扩展文件示例,在名为
<package_name>_ext.py
的模块中实现扩展,并通过idf_extension
入口点组暴露action_extensions
函数。例如,在pyproject.toml
中配置:[project] name = "my_comp" version = "0.1.0" [project.entry-points.idf_extension] my_pkg_ext = "my_component.my_ext:action_extensions"将该包安装到与
idf.py
相同的 Python 环境中(例如在包目录下执行pip install -e .
)。建议使用唯一的模块名(例如<package_name>_ext.py
)避免命名冲突。安装成功后,运行idf.py --help
就可以看到新扩展命令。