01. 准备 ESP-IDF v5.5.4
这节课要完成什么
完成这一课后,你应该能够:
- 说清楚 ESP-IDF 是什么;
- 解释为什么本课程固定使用 v5.5.4;
- 根据网络情况,从 GitHub 或乐鑫下载服务器取得完整的 v5.5.4;
- 在不删除旧版本的情况下并行安装 v5.5.4;
- 确认当前终端真正加载了哪个 ESP-IDF;
- 理解
IDF_PATH和export.sh的作用。
这一课不连接 CAN,也不需要电机上电。
先打开乐鑫官方文档
本教程会把实际走过的安装过程拆开解释,但官方文档仍然是判断安装方法和版本要求的首要依据。下面把完整网址直接列出来,既可以在 Markdown 阅读器中点击,也可以复制到浏览器访问。
ESP-IDF v5.5.4:ESP32-C3 快速入门(中文)
ESP-IDF v5.5.4:Linux 和 macOS 工具链标准设置(中文)
ESP-IDF v5.5.4 官方发布页面
清华大学开源软件镜像站:PyPI 镜像使用帮助
阅读官方页面时,确认页面顶部选择的是目标芯片 ESP32-C3 和版本 v5.5.4,不要误看成 ESP32 或 latest 的说明。
官方安装示例通常把仓库克隆为 ~/esp/esp-idf。本教程为了让 v5.5.2 和 v5.5.4 并行存在,特意使用 ~/esp/esp-idf-v5.5.4 作为目录名。两种命名都可以,后续命令必须与自己的实际目录一致。
先说明教程中的路径
本教程把 ~/esp 作为示例工作目录。~ 和环境变量 $HOME 都表示当前登录用户的主目录:
# $HOME 会展开为当前用户的主目录,本教程统一把练习工程放在它下面。
echo "$HOME"
例如,登录用户为 student 时,~/esp 通常会展开为 /home/student/esp。你的用户名和安装位置可能不同,这完全正常。
后面的命令会尽量写成:
# 进入课程统一使用的 ~/esp 工作目录,后续相对路径都从这里计算。
cd "$HOME/esp"
不要把示例中的 /home/student/... 原样复制到自己的电脑。如果你没有把 ESP-IDF 放在 ~/esp,请把命令中的 "$HOME/esp" 替换成自己的实际工作目录。
命令仍使用双引号保护路径,但 ESP-IDF 源码目录和工程目录本身不要包含空格。ESP-IDF v5.5.4 官方文档明确说明构建系统不支持这两类路径中出现空格。
1. ESP-IDF 是什么
ESP-IDF(Espressif IoT Development Framework)是 Espressif 为 ESP32 系列芯片提供的官方开发框架。它不只是一个编译器,还包括:
芯片和外设驱动
FreeRTOS
构建系统
配置系统
烧录和串口监视工具
Python工具环境
组件管理器
交叉编译工具链
因此 ESP-IDF 版本变化可能同时带来:
- API 名称和参数变化;
- 驱动实现变化;
- 组件最低版本要求变化;
- Python 工具和编译器版本变化;
- 默认配置变化。
这就是为什么教程不能只写“安装任意一个 IDF”。
2. 为什么固定使用 v5.5.4
本课程后半段使用官方组件:
espressif/canopennode 0.1.0
这个组件封装了 CANopenNode。CANopenNode 是一个开源的 CANopen 协议栈,也就是一套已经实现 CANopen 通信规则的软件库。后半段实验会让 ESP32 使用它处理完整的 CANopen 通信;现在不需要学习怎样调用它,只需要知道它也是工程的一项软件依赖。
这个组件自己的依赖声明要求:
# 组件管理器会在编译前检查当前 ESP-IDF 版本;低于 5.5.4 时会直接停止依赖解析。
idf:
version: '>=5.5.4'
实际依赖关系是:
课程后半段的 CANopenNode 实验工程
↓
espressif/canopennode 0.1.0
↓
要求 ESP-IDF >= 5.5.4
我们已经真实验证过:使用 ESP-IDF v5.5.2 时,idf.py set-target esp32c3 在组件依赖求解阶段失败,甚至还没有开始编译 C 代码。
关键理解:这不是 ESP32-C3 不支持 CAN,也不是应用源码写错了,而是组件声明的最低 ESP-IDF 版本没有满足。
理论上可以使用高于 5.5.4 的兼容版本,但课程固定到准确的 v5.5.4,保证 API、构建输出和依赖解析与已经验证的环境一致。学会以后再升级,会更容易判断差异来自哪里。
3. 已经有其他 ESP-IDF 怎么办
不需要删除。不同版本可以放在不同目录,例如:
~/esp/
├── esp-idf/ 旧的 v5.5.2
└── esp-idf-v5.5.4/ 本课程使用的版本 v5.5.4
它们的源码目录互不覆盖。当前终端使用哪一个版本,由你最后加载的 export.sh 决定。
4. 安装系统依赖并检查目标目录
本课程的国内网络安装路线已经在下面的环境完成验证:
| 项目 | 验证环境 |
|---|---|
| 操作系统 | Ubuntu 24.04 LTS |
| CPU 架构 | x86_64 |
| Shell | Bash |
| 系统 Python | Python 3.12.3 |
| 目标芯片 | ESP32-C3 |
| 最终结果 | idf.py --version 输出 ESP-IDF v5.5.4 |
下面的系统软件包命令适用于 Ubuntu 和 Debian 系发行版。Windows、macOS、Arch Linux 等环境的软件包管理方式不同,应改用对应平台的官方安装步骤。
先确认系统和磁盘空间:
# 记录系统版本和剩余磁盘空间,空间不足时先不要开始安装。
cat /etc/os-release
uname -m
python3 --version
df -h "$HOME"
国内路线使用的完整压缩包约为 1.70 GiB,解压后的源码、交叉编译工具和 Python 环境还会继续占用空间。磁盘剩余空间如果只够存放压缩包,不要继续安装。
安装 ESP-IDF 构建依赖,以及国内路线需要的 unzip:
# 安装 ESP-IDF 编译工具和本教程后续会用到的解压、串口工具。
sudo apt update
sudo apt install -y \
git wget flex bison gperf \
python3 python3-pip python3-venv \
cmake ninja-build ccache \
libffi-dev libssl-dev \
dfu-util libusb-1.0-0 unzip
检查后续一定会用到的命令:
# 把完整压缩包解压到固定版本目录。
git --version
wget --version | head -n 1
python3 --version
cmake --version | head -n 1
ninja --version
unzip -v | head -n 1
如果某一条显示 command not found,先处理 apt install 输出中的第一条错误,不要继续下载 ESP-IDF。
创建工作目录并检查目标路径:
# 先确认目标路径不存在,避免覆盖之前的工程或源码。
mkdir -p "$HOME/esp"
cd "$HOME/esp"
pwd
test -e "$HOME/esp/esp-idf-v5.5.4"
echo $?
输出含义:
0 = 路径已经存在,不能直接覆盖
1 = 路径不存在,可以创建
如果目录已经存在,先检查:
# 确认目录确实是完整 Git 仓库,并核对当前版本。
git -C "$HOME/esp/esp-idf-v5.5.4" status
git -C "$HOME/esp/esp-idf-v5.5.4" describe --tags --always
看到陌生内容时不要删除重装。先确认它是不是已经完成的 v5.5.4 安装。
5. 根据网络情况取得 ESP-IDF 源码
安装 ESP-IDF 时会下载三类内容。它们使用的地址并不相同:

