前言
最近因公司业务需要,接触了 ESP32 芯片,中途踩了不少坑,也慢慢熟悉了 ESP32 的开发流程。我使用了乐鑫官方的 ESP-IDF 作为编译工具,其他版本有 arduino-esp32、PlatformIO,但它们底层也是基于 ESP-IDF,只不过进行了一层 API 封装。为了优雅的使用 ESP-IDF,我选择 WSL2 作为我的开发环境,这样做的好处是可以与宿主机隔离,避免污染宿主机环境。
本文将介绍如何基于 WSL2 Ubuntu22.04 系统,搭建一个 ESP-IDF 开发环境,实现成功编译项目并烧录到 ESP32-S3 中。话不多说,马上开始。
流程
具体的流程如下:
使用 apt 安装相关软件包
在终端运行如下命令:
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
注意:CMake 版本需要 3.16 以上,建议使用 20.04 以上的 Ubuntu 系统,这样会自动安装新版本的软件源。
获取 ESP-IDF
接下来获取 ESP-IDF 源码,在终端运行如下命令:
mkdir -p ~/esp
cd ~/esp
git clone -b v5.4.1 --recursive https://github.com/espressif/esp-idf.git
ESP-IDF 将下载至 ~/esp/esp-idf
,建议不要修改下载路径,使用上述路径。
设置工具
由于我使用的是 ESP32-S3,需要为该芯片安装需要用到的工具,在终端运行如下命令:
cd ~/esp/esp-idf
./install.sh esp32s3
如果想安装所有 ESP 的芯片工具,可以运行如下命令:
cd ~/esp/esp-idf
./install.sh all
等待片刻即可安装完成。如果下载安装速度较慢,可以使用国内服务器:
cd ~/esp/esp-idf
export IDF_GITHUB_ASSETS="dl.espressif.cn/github_assets"
./install.sh esp32s3
安装成功之后,导出环境变量,运行如下命令:
. ./export.sh
设置环境变量
接下来进行环境变量设置,让我们可以在终端使用 ESP-IDF 工具进行各种操作,有两种设置环境变量的方式:
- 直接导出:这种方式的缺点是每次重开终端都要运行一大段命令,不太优雅。
终端运行如下命令:
. $HOME/esp/esp-idf/export.sh
- 【推荐】放到 shell 配置中作为别名:这种方式的优点是每次重开终端只需运行别名即可。
复制并粘贴以下命令到 shell 配置文件中(.profile
、.bashrc
、.zprofile
等)
alias get_idf='. $HOME/esp/esp-idf/export.sh'
通过重启终端窗口或运行 source [path to profile]
,如 source ~/.bashrc
来刷新配置文件。
现在可以在任何终端窗口中运行 get_idf
来设置或刷新 ESP-IDF 环境。
编译项目
设置完 ESP-IDF 环境变量之后,就可以愉快的使用了。我们来运行一个 Hello-World 程序看看效果,官方的 ESP-IDF 工具提供了各种示例源码,可以直接使用。
运行如下命令:
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world .
cd hello_world
# 将工程配置为 esp32s3
idf.py set-target esp32s3
配置成功之后,运行如下命令进行项目编译:
idf.py build
运行以上命令可以编译应用程序和所有 ESP-IDF 组件,接着生成引导加载程序、分区表和应用程序二进制文件。
$ idf.py build
Running cmake in directory /path/to/hello_world/build
Executing "cmake -G Ninja --warn-uninitialized /path/to/hello_world"...
Warn about uninitialized values.
-- Found Git: /usr/bin/git (found version "2.17.0")
-- Building empty aws_iot component due to configuration
-- Component names: ...
-- Component paths: ...
... (more lines of build system output)
[527/527] Generating hello_world.bin
esptool.py v2.3.1
Project build complete. To flash, run this command:
../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 921600 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x10000 build/hello_world.bin build 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin
or run 'idf.py -p PORT flash'
烧录固件
在 WSL2 进行固件烧录会比较麻烦,需要用到 usbipd-win 软件,它的作用是将 Windows 的串口转到 WSL2 内部。
- 前往 usbipd-win 项目的最新发布页面。 https://github.com/dorssel/usbipd-win/releases
- 选择.msi 文件,这将下载安装程序。(您可能会收到一个警告,要求您确认信任此下载)。
- 运行下载的 usbipd-win_x.msi 安装程序文件。
安装成功之后,将 ESP32-S3 接入主机,打开 设备管理器,查看端口,可以看到如下:
上图可以看到,我的串口为 COM13。接着,以管理员模式打开 PowerShell,运行如下命令:
usbipd list
会打印如下:
Connected:
BUSID VID:PID DEVICE STATE
1-5 303a:1001 USB 串行设备 (COM13), USB JTAG/serial debug unit Not shared
1-9 05ac:024f USB 输入设备 Not shared
接下来,运行如下命令将 COM13 设置为 Shared 状态:
usbipd bind --busid 1-5
1-5 表示总线ID,请以你的总线ID为准。此时,重新运行 usbipd list
命令,会打印如下输出:
Connected:
BUSID VID:PID DEVICE STATE
1-5 303a:1001 USB 串行设备 (COM13), USB JTAG/serial debug unit Not shared
1-9 05ac:024f USB 输入设备 Shared
之后,将该 COM 口转到 WSL2 内部,运行如下命令:
usbipd attach --wsl --busid 1-5
重新运行 usbipd list
命令,会打印如下输出:
Connected:
BUSID VID:PID DEVICE STATE
1-5 303a:1001 USB 串行设备 (COM13), USB JTAG/serial debug unit Attached
1-9 05ac:024f USB 输入设备 Not shared
表示转到 WSL2 内部成功,此时我们无法在宿主机 Windows 上操作该串口,只能在 WSL2 内部,如果要在宿主机操作该串口,可以拔掉串口线重新插或者运行 usbipd detach --busid 1-5
命令。
打开 WSL2 内部,可以看到在 /dev
目录下会多出一个字符设备:ttyACM0
,此时表现上述操作成功,接下来就可以愉快的进行烧录了,在 hello_world 项目目录下,运行如下命令:
idf.py -p /dev/ttyACM0 flash monitor
注:如果不指定
-p
参数,将会默认使用/dev/ttyACM0
。
monitor
参数用于监控串口日志。
等待片刻烧录成功后,就可以在终端看到相关日志打印了。