目录
ESP-ADF wifi_service子模块esp_wifi_setting配网控制函数详解
版本信息: v2.7-65-gcf908721
本章节分析的源码位于
/components/wifi_service/src/esp_wifi_setting.c
文件
WiFi配网控制函数分析
ESP-ADF的esp_wifi_setting模块提供了一组函数用于控制WiFi配网的启动、停止和资源清理。这些函数构成了配网过程的核心控制接口,使应用程序能够统一管理不同的配网方式。
esp_wifi_setting_start
esp_wifi_setting_start
函数用于启动WiFi配网过程。下面是其源码实现:
/**
* @brief 启动WiFi配网
*
* 该函数完成以下主要操作:
* 1. 检查配网句柄是否有效
* 2. 调用配网实现注册的start函数
*
* 实际的配网启动过程由具体配网实现(如smart_config、blufi等)提供的
* start回调函数完成,如果未注册start函数,则直接返回成功
*
* @param handle 配网接口句柄,由esp_wifi_setting_create创建
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t esp_wifi_setting_start(esp_wifi_setting_handle_t handle)
{
AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);
if (handle->start) {
return handle->start(handle);
}
return ESP_OK;
}
下面的时序图展示了esp_wifi_setting_start
函数的执行流程:
esp_wifi_setting_start
函数通过函数指针调用实际的配网实现提供的启动函数。这种设计体现了ESP-ADF的插件式架构,允许不同的配网方式实现各自的启动逻辑。
esp_wifi_setting_stop
esp_wifi_setting_stop
函数用于停止正在进行的WiFi配网过程。下面是其源码实现:
/**
* @brief 停止WiFi配网
*
* 该函数完成以下主要操作:
* 1. 检查配网句柄是否有效
* 2. 调用配网实现注册的stop函数
*
* 实际的配网停止过程由具体配网实现提供的stop回调函数完成,
* 如果未注册stop函数,则直接返回成功
*
* @param handle 配网接口句柄,由esp_wifi_setting_create创建
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t esp_wifi_setting_stop(esp_wifi_setting_handle_t handle)
{
AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);
if (handle->stop) {
return handle->stop(handle);
}
return ESP_OK;
}
下面的时序图展示了esp_wifi_setting_stop
函数的执行流程:
与esp_wifi_setting_start
类似,esp_wifi_setting_stop
函数通过函数指针调用实际的配网实现提供的停止函数。这使得不同的配网方式可以实现各自特定的停止逻辑,例如释放资源、关闭硬件等。
esp_wifi_setting_teardown
esp_wifi_setting_teardown
函数用于清理WiFi配网相关的资源。下面是其源码实现:
/**
* @brief 清理WiFi配网资源
*
* 该函数完成以下主要操作:
* 1. 检查配网句柄是否有效
* 2. 调用配网实现注册的teardown函数
*
* 实际的资源清理过程由具体配网实现提供的teardown回调函数完成,
* 如果未注册teardown函数,则直接返回成功
*
* 与stop函数不同,teardown通常在配网完成后调用,用于彻底清理资源,
* 并且需要传入wifi_config_t参数,包含获取到的WiFi配置信息
*
* @param handle 配网接口句柄,由esp_wifi_setting_create创建
* @param info WiFi配置信息,包含SSID和密码等
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t esp_wifi_setting_teardown(esp_wifi_setting_handle_t handle, wifi_config_t *info)
{
AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);
if (handle->teardown) {
return handle->teardown(handle, info);
}
return ESP_OK;
}
下面的时序图展示了esp_wifi_setting_teardown
函数的执行流程:
esp_wifi_setting_teardown
与其他两个函数有一个关键区别:它接收额外的wifi_config_t
参数,用于传递获取到的WiFi配置信息。这个函数通常在配网成功获取WiFi信息后调用,目的是清理配网过程中使用的资源,例如关闭创建的任务、释放内存等。
内部实现机制
从上面的分析可以看出,WiFi配网控制函数都采用了基于函数指针的设计模式:
- 统一接口:这三个函数提供了统一的接口,隐藏了不同配网方式的实现细节
- 函数指针委托:实际功能通过调用注册的函数指针实现,展现了多态行为
- 空指针保护:对未注册的函数指针进行了检查,避免了空指针调用
- 成功默认值:当函数指针为NULL时,默认返回ESP_OK而非错误,简化了使用
这种设计有以下几个优点:
- 高度抽象:应用程序只需调用统一接口,不需要关心具体配网实现
- 松散耦合:控制函数与具体实现完全解耦,便于扩展和维护
- 插件式架构:可以轻松添加新的配网方式,只需实现相应的回调函数
- 错误处理:统一的错误检查和返回机制,简化了调用方的处理
函数指针注册机制
这些控制函数能够正常工作的前提是配网实现已经通过esp_wifi_setting_register_function
函数注册了相应的回调函数:
esp_err_t esp_wifi_setting_register_function(esp_wifi_setting_handle_t handle,
wifi_setting_func start,
wifi_setting_func stop,
wifi_setting_teardown_func teardown)
{
handle->start = start;
handle->stop = stop;
handle->teardown = teardown;
return ESP_OK;
}
通过这个注册机制,不同的配网实现可以提供各自特定的启动、停止和清理逻辑,实现了高度的灵活性和可扩展性。
调用关系与控制流
在ESP-ADF的WiFi服务中,配网控制函数的调用关系如下:
- WiFi服务(
wifi_service.c
)在收到配网相关命令时,会调用配网控制函数 - 配网控制函数通过函数指针调用具体配网实现的相应函数
- 具体配网实现执行实际操作,如启动SmartConfig、停止BLE配网等
- 操作结果通过返回值传递回WiFi服务
应用示例
下面是一个使用配网控制函数的简单示例,展示了如何在配网实现中使用这些函数:
#include "esp_log.h"
#include "esp_wifi_setting.h"
#include "audio_mem.h"
static const char *TAG = "CUSTOM_CONFIG";
// 配网实现函数
static esp_err_t custom_config_start(esp_wifi_setting_handle_t handle)
{
ESP_LOGI(TAG, "开始自定义配网");
// 获取用户配置数据
custom_config_t *cfg = esp_wifi_setting_get_data(handle);
if (cfg == NULL) {
ESP_LOGE(TAG, "未找到配置数据");
return ESP_FAIL;
}
// 实现配网启动逻辑,例如:
// 1. 创建任务处理配网
// 2. 初始化必要的硬件
// 3. 设置必要的标志
return ESP_OK;
}
static esp_err_t custom_config_stop(esp_wifi_setting_handle_t handle)
{
ESP_LOGI(TAG, "停止自定义配网");
// 实现配网停止逻辑,例如:
// 1. 关闭硬件
// 2. 设置停止标志
return ESP_OK;
}
static esp_err_t custom_config_teardown(esp_wifi_setting_handle_t handle, wifi_config_t *info)
{
ESP_LOGI(TAG, "清理自定义配网资源");
// 实现资源清理逻辑,例如:
// 1. 删除创建的任务
// 2. 释放分配的内存
// 3. 关闭打开的文件或设备
// 如果info不为NULL,可以处理或记录获取到的WiFi信息
if (info != NULL) {
ESP_LOGI(TAG, "获取到的SSID: %s", info->sta.ssid);
}
return ESP_OK;
}
// 创建配网实例并注册函数
esp_wifi_setting_handle_t custom_config_create(void)
{
// 创建配网接口实例
esp_wifi_setting_handle_t handle = esp_wifi_setting_create("custom_config");
if (handle == NULL) {
ESP_LOGE(TAG, "创建配网接口失败");
return NULL;
}
// 注册配网函数
esp_wifi_setting_register_function(handle,
custom_config_start,
custom_config_stop,
custom_config_teardown);
// 创建并设置配置数据
custom_config_t *cfg = audio_calloc(1, sizeof(custom_config_t));
if (cfg) {
cfg->timeout_sec = 60;
cfg->channel = 6;
esp_wifi_setting_set_data(handle, cfg);
}
return handle;
}
// 使用自定义配网的WiFi服务示例
void app_main(void)
{
// 创建WiFi服务
periph_service_handle_t wifi_service = wifi_service_create(&wifi_cfg);
// 创建自定义配网实例
esp_wifi_setting_handle_t custom_handle = custom_config_create();
// 注册到WiFi服务
int index = 0;
wifi_service_register_setting_handle(wifi_service, custom_handle, &index);
// 设置配网通知回调
esp_wifi_setting_register_notify_handle(custom_handle, wifi_service);
// 启动配网过程
wifi_service_setting_start(wifi_service, index);
// ... 其他应用逻辑 ...
// 停止配网过程
wifi_service_setting_stop(wifi_service, index);
// 销毁服务
wifi_service_destroy(wifi_service);
}
在这个示例中,我们首先创建了一个自定义配网方式,并实现了启动、停止和清理函数。然后,我们将这些函数注册到配网接口,并将配网接口注册到WiFi服务。最后,通过WiFi服务的接口启动和停止配网过程。
配网控制流程
下面的流程图展示了配网过程中各函数的调用关系:
总结
ESP-ADF的WiFi配网控制函数提供了一套灵活、可扩展的接口,用于管理不同WiFi配网方式的启动、停止和资源清理。通过函数指针和多态设计,这些函数实现了配网接口与具体实现的解耦,使开发者能够更方便地添加新的配网方式并集成到WiFi服务中。
这些函数的设计体现了以下几个关键特点:
- 统一接口:提供了统一的调用方式,简化了应用开发
- 插件式架构:基于函数指针实现的多态行为,支持多种配网方式
- 错误处理:完善的参数检查和错误处理,提高了系统稳定性
- 资源管理:通过teardown函数确保资源的正确释放,避免资源泄漏
通过合理使用这些配网控制函数,开发者可以更轻松地实现和管理不同的WiFi配网方式,提高用户体验和系统可靠性。