1.环境依赖
Win10
ESP-IDF: v4.4.6
开发板: ESP32S3
VSCode: 1.91.1 (system setup)
2.背景介绍
在我们基于 ESP-IDF 开发程序的过程中,假如我们在 The ESP Component Registry 里没有找到我们所需要的组件。我们通常会希望把已有的稳定的例程整体迁移到自己的项目中,并且作为一个component 来使用。本次,我们以 blufi 例程为例,介绍改造过程。
3.解决方案
3.1. 跑通 blufi 例程
首先,我们可以在 VSCode 中,按下 F1 ,选择 ESP-IDF: Show Examples Projects ,在搜索栏搜索 blufi ,点击 Create project using example blufi 按钮,选择目录,生成项目。
项目初始化完毕后,我们需要根据芯片型号来进行配置。比如我的是 ESP32S3:
然后,我们开始进行配置,比如你有 PSRAM 啊等等。其中,最重要的就是确认蓝牙已经打开:
先跑通本例程,确保你使用下面官方提供的移动端应用,已经可以正常配置开发板的 Wi-Fi:
3.2. 新建 sample_project 项目,复制例程中的文件
我们可以通过新建一个 sample_project 来添加 blufi 为 component 。
首先我们把 blufi 项目下的 sdkconfig 复制到本项目下,比如说蓝牙是否打开这种问题,就不存在了。 现在我们按下F1,选择 ESP-IDF: Create New ESP-IDF Component,名字就叫 blufi。
💡 如今的 component 非常规范,在 include/ 目录下写 .h 文件,组件根目录下放置 .c 文件。
现在,我们把例程项目中的 .h 和 .c 以及 Kconfig.projbuild 文件复制过来。
这里为了美观,我们稍稍修改带 example 后缀的文件,将例程中的blufi_example.h的代码复制到自动生成的blufi.h文件中,将 blufi_example_main.c 中的内容复制到已自动生成的 blufi.c 文件中。并且,我们全局替换 blufi_example.h 为 blufi.h 。也就是说,文件目录结构如下:
3.3. 修改 app_main 函数
由于程序都有入口点 app_main,我们把组件中的 app_main 更名为 start_blufi,并在 .h 文件里添加上对应的声明。 然后我们进行编译。这个时候,我们会遇到一个异常:
nvs_flash.h: No such file or directory
这就是说,我们的组件缺乏依赖,我们需要在 CMakeLists.txt 中添加依赖,它的写法是:
idf_component_register(SRCS "blufi.c"
INCLUDE_DIRS "include"
REQUIRES nvs_flash
)
💡 这里的依赖组件的查找方式为:先按下 Full Clean 按钮,然后 VSCode 就可以感知到 .h 文件了,跳转到 .h 文件中,看上方 components/ 下的目录是什么,组件就叫什么。
再有,把要编译的所有源文件,也要在 CMakeLists.txt 中描述清楚,那就会变成下面这样:
idf_component_register(SRCS "blufi.c" "blufi_security.c" "blufi_init.c"
INCLUDE_DIRS "include"
REQUIRES nvs_flash
)
大概就是上面这样的修改流程,反复去查看报错,你就能把一个组件的所有依赖排查清楚。如果遇到类型找不到,就 #include 相应的 .h 文件
3.4. 将 nvs_flash 的初始化写到 main.c
通常情况下,官方例程的第一步都是初始化nvs,我们在写项目时,又不可能只包含一个组件。所以我们要避免多次初始化 nvs_flash ,我们删除 blufi.h 中有关于初始化的代码,将 main.c 改为:
#include <stdio.h>
#include "blufi.h"
#include "nvs_flash.h"
void app_main(void)
{
esp_err_t ret;
// Initialize NVS
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
start_blufi();
}
现在,我们进行编译和烧录,不出意外的话,当你看到这样的打印,就表示你已经成功啦:
I (692) wifi:state: assoc -> run (10)
I (792) wifi:connected with zxy-device-2.4, aid = 3, channel 5, BW20, bssid = 76:7d:24:9e:80:b9
I (792) wifi:security: WPA2-PSK, phy: bgn, rssi: -47
I (802) wifi:pm start, type: 1
I (802) wifi:set rx beacon pti, rx_bcn_pti: 14, bcn_timeout: 14, mt_pti: 25000, mt_time: 10000
I (882) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (1812) esp_netif_handlers: sta ip: 192.168.8.88, mask: 255.255.255.0, gw: 192.168.8.1
I (1812) BLUFI_EXAMPLE: BLUFI BLE is not connected yet
4.可能遇到的问题
4.1.PSRAM line mode 错误
会出现类似下面的异常:
psram: PSRAM ID read error: 0x00ffffff, PSRAM chip not found or not supported, or wrong PSRAM line mode
这个异常多半是在选择四线还是八线模式的时候选错了,比如我是八线(Octal),结果错选成了四线(Quad),就会报这种错误。
我们可以打开 SDK Configuration editor ,搜索 Mode,找到类似于 Mode (QUAD/OCT) of SPI RAM chip in use 的配置项,选择上正确的线模式就好。
💡 当然你也可以在 idf.py menuconfig 中进行修改
4.2. blufi 所遵循的协议是什么?
BluFi 是一项基于蓝牙通道的 Wi-Fi 网络配置功能,适用于 ESP32。它通过安全协议将 Wi-Fi 的 SSID、密码等配置信息传输到 ESP32。基于这些信息,ESP32 可进而连接到 AP 或建立 SoftAP。
BluFi 流程的关键部分包括数据的分片、加密以及校验和验证。
关于BluFi,官方有一个 介绍 ,可以通过这个介绍来详细了解它。
结语
如果你和我的开发环境是高度一致的,你可以访问我已经整理好的代码仓库:esp-idf-example2component 来获得一个demo。
欢迎大家在评论区里华山论剑!
修改记录
| 时间 | 内容 |
|---|---|
| 2024-07-29 | 完成初稿 |