BTB Check 模块分析
1. 模块定位与核心价值
btb_check 是华为充电管理系统中的 BTB(Battery To Board,电池到主板)连接器异常监测模块,用于监测电池与主板之间连接器的电压和温度,及时发现接触不良等硬件故障。
核心价值:
🔌 连接器监测:实时监测 BTB 连接器的电压和温度
🛡️ 双路检测:支持主电池和辅助电池双 BTB 检测
📊 差异检测:检测双电池 BTB 之间的电压/温度差异
⚠️ 故障预警:及时发现接触不良、虚接等硬件问题
2. 系统架构
2.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ 调用层 (直充/充电模块) │
└──────────────────────┬──────────────────────────────────────┘
│ API
┌────────────┴────────────┐
│ │
▼ ▼
btb_ck_get_result() btb_ck_get_result_now()
(获取检测结果) (立即检测并返回)
│ │
└────────────┬────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ btb_check.c (核心逻辑) │
├─────────────────────────────────────────────────────────────┤
│ 监控工作队列 (充电启动后 30ms) │
│ ├─ 电压检测工作 (volt_ck_work) │
│ │ • 读取主 BTB 电压 │
│ │ • 读取辅助 BTB 电压(如果配置) │
│ │ • 检查单路阈值 (min_th ~ max_th) │
│ │ • 检查双路差异 (diff_th) │
│ │ │
│ └─ 温度检测工作 (temp_ck_work) │
│ • 读取主 BTB 温度 │
│ • 读取辅助 BTB 温度(如果配置) │
│ • 检查单路阈值 (min_th ~ max_th) │
│ • 检查双路差异 (diff_th) │
└──────────────────────┬──────────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ DC Manager │ │ Battery Temp │ │ Sysfs Node │
│ (电压读取) │ │ (温度读取) │ │ (结果查询) │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ dcm_get_ic_ │ │ bat_temp_get │ │ volt_result │
│ vbtb() │ │ _rt_temp() │ │ temp_result │
└──────────────┘ └──────────────┘ └──────────────┘
2.2 BTB 连接器原理
BTB(Battery To Board): 电池与主板之间的连接器,承载充放电大电流
电池包 ──[BTB 连接器]── 主板充电电路
│
├─ VBAT 正极触点
├─ GND 负极触点
└─ 温度检测触点
故障模式:
• 接触不良 → 电阻增大 → 压降增大 → 温度升高
• 松动虚接 → 间歇性断开 → 电压异常
• 腐蚀氧化 → 阻抗增加 → 发热
双电池 BTB:
┌──────────────────────────────────────┐
│ 主板 │
└────┬────────────────────┬────────────┘
│ 主 BTB │ 辅助 BTB
▼ ▼
┌──────────┐ ┌──────────┐
│ 主电池 │ │ 辅助电池 │
│ (3000mAh) │ │ (2000mAh) │
└──────────┘ └──────────┘
要求:两路 BTB 电压/温度差异 < 阈值
3. 核心数据结构
3.1 检测参数结构
struct btb_ck_para {
int enable;
int is_multi_btb;
int min_th;
int max_th;
int diff_th;
int times;
int dmd_no;
};
3.2 设备结构
struct btb_ck_dev {
struct device *dev;
struct notifier_block nb;
struct delayed_work volt_ck_work;
struct delayed_work temp_ck_work;
struct btb_ck_para volt_ck_para;
struct btb_ck_para temp_ck_para;
unsigned int volt_ck_result;
unsigned int temp_ck_result;
};
3.3 检测结果标志
#define MAIN_BAT_BTB_ERR BIT(0)
#define AUX_BAT_BTB_ERR BIT(1)
#define BTB_BAT_DIFF_ERR BIT(2)
result = 0;
result = MAIN_BAT_BTB_ERR;
result = AUX_BAT_BTB_ERR;
result = BTB_BAT_DIFF_ERR;
result = 0x07;
3.4 检测类型
enum btb_ck_type {
BTB_VOLT_CHECK,
BTB_TEMP_CHECK,
};
4. 核心流程实现
4.1 完整检测流程
┌─────────────────────────────────────────────────────────────┐
│ 1. 充电启动事件 │
│ POWER_NE_CHARGING_START → btb_ck_start() │
└────────────────────┬────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 调度检测工作队列 │
│ 延迟 30ms → schedule_delayed_work(volt_ck_work) │
│ 延迟 30ms → schedule_delayed_work(temp_ck_work) │
└────────────────────┬────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 电压检测 (btb_ck_volt_work) │
│ ① 读取主 BTB 电压 (dcm_get_ic_vbtb) │
│ ② 检查主 BTB: min_th ≤ vbtb ≤ max_th │
│ ③ 如果双路:读取辅助 BTB 电压 │
│ ④ 检查辅助 BTB: min_th ≤ vbtb ≤ max_th │
│ ⑤ 检查差异: |main - aux| ≤ diff_th │
│ ⑥ 多次采样(配置的次数),间隔 30ms │
└────────────────────┬────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 温度检测 (btb_ck_temp_work) │
│ ① 读取主 BTB 温度 (bat_temp_get_rt_temperature) │
│ ② 检查主 BTB: min_th ≤ temp ≤ max_th │
│ ③ 如果双路:读取辅助 BTB 温度 │
│ ④ 检查辅助 BTB: min_th ≤ temp ≤ max_th │
│ ⑤ 检查差异: |main - aux| ≤ diff_th │
│ ⑥ 多次采样(配置的次数),间隔 30ms │
└────────────────────┬────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. 结果存储 │
│ volt_ck_result = 检测结果位掩码 │
│ temp_ck_result = 检测结果位掩码 │
└────────────────────┬────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 6. 上层查询结果 │
│ btb_ck_get_result(BTB_VOLT_CHECK) → volt_ck_result │
│ btb_ck_get_result(BTB_TEMP_CHECK) → temp_ck_result │
└─────────────────────────────────────────────────────────────┘
4.2 电压检测详解
static void btb_ck_bat_volt(struct btb_ck_para *data, unsigned int *result)
{
int main_btb;
int aux_btb;
int btb_diff;
if (data->enable == 0)
return;
main_btb = dcm_get_ic_vbtb(SC_MODE, CHARGE_IC_MAIN);
if ((main_btb < 0) ||
(main_btb > data->max_th) ||
(main_btb < data->min_th))
*result |= MAIN_BAT_BTB_ERR;
hwlog_info("main btb voltage=%dmV\n", main_btb);
if (data->is_multi_btb) {
aux_btb = dcm_get_ic_vbtb(SC_MODE, CHARGE_IC_AUX);
btb_diff = main_btb - aux_btb;
btb_diff = btb_diff > 0 ? btb_diff : -btb_diff;
if ((aux_btb < 0) ||
(aux_btb > data->max_th) ||
(aux_btb < data->min_th))
*result |= AUX_BAT_BTB_ERR;
if (btb_diff > data->diff_th)
*result |= BTB_BAT_DIFF_ERR;
hwlog_info("aux btb voltage=%dmV, btb_diff=%dmV\n",
aux_btb, btb_diff);
}
}
电压检测逻辑:
| 检查项 | 条件 | 错误标志 |
|---|
| 主 BTB 范围 | main_btb < min_th 或 > max_th | MAIN_BAT_BTB_ERR |
| 辅助 BTB 范围 | aux_btb < min_th 或 > max_th | AUX_BAT_BTB_ERR |
| 双路差异 | |main - aux| > diff_th | BTB_BAT_DIFF_ERR |
多次采样机制:
static void btb_ck_bat_volt_by_multi_times(struct btb_ck_para *data,
unsigned int *result)
{
int i;
for (i = 0; i < data->times; i++) {
btb_ck_bat_volt(data, result);
if (*result)
return;
usleep_range(30000, 31000);
}
}
采样策略:
配置采样次数(如 3 次)
每次间隔 30ms(ADC 采样周期)
快速失败:任意一次异常立即返回
全部正常:所有次数都通过才认为正常
4.3 温度检测详解
static void btb_ck_bat_temp(struct btb_ck_para *data, unsigned int *result)
{
int main_btb = 0;
int aux_btb = 0;
int btb_diff;
int i;
int ret;
for (i = 0; i < data->times; i++) {
ret = bat_temp_get_rt_temperature(BTB_TEMP_0, &main_btb);
if ((ret < 0) ||
(main_btb > data->max_th) ||
(main_btb < data->min_th))
*result |= MAIN_BAT_BTB_ERR;
hwlog_info("main btb temp=%d\n", main_btb);
if (data->is_multi_btb) {
ret = bat_temp_get_rt_temperature(BTB_TEMP_1, &aux_btb);
if ((ret < 0) ||
(aux_btb > data->max_th) ||
(aux_btb < data->min_th))
*result |= AUX_BAT_BTB_ERR;
btb_diff = main_btb - aux_btb;
btb_diff = btb_diff > 0 ? btb_diff : -btb_diff;
if (btb_diff > data->diff_th)
*result |= BTB_BAT_DIFF_ERR;
hwlog_info("aux btb temp=%d, btb_diff=%d\n",
aux_btb, btb_diff);
}
if (*result)
return;
usleep_range(30000, 31000);
}
}
温度传感器位置:
电池包内部:
┌─────────────────────────────────┐
│ [BTB 连接器] │
│ ├─ 正极触点 │
│ ├─ 负极触点 │
│ └─ 温度传感器 (BTB_TEMP_0) │
│ │
│ [辅助 BTB 连接器](如果有) │
│ ├─ 正极触点 │
│ ├─ 负极触点 │
│ └─ 温度传感器 (BTB_TEMP_1) │
└─────────────────────────────────┘
4.4 立即检测接口
void btb_ck_get_result_now(int type, unsigned int *result)
{
struct btb_ck_dev *l_dev = btb_ck_get_dev();
if (!l_dev || !result)
return;
switch (type) {
case BTB_VOLT_CHECK:
btb_ck_bat_volt(&l_dev->volt_ck_para, result);
break;
case BTB_TEMP_CHECK:
btb_ck_bat_temp(&l_dev->temp_ck_para, result);
break;
default:
break;
}
}
用途: 直充模块或其他模块需要立即获取 BTB 状态时调用
5. 事件通知处理
5.1 充电事件
static int btb_ck_event_call(struct notifier_block *nb,
unsigned long event, void *data)
{
struct btb_ck_dev *l_dev = btb_ck_get_dev();
switch (event) {
case POWER_NE_CHARGING_STOP:
btb_ck_stop(l_dev);
break;
case POWER_NE_CHARGING_START:
btb_ck_start(l_dev);
break;
}
return NOTIFY_OK;
}
5.2 启动/停止检测
static void btb_ck_start(struct btb_ck_dev *l_dev)
{
cancel_delayed_work(&l_dev->volt_ck_work);
cancel_delayed_work(&l_dev->temp_ck_work);
schedule_delayed_work(&l_dev->volt_ck_work,
msecs_to_jiffies(BTB_CK_WORK_DELAY_TIME));
schedule_delayed_work(&l_dev->temp_ck_work,
msecs_to_jiffies(BTB_CK_WORK_DELAY_TIME));
}
static void btb_ck_stop(struct btb_ck_dev *l_dev)
{
cancel_delayed_work(&l_dev->volt_ck_work);
cancel_delayed_work(&l_dev->temp_ck_work);
}
时序图:
充电器插入
│
▼
POWER_NE_CHARGING_START
│
├─────────► volt_ck_work (30ms 后)
│ │
│ ├─ 采样 1 (0ms)
│ ├─ 采样 2 (30ms)
│ └─ 采样 3 (60ms)
│
└─────────► temp_ck_work (30ms 后)
│
├─ 采样 1 (0ms)
├─ 采样 2 (30ms)
└─ 采样 3 (60ms)
6. Sysfs 接口
6.1 接口列表
/sys/class/hw_power/btb_ck/
├── volt_result
└── temp_result
6.2 接口详解
6.2.1 volt_result(电压检测结果)
读操作:
cat /sys/class/hw_power/btb_ck/volt_result
返回值:
0 - 正常
1 (0x01) - 主 BTB 电压异常
2 (0x02) - 辅助 BTB 电压异常
4 (0x04) - 双 BTB 电压差异过大
7 (0x07) - 所有异常
6.2.2 temp_result(温度检测结果)
读操作:
cat /sys/class/hw_power/btb_ck/temp_result
返回值: 同 volt_result
6.3 使用示例
检查脚本:
#!/bin/bash
volt_result=$(cat /sys/class/hw_power/btb_ck/volt_result)
temp_result=$(cat /sys/class/hw_power/btb_ck/temp_result)
parse_result() {
local result=$1
local type=$2
if [ $result -eq 0 ]; then
echo "$type: PASS"
return 0
fi
echo "$type: FAIL"
[ $((result & 1)) -ne 0 ] && echo " - 主 BTB 异常"
[ $((result & 2)) -ne 0 ] && echo " - 辅助 BTB 异常"
[ $((result & 4)) -ne 0 ] && echo " - 双路差异过大"
return 1
}
parse_result $volt_result "电压检测"
parse_result $temp_result "温度检测"
7. 典型应用场景
7.1 直充启动前检测
场景: 直充模块在启动大电流充电前检查 BTB 状态
int direct_charge_check_btb(void)
{
unsigned int volt_result = 0;
unsigned int temp_result = 0;
btb_ck_get_result_now(BTB_VOLT_CHECK, &volt_result);
btb_ck_get_result_now(BTB_TEMP_CHECK, &temp_result);
if (volt_result != 0) {
hwlog_err("btb voltage check fail: 0x%x\n", volt_result);
return -EINVAL;
}
if (temp_result != 0) {
hwlog_err("btb temp check fail: 0x%x\n", temp_result);
return -EINVAL;
}
return 0;
}
7.2 充电过程监测
场景: 充电过程中周期性检测 BTB 状态
POWER_NE_CHARGING_START → btb_ck_start()
volt_ck_work:
main_btb = dcm_get_ic_vbtb(MAIN) = 4150mV ✓
aux_btb = dcm_get_ic_vbtb(AUX) = 4148mV ✓
diff = |4150 - 4148| = 2mV < 50mV ✓
result = 0 (正常)
temp_ck_work:
main_temp = bat_temp_get(BTB_TEMP_0) = 25℃ ✓
aux_temp = bat_temp_get(BTB_TEMP_1) = 26℃ ✓
diff = |25 - 26| = 1℃ < 5℃ ✓
result = 0 (正常)
7.3 BTB 接触不良检测
场景: BTB 松动导致电压异常
main_btb = 4150mV ✓
aux_btb = 3800mV ✗ (低于 min_th=4000mV)
result = AUX_BAT_BTB_ERR (0x02)
[btb_check] main btb voltage=4150mV
[btb_check] aux btb voltage=3800mV, btb_diff=350mV
[btb_check] btb check type is 0, result=2
btb_ck_get_result(BTB_VOLT_CHECK) = 0x02
→ 禁止启动直充,避免大电流损坏连接器
7.4 双电池不均衡检测
场景: 双电池 BTB 差异过大
main_btb = 4200mV ✓
aux_btb = 4100mV ✓
diff = |4200 - 4100| = 100mV > diff_th=50mV ✗
result = BTB_BAT_DIFF_ERR (0x04)
8. DTS 配置
8.1 配置示例
btb_check {
compatible = "huawei,btb_check";
status = "ok";
/* 电压检测参数 */
/* enable, is_multi_btb, min_th, max_th, diff_th, times, dmd_no */
vol_check_para = <1>, /* 使能电压检测 */
<1>, /* 双 BTB 配置 */
<4000>, /* 最小电压 4000mV */
<4500>, /* 最大电压 4500mV */
<50>, /* 差异阈值 50mV */
<3>, /* 采样 3 次 */
<920000>; /* DMD 编号 */
/* 温度检测参数 */
/* enable, is_multi_btb, min_th, max_th, diff_th, times, dmd_no */
temp_check_para = <1>, /* 使能温度检测 */
<1>, /* 双 BTB 配置 */
<10>, /* 最小温度 10℃ */
<60>, /* 最大温度 60℃ */
<5>, /* 差异阈值 5℃ */
<3>, /* 采样 3 次 */
<920001>; /* DMD 编号 */
};
8.2 参数说明
| 参数 | 类型 | 说明 | 典型值 |
|---|
| enable | int | 是否使能检测 | 1 (使能) |
| is_multi_btb | int | 是否双 BTB | 0 (单路) / 1 (双路) |
| min_th | int | 最小阈值 | 4000mV / 10℃ |
| max_th | int | 最大阈值 | 4500mV / 60℃ |
| diff_th | int | 差异阈值 | 50mV / 5℃ |
| times | int | 采样次数 | 3 次 |
| dmd_no | int | DMD 编号 | 920000 |
8.3 阈值调优建议
电压阈值:
| 参数 | 推荐值 | 调优方向 | 说明 |
|---|
| min_th | 4000mV | 根据电池额定电压调整 | 过低可能遗漏故障 |
| max_th | 4500mV | 根据充电最高电压调整 | 过高可能误判 |
| diff_th | 50mV | 根据双电池配置调整 | 过小容易误触发 |
温度阈值:
| 参数 | 推荐值 | 调优方向 | 说明 |
|---|
| min_th | 10℃ | 根据工作环境调整 | 过低可能在低温环境误判 |
| max_th | 60℃ | 根据安全规范调整 | 过高存在安全隐患 |
| diff_th | 5℃ | 根据散热设计调整 | 过小容易误触发 |
9. 调试方法
9.1 日志分析
使能动态日志:
echo 'file btb_check.c +p' > /sys/kernel/debug/dynamic_debug/control
关键日志:
[btb_check] main btb voltage=4150mV
[btb_check] aux btb voltage=4148mV, btb_diff=2mV
[btb_check] btb check type is 0, result=0
[btb_check] main btb temp=25
[btb_check] aux btb temp=26, btb_diff=1
[btb_check] btb check type is 1, result=0
[btb_check] main btb voltage=4150mV
[btb_check] aux btb voltage=3800mV, btb_diff=350mV
[btb_check] btb check type is 0, result=2 ← AUX_BAT_BTB_ERR
9.2 Sysfs 调试
cat /sys/class/hw_power/btb_ck/volt_result
cat /sys/class/hw_power/btb_ck/temp_result
result=$(cat /sys/class/hw_power/btb_ck/volt_result)
echo "Result: $result"
[ $((result & 1)) -ne 0 ] && echo "主 BTB 异常"
[ $((result & 2)) -ne 0 ] && echo "辅助 BTB 异常"
[ $((result & 4)) -ne 0 ] && echo "差异过大"
9.3 故障诊断流程
问题:BTB 检测异常
├─ 1. 检查配置是否使能
│ └─ DTS 中 enable=1
│
├─ 2. 查看检测结果
│ └─ cat /sys/class/hw_power/btb_ck/volt_result
│
├─ 3. 分析具体异常
│ ├─ bit0=1: 主 BTB 电压异常
│ │ └─ 检查主电池连接器是否松动
│ ├─ bit1=1: 辅助 BTB 电压异常
│ │ └─ 检查辅助电池连接器是否松动
│ └─ bit2=1: 双路差异过大
│ └─ 检查双电池是否容量不匹配
│
├─ 4. 检查硬件
│ ├─ BTB 连接器是否松动
│ ├─ 触点是否氧化
│ └─ 弹片是否变形
│
└─ 5. 调整阈值
└─ 根据实际测量值调整 DTS 参数
10. 设计亮点
10.1 快速失败策略
问题: 多次采样可能延长检测时间
解决方案: 任意一次异常立即返回
for (i = 0; i < data->times; i++) {
btb_ck_bat_volt(data, result);
if (*result)
return;
usleep_range(30000, 31000);
}
优点:
✅ 快速发现故障
✅ 避免延迟直充启动
✅ 减少无效采样
10.2 双路差异检测
问题: 双电池系统单路检测不足
解决方案: 增加差异检测
btb_diff = main_btb - aux_btb;
btb_diff = btb_diff > 0 ? btb_diff : -btb_diff;
if (btb_diff > data->diff_th)
*result |= BTB_BAT_DIFF_ERR;
优点:
✅ 发现单侧接触不良
✅ 检测电池不均衡
✅ 预防充电倾斜
10.3 立即检测接口
问题: 某些场景需要实时获取 BTB 状态
解决方案: 提供同步检测接口
void btb_ck_get_result_now(int type, unsigned int *result);
用途:
10.4 延迟启动检测
问题: 充电启动瞬间电压/温度不稳定
解决方案: 延迟 30ms 后检测
schedule_delayed_work(&l_dev->volt_ck_work,
msecs_to_jiffies(BTB_CK_WORK_DELAY_TIME));
原因:
充电器握手需要时间
电压需要稳定
ADC 需要采样周期
11. 总结
btb_check 模块是华为充电管理系统中的 BTB 连接器健康监测组件,通过以下设计实现了可靠的故障检测:
核心特性:
✅ 双维度检测:电压 + 温度双重监测
✅ 双路支持:主电池 + 辅助电池独立检测
✅ 差异检测:双路 BTB 差异监测,发现不均衡
✅ 快速失败:任意一次异常立即返回
✅ 多次采样:提高检测可靠性
应用价值:
典型应用:
⚡ 直充启动前检查 BTB 连接器状态
🔋 充电过程中监测 BTB 温度
📱 双电池手机不均衡检测
🏭 产线 BTB 连接器测试
该模块充分体现了 预防性检测 和 多重保护 的设计思想,是大电流充电场景下硬件安全监测的重要组件。