- ESP-IDF 源码:从 GitHub 克隆,或者从乐鑫发布服务器下载包含子模块的完整压缩包;
- 编译工具:由
install.sh下载,国内网络可以通过IDF_GITHUB_ASSETS改写其中的 GitHub Release Assets 地址; - Python 包:由
install.sh创建的 Python 环境安装,国内网络可以通过PIP_INDEX_URL指定镜像。
IDF_GITHUB_ASSETS 不会修改 Git 仓库地址,因此不能解决 git clone https://github.com/... 无法访问的问题。源码必须从下面两条路线中选择一条完整执行,不能把未完成的 Git 克隆目录与压缩包解压目录相互覆盖。
路线 A:国内网络下载乐鑫完整压缩包
GitHub 无法打开,或者 git clone 长时间没有进度时,使用这条已经在 Ubuntu 24.04 上完成验证的路线。
进入工作目录并保存固定下载地址:
# 进入课程统一使用的 ~/esp 工作目录,后续相对路径都从这里计算。
cd "$HOME/esp"
export IDF_ARCHIVE_URL="https://dl.espressif.com/github_assets/espressif/esp-idf/releases/download/v5.5.4/esp-idf-v5.5.4.zip"
先检查服务器能否访问:
# 只检查下载地址是否可访问,不下载文件。
wget --spider "$IDF_ARCHIVE_URL"
成功时会看到类似输出:
Remote file exists.
开始下载:
# 使用断点续传下载压缩包,网络中断后可以继续。
wget --continue "$IDF_ARCHIVE_URL"
--continue 表示断点续传。网络中断后,在同一终端回到 ~/esp 再执行这条命令即可继续。重新打开终端后,需要先重新设置 IDF_ARCHIVE_URL。
下载结束后不要立即解压,先检查 ZIP 是否完整:
# 先校验压缩包完整性;出现 CRC 或文件结尾错误时不要解压。
ls -lh "$HOME/esp/esp-idf-v5.5.4.zip"
unzip -t "$HOME/esp/esp-idf-v5.5.4.zip"
最后应出现类似结果:
No errors detected in compressed data of esp-idf-v5.5.4.zip.
如果出现 End-of-central-directory signature not found、unexpected end of file 或 CRC 错误,不要解压。先续传;仍然报错时,保留错误并重新获取完整文件。
确认目标目录不存在后解压:
# 把完整压缩包解压到固定版本目录。
test ! -e "$HOME/esp/esp-idf-v5.5.4"
echo $?
cd "$HOME/esp"
unzip -q esp-idf-v5.5.4.zip
test 输出 0 才表示目标目录不存在。这里必须使用官方发布页单独提供的 esp-idf-v5.5.4.zip。GitHub 页面自动生成的 Source code (zip) 不包含可直接安装的完整子模块内容,不能替代它。
压缩包解压完成只代表 ESP-IDF 源码已经就位,国内路线还没有结束。继续完成第 6 节的源码检查,并在运行 install.sh 之前执行第 7.1 节:同时设置编译工具下载地址和 Python 包镜像。
路线 B:网络可以稳定访问 GitHub
只有目标目录不存在时才执行:
# 从指定标签克隆 ESP-IDF,并把目录名固定为课程使用的版本。
cd "$HOME/esp"
git clone -b v5.5.4 --recursive \
https://github.com/espressif/esp-idf.git \
esp-idf-v5.5.4
各部分含义:
| 参数 | 含义 |
|---|---|
git clone | 下载一个 Git 仓库 |
-b v5.5.4 | 检出 v5.5.4 标签 |
--recursive | 同时下载 ESP-IDF 使用的 Git 子模块 |
| 最后一个参数 | 本地目录名称 |
ESP-IDF 包含子模块。遗漏 --recursive 可能导致后续安装或构建时缺少文件。
6. 检查版本和子模块
无论使用哪条下载路线,都从这里继续:
# 确认目录确实是完整 Git 仓库,并核对当前版本。
cd "$HOME/esp/esp-idf-v5.5.4"
test -x install.sh
echo $?
git describe --tags --always
git status --short
git submodule status
继续安装前应确认:
test输出0,说明install.sh存在并可执行;git describe显示v5.5.4;- 没有意外源码修改;
- 子模块行首不出现表示未初始化的
-。
7. 设置国内镜像并安装 ESP32-C3 工具
源码准备完成后,install.sh 还要下载编译工具和 Python 包。国内网络路线必须先完成下面两个镜像设置,不能直接跳到 ./install.sh esp32c3。
7.1 设置编译工具和 Python 包镜像
IDF_GITHUB_ASSETS用于改写安装脚本访问的 GitHub Release Assets 地址;PIP_INDEX_URL用于指定 ESP-IDF Python 依赖的包索引。
在即将运行安装脚本的同一个终端中执行:
# install.sh 读取这个变量后,会从乐鑫服务器取得交叉编译器等工具,避开 GitHub Assets。
export IDF_GITHUB_ASSETS="dl.espressif.cn/github_assets"
# ESP-IDF 创建自己的 Python 虚拟环境时,pip 会从这个国内镜像下载依赖包。
export PIP_INDEX_URL="https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
马上读回两个变量,避免变量名或地址输入错误:
# 这里不是再次设置变量,而是读回当前终端保存的值;两行都正确后才能运行 install.sh。
printf 'IDF_GITHUB_ASSETS=%s\n' "$IDF_GITHUB_ASSETS"
printf 'PIP_INDEX_URL=%s\n' "$PIP_INDEX_URL"
应当看到:
IDF_GITHUB_ASSETS=dl.espressif.cn/github_assets
PIP_INDEX_URL=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
这两个变量只对当前终端及其随后启动的子进程生效。读回结果正确后,保持当前终端打开。
7.2 运行 ESP32-C3 工具安装脚本
进入 ESP-IDF 源码目录并执行安装脚本:
# 必须留在刚才设置两个镜像变量的同一个终端中,否则新终端读不到这些临时变量。
cd "$HOME/esp/esp-idf-v5.5.4"
# esp32c3 参数只安装当前课程目标芯片需要的工具,减少无关工具下载。
./install.sh esp32c3
esp32c3 参数让脚本只准备课程目标芯片需要的工具。脚本会安装交叉编译器和辅助程序,并在默认的 $HOME/.espressif 下创建 ESP-IDF Python 环境;它不会删除旧 ESP-IDF 源码目录。
成功结束时,末尾会提示下一步加载 export.sh。不要只根据下载进度条判断结果,应确认脚本正常回到 shell 提示符,并查看末尾是否出现完成提示。
常见失败判断:
| 现象 | 先检查什么 | 不要做什么 |
|---|---|---|
| 压缩包下载中断 | 回到 ~/esp,重新设置下载变量并执行 wget --continue | 不要生成多个不同名称的残缺文件 |
unzip -t 报错 | 确认下载是否完整,再续传或重新下载 | 不要解压损坏的 ZIP |
install.sh 仍访问 GitHub | 用 echo "$IDF_GITHUB_ASSETS" 检查当前终端变量 | 不要把该变量误认为 Git 仓库代理 |
| Python 包下载失败 | 用 echo "$PIP_INDEX_URL" 检查索引,并保留第一条 pip 错误 | 不要关闭证书校验掩盖问题 |
No space left on device | 再次运行 df -h "$HOME" | 不要反复重跑安装脚本 |
Permission denied | 检查源码目录和脚本权限 | 不要使用 sudo ./install.sh 改变文件归属 |
排查时保留第一条真正的错误,不要只注意最后的 Installation failed。乐鑫服务器只镜像部分 GitHub Release Assets;某个资源仍然失败时,应记录其完整 URL 和第一条错误,再决定重试或切换网络。
8. 加载环境
打开一个尚未加载本课程 IDF 环境的终端后,执行:
# 在当前终端加载 ESP-IDF 环境;新开终端后需要重新执行。
source "$HOME/esp/esp-idf-v5.5.4/export.sh"
这里的 source 表示在当前 shell 中执行脚本。脚本会设置:
IDF_PATH;idf.py搜索路径;- ESP32-C3 工具链搜索路径;
- ESP-IDF 使用的 Python 环境。
更准确地说,这些变量保存在当前 shell 进程的环境中,并会传给它启动的子进程。source 不会自动修改其他已经打开的终端,也不会自动写入 .bashrc 等启动配置。
新开的终端是否已经有 ESP-IDF 环境,要看你的系统配置:
- 没有配置自动加载时,通常找不到
idf.py; .bashrc等文件加载了旧 IDF 时,可能显示另一个版本;- 配置过 v5.5.4 自动加载,或者新 shell 继承了已有环境时,也可能直接显示 v5.5.4。
因此不要根据“是不是新终端”猜测版本,始终查看 IDF_PATH 和 idf.py --version 的实际输出。
9. 必须进行的环境检查
# 确认目录确实是完整 Git 仓库,并核对当前版本。
echo "$IDF_PATH"
idf.py --version
python --version
git -C "$IDF_PATH" describe --tags --always
IDF_PATH 应指向你安装的 esp-idf-v5.5.4 目录。例如按照本教程的目录安装时,三项关键结果是:
IDF_PATH:<你的主目录>/esp/esp-idf-v5.5.4
idf.py --version:ESP-IDF v5.5.4
git describe:v5.5.4
Python 小版本由 ESP-IDF 安装环境决定,记录实际输出即可。
还可以让 shell 直接比较路径:
# 直接比较 IDF_PATH 与课程路径;返回 0 才表示两者完全一致。
test "$IDF_PATH" = "$HOME/esp/esp-idf-v5.5.4"
echo $?
输出 0 表示两边一致。如果你把 IDF 安装在其他目录,应把右侧改成自己的安装路径。
10. 新终端练习
打开一个新终端,先不要执行 export.sh,查看它原本使用什么环境:
# 逐项确认命令已经安装;没有输出的那一项需要先补装。
echo "$IDF_PATH"
command -v idf.py
idf.py --version
可能出现以下任意一种情况:
| 结果 | 说明 |
|---|---|
idf.py: command not found | 这个 shell 还没有加载 ESP-IDF,属于正常现象 |
| 显示其他 IDF 版本 | PATH 或 shell 启动配置中已有另一个 ESP-IDF |
| 已显示 v5.5.4 | 当前环境已经加载了本课程版本,继续核对 IDF_PATH |
然后在同一个终端中执行:
# 在当前终端加载 ESP-IDF 环境;新开终端后需要重新执行。
source "$HOME/esp/esp-idf-v5.5.4/export.sh"
echo "$IDF_PATH"
command -v idf.py
idf.py --version
最终应确认:
IDF_PATH 指向你安装的 esp-idf-v5.5.4 目录
idf.py --version 显示 ESP-IDF v5.5.4
这个练习真正要说明的是:ESP-IDF 的选择由 shell 环境决定,不能仅凭安装目录存在或终端是不是刚打开来判断。
这一课只需要记住五句话
- ESP-IDF 是一整套 SDK、工具链和构建环境,不只是一个头文件库。
- 官方 CANopenNode 0.1.0 要求 ESP-IDF 至少为 v5.5.4。
- GitHub 克隆和乐鑫完整压缩包都能得到课程需要的源码,但不能混用两个未完成的目录。
- 国内路线在运行
install.sh前还必须设置IDF_GITHUB_ASSETS和PIP_INDEX_URL,压缩包只解决源码获取问题。 - 多个 IDF 可以并行存在,当前终端使用哪个版本由
source .../export.sh决定。
完成检查
在实验记录中保存以下三条命令的实际输出:
# 确认目录确实是完整 Git 仓库,并核对当前版本。
echo "$IDF_PATH"
idf.py --version
git -C "$IDF_PATH" describe --tags --always
三项都指向 v5.5.4,这一课才算通过。
如果使用国内网络路线,还要在安装记录中保留下面两个变量的读回结果,证明工具下载地址和 Python 包镜像都在运行 install.sh 前生效:
# 让 ESP-IDF 的 Python 环境从国内镜像安装依赖包。
printf 'IDF_GITHUB_ASSETS=%s\n' "$IDF_GITHUB_ASSETS"
printf 'PIP_INDEX_URL=%s\n' "$PIP_INDEX_URL"