ESP-ADF battery_service组件之voltage_monitor子模块事件与报告控制函数详解

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_set_event_cb vol_monitor_ctx_t 互斥锁 调用(handle, event_cb, user_ctx) 参数检查 mutex_lock(获取互斥锁) 锁定成功 设置event_cb和user_ctx mutex_unlock(释放互斥锁) 释放成功 返回ESP_OK 返回ESP_FAIL alt [句柄有效] [句柄无效] 应用程序 vol_monitor_set_event_cb vol_monitor_ctx_t 互斥锁

这个函数是电压监控模块的事件处理机制核心,它为应用程序提供了接收电压相关事件的能力。通过设置回调函数,应用程序可以在电压达到特定阈值或定期报告时得到通知。

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_start_freq_report vol_monitor_ctx_t 互斥锁 调用(handle) 参数检查 mutex_lock(获取互斥锁) 锁定成功 设置report_start = report_freq ret = ESP_OK 记录警告日志 ret = ESP_FAIL alt [report_freq > 0] [report_freq <= 0] mutex_unlock(释放互斥锁) 释放成功 返回ret 应用程序 vol_monitor_start_freq_report vol_monitor_ctx_t 互斥锁

这个函数启动定期电压报告机制,激活定时器回调中的报告逻辑。只有当配置的报告频率大于零时,报告才会被启动。

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_stop_freq_report vol_monitor_ctx_t 互斥锁 调用(handle) 参数检查 mutex_lock(获取互斥锁) 锁定成功 设置report_start = 0 mutex_unlock(释放互斥锁) 释放成功 返回ESP_OK 返回ESP_ERR_INVALID_ARG alt [句柄有效] [句柄无效] 应用程序 vol_monitor_stop_freq_report vol_monitor_ctx_t 互斥锁

这个函数通过清除报告启动标志来停止定期电压报告。停止后,定时器回调仍会继续执行,但不会触发定期报告事件。

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 函数的执行流程:

应用程序 vol_monitor_set_report_freq vol_monitor_ctx_t 互斥锁 调用(handle, freq) 参数检查 mutex_lock(获取互斥锁) 锁定成功 更新report_freq = freq 重置read_cnt = 0 更新report_start = report_freq 重置read_cnt = 0 禁用报告report_start = 0 alt [freq > 0 且 report_start > 0] [freq == 0] mutex_unlock(释放互斥锁) 释放成功 返回ESP_OK 返回ESP_ERR_INVALID_ARG alt [句柄有效] [句柄无效] 应用程序 vol_monitor_set_report_freq vol_monitor_ctx_t 互斥锁

这个函数允许动态调整电压报告的频率。当频率设置为0时,将禁用定期报告功能。对于正在运行的报告,函数会重置计数器并更新报告启动标志,使新的频率设置立即生效。

事件处理与报告控制机制

电压监控模块的事件处理与报告控制机制是紧密相关的。事件处理提供了应用程序接收电池状态通知的接口,而报告控制则允许应用程序精确控制何时以及如何接收这些通知。

事件触发流程

下面的图表展示了电压事件的触发流程:

周期性触发
读取电压
返回电压值
判断条件
判断阈值
是且未报告
否或已报告
判断阈值
是且未报告
否或已报告
回调通知
回调通知
回调通知
定时器
电压检查函数
用户电压读取函数
是否满足报告条件?
触发定期报告事件
不报告
电压 <= 低电量阈值?
触发低电量事件
不触发
电压 >= 满电量阈值?
触发满电量事件
不触发
应用程序

报告控制状态机

电压报告控制可以看作一个简单的状态机:

vol_monitor_create
默认状态
vol_monitor_start_freq_report
vol_monitor_stop_freq_report
vol_monitor_set_report_freq(freq > 0)
vol_monitor_set_report_freq(freq = 0)
vol_monitor_set_report_freq
vol_monitor_destroy
vol_monitor_destroy
vol_monitor_destroy
初始化
未启动报告
定期报告中

事件与报告控制函数汇总

事件处理

函数名功能描述
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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

omnibots

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值