目录
ESP-ADF battery_service组件之voltage_monitor子模块事件与报告控制函数详解
版本信息: v2.7-65-gcf908721
本章节分析的源码位于
/components/battery_service/monitors/voltage_monitor.c
文件
事件处理与报告控制函数分析
电压监控模块提供了两类关键功能:事件处理和电压报告控制。事件处理允许应用程序接收电压相关事件,而报告控制功能则允许应用程序配置电压报告的行为。
vol_monitor_set_event_cb
vol_monitor_set_event_cb
函数用于设置事件回调函数,为电压监控模块提供事件通知机制。下面是其源码实现:
/**
* @brief 设置电压监控事件回调函数
*
* 该函数完成以下主要操作:
* 1. 检查句柄有效性
* 2. 获取互斥锁以保护共享数据
* 3. 设置事件回调函数和用户上下文
* 4. 释放互斥锁
*
* 设置的回调函数将在满足报告条件或触发阈值时被调用
*
* @param handle 电压监控句柄
* @param event_cb 事件回调函数
* @param user_ctx 用户上下文数据,将在回调时传递
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t vol_monitor_set_event_cb(vol_monitor_handle_t handle, vol_monitor_event_cb event_cb, void *user_ctx)
{
// 检查句柄是否有效
AUDIO_NULL_CHECK(TAG, handle, return ESP_FAIL);
// 将句柄转换为内部实现类型
vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle;
// 获取互斥锁
mutex_lock(vol_monitor->mutex);
// 设置事件回调函数和用户上下文
vol_monitor->event_cb = event_cb;
vol_monitor->user_ctx = user_ctx;
// 释放互斥锁
mutex_unlock(vol_monitor->mutex);
return ESP_OK;
}
下面的时序图展示了 vol_monitor_set_event_cb
函数的执行流程:
这个函数是电压监控模块的事件处理机制核心,它为应用程序提供了接收电压相关事件的能力。通过设置回调函数,应用程序可以在电压达到特定阈值或定期报告时得到通知。
vol_monitor_start_freq_report
vol_monitor_start_freq_report
函数用于启动定期电压报告。下面是其源码实现:
/**
* @brief 启动定期电压报告
*
* 该函数完成以下主要操作:
* 1. 检查句柄有效性
* 2. 获取互斥锁以保护共享数据
* 3. 检查报告频率是否有效
* 4. 设置报告启动标志
* 5. 释放互斥锁
*
* 启动成功后,电压监控模块将根据配置的频率定期触发电压报告事件
*
* @param handle 电压监控句柄
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t vol_monitor_start_freq_report(vol_monitor_handle_t handle)
{
// 检查句柄是否有效
AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);
// 将句柄转换为内部实现类型
vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle;
esp_err_t ret = ESP_OK;
// 获取互斥锁
mutex_lock(vol_monitor->mutex);
// 检查报告频率并设置报告启动标志
if (vol_monitor->config->report_freq > 0) {
vol_monitor->report_start = vol_monitor->config->report_freq;
ret = ESP_OK;
} else {
ESP_LOGW(TAG, "report freq <= 0");
ret = ESP_FAIL;
}
// 释放互斥锁
mutex_unlock(vol_monitor->mutex);
return ret;
}
下面的时序图展示了 vol_monitor_start_freq_report
函数的执行流程:
这个函数启动定期电压报告机制,激活定时器回调中的报告逻辑。只有当配置的报告频率大于零时,报告才会被启动。
vol_monitor_stop_freq_report
vol_monitor_stop_freq_report
函数用于停止定期电压报告。下面是其源码实现:
/**
* @brief 停止定期电压报告
*
* 该函数完成以下主要操作:
* 1. 检查句柄有效性
* 2. 获取互斥锁以保护共享数据
* 3. 清除报告启动标志
* 4. 释放互斥锁
*
* 停止后,电压监控模块将不再触发定期电压报告事件,但仍会检测并报告阈值事件
*
* @param handle 电压监控句柄
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t vol_monitor_stop_freq_report(vol_monitor_handle_t handle)
{
// 检查句柄是否有效
AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);
// 将句柄转换为内部实现类型
vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle;
// 获取互斥锁
mutex_lock(vol_monitor->mutex);
// 清除报告启动标志
vol_monitor->report_start = 0;
// 释放互斥锁
mutex_unlock(vol_monitor->mutex);
return ESP_OK;
}
下面的时序图展示了 vol_monitor_stop_freq_report
函数的执行流程:
这个函数通过清除报告启动标志来停止定期电压报告。停止后,定时器回调仍会继续执行,但不会触发定期报告事件。
vol_monitor_set_report_freq
vol_monitor_set_report_freq
函数用于设置电压报告频率。下面是其源码实现:
/**
* @brief 设置电压报告频率
*
* 该函数完成以下主要操作:
* 1. 检查句柄有效性
* 2. 获取互斥锁以保护共享数据
* 3. 更新报告频率设置
* 4. 根据新频率更新报告状态
* 5. 释放互斥锁
*
* 可以在运行时动态调整报告频率,立即生效
* 设置为0可以禁用定期报告功能
*
* @param handle 电压监控句柄
* @param freq 新的报告频率
* @return esp_err_t 成功返回ESP_OK,失败返回错误码
*/
esp_err_t vol_monitor_set_report_freq(vol_monitor_handle_t handle, int freq)
{
// 检查句柄是否有效
AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);
// 将句柄转换为内部实现类型
vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle;
// 获取互斥锁
mutex_lock(vol_monitor->mutex);
// 更新报告频率
vol_monitor->config->report_freq = freq;
// 根据新频率更新报告状态
if (vol_monitor->config->report_freq > 0 && vol_monitor->report_start > 0) {
// 重置计数器并更新报告启动标志
vol_monitor->read_cnt = 0;
vol_monitor->report_start = vol_monitor->config->report_freq;
} else if (vol_monitor->config->report_freq == 0) {
// 频率为0时禁用报告
vol_monitor->read_cnt = 0;
vol_monitor->report_start = 0;
}
// 释放互斥锁
mutex_unlock(vol_monitor->mutex);
return ESP_OK;
}
下面的时序图展示了 vol_monitor_set_report_freq
函数的执行流程:
这个函数允许动态调整电压报告的频率。当频率设置为0时,将禁用定期报告功能。对于正在运行的报告,函数会重置计数器并更新报告启动标志,使新的频率设置立即生效。
事件处理与报告控制机制
电压监控模块的事件处理与报告控制机制是紧密相关的。事件处理提供了应用程序接收电池状态通知的接口,而报告控制则允许应用程序精确控制何时以及如何接收这些通知。
事件触发流程
下面的图表展示了电压事件的触发流程:
报告控制状态机
电压报告控制可以看作一个简单的状态机:
事件与报告控制函数汇总
事件处理
函数名 | 功能描述 |
---|---|
vol_monitor_set_event_cb | 设置事件回调函数,用于接收电压相关事件通知 |
电压报告控制
函数名 | 功能描述 |
---|---|
vol_monitor_start_freq_report | 启动定期电压报告,使电压监控模块开始按配置频率报告电压值 |
vol_monitor_stop_freq_report | 停止定期电压报告,不再触发定期报告事件 |
vol_monitor_set_report_freq | 设置电压报告频率,可以在运行时动态调整报告间隔 |
使用示例
下面是电压监控模块事件处理与报告控制的使用示例:
// 定义电压事件处理回调函数
static void voltage_event_handler(int event_id, void *data, void *user_ctx)
{
int voltage = (int)data;
switch (event_id) {
case VOL_MONITOR_EVENT_FREQ_REPORT:
printf("定期电压报告: %d mV\n", voltage);
break;
case VOL_MONITOR_EVENT_BAT_FULL:
printf("电池已充满: %d mV\n", voltage);
break;
case VOL_MONITOR_EVENT_BAT_LOW:
printf("电池电量低: %d mV\n", voltage);
break;
default:
break;
}
}
// 使用示例
void battery_monitor_example(void)
{
// 创建电压监控实例
vol_monitor_handle_t monitor = vol_monitor_create(&vol_config);
if (monitor) {
// 设置事件回调
vol_monitor_set_event_cb(monitor, voltage_event_handler, NULL);
// 启动定期报告
vol_monitor_start_freq_report(monitor);
// ... 应用运行一段时间 ...
// 调整报告频率
vol_monitor_set_report_freq(monitor, 6); // 修改为每6次读取报告一次
// ... 应用继续运行 ...
// 停止报告
vol_monitor_stop_freq_report(monitor);
// 清理资源
vol_monitor_destroy(monitor);
}
}